#include <lustre_log.h>
#include <lustre_linkea.h>
+/* ChangeLog params for automatic purge mechanism */
+/* max time allowed for a user to stay idle in seconds */
+#define CHLOG_MAX_IDLE_TIME 2592000 /* = 30 days */
+/* max gap allowed for a user to stay idle in number of ChangeLog records
+ * this is an evaluation, assuming that chunk-size is LLOG_MIN_CHUNK_SIZE, of
+ * the indexes gap for half full changelogs */
+#define CHLOG_MAX_IDLE_INDEXES (((LLOG_MIN_CHUNK_SIZE - \
+ offsetof(struct llog_log_hdr, \
+ llh_bitmap[0]) - \
+ sizeof(struct llog_rec_tail)) * 4) * \
+ ((LLOG_MIN_CHUNK_SIZE - \
+ offsetof(struct llog_log_hdr, \
+ llh_bitmap[0]) - \
+ sizeof(struct llog_rec_tail)) * 8))
+/* min time in seconds between two gc thread runs if none already started */
+#define CHLOG_MIN_GC_INTERVAL 3600
+/* minimum number of free ChangeLog catalog entries (ie, between cur and
+ * last indexes) before starting garbage collect */
+#define CHLOG_MIN_FREE_CAT_ENTRIES 2
+
/* Changelog flags */
/** changelog is recording */
#define CLM_ON 0x00001
/** some changelog records purged */
#define CLM_PURGE 0x40000
+#define LLOG_CHANGELOG_HDR_SZ (sizeof(struct llog_changelog_rec) - \
+ sizeof(struct changelog_rec))
+
struct mdd_changelog {
spinlock_t mc_lock; /* for index */
int mc_flags;
int mc_mask;
__u64 mc_index;
- __u64 mc_starttime;
+ ktime_t mc_starttime;
spinlock_t mc_user_lock;
int mc_lastuser;
+ struct task_struct *mc_gc_task;
+ time64_t mc_gc_time;
};
static inline __u64 cl_time(void)
struct dt_object *mdd_orphans; /* PENDING directory */
struct proc_dir_entry *mdd_proc_entry;
struct mdd_changelog mdd_cl;
+ unsigned int mdd_changelog_gc;
+ unsigned int mdd_changelog_max_idle_time;
+ unsigned long mdd_changelog_max_idle_indexes;
+ unsigned int mdd_changelog_min_gc_interval;
+ unsigned int mdd_changelog_min_free_cat_entries;
unsigned long mdd_atime_diff;
struct mdd_object *mdd_dot_lustre;
struct mdd_dot_lustre_objs mdd_dot_lustre_objs;
/* The dir object has been unlinked */
DEAD_OBJ = 1 << 0,
ORPHAN_OBJ = 1 << 1,
+ VOLATILE_OBJ = 1 << 4,
};
struct mdd_object {
- struct md_object mod_obj;
- /* open count */
- __u32 mod_count;
- __u32 mod_valid;
- __u64 mod_cltime;
- unsigned long mod_flags;
+ struct md_object mod_obj;
+ /* open count */
+ u32 mod_count;
+ u32 mod_valid;
+ ktime_t mod_cltime;
+ unsigned long mod_flags;
};
struct mdd_thread_info {
struct lu_buf mti_buf[4];
struct lu_buf mti_big_buf; /* biggish persistent buf */
struct lu_buf mti_link_buf; /* buf for link ea */
+ struct lu_buf mti_xattr_buf;
struct obdo mti_oa;
- char mti_xattr_buf[LUSTRE_POSIX_ACL_MAX_SIZE];
struct dt_allocation_hint mti_hint;
struct dt_object_format mti_dof;
struct linkea_data mti_link_data;
struct md_op_spec mti_spec;
struct dt_insert_rec mti_dt_rec;
- struct lfsck_request mti_lr;
+ struct lfsck_req_local mti_lrl;
struct lu_seq_range mti_range;
};
-enum mdd_links_add_overflow {
- MLAO_IGNORE = false,
- MLAO_CHECK = true,
-};
-
extern const char orph_index_name[];
int mdd_la_get(const struct lu_env *env, struct mdd_object *obj,
int mdd_update_time(const struct lu_env *env, struct mdd_object *obj,
const struct lu_attr *oattr, struct lu_attr *attr,
struct thandle *handle);
-int mdd_object_create_internal(const struct lu_env *env, struct mdd_object *p,
+int mdd_create_object_internal(const struct lu_env *env, struct mdd_object *p,
struct mdd_object *c, struct lu_attr *attr,
struct thandle *handle,
const struct md_op_spec *spec,
int mdd_lookup(const struct lu_env *env,
struct md_object *pobj, const struct lu_name *lname,
struct lu_fid* fid, struct md_op_spec *spec);
-int mdd_links_read(const struct lu_env *env, struct mdd_object *mdd_obj,
- struct linkea_data *ldata);
-int mdd_declare_links_add(const struct lu_env *env, struct mdd_object *mdd_obj,
- struct thandle *handle, struct linkea_data *ldata,
- enum mdd_links_add_overflow overflow);
int mdd_links_write(const struct lu_env *env, struct mdd_object *mdd_obj,
struct linkea_data *ldata, struct thandle *handle);
struct lu_buf *mdd_links_get(const struct lu_env *env,
const struct lu_name *sname,
struct thandle *handle);
void mdd_changelog_rec_ext_jobid(struct changelog_rec *rec, const char *jobid);
+void mdd_changelog_rec_ext_extra_flags(struct changelog_rec *rec, __u64 eflags);
+void mdd_changelog_rec_extra_uidgid(struct changelog_rec *rec,
+ __u64 uid, __u64 gid);
int mdd_changelog_store(const struct lu_env *env, struct mdd_device *mdd,
struct llog_changelog_rec *rec, struct thandle *th);
int mdd_changelog_data_store(const struct lu_env *env, struct mdd_device *mdd,
const struct lu_name *sname,
struct thandle *handle);
int mdd_invalidate(const struct lu_env *env, struct md_object *obj);
-int mdd_declare_object_create_internal(const struct lu_env *env,
+int mdd_declare_create_object_internal(const struct lu_env *env,
struct mdd_object *p,
struct mdd_object *c,
struct lu_attr *attr,
int mdd_generic_thread_start(struct mdd_generic_thread *thread,
int (*func)(void *), void *data, char *name);
void mdd_generic_thread_stop(struct mdd_generic_thread *thread);
+int mdd_changelog_user_purge(const struct lu_env *env, struct mdd_device *mdd,
+ __u32 id);
/* mdd_prepare.c */
int mdd_compat_fixes(const struct lu_env *env, struct mdd_device *mdd);
return obj && obj->mod_flags & DEAD_OBJ;
}
+static inline bool mdd_is_volatile_obj(struct mdd_object *obj)
+{
+ return obj->mod_flags & VOLATILE_OBJ;
+}
+
static inline int mdd_object_exists(struct mdd_object *obj)
{
return lu_object_exists(mdd2lu_obj(obj));
return dt_invalidate(env, mdd_object_child(obj));
}
+static inline int
+mdo_declare_layout_change(const struct lu_env *env, struct mdd_object *obj,
+ struct md_layout_change *mlc, struct thandle *handle)
+{
+ return dt_declare_layout_change(env, mdd_object_child(obj),
+ mlc, handle);
+}
+
+static inline int
+mdo_layout_change(const struct lu_env *env, struct mdd_object *obj,
+ struct md_layout_change *mlc, struct thandle *handle)
+{
+ return dt_layout_change(env, mdd_object_child(obj), mlc, handle);
+}
+
static inline
int mdo_declare_index_insert(const struct lu_env *env, struct mdd_object *obj,
const struct lu_fid *fid, __u32 type,
}
static inline int
-mdo_declare_create_obj(const struct lu_env *env, struct mdd_object *o,
- struct lu_attr *attr,
- struct dt_allocation_hint *hint,
- struct dt_object_format *dof,
- struct thandle *handle)
+mdo_declare_create_object(const struct lu_env *env, struct mdd_object *obj,
+ struct lu_attr *attr, struct dt_allocation_hint *hint,
+ struct dt_object_format *dof, struct thandle *handle)
{
- struct dt_object *next = mdd_object_child(o);
+ struct dt_object *next = mdd_object_child(obj);
return dt_declare_create(env, next, attr, hint, dof, handle);
}
static inline int
-mdo_create_obj(const struct lu_env *env, struct mdd_object *o,
- struct lu_attr *attr,
- struct dt_allocation_hint *hint,
- struct dt_object_format *dof,
- struct thandle *handle)
+mdo_create_object(const struct lu_env *env, struct mdd_object *obj,
+ struct lu_attr *attr, struct dt_allocation_hint *hint,
+ struct dt_object_format *dof, struct thandle *handle)
{
- struct dt_object *next = mdd_object_child(o);
+ struct dt_object *next = mdd_object_child(obj);
return dt_create(env, next, attr, hint, dof, handle);
}