Whamcloud - gitweb
LU-3319 procfs: move mdd/ofd proc handling to seq_files
[fs/lustre-release.git] / lustre / lfsck / lfsck_layout.c
index 98e61d2..cb39f8c 100644 (file)
@@ -492,7 +492,7 @@ static struct lfsck_rbtree_node *lfsck_rbtree_new(const struct lu_env *env,
                return ERR_PTR(-ENOMEM);
        }
 
-       rb_init_node(&lrn->lrn_node);
+       RB_CLEAR_NODE(&lrn->lrn_node);
        lrn->lrn_seq = fid_seq(fid);
        lrn->lrn_first_oid = fid_oid(fid) & ~LFSCK_RBTREE_BITMAP_MASK;
        atomic_set(&lrn->lrn_known_count, 0);
@@ -1460,6 +1460,7 @@ static int lfsck_layout_master_notify_others(const struct lu_env *env,
                        break;
 
                /* link other MDT targets locallly. */
+               ltds = &lfsck->li_mdt_descs;
                spin_lock(&ltds->ltd_lock);
                cfs_foreach_bit(ltds->ltd_tgts_bitmap, idx) {
                        ltd = LTD_TGT(ltds, idx);
@@ -1905,17 +1906,57 @@ out:
 }
 
 /**
- * \retval      +1: repaired
- * \retval       0: did nothing
- * \retval     -ve: on error
+ * This function will create the MDT-object will the given (partial) LOV EA.
+ *
+ * Under some data corruption cases, the MDT-object of the file may be lost,
+ * but its OST-objects, or some of them are there. The layout LFSCK needs to
+ * re-create the MDT-object with the orphan OST-object(s) information.
+ *
+ * On the other hand, the LFSCK may has created some OST-object for repairing
+ * dangling LOV EA reference, but as the LFSCK processing, it may find that
+ * the old OST-object is there and should replace the former new created OST
+ * object. Unfortunately, some others have modified such newly created object.
+ * To keep the data (both new and old), the LFSCK will create MDT-object with
+ * new FID to reference the original OST-object.
+ *
+ * \param[in] env      pointer to the thread context
+ * \param[in] com      pointer to the lfsck component
+ * \param[in] ltd      pointer to target device descriptor
+ * \param[in] rec      pointer to the record for the orphan OST-object
+ * \param[in] cfid     pointer to FID for the orphan OST-object
+ * \param[in] infix    additional information, such as the FID for original
+ *                     MDT-object and the stripe offset in the LOV EA
+ * \param[in] type     the type for describing why the orphan MDT-object is
+ *                     created. The rules are as following:
+ *
+ *  type "C":          Multiple OST-objects claim the same MDT-object and the
+ *                     same slot in the layout EA. Then the LFSCK will create
+ *                     new MDT-object(s) to hold the conflict OST-object(s).
+ *
+ *  type "N":          The orphan OST-object does not know which one was the
+ *                     real parent MDT-object, so the LFSCK uses new FID for
+ *                     its parent MDT-object.
+ *
+ *  type "R":          The orphan OST-object knows its parent MDT-object FID,
+ *                     but does not know the position (the file name) in the
+ *                     namespace.
+ *
+ * The orphan name will be like:
+ * ${FID}-${infix}-${type}-${conflict_version}
+ *
+ * \param[in] ea_off   the stripe offset in the LOV EA
+ *
+ * \retval             positive on repaired something
+ * \retval             if needs to repair nothing
+ * \retval             negative error number on failure
  */
 static int lfsck_layout_recreate_parent(const struct lu_env *env,
                                        struct lfsck_component *com,
                                        struct lfsck_tgt_desc *ltd,
                                        struct lu_orphan_rec *rec,
                                        struct lu_fid *cfid,
-                                       const char *prefix,
-                                       const char *postfix,
+                                       const char *infix,
+                                       const char *type,
                                        __u32 ea_off)
 {
        struct lfsck_thread_info        *info   = lfsck_env_info(env);
@@ -1963,48 +2004,24 @@ static int lfsck_layout_recreate_parent(const struct lu_env *env,
                        RETURN(PTR_ERR(cobj));
        }
 
-       CDEBUG(D_LFSCK, "Re-create the lost MDT-object: parent "
-              DFID", child "DFID", OST-index %u, stripe-index %u, "
-              "prefix %s, postfix %s\n",
-              PFID(pfid), PFID(cfid), ltd->ltd_index, ea_off, prefix, postfix);
+       CDEBUG(D_LFSCK, "Re-create the lost MDT-object: parent "DFID", child "
+              DFID", OST-index %u, stripe-index %u, infix %s, type %s\n",
+              PFID(pfid), PFID(cfid), ltd->ltd_index, ea_off, infix, type);
 
        pobj = lfsck_object_find_by_dev(env, lfsck->li_bottom, pfid);
        if (IS_ERR(pobj))
                GOTO(put, rc = PTR_ERR(pobj));
 
-       LASSERT(prefix != NULL);
-       LASSERT(postfix != NULL);
+       LASSERT(infix != NULL);
+       LASSERT(type != NULL);
 
-       /** name rules:
-        *
-        *  1. Use the MDT-object's FID as the name with prefix and postfix.
-        *
-        *  1.1 prefix "C-":    More than one OST-objects claim the same
-        *                      MDT-object and the same slot in the layout EA.
-        *                      It may be created for dangling referenced MDT
-        *                      object or may be not.
-        *  1.2 prefix "N-":    The orphan OST-object does not know which one
-        *                      is the real parent, so the LFSCK assign a new
-        *                      FID as its parent.
-        *  1.3 prefix "R-":    The orphan OST-object know its parent FID but
-        *                      does not know the position in the namespace.
-        *
-        *  2. If there is name conflict, append more index for new name. */
-       sprintf(name, "%s"DFID"%s", prefix, PFID(pfid), postfix);
        do {
+               snprintf(name, NAME_MAX, DFID"%s-%s-%d", PFID(pfid), infix,
+                        type, idx++);
                rc = dt_lookup(env, lfsck->li_lpf_obj, (struct dt_rec *)tfid,
                               (const struct dt_key *)name, BYPASS_CAPA);
                if (rc != 0 && rc != -ENOENT)
                        GOTO(put, rc);
-
-               if (unlikely(rc == 0)) {
-                       CWARN("%s: The name %s under lost+found has been used "
-                             "by the "DFID". Try to increase the FID version "
-                             "for the new file name.\n",
-                             lfsck_lfsck2name(lfsck), name, PFID(tfid));
-                       sprintf(name, "%s"DFID"%s-%d", prefix, PFID(pfid),
-                               postfix, ++idx);
-               }
        } while (rc == 0);
 
        memset(la, 0, sizeof(*la));
@@ -2298,7 +2315,7 @@ static int lfsck_layout_conflict_create(const struct lu_env *env,
        struct lfsck_thread_info *info          = lfsck_env_info(env);
        struct lu_fid            *cfid2         = &info->lti_fid2;
        struct ost_id            *oi            = &info->lti_oi;
-       char                     *postfix       = info->lti_tmpbuf;
+       char                     *infix         = info->lti_tmpbuf;
        struct lov_mds_md_v1     *lmm           = ea_buf->lb_buf;
        struct dt_device         *dev           = com->lc_lfsck->li_bottom;
        struct thandle           *th            = NULL;
@@ -2334,10 +2351,10 @@ static int lfsck_layout_conflict_create(const struct lu_env *env,
                ea_buf->lb_len = ori_len;
 
                fid_zero(&rec->lor_fid);
-               snprintf(postfix, LFSCK_TMPBUF_LEN, "-"DFID"-%x",
+               snprintf(infix, LFSCK_TMPBUF_LEN, "-"DFID"-%x",
                         PFID(lu_object_fid(&parent->do_lu)), ea_off);
                rc = lfsck_layout_recreate_parent(env, com, ltd, rec, cfid,
-                                                 "C-", postfix, ea_off);
+                                                 infix, "C", ea_off);
 
                RETURN(rc);
        }
@@ -2648,7 +2665,7 @@ static int lfsck_layout_scan_orphan_one(const struct lu_env *env,
 
        if (fid_is_zero(pfid)) {
                rc = lfsck_layout_recreate_parent(env, com, ltd, rec, cfid,
-                                                 "N-", "", ea_off);
+                                                 "", "N", ea_off);
                GOTO(out, rc);
        }
 
@@ -2666,7 +2683,7 @@ static int lfsck_layout_scan_orphan_one(const struct lu_env *env,
        if (dt_object_exists(parent) == 0) {
                lu_object_put(env, &parent->do_lu);
                rc = lfsck_layout_recreate_parent(env, com, ltd, rec, cfid,
-                                                 "R-", "", ea_off);
+                                                 "", "R", ea_off);
                GOTO(out, rc);
        }
 
@@ -4949,69 +4966,53 @@ static int lfsck_layout_slave_post(const struct lu_env *env,
 }
 
 static int lfsck_layout_dump(const struct lu_env *env,
-                            struct lfsck_component *com, char *buf, int len)
+                            struct lfsck_component *com, struct seq_file *m)
 {
        struct lfsck_instance   *lfsck = com->lc_lfsck;
        struct lfsck_bookmark   *bk    = &lfsck->li_bookmark_ram;
        struct lfsck_layout     *lo    = com->lc_file_ram;
-       int                      save  = len;
-       int                      ret   = -ENOSPC;
        int                      rc;
 
        down_read(&com->lc_sem);
-       rc = snprintf(buf, len,
-                     "name: lfsck_layout\n"
+       seq_printf(m, "name: lfsck_layout\n"
                      "magic: %#x\n"
                      "version: %d\n"
                      "status: %s\n",
                      lo->ll_magic,
                      bk->lb_version,
                      lfsck_status2names(lo->ll_status));
-       if (rc <= 0)
-               goto out;
 
-       buf += rc;
-       len -= rc;
-       rc = lfsck_bits_dump(&buf, &len, lo->ll_flags, lfsck_flags_names,
-                            "flags");
+       rc = lfsck_bits_dump(m, lo->ll_flags, lfsck_flags_names, "flags");
        if (rc < 0)
                goto out;
 
-       rc = lfsck_bits_dump(&buf, &len, bk->lb_param, lfsck_param_names,
-                            "param");
+       rc = lfsck_bits_dump(m, bk->lb_param, lfsck_param_names, "param");
        if (rc < 0)
                goto out;
 
-       rc = lfsck_time_dump(&buf, &len, lo->ll_time_last_complete,
+       rc = lfsck_time_dump(m, lo->ll_time_last_complete,
                             "time_since_last_completed");
        if (rc < 0)
                goto out;
 
-       rc = lfsck_time_dump(&buf, &len, lo->ll_time_latest_start,
+       rc = lfsck_time_dump(m, lo->ll_time_latest_start,
                             "time_since_latest_start");
        if (rc < 0)
                goto out;
 
-       rc = lfsck_time_dump(&buf, &len, lo->ll_time_last_checkpoint,
+       rc = lfsck_time_dump(m, lo->ll_time_last_checkpoint,
                             "time_since_last_checkpoint");
        if (rc < 0)
                goto out;
 
-       rc = snprintf(buf, len,
-                     "latest_start_position: "LPU64"\n"
+       seq_printf(m, "latest_start_position: "LPU64"\n"
                      "last_checkpoint_position: "LPU64"\n"
                      "first_failure_position: "LPU64"\n",
                      lo->ll_pos_latest_start,
                      lo->ll_pos_last_checkpoint,
                      lo->ll_pos_first_inconsistent);
-       if (rc <= 0)
-               goto out;
 
-       buf += rc;
-       len -= rc;
-
-       rc = snprintf(buf, len,
-                     "success_count: %u\n"
+       seq_printf(m, "success_count: %u\n"
                      "repaired_dangling: "LPU64"\n"
                      "repaired_unmatched_pair: "LPU64"\n"
                      "repaired_multiple_referenced: "LPU64"\n"
@@ -5031,11 +5032,6 @@ static int lfsck_layout_dump(const struct lu_env *env,
                      lo->ll_objs_skipped,
                      lo->ll_objs_failed_phase1,
                      lo->ll_objs_failed_phase2);
-       if (rc <= 0)
-               goto out;
-
-       buf += rc;
-       len -= rc;
 
        if (lo->ll_status == LS_SCANNING_PHASE1) {
                __u64 pos;
@@ -5053,8 +5049,7 @@ static int lfsck_layout_dump(const struct lu_env *env,
                        do_div(new_checked, duration);
                if (rtime != 0)
                        do_div(speed, rtime);
-               rc = snprintf(buf, len,
-                             "checked_phase1: "LPU64"\n"
+               seq_printf(m, "checked_phase1: "LPU64"\n"
                              "checked_phase2: "LPU64"\n"
                              "run_time_phase1: %u seconds\n"
                              "run_time_phase2: %u seconds\n"
@@ -5068,11 +5063,6 @@ static int lfsck_layout_dump(const struct lu_env *env,
                              lo->ll_run_time_phase2,
                              speed,
                              new_checked);
-               if (rc <= 0)
-                       goto out;
-
-               buf += rc;
-               len -= rc;
 
                LASSERT(lfsck->li_di_oit != NULL);
 
@@ -5085,12 +5075,8 @@ static int lfsck_layout_dump(const struct lu_env *env,
                pos = iops->store(env, lfsck->li_di_oit);
                if (!lfsck->li_current_oit_processed)
                        pos--;
-               rc = snprintf(buf, len, "current_position: "LPU64"\n", pos);
-               if (rc <= 0)
-                       goto out;
+               seq_printf(m, "current_position: "LPU64"\n", pos);
 
-               buf += rc;
-               len -= rc;
        } else if (lo->ll_status == LS_SCANNING_PHASE2) {
                cfs_duration_t duration = cfs_time_current() -
                                          lfsck->li_time_last_checkpoint;
@@ -5108,29 +5094,26 @@ static int lfsck_layout_dump(const struct lu_env *env,
                        do_div(speed1, lo->ll_run_time_phase1);
                if (rtime != 0)
                        do_div(speed2, rtime);
-               rc = snprintf(buf, len,
-                             "checked_phase1: "LPU64"\n"
-                             "checked_phase2: "LPU64"\n"
-                             "run_time_phase1: %u seconds\n"
-                             "run_time_phase2: %u seconds\n"
-                             "average_speed_phase1: "LPU64" items/sec\n"
-                             "average_speed_phase2: "LPU64" items/sec\n"
-                             "real-time_speed_phase1: N/A\n"
-                             "real-time_speed_phase2: "LPU64" items/sec\n"
-                             "current_position: "DFID"\n",
-                             lo->ll_objs_checked_phase1,
-                             checked,
-                             lo->ll_run_time_phase1,
-                             rtime,
-                             speed1,
-                             speed2,
-                             new_checked,
-                             PFID(&com->lc_fid_latest_scanned_phase2));
+               rc = seq_printf(m, "checked_phase1: "LPU64"\n"
+                               "checked_phase2: "LPU64"\n"
+                               "run_time_phase1: %u seconds\n"
+                               "run_time_phase2: %u seconds\n"
+                               "average_speed_phase1: "LPU64" items/sec\n"
+                               "average_speed_phase2: "LPU64" items/sec\n"
+                               "real-time_speed_phase1: N/A\n"
+                               "real-time_speed_phase2: "LPU64" items/sec\n"
+                               "current_position: "DFID"\n",
+                               lo->ll_objs_checked_phase1,
+                               checked,
+                               lo->ll_run_time_phase1,
+                               rtime,
+                               speed1,
+                               speed2,
+                               new_checked,
+                               PFID(&com->lc_fid_latest_scanned_phase2));
                if (rc <= 0)
                        goto out;
 
-               buf += rc;
-               len -= rc;
        } else {
                __u64 speed1 = lo->ll_objs_checked_phase1;
                __u64 speed2 = lo->ll_objs_checked_phase2;
@@ -5139,34 +5122,26 @@ static int lfsck_layout_dump(const struct lu_env *env,
                        do_div(speed1, lo->ll_run_time_phase1);
                if (lo->ll_run_time_phase2 != 0)
                        do_div(speed2, lo->ll_run_time_phase2);
-               rc = snprintf(buf, len,
-                             "checked_phase1: "LPU64"\n"
-                             "checked_phase2: "LPU64"\n"
-                             "run_time_phase1: %u seconds\n"
-                             "run_time_phase2: %u seconds\n"
-                             "average_speed_phase1: "LPU64" items/sec\n"
-                             "average_speed_phase2: "LPU64" objs/sec\n"
-                             "real-time_speed_phase1: N/A\n"
-                             "real-time_speed_phase2: N/A\n"
-                             "current_position: N/A\n",
-                             lo->ll_objs_checked_phase1,
-                             lo->ll_objs_checked_phase2,
-                             lo->ll_run_time_phase1,
-                             lo->ll_run_time_phase2,
-                             speed1,
-                             speed2);
-               if (rc <= 0)
-                       goto out;
-
-               buf += rc;
-               len -= rc;
+               seq_printf(m, "checked_phase1: "LPU64"\n"
+                          "checked_phase2: "LPU64"\n"
+                          "run_time_phase1: %u seconds\n"
+                          "run_time_phase2: %u seconds\n"
+                          "average_speed_phase1: "LPU64" items/sec\n"
+                          "average_speed_phase2: "LPU64" objs/sec\n"
+                          "real-time_speed_phase1: N/A\n"
+                          "real-time_speed_phase2: N/A\n"
+                          "current_position: N/A\n",
+                          lo->ll_objs_checked_phase1,
+                          lo->ll_objs_checked_phase2,
+                          lo->ll_run_time_phase1,
+                          lo->ll_run_time_phase2,
+                          speed1,
+                          speed2);
        }
-       ret = save - len;
-
 out:
        up_read(&com->lc_sem);
 
-       return ret;
+       return rc;
 }
 
 static int lfsck_layout_master_double_scan(const struct lu_env *env,
@@ -5288,6 +5263,10 @@ static void lfsck_layout_master_data_release(const struct lu_env *env,
                                 ltd_layout_list) {
                list_del_init(&ltd->ltd_layout_list);
        }
+       spin_unlock(&ltds->ltd_lock);
+
+       ltds = &lfsck->li_mdt_descs;
+       spin_lock(&ltds->ltd_lock);
        list_for_each_entry_safe(ltd, next, &llmd->llmd_mdt_phase1_list,
                                 ltd_layout_phase_list) {
                list_del_init(&ltd->ltd_layout_phase_list);