Whamcloud - gitweb
LU-6109 lfsck: check FID validity before locating object
[fs/lustre-release.git] / lustre / lfsck / lfsck_namespace.c
index 91e0355..6e29717 100644 (file)
@@ -584,6 +584,9 @@ int lfsck_namespace_trace_update(const struct lu_env *env,
 
        LASSERT(flags != 0);
 
+       if (unlikely(!fid_is_sane(fid)))
+               RETURN(0);
+
        idx = lfsck_sub_trace_file_fid2idx(fid);
        obj = com->lc_sub_trace_objs[idx].lsto_obj;
        mutex_lock(&com->lc_sub_trace_objs[idx].lsto_mutex);
@@ -4947,7 +4950,7 @@ static int lfsck_namespace_assistant_handler_p1(const struct lu_env *env,
        bool                        bad_hash = false;
        int                         idx      = 0;
        int                         count    = 0;
-       int                         rc;
+       int                         rc       = 0;
        enum lfsck_namespace_inconsistency_type type = LNIT_NONE;
        ENTRY;
 
@@ -4972,6 +4975,24 @@ static int lfsck_namespace_assistant_handler_p1(const struct lu_env *env,
                GOTO(out, rc);
        }
 
+       if (unlikely(!fid_is_sane(&lnr->lnr_fid))) {
+               CDEBUG(D_LFSCK, "%s: dir scan find invalid FID "DFID
+                      " for the name entry %.*s under "DFID"\n",
+                      lfsck_lfsck2name(lfsck), PFID(&lnr->lnr_fid),
+                      lnr->lnr_namelen, lnr->lnr_name, PFID(pfid));
+
+               if (strcmp(lnr->lnr_name, dotdot) != 0)
+                       /* invalid FID means bad name entry, remove it. */
+                       type = LNIT_BAD_DIRENT;
+               else
+                       /* If the parent FID is invalid, we cannot remove
+                        * the ".." entry directly. */
+                       rc = lfsck_namespace_trace_update(env, com, pfid,
+                                               LNTF_CHECK_PARENT, true);
+
+               GOTO(out, rc);
+       }
+
        if (unlikely(lnr->lnr_dir_cookie == MDS_DIR_END_OFF)) {
                rc = lfsck_namespace_striped_dir_rescan(env, com, lnr);
 
@@ -6033,6 +6054,13 @@ lfsck_namespace_assistant_sync_failures_interpret(const struct lu_env *env,
                                                  struct ptlrpc_request *req,
                                                  void *args, int rc)
 {
+       if (rc == 0) {
+               struct lfsck_async_interpret_args *laia = args;
+               struct lfsck_tgt_desc             *ltd  = laia->laia_ltd;
+
+               ltd->ltd_synced_failures = 1;
+       }
+
        return 0;
 }
 
@@ -6069,9 +6097,13 @@ static void lfsck_namespace_assistant_sync_failures(const struct lu_env *env,
        struct lfsck_tgt_descs            *ltds  = &lfsck->li_mdt_descs;
        struct lfsck_tgt_desc             *ltd;
        struct ptlrpc_request_set         *set;
+       __u32                              idx;
        int                                rc    = 0;
        ENTRY;
 
+       if (!lad->lad_incomplete)
+               RETURN_EXIT;
+
        set = ptlrpc_prep_set();
        if (set == NULL)
                GOTO(out, rc = -ENOMEM);
@@ -6080,25 +6112,12 @@ static void lfsck_namespace_assistant_sync_failures(const struct lu_env *env,
        memset(laia, 0, sizeof(*laia));
        lad->lad_touch_gen++;
 
-       spin_lock(&ltds->ltd_lock);
-       while (!list_empty(&lad->lad_mdt_list)) {
-               ltd = list_entry(lad->lad_mdt_list.next,
-                                struct lfsck_tgt_desc,
-                                ltd_namespace_list);
-               if (ltd->ltd_namespace_gen == lad->lad_touch_gen)
-                       break;
-
-               ltd->ltd_namespace_gen = lad->lad_touch_gen;
-               list_move_tail(&ltd->ltd_namespace_list,
-                              &lad->lad_mdt_list);
-               if (!lad->lad_incomplete ||
-                   !cfs_bitmap_check(lad->lad_bitmap, ltd->ltd_index)) {
-                       ltd->ltd_namespace_failed = 0;
-                       continue;
-               }
+       down_read(&ltds->ltd_rw_sem);
+       cfs_foreach_bit(lad->lad_bitmap, idx) {
+               ltd = LTD_TGT(ltds, idx);
+               LASSERT(ltd != NULL);
 
-               ltd->ltd_namespace_failed = 1;
-               spin_unlock(&ltds->ltd_lock);
+               laia->laia_ltd = ltd;
                rc = lfsck_async_request(env, ltd->ltd_exp, lr, set,
                        lfsck_namespace_assistant_sync_failures_interpret,
                        laia, LFSCK_NOTIFY);
@@ -6106,10 +6125,8 @@ static void lfsck_namespace_assistant_sync_failures(const struct lu_env *env,
                        CDEBUG(D_LFSCK, "%s: namespace LFSCK assistant fail "
                               "to sync failure with MDT %x: rc = %d\n",
                               lfsck_lfsck2name(lfsck), ltd->ltd_index, rc);
-
-               spin_lock(&ltds->ltd_lock);
        }
-       spin_unlock(&ltds->ltd_lock);
+       up_read(&ltds->ltd_rw_sem);
 
        rc = ptlrpc_set_wait(set);
        ptlrpc_set_destroy(set);