Whamcloud - gitweb
LU-14489 utils: fix 'lfs find --mdt-count' 66/43866/3
authorAndreas Dilger <adilger@whamcloud.com>
Fri, 28 May 2021 21:15:10 +0000 (15:15 -0600)
committerOleg Drokin <green@whamcloud.com>
Mon, 21 Jun 2021 22:16:16 +0000 (22:16 +0000)
Running "lfs find --mdt-count" causes the find to exit if there
is no directory striping, rather than continuing to the next item.

If cb_get_dirstripe() receives ENODATA then it should consider
that directory as not having any striping and move on, rather
than returning this error to the caller.

Don't crash in cb_getdirstripe() if it is called with a NULL
directory pointer or no directory is opened.

Test-Parameters: trivial
Signed-off-by: Andreas Dilger <adilger@whamcloud.com>
Change-Id: If8dd135a86a6a8911bf804542132b2e7a3ce7057
Reviewed-on: https://review.whamcloud.com/43866
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Lai Siyao <lai.siyao@whamcloud.com>
Reviewed-by: Olaf Faaland-LLNL <faaland1@llnl.gov>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/doc/lfs-find.1
lustre/tests/sanity.sh
lustre/utils/liblustreapi.c

index 4360dd7..483227e 100644 (file)
@@ -166,9 +166,15 @@ Simple hash function that sums all of the characters in the filename.
 This is mostly for testing, or if it is known that filenames will use
 sequential filenames.
 .RE
+This implicitly selects only directories to be matched, like
+.B -type d
+and not other file types.
 .TP
 .BR --mdt-count | -T
-The DNE striped directory has the given number of MDT shards.
+The DNE striped directory has the given number of MDT shards.  This
+implicitly selects only directories to be matched, like
+.B -type d
+and not other file types.
 .TP
 .BR --mirror-count | -N
 The file has \fIn\fR mirrors in its layout.
index 58f7462..543c3fd 100755 (executable)
@@ -6665,6 +6665,36 @@ test_56rb() {
 }
 run_test 56rb "check lfs find --size --ost/--mdt works"
 
+test_56rc() {
+       (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
+       local dir=$DIR/$tdir
+       local found
+
+       test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
+       $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
+       (( $MDSCOUNT > 2 )) &&
+               $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
+       mkdir $dir/$tdir-{1..10}
+       touch $dir/$tfile-{1..10}
+
+       found=$($LFS find $dir --mdt-count 2 | wc -l)
+       expect=11
+       (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
+
+       found=$($LFS find $dir -T +1 | wc -l)
+       (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
+       (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
+
+       found=$($LFS find $dir --mdt-hash all_char | wc -l)
+       expect=11
+       (( $found == $expect )) || error "found $found all_char, expect $expect"
+
+       found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
+       (( $MDSCOUNT > 2 )) && expect=10 || expect=0
+       (( $found == $expect )) || error "found $found all_char, expect $expect"
+}
+run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
+
 test_56s() { # LU-611 #LU-9369
        [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
 
index 80ca61e..42db6d6 100644 (file)
@@ -1806,6 +1806,11 @@ typedef int (semantic_func_t)(char *path, int p, int *d,
 
 #define OBD_NOT_FOUND           (-1)
 
+static bool lmv_is_foreign(__u32 magic)
+{
+       return magic == LMV_MAGIC_FOREIGN;
+}
+
 static void find_param_fini(struct find_param *param)
 {
        if (param->fp_migrate)
@@ -1903,6 +1908,8 @@ static int cb_get_dirstripe(char *path, int *d, struct find_param *param)
        int ret;
        bool did_nofollow = false;
 
+       if (!d || *d < 0)
+               return -ENOTDIR;
 again:
        param->fp_lmv_md->lum_stripe_count = param->fp_lmv_stripe_count;
        if (param->fp_get_default_lmv)
@@ -1945,7 +1952,7 @@ again:
                int lmv_size;
 
                /* if foreign LMV case, fake stripes number */
-               if (param->fp_lmv_md->lum_magic == LMV_MAGIC_FOREIGN) {
+               if (lmv_is_foreign(param->fp_lmv_md->lum_magic)) {
                        struct lmv_foreign_md *lfm;
 
                        lfm = (struct lmv_foreign_md *)param->fp_lmv_md;
@@ -1981,6 +1988,7 @@ again:
                }
                goto again;
        }
+
        return ret;
 }
 
@@ -4657,7 +4665,7 @@ static int find_check_foreign(struct find_param *param)
                struct lmv_foreign_md *lfm;
 
                lfm = (void *)param->fp_lmv_md;
-               if (lfm->lfm_magic != LMV_MAGIC_FOREIGN) {
+               if (lmv_is_foreign(lfm->lfm_magic)) {
                        if (param->fp_foreign_type == LU_FOREIGN_TYPE_UNKNOWN)
                                return param->fp_exclude_foreign ? 1 : -1;
                        return -1;
@@ -4920,16 +4928,21 @@ static int cb_find_init(char *path, int p, int *dp,
        }
 
        /* See if we can check the file type from the dirent. */
-       if (param->fp_type != 0 && de != NULL && de->d_type != DT_UNKNOWN) {
-               checked_type = 1;
+       if (de != NULL && de->d_type != DT_UNKNOWN) {
+               if (param->fp_type != 0) {
+                       checked_type = 1;
 
-               if (DTTOIF(de->d_type) == param->fp_type) {
-                       if (param->fp_exclude_type)
-                               goto decided;
-               } else {
-                       if (!param->fp_exclude_type)
-                               goto decided;
+                       if (DTTOIF(de->d_type) == param->fp_type) {
+                               if (param->fp_exclude_type)
+                                       goto decided;
+                       } else {
+                               if (!param->fp_exclude_type)
+                                       goto decided;
+                       }
                }
+               if ((param->fp_check_mdt_count || param->fp_hash_type ||
+                    param->fp_check_hash_flag) && de->d_type != DT_DIR)
+                       goto decided;
        }
 
        ret = 0;
@@ -4952,23 +4965,66 @@ static int cb_find_init(char *path, int p, int *dp,
                decision = 0;
 
        if (decision == 0) {
-               if (d != -1 && (param->fp_check_mdt_count ||
-                   param->fp_hash_type || param->fp_check_foreign ||
-                   param->fp_check_hash_flag)) {
+               if (d != -1 &&
+                   (param->fp_check_mdt_count || param->fp_hash_type ||
+                    param->fp_check_hash_flag || param->fp_check_foreign)) {
                        param->fp_get_lmv = 1;
                        ret = cb_get_dirstripe(path, &d, param);
                        if (ret != 0) {
-                               /*
-                                * XXX this works to decide for foreign
-                                * criterion only
-                                */
-                               if (errno == ENODATA &&
-                                   param->fp_check_foreign) {
-                                       if (param->fp_exclude_foreign)
-                                               goto foreign;
-                                       goto decided;
+                               if (errno == ENODATA) {
+                                       ret = 0;
+                                       if (param->fp_check_mdt_count ||
+                                           param->fp_hash_type ||
+                                           param->fp_check_hash_flag) {
+                                               param->fp_lmv_md->lum_stripe_count = 0;
+                                               param->fp_lmv_md->lum_hash_type = 0;
+                                       }
+                                       if (param->fp_check_foreign) {
+                                               if (param->fp_exclude_foreign)
+                                                       goto print;
+                                               goto decided;
+                                       }
+                               } else {
+                                       return ret;
                                }
-                               return ret;
+                       }
+
+                       if (param->fp_check_mdt_count) {
+                               if (lmv_is_foreign(param->fp_lmv_md->lum_magic))
+                                       goto decided;
+
+                               decision = find_value_cmp(param->fp_lmv_md->lum_stripe_count,
+                                                         param->fp_mdt_count,
+                                                         param->fp_mdt_count_sign,
+                                                         param->fp_exclude_mdt_count, 1, 0);
+                               if (decision == -1)
+                                       goto decided;
+                       }
+
+                       if (param->fp_hash_type) {
+                               __u32 found;
+                               __u32 type = param->fp_lmv_md->lum_hash_type &
+                                       LMV_HASH_TYPE_MASK;
+
+                               if (lmv_is_foreign(param->fp_lmv_md->lum_magic))
+                                       goto decided;
+
+                               found = (1 << type) & param->fp_hash_type;
+                               if ((found && param->fp_exclude_hash_type) ||
+                                   (!found && !param->fp_exclude_hash_type))
+                                       goto decided;
+                       }
+
+                       if (param->fp_check_hash_flag) {
+                               __u32 flags = param->fp_lmv_md->lum_hash_type &
+                                       ~LMV_HASH_TYPE_MASK;
+
+                               if (lmv_is_foreign(param->fp_lmv_md->lum_magic))
+                                       goto decided;
+
+                               if (!(flags & param->fp_hash_inflags) ||
+                                   (flags & param->fp_hash_exflags))
+                                       goto decided;
                        }
                }
 
@@ -5034,6 +5090,10 @@ static int cb_find_init(char *path, int p, int *dp,
        }
 
        if (param->fp_type && !checked_type) {
+               if ((param->fp_check_mdt_count || param->fp_check_hash_flag ||
+                    param->fp_hash_type) && !S_ISDIR(lmd->lmd_stx.stx_mode))
+                       goto decided;
+
                if ((lmd->lmd_stx.stx_mode & S_IFMT) == param->fp_type) {
                        if (param->fp_exclude_type)
                                goto decided;
@@ -5097,61 +5157,12 @@ static int cb_find_init(char *path, int p, int *dp,
                        goto decided;
        }
 
-       if (param->fp_check_mdt_count) {
-               if (param->fp_lmv_md->lum_magic == LMV_MAGIC_FOREIGN) {
-                       decision = -1;
-                       goto decided;
-               }
-
-               decision = find_value_cmp(
-                               param->fp_lmv_md->lum_stripe_count,
-                               param->fp_mdt_count,
-                               param->fp_mdt_count_sign,
-                               param->fp_exclude_mdt_count, 1, 0);
-               if (decision == -1)
-                       goto decided;
-       }
-
        if (param->fp_check_layout) {
                decision = find_check_layout(param);
                if (decision == -1)
                        goto decided;
        }
 
-       if (param->fp_hash_type) {
-               __u32 found;
-               __u32 type = param->fp_lmv_md->lum_hash_type &
-                            LMV_HASH_TYPE_MASK;
-
-               if (param->fp_lmv_md->lum_magic == LMV_MAGIC_FOREIGN) {
-                       decision = -1;
-                       goto decided;
-               }
-
-               found = (1 << type) & param->fp_hash_type;
-               if ((found && param->fp_exclude_hash_type) ||
-                   (!found && !param->fp_exclude_hash_type)) {
-                       decision = -1;
-                       goto decided;
-               }
-       }
-
-       if (param->fp_check_hash_flag) {
-               __u32 flags = param->fp_lmv_md->lum_hash_type &
-                             ~LMV_HASH_TYPE_MASK;
-
-               if (param->fp_lmv_md->lum_magic == LMV_MAGIC_FOREIGN) {
-                       decision = -1;
-                       goto decided;
-               }
-
-               if (!(flags & param->fp_hash_inflags) ||
-                    (flags & param->fp_hash_exflags)) {
-                       decision = -1;
-                       goto decided;
-               }
-       }
-
        /* If an OBD UUID is specified but none matches, skip this file. */
        if ((param->fp_obd_uuid && param->fp_obd_index == OBD_NOT_FOUND) ||
            (param->fp_mdt_uuid && param->fp_mdt_index == OBD_NOT_FOUND))
@@ -5388,12 +5399,9 @@ obd_matches:
                        goto decided;
        }
 
-foreign:
-       llapi_printf(LLAPI_MSG_NORMAL, "%s", path);
-       if (param->fp_zero_end)
-               llapi_printf(LLAPI_MSG_NORMAL, "%c", '\0');
-       else
-               llapi_printf(LLAPI_MSG_NORMAL, "\n");
+print:
+       llapi_printf(LLAPI_MSG_NORMAL, "%s%c", path,
+                    param->fp_zero_end ? '\0' : '\n');
 
 decided:
        ret = 0;