Whamcloud - gitweb
LU-6066 lfsck: handle file's nlink attribute properly
[fs/lustre-release.git] / lustre / lfsck / lfsck_namespace.c
index 7032827..5a5eb48 100644 (file)
@@ -20,7 +20,7 @@
  * GPL HEADER END
  */
 /*
- * Copyright (c) 2012, 2013, Intel Corporation.
+ * Copyright (c) 2013, 2014, Intel Corporation.
  */
 /*
  * lustre/lfsck/lfsck_namespace.c
@@ -1973,8 +1973,6 @@ int lfsck_namespace_rebuild_linkea(const struct lu_env *env,
        int                              rc     = 0;
        ENTRY;
 
-       LASSERT(!dt_object_remote(obj));
-
        th = dt_trans_create(env, dev);
        if (IS_ERR(th))
                GOTO(log, rc = PTR_ERR(th));
@@ -2890,7 +2888,7 @@ next:
  * \param[in] env      pointer to the thread context
  * \param[in] com      pointer to the lfsck component
  * \param[in] obj      pointer to the dt_object to be handled
- * \param[in,out] nlink        pointer to buffer to object's hard lock count before
+ * \param[in,out] la   pointer to buffer to object's attribute before
  *                     and after the repairing
  *
  * \retval             positive number for repaired cases
@@ -2899,10 +2897,10 @@ next:
  */
 static int lfsck_namespace_repair_nlink(const struct lu_env *env,
                                        struct lfsck_component *com,
-                                       struct dt_object *obj, __u32 *nlink)
+                                       struct dt_object *obj,
+                                       struct lu_attr *la)
 {
        struct lfsck_thread_info        *info   = lfsck_env_info(env);
-       struct lu_attr                  *la     = &info->lti_la3;
        struct lu_fid                   *tfid   = &info->lti_fid3;
        struct lfsck_namespace          *ns     = com->lc_file_ram;
        struct lfsck_instance           *lfsck  = com->lc_lfsck;
@@ -2912,7 +2910,7 @@ static int lfsck_namespace_repair_nlink(const struct lu_env *env,
        struct thandle                  *th     = NULL;
        struct linkea_data               ldata  = { 0 };
        struct lustre_handle             lh     = { 0 };
-       __u32                            old    = *nlink;
+       __u32                            old    = la->la_nlink;
        int                              rc     = 0;
        __u8                             flags;
        ENTRY;
@@ -2963,17 +2961,19 @@ static int lfsck_namespace_repair_nlink(const struct lu_env *env,
        if (flags & LNTF_SKIP_NLINK)
                GOTO(unlock, rc = 0);
 
-       rc = lfsck_links_read2(env, child, &ldata);
-       if (rc == -ENODATA)
-               GOTO(unlock, rc = 0);
+       rc = dt_attr_get(env, child, la, BYPASS_CAPA);
+       if (rc != 0)
+               GOTO(unlock, rc = (rc == -ENOENT ? 0 : rc));
 
+       rc = lfsck_links_read2(env, child, &ldata);
        if (rc != 0)
-               GOTO(unlock, rc);
+               GOTO(unlock, rc = (rc == -ENODATA ? 0 : rc));
 
-       if (*nlink == ldata.ld_leh->leh_reccount)
+       if (la->la_nlink == ldata.ld_leh->leh_reccount ||
+           unlikely(la->la_nlink == 0))
                GOTO(unlock, rc = 0);
 
-       la->la_nlink = *nlink = ldata.ld_leh->leh_reccount;
+       la->la_nlink = ldata.ld_leh->leh_reccount;
        if (lfsck->li_bookmark_ram.lb_param & LPF_DRYRUN)
                GOTO(unlock, rc = 1);
 
@@ -2994,7 +2994,7 @@ log:
 
        CDEBUG(D_LFSCK, "%s: namespace LFSCK repaired the object "DFID"'s "
               "nlink count from %u to %u: rc = %d\n",
-              lfsck_lfsck2name(lfsck), PFID(cfid), old, *nlink, rc);
+              lfsck_lfsck2name(lfsck), PFID(cfid), old, la->la_nlink, rc);
 
        if (rc != 0)
                ns->ln_flags |= LF_INCONSISTENT;
@@ -3572,37 +3572,38 @@ out:
                count = ldata.ld_leh->leh_reccount;
        }
 
-       /* If the LFSCK is marked as LF_INCOMPLETE, then means some
-        * MDT has ever tried to verify some remote MDT-object that
-        * resides on this MDT, but this MDT failed to respond such
-        * request. So means there may be some remote name entry on
-        * other MDT that references this object with another name,
-        * so we cannot know whether this linkEA is valid or not.
-        * So keep it there and maybe resolved when next LFSCK run. */
-       if (count == 0 && !(ns->ln_flags & LF_INCOMPLETE)) {
-               /* If the child becomes orphan, then insert it into
-                * the global .lustre/lost+found/MDTxxxx directory. */
-               rc = lfsck_namespace_insert_orphan(env, com, child, "", "O",
-                                                  &count);
-               if (rc < 0)
-                       return rc;
+       if (count == 0) {
+               /* If the LFSCK is marked as LF_INCOMPLETE, then means some
+                * MDT has ever tried to verify some remote MDT-object that
+                * resides on this MDT, but this MDT failed to respond such
+                * request. So means there may be some remote name entry on
+                * other MDT that references this object with another name,
+                * so we cannot know whether this linkEA is valid or not.
+                * So keep it there and maybe resolved when next LFSCK run. */
+               if (!(ns->ln_flags & LF_INCOMPLETE)) {
+                       /* If the child becomes orphan, then insert it into
+                        * the global .lustre/lost+found/MDTxxxx directory. */
+                       rc = lfsck_namespace_insert_orphan(env, com, child,
+                                                          "", "O", &count);
+                       if (rc < 0)
+                               return rc;
 
-               if (rc > 0) {
-                       ns->ln_mul_ref_repaired++;
-                       repaired = true;
+                       if (rc > 0) {
+                               ns->ln_mul_ref_repaired++;
+                               repaired = true;
+                       }
                }
-       }
-
-       rc = dt_attr_get(env, child, la, BYPASS_CAPA);
-       if (rc != 0)
-               return rc;
+       } else {
+               rc = dt_attr_get(env, child, la, BYPASS_CAPA);
+               if (rc != 0)
+                       return rc;
 
-       if (la->la_nlink != count) {
-               rc = lfsck_namespace_repair_nlink(env, com, child,
-                                                 &la->la_nlink);
-               if (rc > 0) {
-                       ns->ln_objs_nlink_repaired++;
-                       rc = 0;
+               if (la->la_nlink != 0 && la->la_nlink != count) {
+                       rc = lfsck_namespace_repair_nlink(env, com, child, la);
+                       if (rc > 0) {
+                               ns->ln_objs_nlink_repaired++;
+                               rc = 0;
+                       }
                }
        }
 
@@ -4150,9 +4151,28 @@ static int lfsck_namespace_exec_dir(const struct lu_env *env,
                                    struct lfsck_component *com,
                                    struct lu_dirent *ent, __u16 type)
 {
-       struct lfsck_assistant_data     *lad    = com->lc_data;
+       struct lfsck_assistant_data     *lad     = com->lc_data;
+       struct lfsck_instance           *lfsck   = com->lc_lfsck;
        struct lfsck_namespace_req      *lnr;
-       bool                             wakeup = false;
+       struct lfsck_bookmark           *bk      = &lfsck->li_bookmark_ram;
+       struct ptlrpc_thread            *mthread = &lfsck->li_thread;
+       struct ptlrpc_thread            *athread = &lad->lad_thread;
+       struct l_wait_info               lwi     = { 0 };
+       bool                             wakeup  = false;
+
+       l_wait_event(mthread->t_ctl_waitq,
+                    bk->lb_async_windows == 0 ||
+                    lad->lad_prefetched < bk->lb_async_windows ||
+                    !thread_is_running(mthread) ||
+                    thread_is_stopped(athread),
+                    &lwi);
+
+       if (unlikely(!thread_is_running(mthread)) ||
+                    thread_is_stopped(athread))
+               return 0;
+
+       if (unlikely(lfsck_is_dead_obj(lfsck->li_obj_dir)))
+               return 0;
 
        lnr = lfsck_namespace_assistant_req_init(com->lc_lfsck, ent, type);
        if (IS_ERR(lnr)) {
@@ -4304,8 +4324,8 @@ lfsck_namespace_dump(const struct lu_env *env, struct lfsck_component *com,
                                          lfsck->li_time_last_checkpoint;
                __u64 checked = ns->ln_items_checked + com->lc_new_checked;
                __u64 speed = checked;
-               __u64 new_checked = msecs_to_jiffies(com->lc_new_checked *
-                                                    MSEC_PER_SEC);
+               __u64 new_checked = com->lc_new_checked *
+                                   msecs_to_jiffies(MSEC_PER_SEC);
                __u32 rtime = ns->ln_run_time_phase1 +
                              cfs_duration_sec(duration + HALF_SEC);
 
@@ -4359,8 +4379,8 @@ lfsck_namespace_dump(const struct lu_env *env, struct lfsck_component *com,
                                com->lc_new_checked;
                __u64 speed1 = ns->ln_items_checked;
                __u64 speed2 = checked;
-               __u64 new_checked = msecs_to_jiffies(com->lc_new_checked *
-                                                    MSEC_PER_SEC);
+               __u64 new_checked = com->lc_new_checked *
+                                   msecs_to_jiffies(MSEC_PER_SEC);
                __u32 rtime = ns->ln_run_time_phase2 +
                              cfs_duration_sec(duration + HALF_SEC);