From: Vladimir Saveliev Date: Tue, 13 Aug 2024 12:03:52 +0000 (+0300) Subject: LU-18138 mdd: handle corner case for .lustre on readdir X-Git-Tag: 2.15.90~23 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=609fc54142281d3ac5e36b257f8890a2fb0c96a0;p=fs%2Flustre-release.git LU-18138 mdd: handle corner case for .lustre on readdir If '.lustre' entry is dispaced into last directory block and is alone in it - the entry to returned by mdd_readdir. Test to illustrate the issus is added. Fixes: e6b8e3a86b ("LU-5044 mdd: do not return .lustre from readdir") Signed-off-by: Vladimir Saveliev Change-Id: Ib4dfe92b66932ede1b1336e55f1af33c1fc6c878 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/56021 Reviewed-by: Oleg Drokin Reviewed-by: Lai Siyao Reviewed-by: Shaun Tancheff Tested-by: jenkins Tested-by: Maloo --- diff --git a/lustre/mdd/mdd_object.c b/lustre/mdd/mdd_object.c index 8165c07..ab48418 100644 --- a/lustre/mdd/mdd_object.c +++ b/lustre/mdd/mdd_object.c @@ -4092,14 +4092,20 @@ out: last->lde_reclen = 0; /* end mark */ } out_err: - if (result > 0) + if (result > 0) { /* end of directory */ dp->ldp_hash_end = cpu_to_le64(MDS_DIR_END_OFF); - else if (result < 0) + if (last == NULL && fid_is_dot_lustre(&fid)) + /* + * .lustre is last in directory and alone in + * last directory block + */ + dp->ldp_flags = cpu_to_le32(LDF_EMPTY); + } else if (result < 0) { CWARN("%s: build page failed for "DFID": rc = %d\n", lu_dev_name(obj->do_lu.lo_dev), PFID(lu_object_fid(&obj->do_lu)), result); - + } return result; } diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 3b2c54f..7852a5f 100755 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -18291,6 +18291,40 @@ test_154e() } run_test 154e ".lustre is not returned by readdir" +test_154ea() +{ + stack_trap "rm -rf $MOUNT/[abcdeg]*" EXIT + + # long specially selected names are to displace .lustre out of + # first directory block + touch $MOUNT/$(printf "a%0100x" 6) + for i in 11 15 + do + touch $MOUNT/$(printf "a%0254x" $i) + done + touch $MOUNT/$(printf "b%0254x" $i) + for i in 16 6 7 + do + touch $MOUNT/$(printf "c%0254x" $i) + done + for i in 4 10 8 + do + touch $MOUNT/$(printf "d%0254x" $i) + done + for i in 1 14 + do + touch /mnt/lustre/$(printf "e%0254x" $i) + done + for i in 13 14 + do + touch /mnt/lustre/$(printf "g%0254x" $i) + done + if ls -a $MOUNT | grep -q '^\.lustre$'; then + error ".lustre returned by readdir" + fi +} +run_test 154ea ".lustre is not returned by readdir (2)" + test_154f() { [ -n "$FILESET" ] && skip "SKIP due to FILESET set"