From a3b30423c6067b3e8644ecfb3269f8837af7e4cd Mon Sep 17 00:00:00 2001 From: Lai Siyao Date: Mon, 20 Jan 2020 12:23:45 +0800 Subject: [PATCH] LU-13157 mdd: migrate readlink from wrong place 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 Change-Id: Ia13b1f1079efc4ebd22ec400f1a909ff7ec2095d Reviewed-on: https://review.whamcloud.com/37285 Tested-by: jenkins Tested-by: Maloo Reviewed-by: John L. Hammond Reviewed-by: Andreas Dilger --- lustre/osd-ldiskfs/osd_io.c | 30 +++++++++++++++++++----------- lustre/tests/sanity.sh | 26 ++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/lustre/osd-ldiskfs/osd_io.c b/lustre/osd-ldiskfs/osd_io.c index 3f0bc7b..34090a8 100644 --- a/lustre/osd-ldiskfs/osd_io.c +++ b/lustre/osd-ldiskfs/osd_io.c @@ -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, diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index f705935..55a68843 100755 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -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 -- 1.8.3.1