Whamcloud - gitweb
LU-8929 lfsck: dumper gets current position properly
[fs/lustre-release.git] / lustre / lfsck / lfsck_lib.c
index f6406e0..98f7e24 100644 (file)
@@ -20,7 +20,7 @@
  * GPL HEADER END
  */
 /*
- * Copyright (c) 2013, 2015, Intel Corporation.
+ * Copyright (c) 2013, 2016, Intel Corporation.
  */
 /*
  * lustre/lfsck/lfsck_lib.c
@@ -32,7 +32,7 @@
 
 #include <linux/kthread.h>
 #include <linux/sched.h>
-#include <libcfs/list.h>
+#include <linux/list.h>
 #include <lu_object.h>
 #include <dt_object.h>
 #include <md_object.h>
@@ -86,6 +86,8 @@ const char *lfsck_param_names[] = {
        "orphan",
        "create_ostobj",
        "create_mdtobj",
+       NULL,
+       "delay_create_ostobj",
        NULL
 };
 
@@ -191,8 +193,8 @@ static int __lfsck_add_target(const struct lu_env *env,
        if (index >= ltds->ltd_tgts_bitmap->size) {
                __u32 newsize = max((__u32)ltds->ltd_tgts_bitmap->size,
                                    (__u32)BITS_PER_LONG);
-               cfs_bitmap_t *old_bitmap = ltds->ltd_tgts_bitmap;
-               cfs_bitmap_t *new_bitmap;
+               struct cfs_bitmap *old_bitmap = ltds->ltd_tgts_bitmap;
+               struct cfs_bitmap *new_bitmap;
 
                while (newsize < index + 1)
                        newsize <<= 1;
@@ -531,6 +533,14 @@ int lfsck_find_mdt_idx_by_fid(const struct lu_env *env,
        struct lu_seq_range     *range  = &lfsck_env_info(env)->lti_range;
        int                      rc;
 
+       if (unlikely(fid_seq(fid) == FID_SEQ_LOCAL_FILE)) {
+               /* "ROOT" is always on the MDT0. */
+               if (lu_fid_eq(fid, &lfsck->li_global_root_fid))
+                       return 0;
+
+               return lfsck_dev_idx(lfsck);
+       }
+
        fld_range_set_mdt(range);
        rc = fld_server_lookup(env, ss->ss_server_fld, fid_seq(fid), range);
        if (rc == 0)
@@ -634,13 +644,9 @@ static int lfsck_create_lpf_local(const struct lu_env *env,
        int                      rc;
        ENTRY;
 
-       rc = linkea_data_new(&ldata,
-                            &lfsck_env_info(env)->lti_linkea_buf2);
-       if (rc != 0)
-               RETURN(rc);
-
        cname = lfsck_name_get_const(env, name, strlen(name));
-       rc = linkea_add_buf(&ldata, cname, lfsck_dto2fid(parent));
+       rc = linkea_links_new(&ldata, &lfsck_env_info(env)->lti_linkea_buf2,
+                             cname, lfsck_dto2fid(parent));
        if (rc != 0)
                RETURN(rc);
 
@@ -793,13 +799,9 @@ static int lfsck_create_lpf_remote(const struct lu_env *env,
        int                      rc;
        ENTRY;
 
-       rc = linkea_data_new(&ldata,
-                            &lfsck_env_info(env)->lti_linkea_buf2);
-       if (rc != 0)
-               RETURN(rc);
-
        cname = lfsck_name_get_const(env, name, strlen(name));
-       rc = linkea_add_buf(&ldata, cname, lfsck_dto2fid(parent));
+       rc = linkea_links_new(&ldata, &lfsck_env_info(env)->lti_linkea_buf2,
+                             cname, lfsck_dto2fid(parent));
        if (rc != 0)
                RETURN(rc);
 
@@ -1034,7 +1036,7 @@ static int lfsck_create_lpf(const struct lu_env *env,
                *cfid = bk->lb_lpf_fid;
        }
 
-       child = lfsck_object_find_bottom(env, lfsck, cfid);
+       child = lfsck_object_find_bottom_new(env, lfsck, cfid);
        if (IS_ERR(child))
                GOTO(unlock, rc = PTR_ERR(child));
 
@@ -1738,17 +1740,14 @@ static inline int lfsck_instance_add(struct lfsck_instance *lfsck)
        return 0;
 }
 
-int lfsck_bits_dump(struct seq_file *m, int bits, const char *names[],
-                   const char *prefix)
+void lfsck_bits_dump(struct seq_file *m, int bits, const char *names[],
+                    const char *prefix)
 {
        int flag;
        int i;
        bool newline = (bits != 0 ? false : true);
-       int rc;
 
-       rc = seq_printf(m, "%s:%c", prefix, bits != 0 ? ' ' : '\n');
-       if (rc < 0)
-               return rc;
+       seq_printf(m, "%s:%c", prefix, bits != 0 ? ' ' : '\n');
 
        for (i = 0, flag = 1; bits != 0; i++, flag = 1 << i) {
                if (flag & bits) {
@@ -1757,54 +1756,43 @@ int lfsck_bits_dump(struct seq_file *m, int bits, const char *names[],
                                if (bits == 0)
                                        newline = true;
 
-                               rc = seq_printf(m, "%s%c", names[i],
-                                               newline ? '\n' : ',');
-                               if (rc < 0)
-                                       return rc;
+                               seq_printf(m, "%s%c", names[i],
+                                          newline ? '\n' : ',');
                        }
                }
        }
 
        if (!newline)
-               rc = seq_printf(m, "\n");
-
-       return rc;
+               seq_putc(m, '\n');
 }
 
-int lfsck_time_dump(struct seq_file *m, __u64 time, const char *name)
+void lfsck_time_dump(struct seq_file *m, __u64 time, const char *name)
 {
-       int rc;
-
        if (time == 0) {
-               rc = seq_printf(m, "%s_time: N/A\n", name);
-               if (rc == 0)
-                       rc = seq_printf(m, "time_since_%s: N/A\n", name);
-
-               return rc;
+               seq_printf(m, "%s_time: N/A\n", name);
+               seq_printf(m, "time_since_%s: N/A\n", name);
+       } else {
+               seq_printf(m, "%s_time: %llu\n", name, time);
+               seq_printf(m, "time_since_%s: %llu seconds\n",
+                          name, cfs_time_current_sec() - time);
        }
-
-       rc = seq_printf(m, "%s_time: "LPU64"\n", name, time);
-       if (rc == 0)
-               rc = seq_printf(m, "time_since_%s: "LPU64" seconds\n",
-                               name, cfs_time_current_sec() - time);
-
-       return rc;
 }
 
-int lfsck_pos_dump(struct seq_file *m, struct lfsck_position *pos,
-                  const char *prefix)
+void lfsck_pos_dump(struct seq_file *m, struct lfsck_position *pos,
+                   const char *prefix)
 {
        if (fid_is_zero(&pos->lp_dir_parent)) {
-               if (pos->lp_oit_cookie == 0)
-                       return seq_printf(m, "%s: N/A, N/A, N/A\n", prefix);
-
-               return seq_printf(m, "%s: "LPU64", N/A, N/A\n",
-                                 prefix, pos->lp_oit_cookie);
+               if (pos->lp_oit_cookie == 0) {
+                       seq_printf(m, "%s: N/A, N/A, N/A\n", prefix);
+                       return;
+               }
+               seq_printf(m, "%s: %llu, N/A, N/A\n",
+                          prefix, pos->lp_oit_cookie);
+       } else {
+               seq_printf(m, "%s: %llu, "DFID", %#llx\n",
+                          prefix, pos->lp_oit_cookie,
+                          PFID(&pos->lp_dir_parent), pos->lp_dir_cookie);
        }
-
-       return seq_printf(m, "%s: "LPU64", "DFID", "LPX64"\n",
-                         prefix, pos->lp_oit_cookie,
-                         PFID(&pos->lp_dir_parent), pos->lp_dir_cookie);
 }
 
 void lfsck_pos_fill(const struct lu_env *env, struct lfsck_instance *lfsck,
@@ -2640,6 +2628,96 @@ void lfsck_quit_generic(const struct lu_env *env,
                     &lwi);
 }
 
+int lfsck_load_one_trace_file(const struct lu_env *env,
+                             struct lfsck_component *com,
+                             struct dt_object *parent,
+                             struct dt_object **child,
+                             const struct dt_index_features *ft,
+                             const char *name, bool reset)
+{
+       struct lfsck_instance *lfsck = com->lc_lfsck;
+       struct dt_object *obj;
+       int rc;
+       ENTRY;
+
+       if (*child != NULL) {
+               struct dt_it *it;
+               const struct dt_it_ops *iops;
+               struct lu_fid *fid = &lfsck_env_info(env)->lti_fid3;
+
+               if (!reset)
+                       RETURN(0);
+
+               obj = *child;
+               rc = obj->do_ops->do_index_try(env, obj, ft);
+               if (rc)
+                       /* unlink by force */
+                       goto unlink;
+
+               iops = &obj->do_index_ops->dio_it;
+               it = iops->init(env, obj, 0);
+               if (IS_ERR(it))
+                       /* unlink by force */
+                       goto unlink;
+
+               fid_zero(fid);
+               rc = iops->get(env, it, (const struct dt_key *)fid);
+               if (rc >= 0) {
+                       rc = iops->next(env, it);
+                       iops->put(env, it);
+               }
+               iops->fini(env, it);
+               if (rc > 0)
+                       /* "rc > 0" means the index file is empty. */
+                       RETURN(0);
+
+unlink:
+               /* The old index is not empty, remove it firstly. */
+               rc = local_object_unlink(env, lfsck->li_bottom, parent, name);
+
+               CDEBUG(D_LFSCK, "%s: unlink lfsck sub trace file %s: rc = %d\n",
+                      lfsck_lfsck2name(com->lc_lfsck), name, rc);
+
+               if (rc)
+                       RETURN(rc);
+
+               lfsck_object_put(env, *child);
+               *child = NULL;
+       }
+
+       obj = local_index_find_or_create(env, lfsck->li_los, parent, name,
+                                        S_IFREG | S_IRUGO | S_IWUSR, ft);
+       if (IS_ERR(obj))
+               RETURN(PTR_ERR(obj));
+
+       rc = obj->do_ops->do_index_try(env, obj, ft);
+       if (rc == 0)
+               *child = obj;
+
+       RETURN(rc);
+}
+
+int lfsck_load_sub_trace_files(const struct lu_env *env,
+                              struct lfsck_component *com,
+                              const struct dt_index_features *ft,
+                              const char *prefix, bool reset)
+{
+       char *name = lfsck_env_info(env)->lti_key;
+       struct lfsck_sub_trace_obj *lsto;
+       int rc;
+       int i;
+
+       for (i = 0, rc = 0, lsto = &com->lc_sub_trace_objs[0];
+            i < LFSCK_STF_COUNT && rc == 0; i++, lsto++) {
+               snprintf(name, NAME_MAX, "%s_%02d", prefix, i);
+               rc = lfsck_load_one_trace_file(env, com,
+                               com->lc_lfsck->li_lfsck_dir,
+                               &lsto->lsto_obj, ft, name, reset);
+       }
+
+       return rc;
+}
+
 /* external interfaces */
 
 int lfsck_get_speed(struct seq_file *m, struct dt_device *key)
@@ -2667,7 +2745,7 @@ int lfsck_get_speed(struct seq_file *m, struct dt_device *key)
 }
 EXPORT_SYMBOL(lfsck_get_speed);
 
-int lfsck_set_speed(struct dt_device *key, int val)
+int lfsck_set_speed(struct dt_device *key, __u32 val)
 {
        struct lu_env           env;
        struct lfsck_instance  *lfsck;
@@ -2772,7 +2850,7 @@ int lfsck_dump(struct seq_file *m, struct dt_device *key, enum lfsck_type type)
        if (likely(lfsck != NULL)) {
                com = lfsck_component_find(lfsck, type);
                if (likely(com != NULL)) {
-                       rc = com->lc_ops->lfsck_dump(&env, com, m);
+                       com->lc_ops->lfsck_dump(&env, com, m);
                        lfsck_component_put(&env, com);
                } else {
                        rc = -ENOTSUPP;
@@ -3346,8 +3424,6 @@ int lfsck_in_notify(const struct lu_env *env, struct dt_device *key,
        case LE_FID_ACCESSED:
        case LE_PEER_EXIT:
        case LE_CONDITIONAL_DESTROY:
-       case LE_SKIP_NLINK_DECLARE:
-       case LE_SKIP_NLINK:
        case LE_SET_LMV_MASTER:
        case LE_SET_LMV_SLAVE:
        case LE_PAIRS_VERIFY: {