Whamcloud - gitweb
LU-11130 osd-ldiskfs: create non-empty local agent symlinks 97/32797/9
authorAlexander Zarochentsev <c17826@cray.com>
Sat, 7 Jul 2018 21:21:36 +0000 (00:21 +0300)
committerOleg Drokin <green@whamcloud.com>
Tue, 13 Nov 2018 06:14:19 +0000 (06:14 +0000)
e2fsck doesn't like zero-sized symlink inodes created by
osd_create_local_agent_inode().  Store the FID of the remote
inode as the symlink target so that it is possible to debug
where this symlink comes from in case there is some problem
in the future.

It would be better to just migrate the whole symlink instead
of creating a remote symlink, in the very common case where
there is not a hard link to the symlink (which POSIX allows,
but is extremely uncommon).  For the short term, we store
keep the remote symlinks to ensure on-disk consistency with
this simple patch, until the migration code can be fixed.

Cray-bug-id: LUS-6189
Change-Id: Ida43616c51b6903f0a51aeec05a9a2dd189efe31
Signed-off-by: Alexander Zarochentsev <c17826@cray.com>
Signed-off-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-on: https://review.whamcloud.com/32797
Tested-by: Jenkins
Reviewed-by: Lai Siyao <lai.siyao@whamcloud.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
lustre/osd-ldiskfs/osd_handler.c
lustre/tests/conf-sanity.sh

index f6174ef..12b1d32 100644 (file)
@@ -3767,6 +3767,19 @@ static struct inode *osd_create_local_agent_inode(const struct lu_env *env,
         */
        local->i_gid = current_fsgid();
        ldiskfs_set_inode_state(local, LDISKFS_STATE_LUSTRE_NOSCRUB);
         */
        local->i_gid = current_fsgid();
        ldiskfs_set_inode_state(local, LDISKFS_STATE_LUSTRE_NOSCRUB);
+
+       /* e2fsck doesn't like empty symlinks.  Store remote FID as symlink.
+        * That gives e2fsck something to look at and be happy, and allows
+        * debugging if we need to determine where this symlink came from.
+        */
+       if (S_ISLNK(type)) {
+               CLASSERT(LDISKFS_N_BLOCKS * 4 >= FID_LEN + 1);
+               rc = snprintf((char *)LDISKFS_I(local)->i_data,
+                             LDISKFS_N_BLOCKS * 4, DFID, PFID(fid));
+
+               i_size_write(local, rc);
+               LDISKFS_I(local)->i_disksize = rc;
+       }
        unlock_new_inode(local);
 
        /* Agent inode should not have project ID */
        unlock_new_inode(local);
 
        /* Agent inode should not have project ID */
index 4ed9e77..49403bc 100644 (file)
@@ -8177,6 +8177,31 @@ test_117() {
 }
 run_test 117 "lctl get_param return errors properly"
 
 }
 run_test 117 "lctl get_param return errors properly"
 
+test_120() { # LU-11130
+       [ "$MDSCOUNT" -lt 2 ] && skip "mdt count < 2"
+       [ $(facet_fstype $SINGLEMDS) != "ldiskfs" ] &&
+               skip "ldiskfs only test"
+       [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
+               skip "Need DNE2 capable MD target with LU-11130 fix"
+
+       setup
+
+       local mds1host=$(facet_active_host mds1)
+       local mds1dev=$(mdsdevname 1)
+
+       $LFS mkdir -i 1 $DIR/$tdir
+       $LFS mkdir -i 0 $DIR/$tdir/mds1dir
+
+       ln -s foo $DIR/$tdir/bar
+       mv $DIR/$tdir/bar $DIR/$tdir/mds1dir/bar2 ||
+               error "cross-target rename failed"
+
+       stopall
+
+       run_e2fsck $mds1host $mds1dev "-n"
+}
+run_test 120 "cross-target rename should not create bad symlinks"
+
 test_122() {
        [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
        [[ $(lustre_version_code ost1) -ge $(version_code 2.11.53) ]] ||
 test_122() {
        [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
        [[ $(lustre_version_code ost1) -ge $(version_code 2.11.53) ]] ||