Whamcloud - gitweb
LU-18138 mdd: handle corner case for .lustre on readdir 21/56021/3
authorVladimir Saveliev <vladimir.saveliev@hpe.com>
Tue, 13 Aug 2024 12:03:52 +0000 (15:03 +0300)
committerOleg Drokin <green@whamcloud.com>
Fri, 23 Aug 2024 22:06:35 +0000 (22:06 +0000)
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 <vladimir.saveliev@hpe.com>
Change-Id: Ib4dfe92b66932ede1b1336e55f1af33c1fc6c878
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/56021
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Reviewed-by: Lai Siyao <lai.siyao@whamcloud.com>
Reviewed-by: Shaun Tancheff <shaun.tancheff@hpe.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
lustre/mdd/mdd_object.c
lustre/tests/sanity.sh

index 8165c07..ab48418 100644 (file)
@@ -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;
 }
 
index 3b2c54f..7852a5f 100755 (executable)
@@ -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"