Whamcloud - gitweb
LU-6895 lfsck: not destroy directory when fix FID-in-dirent
[fs/lustre-release.git] / lustre / lfsck / lfsck_engine.c
index 3c98c2b..ba65343 100644 (file)
@@ -20,7 +20,7 @@
  * GPL HEADER END
  */
 /*
- * Copyright (c) 2012, 2013, Intel Corporation.
+ * Copyright (c) 2013, 2014, Intel Corporation.
  */
 /*
  * lustre/lfsck/lfsck_engine.c
@@ -98,7 +98,7 @@ static int lfsck_update_lma(const struct lu_env *env,
 {
        struct lfsck_thread_info        *info   = lfsck_env_info(env);
        struct lfsck_bookmark           *bk     = &lfsck->li_bookmark_ram;
-       struct dt_device                *dt     = lfsck->li_bottom;
+       struct dt_device                *dev    = lfsck_obj2dev(obj);
        struct lustre_mdt_attrs         *lma    = &info->lti_lma;
        struct lu_buf                   *buf;
        struct thandle                  *th;
@@ -110,7 +110,7 @@ static int lfsck_update_lma(const struct lu_env *env,
                RETURN(0);
 
        buf = lfsck_buf_get(env, info->lti_lma_old, LMA_OLD_SIZE);
-       rc = dt_xattr_get(env, obj, buf, XATTR_NAME_LMA, BYPASS_CAPA);
+       rc = dt_xattr_get(env, obj, buf, XATTR_NAME_LMA);
        if (rc < 0) {
                if (rc != -ENODATA)
                        RETURN(rc);
@@ -129,7 +129,7 @@ static int lfsck_update_lma(const struct lu_env *env,
        }
        lustre_lma_swab(lma);
 
-       th = dt_trans_create(env, dt);
+       th = dt_trans_create(env, dev);
        if (IS_ERR(th))
                RETURN(PTR_ERR(th));
 
@@ -138,16 +138,16 @@ static int lfsck_update_lma(const struct lu_env *env,
        if (rc != 0)
                GOTO(stop, rc);
 
-       rc = dt_trans_start(env, dt, th);
+       rc = dt_trans_start_local(env, dev, th);
        if (rc != 0)
                GOTO(stop, rc);
 
-       rc = dt_xattr_set(env, obj, buf, XATTR_NAME_LMA, fl, th, BYPASS_CAPA);
+       rc = dt_xattr_set(env, obj, buf, XATTR_NAME_LMA, fl, th);
 
        GOTO(stop, rc);
 
 stop:
-       dt_trans_stop(env, dt, th);
+       dt_trans_stop(env, dev, th);
        return rc;
 }
 
@@ -159,7 +159,7 @@ static int lfsck_parent_fid(const struct lu_env *env, struct dt_object *obj,
                return -ENOTDIR;
 
        return dt_lookup(env, obj, (struct dt_rec *)fid,
-                        (const struct dt_key *)"..", BYPASS_CAPA);
+                        (const struct dt_key *)"..");
 }
 
 /**
@@ -194,9 +194,8 @@ static int lfsck_needs_scan_dir(const struct lu_env *env,
        struct lfsck_thread_info *info    = lfsck_env_info(env);
        struct lu_fid            *fid     = &info->lti_fid;
        struct lu_seq_range      *range   = &info->lti_range;
-       struct dt_device         *dev     = lfsck->li_bottom;
-       struct seq_server_site   *ss      = lu_site2seq(dev->dd_lu_dev.ld_site);
-       __u32                     idx     = lfsck_dev_idx(dev);
+       struct seq_server_site   *ss      = lfsck_dev_site(lfsck);
+       __u32                     idx     = lfsck_dev_idx(lfsck);
        int                       depth   = 0;
        int                       rc      = 0;
 
@@ -237,7 +236,7 @@ static int lfsck_needs_scan_dir(const struct lu_env *env,
                        return 1;
 
                if (obj == NULL) {
-                       obj = lfsck_object_find(env, lfsck, fid);
+                       obj = lfsck_object_find_bottom(env, lfsck, fid);
                        if (IS_ERR(obj))
                                return PTR_ERR(obj);
 
@@ -254,8 +253,7 @@ static int lfsck_needs_scan_dir(const struct lu_env *env,
                }
 
                rc = dt_xattr_get(env, obj,
-                                 lfsck_buf_get(env, NULL, 0), XATTR_NAME_LINK,
-                                 BYPASS_CAPA);
+                                 lfsck_buf_get(env, NULL, 0), XATTR_NAME_LINK);
                dt_read_unlock(env, obj);
                if (rc >= 0)
                        GOTO(out, rc = 1);
@@ -327,25 +325,14 @@ static int lfsck_load_stripe_lmv(const struct lu_env *env,
                        RETURN(-ENOMEM);
                }
 
-               /* Find the object against the bottom device. */
-               obj = lfsck_object_find_by_dev(env, lfsck->li_bottom,
-                                              lfsck_dto2fid(obj));
-               if (IS_ERR(obj)) {
-                       OBD_FREE_LARGE(lslr, sizeof(*lslr) * stripes);
-                       OBD_FREE_PTR(llmv);
-
-                       RETURN(PTR_ERR(obj));
-               }
-
                llmv->ll_stripes_allocated = stripes;
                llmv->ll_hash_type = LMV_HASH_TYPE_UNKNOWN;
                llmv->ll_lslr = lslr;
-               lfsck->li_obj_dir = obj;
        } else {
                llmv->ll_lmv_slave = 1;
-               lfsck->li_obj_dir = lfsck_object_get(obj);
        }
 
+       lfsck->li_obj_dir = lfsck_object_get(obj);
        llmv->ll_lmv = *lmv;
        atomic_set(&llmv->ll_ref, 1);
        lfsck->li_lmv = llmv;
@@ -428,7 +415,7 @@ int lfsck_open_dir(const struct lu_env *env,
        }
 
        iops = &obj->do_index_ops->dio_it;
-       di = iops->init(env, obj, lfsck->li_args_dir, BYPASS_CAPA);
+       di = iops->init(env, obj, lfsck->li_args_dir);
        if (IS_ERR(di))
                GOTO(out, rc = PTR_ERR(di));
 
@@ -530,7 +517,7 @@ static int lfsck_prep(const struct lu_env *env, struct lfsck_instance *lfsck,
                GOTO(out, rc = 0);
 
        /* Find the directory for namespace-based traverse. */
-       obj = lfsck_object_find(env, lfsck, &pos->lp_dir_parent);
+       obj = lfsck_object_find_bottom(env, lfsck, &pos->lp_dir_parent);
        if (IS_ERR(obj))
                RETURN(PTR_ERR(obj));
 
@@ -621,13 +608,14 @@ out:
 
 static int lfsck_exec_dir(const struct lu_env *env,
                          struct lfsck_instance *lfsck,
+                         struct lfsck_assistant_object *lso,
                          struct lu_dirent *ent, __u16 type)
 {
        struct lfsck_component *com;
        int                     rc;
 
        list_for_each_entry(com, &lfsck->li_list_scan, lc_link) {
-               rc = com->lc_ops->lfsck_exec_dir(env, com, ent, type);
+               rc = com->lc_ops->lfsck_exec_dir(env, com, lso, ent, type);
                if (rc != 0)
                        return rc;
        }
@@ -756,29 +744,20 @@ static int lfsck_master_dir_engine(const struct lu_env *env,
                        (struct lu_dirent *)info->lti_key;
        struct lfsck_bookmark           *bk     = &lfsck->li_bookmark_ram;
        struct ptlrpc_thread            *thread = &lfsck->li_thread;
+       struct lfsck_assistant_object   *lso    = NULL;
        int                              rc;
        __u16                            type;
        ENTRY;
 
        do {
-               if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_DELAY2) &&
-                   cfs_fail_val > 0) {
-                       struct l_wait_info lwi;
-
-                       lwi = LWI_TIMEOUT(cfs_time_seconds(cfs_fail_val),
-                                         NULL, NULL);
-                       l_wait_event(thread->t_ctl_waitq,
-                                    !thread_is_running(thread),
-                                    &lwi);
-
-                       if (unlikely(!thread_is_running(thread))) {
-                               CDEBUG(D_LFSCK, "%s: scan dir exit for engine "
-                                      "stop, parent "DFID", cookie "LPX64"\n",
-                                      lfsck_lfsck2name(lfsck),
-                                      PFID(lfsck_dto2fid(dir)),
-                                      lfsck->li_cookie_dir);
-                               RETURN(0);
-                       }
+               if (CFS_FAIL_TIMEOUT(OBD_FAIL_LFSCK_DELAY2, cfs_fail_val) &&
+                   unlikely(!thread_is_running(thread))) {
+                       CDEBUG(D_LFSCK, "%s: scan dir exit for engine stop, "
+                              "parent "DFID", cookie "LPX64"\n",
+                              lfsck_lfsck2name(lfsck),
+                              PFID(lfsck_dto2fid(dir)), lfsck->li_cookie_dir);
+
+                       GOTO(out, rc = 0);
                }
 
                lfsck->li_new_scanned++;
@@ -796,25 +775,41 @@ static int lfsck_master_dir_engine(const struct lu_env *env,
                               lfsck->li_cookie_dir, rc);
                        lfsck_fail(env, lfsck, true);
                        if (bk->lb_param & LPF_FAILOUT)
-                               RETURN(rc);
+                               GOTO(out, rc);
                        else
                                goto checkpoint;
                }
 
-               if (ent->lde_attrs & LUDA_IGNORE &&
-                   strcmp(ent->lde_name, dotdot) != 0)
+               if (ent->lde_attrs & LUDA_IGNORE)
                        goto checkpoint;
 
+               /* skip dot entry. */
+               if (ent->lde_namelen == 1 && ent->lde_name[0] == '.')
+                       goto checkpoint;
+
+               if (lso == NULL) {
+                       lso = lfsck_assistant_object_init(env,
+                               lfsck_dto2fid(dir), NULL,
+                               lfsck->li_pos_current.lp_oit_cookie, true);
+                       if (IS_ERR(lso)) {
+                               if (bk->lb_param & LPF_FAILOUT)
+                                       RETURN(PTR_ERR(lso));
+
+                               lso = NULL;
+                               goto checkpoint;
+                       }
+               }
+
                /* The type in the @ent structure may has been overwritten,
                 * so we need to pass the @type parameter independently. */
-               rc = lfsck_exec_dir(env, lfsck, ent, type);
+               rc = lfsck_exec_dir(env, lfsck, lso, ent, type);
                if (rc != 0 && bk->lb_param & LPF_FAILOUT)
-                       RETURN(rc);
+                       GOTO(out, rc);
 
 checkpoint:
                rc = lfsck_checkpoint(env, lfsck);
                if (rc != 0 && bk->lb_param & LPF_FAILOUT)
-                       RETURN(rc);
+                       GOTO(out, rc);
 
                /* Rate control. */
                lfsck_control_speed(lfsck);
@@ -824,14 +819,14 @@ checkpoint:
                               lfsck_lfsck2name(lfsck),
                               PFID(lfsck_dto2fid(dir)),
                               lfsck->li_cookie_dir);
-                       RETURN(0);
+                       GOTO(out, rc = 0);
                }
 
                if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_FATAL2)) {
                        spin_lock(&lfsck->li_lock);
                        thread_set_flags(thread, SVC_STOPPING);
                        spin_unlock(&lfsck->li_lock);
-                       RETURN(-EINVAL);
+                       GOTO(out, rc = -EINVAL);
                }
 
                rc = iops->next(env, di);
@@ -840,7 +835,13 @@ checkpoint:
        if (rc > 0 && !lfsck->li_oit_over)
                lfsck_close_dir(env, lfsck, rc);
 
-       RETURN(rc);
+       GOTO(out, rc);
+
+out:
+       if (lso != NULL)
+               lfsck_assistant_object_put(env, lso);
+
+       return rc;
 }
 
 /**
@@ -875,9 +876,8 @@ static int lfsck_master_oit_engine(const struct lu_env *env,
        struct lu_fid            *fid   = &info->lti_fid;
        struct lfsck_bookmark    *bk    = &lfsck->li_bookmark_ram;
        struct ptlrpc_thread     *thread = &lfsck->li_thread;
-       struct dt_device         *dev   = lfsck->li_bottom;
-       struct seq_server_site   *ss    = lu_site2seq(dev->dd_lu_dev.ld_site);
-       __u32                    idx    = lfsck_dev_idx(dev);
+       struct seq_server_site   *ss    = lfsck_dev_site(lfsck);
+       __u32                    idx    = lfsck_dev_idx(lfsck);
        int                      rc;
        ENTRY;
 
@@ -897,23 +897,13 @@ static int lfsck_master_oit_engine(const struct lu_env *env,
                if (unlikely(lfsck->li_oit_over))
                        RETURN(1);
 
-               if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_DELAY1) &&
-                   cfs_fail_val > 0) {
-                       struct l_wait_info lwi;
-
-                       lwi = LWI_TIMEOUT(cfs_time_seconds(cfs_fail_val),
-                                         NULL, NULL);
-                       l_wait_event(thread->t_ctl_waitq,
-                                    !thread_is_running(thread),
-                                    &lwi);
+               if (CFS_FAIL_TIMEOUT(OBD_FAIL_LFSCK_DELAY1, cfs_fail_val) &&
+                   unlikely(!thread_is_running(thread))) {
+                       CDEBUG(D_LFSCK, "%s: OIT scan exit for engine stop, "
+                              "cookie "LPU64"\n",
+                              lfsck_lfsck2name(lfsck), iops->store(env, di));
 
-                       if (unlikely(!thread_is_running(thread))) {
-                               CDEBUG(D_LFSCK, "%s: OIT scan exit for engine "
-                                      "stop, cookie "LPU64"\n",
-                                      lfsck_lfsck2name(lfsck),
-                                      iops->store(env, di));
-                               RETURN(0);
-                       }
+                       RETURN(0);
                }
 
                if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_CRASH))
@@ -953,6 +943,13 @@ static int lfsck_master_oit_engine(const struct lu_env *env,
                                goto checkpoint;
                }
 
+               if (unlikely(!fid_is_sane(fid))) {
+                       CDEBUG(D_LFSCK, "%s: OIT scan find invalid FID "DFID
+                              ", skip it\n",
+                              lfsck_lfsck2name(lfsck), PFID(fid));
+                       goto checkpoint;
+               }
+
                if (fid_is_idif(fid)) {
                        __u32 idx1 = fid_idif_ost_idx(fid);
 
@@ -993,7 +990,7 @@ static int lfsck_master_oit_engine(const struct lu_env *env,
                        }
                }
 
-               target = lfsck_object_find(env, lfsck, fid);
+               target = lfsck_object_find_bottom(env, lfsck, fid);
                if (IS_ERR(target)) {
                        CDEBUG(D_LFSCK, "%s: OIT scan failed at find target "
                               DFID", cookie "LPU64": rc = %d\n",
@@ -1082,7 +1079,7 @@ int lfsck_master_engine(void *args)
                               lfsck_lfsck2name(lfsck), rc);
        }
 
-       oit_di = oit_iops->init(env, oit_obj, lfsck->li_args_oit, BYPASS_CAPA);
+       oit_di = oit_iops->init(env, oit_obj, lfsck->li_args_oit);
        if (IS_ERR(oit_di)) {
                rc = PTR_ERR(oit_di);
                CDEBUG(D_LFSCK, "%s: master engine fail to init iteration: "
@@ -1124,6 +1121,7 @@ int lfsck_master_engine(void *args)
        else
                rc = 1;
 
+       lfsck_pos_fill(env, lfsck, &lfsck->li_pos_checkpoint, false);
        CDEBUG(D_LFSCK, "LFSCK exit: oit_flags = %#x, dir_flags = %#x, "
               "oit_cookie = "LPU64", dir_cookie = "LPX64", parent = "DFID
               ", pid = %d, rc = %d\n", lfsck->li_args_oit, lfsck->li_args_dir,
@@ -1207,7 +1205,6 @@ static int lfsck_assistant_query_others(const struct lu_env *env,
 
        lad->lad_touch_gen++;
        memset(lr, 0, sizeof(*lr));
-       lr->lr_index = lfsck_dev_idx(lfsck->li_bottom);
        lr->lr_event = LE_QUERY;
        lr->lr_active = com->lc_type;
        laia->laia_com = com;
@@ -1289,7 +1286,7 @@ out:
 }
 
 /**
- * Notify the LFSCK event to the instatnces on remote servers.
+ * Notify the LFSCK event to the instances on remote servers.
  *
  * The LFSCK assistant thread notifies the LFSCK instances on other
  * servers (MDT/OST) about some events, such as start new scanning,
@@ -1324,7 +1321,7 @@ static int lfsck_assistant_notify_others(const struct lu_env *env,
        if (set == NULL)
                RETURN(-ENOMEM);
 
-       lr->lr_index = lfsck_dev_idx(lfsck->li_bottom);
+       lr->lr_index = lfsck_dev_idx(lfsck);
        lr->lr_active = com->lc_type;
        laia->laia_com = com;
        laia->laia_lr = lr;
@@ -1335,8 +1332,7 @@ static int lfsck_assistant_notify_others(const struct lu_env *env,
                if (com->lc_type != LFSCK_TYPE_LAYOUT)
                        goto next;
 
-               lr->lr_valid = LSV_SPEED_LIMIT | LSV_ERROR_HANDLE | LSV_DRYRUN |
-                              LSV_ASYNC_WINDOWS | LSV_CREATE_OSTOBJ;
+               lr->lr_valid = LSV_SPEED_LIMIT | LSV_ERROR_HANDLE | LSV_DRYRUN;
                lr->lr_speed = bk->lb_speed_limit;
                lr->lr_version = bk->lb_version;
                lr->lr_param |= bk->lb_param;
@@ -1353,6 +1349,7 @@ static int lfsck_assistant_notify_others(const struct lu_env *env,
 
                        laia->laia_ltd = ltd;
                        ltd->ltd_layout_done = 0;
+                       ltd->ltd_synced_failures = 0;
                        rc = lfsck_async_request(env, ltd->ltd_exp, lr, set,
                                        lfsck_async_interpret_common,
                                        laia, LFSCK_NOTIFY);
@@ -1383,7 +1380,7 @@ next:
                spin_lock(&ltds->ltd_lock);
                if (com->lc_type == LFSCK_TYPE_LAYOUT) {
                        cfs_foreach_bit(ltds->ltd_tgts_bitmap, idx) {
-                               ltd = LTD_TGT(ltds, idx);
+                               ltd = lfsck_ltd2tgt(ltds, idx);
                                LASSERT(ltd != NULL);
 
                                if (!list_empty(&ltd->ltd_layout_list))
@@ -1396,7 +1393,7 @@ next:
                        }
                } else {
                        cfs_foreach_bit(ltds->ltd_tgts_bitmap, idx) {
-                               ltd = LTD_TGT(ltds, idx);
+                               ltd = lfsck_ltd2tgt(ltds, idx);
                                LASSERT(ltd != NULL);
 
                                if (!list_empty(&ltd->ltd_namespace_list))
@@ -1547,7 +1544,7 @@ again:
 
                        *gen = lad->lad_touch_gen;
                        list_move_tail(list, &lad->lad_mdt_list);
-                       if (ltd->ltd_namespace_failed)
+                       if (ltd->ltd_synced_failures)
                                continue;
 
                        atomic_inc(&ltd->ltd_ref);
@@ -1662,10 +1659,7 @@ int lfsck_assistant_engine(void *args)
                        /* Wake up the main engine thread only when the list
                         * is empty or half of the prefetched items have been
                         * handled to avoid too frequent thread schedule. */
-                       if (lad->lad_prefetched == 0 ||
-                           (bk->lb_async_windows != 0 &&
-                            bk->lb_async_windows / 2 ==
-                            lad->lad_prefetched))
+                       if (lad->lad_prefetched <= (bk->lb_async_windows / 2))
                                wakeup = true;
                        spin_unlock(&lad->lad_lock);
                        if (wakeup)
@@ -1699,18 +1693,18 @@ int lfsck_assistant_engine(void *args)
                        lad->lad_to_post = 0;
                        LASSERT(lad->lad_post_result > 0);
 
+                       /* Wakeup the master engine to go ahead. */
+                       wake_up_all(&mthread->t_ctl_waitq);
+
                        memset(lr, 0, sizeof(*lr));
                        lr->lr_event = LE_PHASE1_DONE;
                        lr->lr_status = lad->lad_post_result;
                        rc = lfsck_assistant_notify_others(env, com, lr);
-                       if (rc != 0)
-                               CDEBUG(D_LFSCK, "%s: LFSCK assistant failed to "
-                                      "notify others for %s post: rc = %d\n",
-                                      lfsck_lfsck2name(lfsck),
-                                      lad->lad_name, rc);
 
-                       /* Wakeup the master engine to go ahead. */
-                       wake_up_all(&mthread->t_ctl_waitq);
+                       CDEBUG(D_LFSCK, "%s: LFSCK assistant notified "
+                              "others for %s post: rc = %d\n",
+                              lfsck_lfsck2name(lfsck),
+                              lad->lad_name, rc);
                }
 
                if (lad->lad_to_double_scan) {