Whamcloud - gitweb
LU-1110 fid: add full support for open-by-fid
authorLai Siyao <laisiyao@whamcloud.com>
Wed, 29 Feb 2012 04:44:54 +0000 (12:44 +0800)
committerOleg Drokin <green@whamcloud.com>
Thu, 29 Mar 2012 03:34:34 +0000 (23:34 -0400)
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 <laisiyao@whamcloud.com>
Change-Id: I10869923e861ac0165886a48880f58e1269554ec
Reviewed-on: http://review.whamcloud.com/2224
Reviewed-by: Bobi Jam <bobijam@whamcloud.com>
Reviewed-by: wangdi <di.wang@whamcloud.com>
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Fan Yong <yong.fan@whamcloud.com>
Reviewed-by: Faccini Bruno <bruno.faccini@bull.net>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/mdt/mdt_handler.c
lustre/mdt/mdt_internal.h
lustre/mdt/mdt_open.c
lustre/mdt/mdt_reint.c
lustre/tests/sanity.sh

index 0a18671..9b60848 100644 (file)
@@ -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);
 
index 3ab8125..8c60700 100644 (file)
@@ -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;
index 47628a1..a717089 100644 (file)
@@ -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);
index 8ecb298..032c0f9 100644 (file)
@@ -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 */
index 1aeb8e8..d0cb980 100644 (file)
@@ -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