Whamcloud - gitweb
LU-13157 mdd: migrate readlink from wrong place 85/37285/4
authorLai Siyao <lai.siyao@whamcloud.com>
Mon, 20 Jan 2020 04:23:45 +0000 (12:23 +0800)
committerOleg Drokin <green@whamcloud.com>
Tue, 31 Mar 2020 07:00:30 +0000 (07:00 +0000)
In osd_read(), if symlink name buf length is smaller than i_size,
return -EOVERFLOW, and compare inline data length with i_size
instead of buflen.

Updated sanity.sh 230b.

Signed-off-by: Lai Siyao <lai.siyao@whamcloud.com>
Change-Id: Ia13b1f1079efc4ebd22ec400f1a909ff7ec2095d
Reviewed-on: https://review.whamcloud.com/37285
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: John L. Hammond <jhammond@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
lustre/osd-ldiskfs/osd_io.c
lustre/tests/sanity.sh

index 3f0bc7b..34090a8 100644 (file)
@@ -1495,19 +1495,27 @@ int osd_ldiskfs_read(struct inode *inode, void *buf, int size, loff_t *offs)
 static ssize_t osd_read(const struct lu_env *env, struct dt_object *dt,
                        struct lu_buf *buf, loff_t *pos)
 {
-        struct inode *inode = osd_dt_obj(dt)->oo_inode;
-        int           rc;
+       struct inode *inode = osd_dt_obj(dt)->oo_inode;
+       int rc;
 
-        /* Read small symlink from inode body as we need to maintain correct
-         * on-disk symlinks for ldiskfs.
-         */
-        if (S_ISLNK(dt->do_lu.lo_header->loh_attr) &&
-            (buf->lb_len < sizeof(LDISKFS_I(inode)->i_data)))
-                rc = osd_ldiskfs_readlink(inode, buf->lb_buf, buf->lb_len);
-        else
-                rc = osd_ldiskfs_read(inode, buf->lb_buf, buf->lb_len, pos);
+       /* Read small symlink from inode body as we need to maintain correct
+        * on-disk symlinks for ldiskfs.
+        */
+       if (S_ISLNK(dt->do_lu.lo_header->loh_attr)) {
+               loff_t size = i_size_read(inode);
 
-        return rc;
+               if (buf->lb_len < size)
+                       return -EOVERFLOW;
+
+               if (size < sizeof(LDISKFS_I(inode)->i_data))
+                       rc = osd_ldiskfs_readlink(inode, buf->lb_buf, size);
+               else
+                       rc = osd_ldiskfs_read(inode, buf->lb_buf, size, pos);
+       } else {
+               rc = osd_ldiskfs_read(inode, buf->lb_buf, buf->lb_len, pos);
+       }
+
+       return rc;
 }
 
 static inline int osd_extents_enabled(struct super_block *sb,
index f705935..55a6884 100755 (executable)
@@ -16725,6 +16725,27 @@ test_230b() {
        ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
        ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
 
+       local len
+       local lnktgt
+
+       # inline symlink
+       for len in 58 59 60; do
+               lnktgt=$(str_repeat 'l' $len)
+               touch $migrate_dir/$lnktgt
+               ln -s $lnktgt $migrate_dir/${len}char_ln
+       done
+
+       # PATH_MAX
+       for len in 4094 4095; do
+               lnktgt=$(str_repeat 'l' $len)
+               ln -s $lnktgt $migrate_dir/${len}char_ln
+       done
+
+       # NAME_MAX
+       for len in 254 255; do
+               touch $migrate_dir/$(str_repeat 'l' $len)
+       done
+
        $LFS migrate -m $MDTIDX $migrate_dir ||
                error "fails on migrating remote dir to MDT1"
 
@@ -16732,7 +16753,8 @@ test_230b() {
        for ((i = 0; i < 10; i++)); do
                for file in $(find $migrate_dir/dir_${i}); do
                        mdt_index=$($LFS getstripe -m $file)
-                       [ $mdt_index == $MDTIDX ] ||
+                       # broken symlink getstripe will fail
+                       [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
                                error "$file is not on MDT${MDTIDX}"
                done
        done
@@ -16796,7 +16818,7 @@ test_230b() {
        echo "migrate back to MDT0, checking.."
        for file in $(find $migrate_dir); do
                mdt_index=$($LFS getstripe -m $file)
-               [ $mdt_index == $MDTIDX ] ||
+               [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
                        error "$file is not on MDT${MDTIDX}"
        done