*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
+ * http://www.gnu.org/licenses/gpl-2.0.html
*
* GPL HEADER END
*/
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2011, 2014, Intel Corporation.
+ * Copyright (c) 2011, 2017, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
#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))
+/* mc_gc_task values */
+/** no GC thread to be started **/
+#define MDD_CHLG_GC_NONE NULL
+/** a GC thread need to be started **/
+#define MDD_CHLG_GC_NEED (struct task_struct *)(-1)
+/** a GC thread will be started now **/
+#define MDD_CHLG_GC_START (struct task_struct *)(-2)
+/** else the started task_struct address when running **/
+
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;
+ int mc_users; /* registered users number */
+ struct task_struct *mc_gc_task;
+ time64_t mc_gc_time; /* last GC check or run time */
+ unsigned int mc_deniednext; /* interval for recording denied
+ * accesses
+ */
};
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 long mdd_atime_diff;
+ unsigned int mdd_changelog_gc;
+ time64_t mdd_changelog_max_idle_time;
+ unsigned long mdd_changelog_max_idle_indexes;
+ time64_t mdd_changelog_min_gc_interval;
+ unsigned int mdd_changelog_min_free_cat_entries;
+ time64_t mdd_atime_diff;
struct mdd_object *mdd_dot_lustre;
struct mdd_dot_lustre_objs mdd_dot_lustre_objs;
unsigned int mdd_sync_permission;
int mdd_connects;
struct local_oid_storage *mdd_los;
- struct mdd_generic_thread mdd_orph_cleanup_thread;
+ struct mdd_generic_thread mdd_orphan_cleanup_thread;
};
enum mod_flags {
/* 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 list_head mod_users; /**< unique user opens */
};
struct mdd_thread_info {
* then mti_ent::lde_name will be mti_key. */
struct lu_dirent mti_ent;
char mti_key[NAME_MAX + 16];
+ char mti_name[NAME_MAX + 1];
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 lmv_user_md mti_lmu;
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;
+ union lmv_mds_md mti_lmv;
};
-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,
struct lu_attr *la);
int mdd_attr_get(const struct lu_env *env, struct md_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_write_locked(const struct lu_env *env, struct mdd_object *obj);
/* mdd_dir.c */
-int mdd_is_subdir(const struct lu_env *env, struct md_object *mo,
- const struct lu_fid *fid, struct lu_fid *sfid);
int mdd_may_create(const struct lu_env *env, struct mdd_object *pobj,
const struct lu_attr *pattr, struct mdd_object *cobj,
bool check_perm);
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,
struct thandle *handle,
struct linkea_data *ldata,
int first, int check);
+int mdd_dir_layout_shrink(const struct lu_env *env,
+ struct md_object *md_obj,
+ const struct lu_buf *lmu_buf);
struct mdd_thread_info *mdd_env_info(const struct lu_env *env);
const void *area, ssize_t len);
int mdd_orphan_cleanup(const struct lu_env *env, struct mdd_device *d);
-int __mdd_orphan_add(const struct lu_env *, struct mdd_object *,
- struct thandle *);
-int __mdd_orphan_del(const struct lu_env *, struct mdd_object *,
- struct thandle *);
-int orph_index_init(const struct lu_env *env, struct mdd_device *mdd);
-void orph_index_fini(const struct lu_env *env, struct mdd_device *mdd);
-int orph_declare_index_insert(const struct lu_env *, struct mdd_object *,
- umode_t mode, struct thandle *);
-int orph_declare_index_delete(const struct lu_env *, struct mdd_object *,
- struct thandle *);
+int mdd_orphan_insert(const struct lu_env *env, struct mdd_object *obj,
+ struct thandle *thandle);
+int mdd_orphan_delete(const struct lu_env *env, struct mdd_object *obj,
+ struct thandle *thandle);
+int mdd_orphan_index_init(const struct lu_env *env, struct mdd_device *mdd);
+void mdd_orphan_index_fini(const struct lu_env *env, struct mdd_device *mdd);
+int mdd_orphan_declare_insert(const struct lu_env *env, struct mdd_object *obj,
+ umode_t mode, struct thandle *thandle);
+int mdd_orphan_declare_delete(const struct lu_env *env, struct mdd_object *obj,
+ struct thandle *thandle);
/* mdd_lproc.c */
int mdd_procfs_init(struct mdd_device *mdd, const char *name);
extern const struct md_object_operations mdd_obj_ops;
int mdd_readlink(const struct lu_env *env, struct md_object *obj,
struct lu_buf *buf);
-int accmode(const struct lu_env *env, const struct lu_attr *la, int flags);
extern struct lu_context_key mdd_thread_key;
extern const struct lu_device_operations mdd_lu_ops;
int mdd_readpage(const struct lu_env *env, struct md_object *obj,
const struct lu_rdpg *rdpg);
int mdd_declare_changelog_store(const struct lu_env *env,
- struct mdd_device *mdd,
- const struct lu_name *tname,
- const struct lu_name *sname,
- struct thandle *handle);
+ struct mdd_device *mdd,
+ enum changelog_rec_type type,
+ const struct lu_name *tname,
+ 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);
+void mdd_changelog_rec_extra_nid(struct changelog_rec *rec,
+ lnet_nid_t nid);
+void mdd_changelog_rec_extra_omode(struct changelog_rec *rec, u32 flags);
+void mdd_changelog_rec_extra_xattr(struct changelog_rec *rec,
+ const char *xattr_name);
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,
- enum changelog_rec_type type, int flags,
+ enum changelog_rec_type type,
+ enum changelog_rec_flags clf_flags,
struct mdd_object *mdd_obj,
struct thandle *handle);
int mdd_changelog_ns_store(const struct lu_env *env, struct mdd_device *mdd,
enum changelog_rec_type type,
- enum changelog_rec_flags crf,
+ enum changelog_rec_flags clf_flags,
struct mdd_object *target,
const struct lu_fid *tpfid,
const struct lu_fid *sfid,
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,
struct thandle *handle,
const struct md_op_spec *spec,
struct dt_allocation_hint *hint);
-int mdd_get_lov_ea(const struct lu_env *env, struct mdd_object *obj,
- struct lu_buf *lmm_buf);
+int mdd_stripe_get(const struct lu_env *env, struct mdd_object *obj,
+ struct lu_buf *lmm_buf, const char *name);
+int mdd_changelog_data_store_xattr(const struct lu_env *env,
+ struct mdd_device *mdd,
+ enum changelog_rec_type type,
+ enum changelog_rec_flags clf_flags,
+ struct mdd_object *mdd_obj,
+ const char *xattr_name,
+ struct thandle *handle);
/* mdd_trans.c */
void mdd_object_make_hint(const struct lu_env *env, struct mdd_object *parent,
__u32 *mode);
int __mdd_permission_internal(const struct lu_env *env, struct mdd_object *obj,
const struct lu_attr *la, int mask, int role);
-int mdd_permission(const struct lu_env *env,
- struct md_object *pobj, struct md_object *cobj,
- struct md_attr *ma, int mask);
+int mdd_permission(const struct lu_env *env, struct md_object *pobj,
+ struct md_object *cobj, struct md_attr *ma, int mask);
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 bool mdd_is_orphan_obj(struct mdd_object *obj)
+{
+ return obj->mod_flags & ORPHAN_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);
}
return dt_destroy(env, next, handle);
}
+static inline bool mdd_changelog_enabled(const struct lu_env *env,
+ struct mdd_device *mdd,
+ enum changelog_rec_type type)
+{
+ const struct lu_ucred *uc;
+
+ if ((mdd->mdd_cl.mc_flags & CLM_ON) &&
+ (mdd->mdd_cl.mc_mask & (1 << type))) {
+ uc = lu_ucred_check(env);
+
+ return uc != NULL ? uc->uc_enable_audit : true;
+ } else {
+ return false;
+ }
+}
+
#endif