From: Lai Siyao Date: Wed, 29 Feb 2012 04:44:54 +0000 (+0800) Subject: LU-1110 fid: add full support for open-by-fid X-Git-Tag: 2.2.51~39 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=f69c66ab5688f561a2302705677e240a5fcaf609 LU-1110 fid: add full support for open-by-fid Op-by-fid which involves parent change are not permitted: link/unlink/rename/create/open(CREATE) return -EPERM directly in case dt operations are triggered, but obf object doesn't have disk object, which will panic. Add more sanity tests for op-by-fid. Signed-off-by: Lai Siyao Change-Id: I10869923e861ac0165886a48880f58e1269554ec Reviewed-on: http://review.whamcloud.com/2224 Reviewed-by: Bobi Jam Reviewed-by: wangdi Tested-by: Hudson Tested-by: Maloo Reviewed-by: Fan Yong Reviewed-by: Faccini Bruno Reviewed-by: Oleg Drokin --- diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c index 0a18671..9b60848 100644 --- a/lustre/mdt/mdt_handler.c +++ b/lustre/mdt/mdt_handler.c @@ -815,6 +815,7 @@ static int mdt_raw_lookup(struct mdt_thread_info *info, LASSERT(!info->mti_cross_ref); /* Only got the fid of this obj by name */ + fid_zero(child_fid); rc = mdo_lookup(info->mti_env, next, lname, child_fid, &info->mti_spec); #if 0 @@ -979,6 +980,7 @@ static int mdt_getattr_name_lock(struct mdt_thread_info *info, } /* step 2: lookup child's fid by name */ + fid_zero(child_fid); rc = mdo_lookup(info->mti_env, next, lname, child_fid, &info->mti_spec); diff --git a/lustre/mdt/mdt_internal.h b/lustre/mdt/mdt_internal.h index 3ab8125..8c60700 100644 --- a/lustre/mdt/mdt_internal.h +++ b/lustre/mdt/mdt_internal.h @@ -463,11 +463,16 @@ static inline int mdt_object_exists(const struct mdt_object *o) return lu_object_exists(&o->mot_obj.mo_lu); } -static inline const struct lu_fid *mdt_object_fid(struct mdt_object *o) +static inline const struct lu_fid *mdt_object_fid(const struct mdt_object *o) { return lu_object_fid(&o->mot_obj.mo_lu); } +static inline int mdt_object_obf(const struct mdt_object *o) +{ + return lu_fid_eq(mdt_object_fid(o), &LU_OBF_FID); +} + static inline struct lu_site *mdt_lu_site(const struct mdt_device *mdt) { return mdt->mdt_md_dev.md_lu_dev.ld_site; diff --git a/lustre/mdt/mdt_open.c b/lustre/mdt/mdt_open.c index 47628a1..a717089 100644 --- a/lustre/mdt/mdt_open.c +++ b/lustre/mdt/mdt_open.c @@ -1375,6 +1375,9 @@ int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc) mdt_set_capainfo(info, 1, child_fid, BYPASS_CAPA); if (result == -ENOENT) { + if (mdt_object_obf(parent)) + GOTO(out_child, result = -EPERM); + /* save versions in reply */ mdt_version_get_save(info, parent, 0); mdt_version_get_save(info, child, 1); diff --git a/lustre/mdt/mdt_reint.c b/lustre/mdt/mdt_reint.c index 8ecb298..032c0f9 100644 --- a/lustre/mdt/mdt_reint.c +++ b/lustre/mdt/mdt_reint.c @@ -294,6 +294,9 @@ static int mdt_md_create(struct mdt_thread_info *info) if (IS_ERR(parent)) RETURN(PTR_ERR(parent)); + if (mdt_object_obf(parent)) + GOTO(out_put_parent, rc = -EPERM); + rc = mdt_version_get_check_save(info, parent, 0); if (rc) GOTO(out_put_parent, rc); @@ -698,6 +701,9 @@ static int mdt_reint_unlink(struct mdt_thread_info *info, GOTO(out, rc); } + if (mdt_object_obf(mp)) + GOTO(out_unlock_parent, rc = -EPERM); + rc = mdt_version_get_check_save(info, mp, 0); if (rc) GOTO(out_unlock_parent, rc); @@ -727,6 +733,7 @@ static int mdt_reint_unlink(struct mdt_thread_info *info, /* step 2: find & lock the child */ lname = mdt_name(info->mti_env, (char *)rr->rr_name, rr->rr_namelen); /* lookup child object along with version checking */ + fid_zero(child_fid); rc = mdt_lookup_version_check(info, mp, lname, child_fid, 1); if (rc != 0) GOTO(out_unlock_parent, rc); @@ -844,6 +851,9 @@ static int mdt_reint_link(struct mdt_thread_info *info, if (IS_ERR(mp)) RETURN(PTR_ERR(mp)); + if (mdt_object_obf(mp)) + GOTO(out_unlock_parent, rc = -EPERM); + rc = mdt_version_get_check_save(info, mp, 0); if (rc) GOTO(out_unlock_parent, rc); @@ -1147,6 +1157,9 @@ static int mdt_reint_rename(struct mdt_thread_info *info, if (IS_ERR(msrcdir)) GOTO(out_rename_lock, rc = PTR_ERR(msrcdir)); + if (mdt_object_obf(msrcdir)) + GOTO(out_unlock_source, rc = -EPERM); + rc = mdt_version_get_check_save(info, msrcdir, 0); if (rc) GOTO(out_unlock_source, rc); @@ -1171,6 +1184,9 @@ static int mdt_reint_rename(struct mdt_thread_info *info, if (IS_ERR(mtgtdir)) GOTO(out_unlock_source, rc = PTR_ERR(mtgtdir)); + if (mdt_object_obf(mtgtdir)) + GOTO(out_put_target, rc = -EPERM); + /* check early, the real version will be saved after locking */ rc = mdt_version_get_check(info, mtgtdir, 1); if (rc) @@ -1194,6 +1210,7 @@ static int mdt_reint_rename(struct mdt_thread_info *info, /* step 3: find & lock the old object. */ lname = mdt_name(info->mti_env, (char *)rr->rr_name, rr->rr_namelen); mdt_name_copy(&slname, lname); + fid_zero(old_fid); rc = mdt_lookup_version_check(info, msrcdir, &slname, old_fid, 2); if (rc != 0) GOTO(out_unlock_target, rc); @@ -1223,6 +1240,7 @@ static int mdt_reint_rename(struct mdt_thread_info *info, /* new target object may not exist now */ lname = mdt_name(info->mti_env, (char *)rr->rr_tgt, rr->rr_tgtlen); /* lookup with version checking */ + fid_zero(new_fid); rc = mdt_lookup_version_check(info, mtgtdir, lname, new_fid, 3); if (rc == 0) { /* the new_fid should have been filled at this moment */ diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 1aeb8e8..d0cb980 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -7555,12 +7555,68 @@ test_154() { rc=$? [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile." - echo "open fid $fid" - diff /etc/hosts $DIR/.lustre/fid/$fid || error "open by fid failed: did not find expected data in file." + ffid=$DIR/.lustre/fid/$fid + + echo "stat fid $fid" + stat $ffid > /dev/null || error "stat $ffid failed." + echo "touch fid $fid" + touch $ffid || error "touch $ffid failed." + echo "write to fid $fid" + cat /etc/hosts > $ffid || error "write $ffid failed." + echo "read fid $fid" + diff /etc/hosts $ffid || error "read $ffid failed." + echo "append write to fid $fid" + cat /etc/hosts >> $ffid || error "append write $ffid failed." + echo "rename fid $fid" + mv $ffid $DIR/$tfile.1 && error "rename $ffid to $tfile.1 should fail." + touch $DIR/$tfile.1 + mv $DIR/$tfile.1 $ffid && error "rename $tfile.1 to $ffid should fail." + rm -f $DIR/$tfile.1 + echo "truncate fid $fid" + $TRUNCATE $ffid 777 || error "truncate $ffid failed." + echo "link fid $fid" + ln -f $ffid $DIR/tfile.lnk || error "link $ffid failed." + if [ -n $(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl) ]; then + echo "setfacl fid $fid" + setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed." + echo "getfacl fid $fid" + getfacl $ffid >/dev/null || error "getfacl $ffid failed." + fi + echo "unlink fid $fid" + unlink $DIR/.lustre/fid/$fid && error "unlink $ffid should fail." + echo "mknod fid $fid" + mknod $ffid c 1 3 && error "mknod $ffid should fail." + + fid=[0xf00000400:0x1:0x0] + ffid=$DIR/.lustre/fid/$fid + + echo "stat non-exist fid $fid" + stat $ffid > /dev/null && error "stat non-exist $ffid should fail." + echo "write to non-exist fid $fid" + cat /etc/hosts > $ffid && error "write non-exist $ffid should fail." + echo "link new fid $fid" + ln $DIR/$tfile $ffid && error "link $ffid should fail." + + mkdir -p $DIR/$tdir + touch $DIR/$tdir/$tfile + fid=$($LFS path2fid $DIR/$tdir) + rc=$? + [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile." + + ffid=$DIR/.lustre/fid/$fid + + echo "ls $fid" + ls $ffid > /dev/null || error "ls $ffid failed." + echo "touch $fid/$tfile.1" + touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed." + + echo "touch $DIR/.lustre/fid/$tfile" + touch $DIR/.lustre/fid/$tfile && \ + error "touch $DIR/.lustre/fid/$tfile should fail." - echo "Opening a file by FID succeeded" + echo "Open-by-FID succeeded" } -run_test 154 "Opening a file by FID" +run_test 154 "Open-by-FID" test_155_small_load() { local temp=$TMP/$tfile