* GPL HEADER END
*/
/*
- * Copyright (c) 2013, 2015, Intel Corporation.
+ * Copyright (c) 2013, 2016, Intel Corporation.
*/
/*
* lustre/lfsck/lfsck_lib.c
#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>
"orphan",
"create_ostobj",
"create_mdtobj",
+ NULL,
+ "delay_create_ostobj",
NULL
};
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)
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);
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);
*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));
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) {
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,
&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)
}
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;
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;
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: {