From f9659fd87771122d01a4fafb09ba59c4cf0091ab Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Wed, 10 Apr 2013 12:48:11 -0500 Subject: [PATCH] LU-2780 mdd: use a real inode for .lustre/fid Use a real inode .lustre/fid thereby allowing traditional DACs to govern open by fid. Set the default mode of .lustre/fid to 0100/d--x------. Remove the prohibition on setting attributes of .lustre and .lustre/fid in mdt_reint_setattr(). Don't set IMMUTE_OBJ in .lustre/fid's mod_flags and remove the check for IMMUTE_OBJ in mdd_create_data(). Add a check to sanity test_154 to ensure that setattr works on .lustre/fid. Intel-bug-id: INTL-5 Signed-off-by: John L. Hammond Change-Id: I372e9d6bb230e5b078dbf028fdc4348dfa192f93 Reviewed-on: http://review.whamcloud.com/5298 Tested-by: Hudson Reviewed-by: Andreas Dilger Reviewed-by: Mike Pershin Tested-by: Maloo --- lustre/mdd/mdd_device.c | 406 ++++-------------------------------------------- lustre/mdd/mdd_dir.c | 5 - lustre/mdt/mdt_reint.c | 4 - lustre/tests/sanity.sh | 25 ++- 4 files changed, 46 insertions(+), 394 deletions(-) diff --git a/lustre/mdd/mdd_device.c b/lustre/mdd/mdd_device.c index bd1e80a..9633cfd 100644 --- a/lustre/mdd/mdd_device.c +++ b/lustre/mdd/mdd_device.c @@ -538,361 +538,6 @@ int mdd_changelog_write_header(const struct lu_env *env, RETURN(rc); } -static int dot_lustre_mdd_permission(const struct lu_env *env, - struct md_object *pobj, - struct md_object *cobj, - struct md_attr *attr, int mask) -{ - if (mask & ~(MAY_READ | MAY_EXEC)) - return -EPERM; - else - return 0; -} - -static int dot_lustre_mdd_xattr_get(const struct lu_env *env, - struct md_object *obj, struct lu_buf *buf, - const char *name) -{ - return 0; -} - -static int dot_lustre_mdd_xattr_list(const struct lu_env *env, - struct md_object *obj, struct lu_buf *buf) -{ - return 0; -} - -static int dot_lustre_mdd_xattr_set(const struct lu_env *env, - struct md_object *obj, - const struct lu_buf *buf, const char *name, - int fl) -{ - return -EPERM; -} - -static int dot_lustre_mdd_xattr_del(const struct lu_env *env, - struct md_object *obj, - const char *name) -{ - return -EPERM; -} - -static int dot_lustre_mdd_swap_layouts(const struct lu_env *env, - struct md_object *obj1, - struct md_object *obj2, - __u64 flags) -{ - return -EPERM; -} - -static int dot_lustre_mdd_readlink(const struct lu_env *env, - struct md_object *obj, struct lu_buf *buf) -{ - return 0; -} - -static int dot_lustre_mdd_object_create(const struct lu_env *env, - struct md_object *obj, - const struct md_op_spec *spec, - struct md_attr *ma) -{ - return -EPERM; -} - -static int dot_lustre_mdd_ref_add(const struct lu_env *env, - struct md_object *obj, - const struct md_attr *ma) -{ - return -EPERM; -} - -static int dot_lustre_mdd_ref_del(const struct lu_env *env, - struct md_object *obj, - struct md_attr *ma) -{ - return -EPERM; -} - -static int dot_lustre_mdd_open(const struct lu_env *env, struct md_object *obj, - int flags) -{ - struct mdd_object *mdd_obj = md2mdd_obj(obj); - - mdd_write_lock(env, mdd_obj, MOR_TGT_CHILD); - mdd_obj->mod_count++; - mdd_write_unlock(env, mdd_obj); - - return 0; -} - -static int dot_lustre_mdd_close(const struct lu_env *env, struct md_object *obj, - struct md_attr *ma, int mode) -{ - struct mdd_object *mdd_obj = md2mdd_obj(obj); - - mdd_write_lock(env, mdd_obj, MOR_TGT_CHILD); - mdd_obj->mod_count--; - mdd_write_unlock(env, mdd_obj); - - return 0; -} - -static int dot_lustre_mdd_object_sync(const struct lu_env *env, - struct md_object *obj) -{ - return -ENOSYS; -} - -static int dot_file_lock(const struct lu_env *env, struct md_object *obj, - struct lov_mds_md *lmm, struct ldlm_extent *extent, - struct lustre_handle *lockh) -{ - return -ENOSYS; -} - -static int dot_file_unlock(const struct lu_env *env, struct md_object *obj, - struct lov_mds_md *lmm, struct lustre_handle *lockh) -{ - return -ENOSYS; -} - -static struct md_object_operations mdd_dot_lustre_obj_ops = { - .moo_permission = dot_lustre_mdd_permission, - .moo_attr_get = mdd_attr_get, - .moo_attr_set = mdd_attr_set, - .moo_xattr_get = dot_lustre_mdd_xattr_get, - .moo_xattr_list = dot_lustre_mdd_xattr_list, - .moo_xattr_set = dot_lustre_mdd_xattr_set, - .moo_xattr_del = dot_lustre_mdd_xattr_del, - .moo_swap_layouts = dot_lustre_mdd_swap_layouts, - .moo_readpage = mdd_readpage, - .moo_readlink = dot_lustre_mdd_readlink, - .moo_object_create = dot_lustre_mdd_object_create, - .moo_ref_add = dot_lustre_mdd_ref_add, - .moo_ref_del = dot_lustre_mdd_ref_del, - .moo_open = dot_lustre_mdd_open, - .moo_close = dot_lustre_mdd_close, - .moo_capa_get = mdd_capa_get, - .moo_object_sync = dot_lustre_mdd_object_sync, - .moo_file_lock = dot_file_lock, - .moo_file_unlock = dot_file_unlock, -}; - - -static int dot_lustre_mdd_lookup(const struct lu_env *env, struct md_object *p, - const struct lu_name *lname, struct lu_fid *f, - struct md_op_spec *spec) -{ - if (strcmp(lname->ln_name, mdd_obf_dir_name) == 0) { - *f = LU_OBF_FID; - return 0; - } - - return -ENOENT; -} - -static mdl_mode_t dot_lustre_mdd_lock_mode(const struct lu_env *env, - struct md_object *obj, - mdl_mode_t mode) -{ - return MDL_MINMODE; -} - -static int dot_lustre_mdd_create(const struct lu_env *env, - struct md_object *pobj, - const struct lu_name *lname, - struct md_object *child, - struct md_op_spec *spec, - struct md_attr* ma) -{ - return -EPERM; -} - -static int dot_lustre_mdd_create_data(const struct lu_env *env, - struct md_object *p, - struct md_object *o, - const struct md_op_spec *spec, - struct md_attr *ma) -{ - return -EPERM; -} - -static int dot_lustre_mdd_rename(const struct lu_env *env, - struct md_object *src_pobj, - struct md_object *tgt_pobj, - const struct lu_fid *lf, - const struct lu_name *lsname, - struct md_object *tobj, - const struct lu_name *ltname, - struct md_attr *ma) -{ - return -EPERM; -} - -static int dot_lustre_mdd_link(const struct lu_env *env, - struct md_object *tgt_obj, - struct md_object *src_obj, - const struct lu_name *lname, - struct md_attr *ma) -{ - return -EPERM; -} - -static int dot_lustre_mdd_unlink(const struct lu_env *env, - struct md_object *pobj, - struct md_object *cobj, - const struct lu_name *lname, - struct md_attr *ma, int no_name) -{ - return -EPERM; -} - -static int dot_lustre_mdd_name_insert(const struct lu_env *env, - struct md_object *obj, - const struct lu_name *lname, - const struct lu_fid *fid, - const struct md_attr *ma) -{ - return -EPERM; -} - -static int dot_lustre_mdd_name_remove(const struct lu_env *env, - struct md_object *obj, - const struct lu_name *lname, - const struct md_attr *ma) -{ - return -EPERM; -} - -static int dot_lustre_mdd_rename_tgt(const struct lu_env *env, - struct md_object *pobj, - struct md_object *tobj, - const struct lu_fid *fid, - const struct lu_name *lname, - struct md_attr *ma) -{ - return -EPERM; -} - - -static struct md_dir_operations mdd_dot_lustre_dir_ops = { - .mdo_is_subdir = mdd_is_subdir, - .mdo_lookup = dot_lustre_mdd_lookup, - .mdo_lock_mode = dot_lustre_mdd_lock_mode, - .mdo_create = dot_lustre_mdd_create, - .mdo_create_data = dot_lustre_mdd_create_data, - .mdo_rename = dot_lustre_mdd_rename, - .mdo_link = dot_lustre_mdd_link, - .mdo_unlink = dot_lustre_mdd_unlink, - .mdo_name_insert = dot_lustre_mdd_name_insert, - .mdo_name_remove = dot_lustre_mdd_name_remove, - .mdo_rename_tgt = dot_lustre_mdd_rename_tgt, -}; - -static int obf_attr_get(const struct lu_env *env, struct md_object *obj, - struct md_attr *ma) -{ - struct mdd_device *mdd = mdo2mdd(obj); - - /* "fid" is a virtual object and hence does not have any "real" - * attributes. So we reuse attributes of .lustre for "fid" dir */ - return mdd_attr_get(env, &mdd->mdd_dot_lustre->mod_obj, ma); -} - -static int obf_attr_set(const struct lu_env *env, struct md_object *obj, - const struct md_attr *ma) -{ - return -EPERM; -} - -static int obf_xattr_list(const struct lu_env *env, - struct md_object *obj, struct lu_buf *buf) -{ - return 0; -} - -static int obf_xattr_get(const struct lu_env *env, - struct md_object *obj, struct lu_buf *buf, - const char *name) -{ - struct mdd_device *mdd = mdo2mdd(obj); - struct mdd_object *root; - int rc = 0; - - /* - * .lustre returns default striping which is 'stored' - * in the root - */ - if (strcmp(name, XATTR_NAME_LOV) == 0) { - root = mdd_object_find(env, mdd, &mdd->mdd_local_root_fid); - if (IS_ERR(root)) - return PTR_ERR(root); - rc = mdo_xattr_get(env, root, buf, name, - mdd_object_capa(env, md2mdd_obj(obj))); - mdd_object_put(env, root); - } - - return rc; -} - -static int obf_xattr_set(const struct lu_env *env, - struct md_object *obj, - const struct lu_buf *buf, const char *name, - int fl) -{ - return -EPERM; -} - -static int obf_xattr_del(const struct lu_env *env, - struct md_object *obj, - const char *name) -{ - return -EPERM; -} - -static int obf_mdd_open(const struct lu_env *env, struct md_object *obj, - int flags) -{ - struct mdd_object *mdd_obj = md2mdd_obj(obj); - - mdd_write_lock(env, mdd_obj, MOR_TGT_CHILD); - mdd_obj->mod_count++; - mdd_write_unlock(env, mdd_obj); - - return 0; -} - -static int obf_mdd_close(const struct lu_env *env, struct md_object *obj, - struct md_attr *ma, int mode) -{ - struct mdd_object *mdd_obj = md2mdd_obj(obj); - - mdd_write_lock(env, mdd_obj, MOR_TGT_CHILD); - mdd_obj->mod_count--; - mdd_write_unlock(env, mdd_obj); - - return 0; -} - -/** Nothing to list in "fid" directory */ -static int obf_mdd_readpage(const struct lu_env *env, struct md_object *obj, - const struct lu_rdpg *rdpg) -{ - return -EPERM; -} - -static struct md_object_operations mdd_obf_obj_ops = { - .moo_attr_get = obf_attr_get, - .moo_attr_set = obf_attr_set, - .moo_xattr_list = obf_xattr_list, - .moo_xattr_get = obf_xattr_get, - .moo_xattr_set = obf_xattr_set, - .moo_xattr_del = obf_xattr_del, - .moo_open = obf_mdd_open, - .moo_close = obf_mdd_close, - .moo_readpage = obf_mdd_readpage, -}; - /** * Lookup method for "fid" object. Only filenames with correct SEQ:OID format * are valid. We also check if object with passed fid exists or not. @@ -978,27 +623,6 @@ static struct md_dir_operations mdd_obf_dir_ops = { .mdo_unlink = obf_unlink }; -/** - * Create special in-memory "fid" object for open-by-fid. - */ -static int mdd_obf_setup(const struct lu_env *env, struct mdd_device *m) -{ - struct mdd_object *mdd_obf; - - mdd_obf = mdd_object_find(env, m, &LU_OBF_FID); - if (mdd_obf == NULL || IS_ERR(mdd_obf)) - return -ENOENT; - - m->mdd_dot_lustre_objs.mdd_obf = mdd_obf; - mdd_obf->mod_obj.mo_dir_ops = &mdd_obf_dir_ops; - mdd_obf->mod_obj.mo_ops = &mdd_obf_obj_ops; - /* Don't allow objects to be created in "fid" dir */ - mdd_obf->mod_flags |= IMMUTE_OBJ; - - mdd2lu_obj(mdd_obf)->lo_header->loh_attr |= LOHA_EXISTS | S_IFDIR; - return 0; -} - static struct md_object *mdo_locate(const struct lu_env *env, struct md_device *md, const struct lu_fid *fid) @@ -1017,6 +641,34 @@ static struct md_object *mdo_locate(const struct lu_env *env, return mdo; } +/** + * Create special in-memory "fid" object for open-by-fid. + */ +static int mdd_obf_setup(const struct lu_env *env, struct mdd_device *m) +{ + struct md_object *mdo; + struct mdd_object *mdd_obf; + struct lu_fid fid = LU_OBF_FID; + int rc; + + rc = mdd_local_file_create(env, m, mdd_object_fid(m->mdd_dot_lustre), + mdd_obf_dir_name, S_IFDIR | S_IXUSR, &fid); + if (rc < 0) + RETURN(rc); + + mdo = mdo_locate(env, &m->mdd_md_dev, &fid); + if (IS_ERR(mdo)) + RETURN(PTR_ERR(mdo)); + + LASSERT(lu_object_exists(&mdo->mo_lu)); + + mdd_obf = md2mdd_obj(mdo); + mdd_obf->mod_obj.mo_dir_ops = &mdd_obf_dir_ops; + m->mdd_dot_lustre_objs.mdd_obf = mdd_obf; + + return 0; +} + /** Setup ".lustre" directory object */ static int mdd_dot_lustre_setup(const struct lu_env *env, struct mdd_device *m) { @@ -1039,8 +691,6 @@ static int mdd_dot_lustre_setup(const struct lu_env *env, struct mdd_device *m) LASSERT(lu_object_exists(&mdo->mo_lu)); m->mdd_dot_lustre = md2mdd_obj(mdo); - m->mdd_dot_lustre->mod_obj.mo_dir_ops = &mdd_dot_lustre_dir_ops; - m->mdd_dot_lustre->mod_obj.mo_ops = &mdd_dot_lustre_obj_ops; rc = mdd_obf_setup(env, m); if (rc) { diff --git a/lustre/mdd/mdd_dir.c b/lustre/mdd/mdd_dir.c index b9fcaac..82c5d1ad 100644 --- a/lustre/mdd/mdd_dir.c +++ b/lustre/mdd/mdd_dir.c @@ -1571,11 +1571,6 @@ static int mdd_create_data(const struct lu_env *env, struct md_object *pobj, int rc; ENTRY; - /* do not let users to create stripes via .lustre/ - * mdd_obf_setup() sets IMMUTE_OBJ on this directory */ - if (pobj && mdd_pobj->mod_flags & IMMUTE_OBJ) - RETURN(-ENOENT); - rc = mdd_cd_sanity_check(env, son); if (rc) RETURN(rc); diff --git a/lustre/mdt/mdt_reint.c b/lustre/mdt/mdt_reint.c index 9576882..38bd0ad 100644 --- a/lustre/mdt/mdt_reint.c +++ b/lustre/mdt/mdt_reint.c @@ -502,10 +502,6 @@ static int mdt_reint_setattr(struct mdt_thread_info *info, if (info->mti_dlm_req) ldlm_request_cancel(req, info->mti_dlm_req, 0); - if ((fid_is_obf(rr->rr_fid1) || fid_is_dot_lustre(rr->rr_fid1)) && - !OBD_FAIL_CHECK(OBD_FAIL_OSD_FID_MAPPING)) - RETURN(-EPERM); - repbody = req_capsule_server_get(info->mti_pill, &RMF_MDT_BODY); mo = mdt_object_find(info->mti_env, info->mti_mdt, rr->rr_fid1); if (IS_ERR(mo)) diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index e9f2966..f206bea 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -8686,16 +8686,13 @@ dot_lustre_fid_permission_check() { error "touch $MOUNT/.lustre/fid/$tfile should fail." echo "setxattr to $MOUNT/.lustre/fid" - setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid && - error "setxattr should fail." + setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid echo "listxattr for $MOUNT/.lustre/fid" - getfattr -d -m "^trusted" $MOUNT/.lustre/fid && - error "listxattr should fail." + getfattr -d -m "^trusted" $MOUNT/.lustre/fid echo "delxattr from $MOUNT/.lustre/fid" - setfattr -x trusted.name1 $MOUNT/.lustre/fid && - error "delxattr should fail." + setfattr -x trusted.name1 $MOUNT/.lustre/fid echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]" touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] && @@ -8714,6 +8711,21 @@ dot_lustre_fid_permission_check() { mrename $MOUNT/.lustre $MOUNT/.lustre/fid/$fid/.lustre && error "rename .lustre to itself should fail." + local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid) + local new_obf_mode=777 + + echo "change mode of $DIR/.lustre/fid to $new_obf_mode" + chmod $new_obf_mode $DIR/.lustre/fid || + error "chmod $new_obf_mode $DIR/.lustre/fid failed" + + local obf_mode=$(stat --format=%a $DIR/.lustre/fid) + [ $obf_mode -eq $new_obf_mode ] || + error "stat $DIR/.lustre/fid returned wrong mode $obf_mode" + + echo "restore mode of $DIR/.lustre/fid to $old_obf_mode" + chmod $old_obf_mode $DIR/.lustre/fid || + error "chmod $old_obf_mode $DIR/.lustre/fid failed" + $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2 fid=$($LFS path2fid $test_dir/$tfile-2) echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid" @@ -8745,7 +8757,6 @@ test_154a() { error "dot lustre permission check $fid failed" rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked" - chmod 777 $MOUNT/.lustre && error ".lustre is not allowed to be chmod" touch $MOUNT/.lustre/file && error "creation is not allowed under .lustre" -- 1.8.3.1