#include <lustre_acl.h>
#include <lustre_compat.h>
-#include <lustre_eacl.h>
#include <md_object.h>
#include <dt_object.h>
#include <lustre_lfsck.h>
#define CLM_FINI 0x20000
/** some changelog records purged */
#define CLM_PURGE 0x40000
+/** changelog cleanup done, to prevent double cleanup */
+#define CLM_CLEANUP_DONE 0x80000
#define LLOG_CHANGELOG_HDR_SZ (sizeof(struct llog_changelog_rec) - \
sizeof(struct changelog_rec))
enum mod_flags {
/* The dir object has been unlinked */
- DEAD_OBJ = 1 << 0,
- ORPHAN_OBJ = 1 << 1,
- VOLATILE_OBJ = 1 << 4,
+ DEAD_OBJ = BIT(0),
+ ORPHAN_OBJ = BIT(1),
+ VOLATILE_OBJ = BIT(4),
};
struct mdd_object {
struct list_head mod_users; /**< unique user opens */
};
+#define MTI_KEEP_KEY 0x01
+
struct mdd_thread_info {
struct lu_fid mti_fid;
struct lu_fid mti_fid2; /* used for be & cpu converting */
* then mti_ent::lde_name will be mti_key. */
struct lu_dirent mti_ent;
char mti_key[NAME_MAX + 16];
+ int mti_flags;
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;
- 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 lfsck_req_local mti_lrl;
struct lu_seq_range mti_range;
union lmv_mds_md mti_lmv;
+ struct md_layout_change mti_mlc;
};
int mdd_la_get(const struct lu_env *env, struct mdd_object *obj,
struct lu_fid* fid, struct md_op_spec *spec);
int mdd_links_write(const struct lu_env *env, struct mdd_object *mdd_obj,
struct linkea_data *ldata, struct thandle *handle);
+int mdd_links_read(const struct lu_env *env,
+ struct mdd_object *mdd_obj,
+ struct linkea_data *ldata);
struct lu_buf *mdd_links_get(const struct lu_env *env,
struct mdd_object *mdd_obj);
int mdd_links_rename(const struct lu_env *env,
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 md_layout_change *mlc);
+int mdd_dir_layout_split(const struct lu_env *env, struct md_object *o,
+ struct md_layout_change *mlc);
int mdd_changelog_write_rec(const struct lu_env *env,
struct llog_handle *loghandle,
umode_t mode, struct thandle *thandle);
int mdd_orphan_declare_delete(const struct lu_env *env, struct mdd_object *obj,
struct thandle *thandle);
+int mdd_dir_is_empty(const struct lu_env *env, struct mdd_object *dir);
/* mdd_lproc.c */
int mdd_procfs_init(struct mdd_device *mdd, const char *name);
enum changelog_rec_type type,
enum changelog_rec_flags clf_flags,
struct mdd_object *mdd_obj,
- struct thandle *handle);
+ struct thandle *handle,
+ const struct lu_fid *pfid);
int mdd_changelog_ns_store(const struct lu_env *env, struct mdd_device *mdd,
enum changelog_rec_type type,
enum changelog_rec_flags clf_flags,
int __mdd_fix_mode_acl(const struct lu_env *env, struct lu_buf *buf,
__u32 *mode);
int __mdd_permission_internal(const struct lu_env *env, struct mdd_object *obj,
- const struct lu_attr *la, int mask, int role);
+ const struct lu_attr *la, unsigned int may_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);
+ struct md_object *cobj, struct md_attr *ma,
+ unsigned int may_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);
/* mdd_prepare.c */
int mdd_compat_fixes(const struct lu_env *env, struct mdd_device *mdd);
+/* acl.c */
+extern int lustre_posix_acl_permission(struct lu_ucred *mu,
+ const struct lu_attr *la,
+ unsigned int may_mask,
+ posix_acl_xattr_entry *entry,
+ int count);
+extern int lustre_posix_acl_chmod_masq(posix_acl_xattr_entry *entry,
+ __u32 mode, int count);
+extern int lustre_posix_acl_create_masq(posix_acl_xattr_entry *entry,
+ __u32 *pmode, int count);
+extern int lustre_posix_acl_equiv_mode(posix_acl_xattr_entry *entry,
+ mode_t *mode_p, int count);
+
/* inline functions */
static inline int lu_device_is_mdd(struct lu_device *d)
{
static inline struct mdd_device *lu2mdd_dev(struct lu_device *d)
{
- LASSERT(lu_device_is_mdd(d));
- return container_of0(d, struct mdd_device, mdd_md_dev.md_lu_dev);
+ LASSERT(lu_device_is_mdd(d));
+ return container_of_safe(d, struct mdd_device, mdd_md_dev.md_lu_dev);
}
static inline struct lu_device *mdd2lu_dev(struct mdd_device *mdd)
static inline struct mdd_object *lu2mdd_obj(struct lu_object *o)
{
- LASSERT(ergo(o != NULL, lu_device_is_mdd(o->lo_dev)));
- return container_of0(o, struct mdd_object, mod_obj.mo_lu);
+ LASSERT(ergo(o != NULL, lu_device_is_mdd(o->lo_dev)));
+ return container_of_safe(o, struct mdd_object,
+ mod_obj.mo_lu);
}
static inline struct mdd_device *mdo2mdd(struct md_object *mdo)
{
- return lu2mdd_dev(mdo->mo_lu.lo_dev);
+ return lu2mdd_dev(mdo->mo_lu.lo_dev);
}
static inline struct mdd_object *md2mdd_obj(struct md_object *mdo)
{
- return container_of0(mdo, struct mdd_object, mod_obj);
+ return container_of_safe(mdo, struct mdd_object, mod_obj);
}
static inline const
static inline struct dt_object *mdd_object_child(struct mdd_object *obj)
{
- return container_of0(lu_object_next(mdd2lu_obj(obj)),
- struct dt_object, do_lu);
+ return container_of(lu_object_next(mdd2lu_obj(obj)),
+ struct dt_object, do_lu);
}
static inline struct obd_device *mdd2obd_dev(struct mdd_device *mdd)
static inline int mdd_permission_internal(const struct lu_env *env,
struct mdd_object *obj,
- const struct lu_attr *la, int mask)
+ const struct lu_attr *la,
+ unsigned int may_mask)
{
- return __mdd_permission_internal(env, obj, la, mask, -1);
+ return __mdd_permission_internal(env, obj, la, may_mask, -1);
}
static inline int mdd_permission_internal_locked(const struct lu_env *env,
struct mdd_object *obj,
const struct lu_attr *la,
- int mask,
+ unsigned int may_mask,
enum dt_object_role role)
{
- return __mdd_permission_internal(env, obj, la, mask, role);
+ return __mdd_permission_internal(env, obj, la, may_mask, role);
}
/* mdd inline func for calling osd_dt_object ops */
const char *name,
int fl, struct thandle *handle)
{
- struct dt_object *next = mdd_object_child(obj);
- return dt_declare_xattr_set(env, next, buf, name, fl, handle);
+ struct dt_object *next = mdd_object_child(obj);
+ int rc;
+
+ rc = dt_declare_xattr_set(env, next, buf, name, fl, handle);
+ if (rc >= 0 && strcmp(name, LL_XATTR_NAME_ENCRYPTION_CONTEXT) == 0) {
+ struct lu_attr la = { 0 };
+
+ la.la_valid = LA_FLAGS;
+ la.la_flags = LUSTRE_ENCRYPT_FL;
+ rc = dt_declare_attr_set(env, next, &la, handle);
+ }
+ return rc;
}
static inline int mdo_xattr_set(const struct lu_env *env,struct mdd_object *obj,
int fl, struct thandle *handle)
{
struct dt_object *next = mdd_object_child(obj);
+ int rc = 0;
if (!mdd_object_exists(obj))
return -ENOENT;
- return dt_xattr_set(env, next, buf, name, fl, handle);
+ /* If we are about to set the LL_XATTR_NAME_ENCRYPTION_CONTEXT
+ * xattr, it means the file/dir is encrypted. In that case we want
+ * to set the LUSTRE_ENCRYPT_FL flag as well: it will be stored
+ * into the LMA, making it more efficient to recognise we are
+ * dealing with an encrypted file/dir, as LMA info is cached upon
+ * object init.
+ * However, marking a dir as encrypted is only possible if it is
+ * being created or migrated (LU_XATTR_CREATE flag not set), or
+ * if it is empty.
+ */
+ if ((strcmp(name, LL_XATTR_NAME_ENCRYPTION_CONTEXT) == 0) &&
+ (!S_ISDIR(mdd_object_type(obj)) ||
+ !(fl & LU_XATTR_CREATE) ||
+ (rc = mdd_dir_is_empty(env, obj)) == 0)) {
+ struct lu_attr la = { 0 };
+
+ la.la_valid = LA_FLAGS;
+ la.la_flags = LUSTRE_ENCRYPT_FL;
+ rc = dt_attr_set(env, next, &la, handle);
+ }
+ if (rc >= 0)
+ rc = dt_xattr_set(env, next, buf, name, fl, handle);
+
+ return rc;
}
static inline int mdo_declare_xattr_del(const struct lu_env *env,
const struct lu_ucred *uc;
if ((mdd->mdd_cl.mc_flags & CLM_ON) &&
- (mdd->mdd_cl.mc_mask & (1 << type))) {
+ (mdd->mdd_cl.mc_mask & BIT(type))) {
uc = lu_ucred_check(env);
return uc != NULL ? uc->uc_enable_audit : true;