* GPL HEADER END
*/
/*
- * Copyright (c) 2014, Intel Corporation.
+ * Copyright (c) 2014, 2016, Intel Corporation.
*/
/*
* lustre/lfsck/lfsck_layout.c
__u64 llst_gen;
atomic_t llst_ref;
__u32 llst_index;
+ /* How many times we have failed to get the master status. */
+ int llst_failures;
};
struct lfsck_layout_slave_data {
return 0;
}
-#define LFSCK_RBTREE_BITMAP_SIZE PAGE_CACHE_SIZE
+#define LFSCK_RBTREE_BITMAP_SIZE PAGE_SIZE
#define LFSCK_RBTREE_BITMAP_WIDTH (LFSCK_RBTREE_BITMAP_SIZE << 3)
#define LFSCK_RBTREE_BITMAP_MASK (LFSCK_RBTREE_BITMAP_WIDTH - 1)
le64_to_cpu(src->ll_objs_repaired[i]);
des->ll_objs_skipped = le64_to_cpu(src->ll_objs_skipped);
des->ll_bitmap_size = le32_to_cpu(src->ll_bitmap_size);
+ fid_le_to_cpu(&des->ll_fid_latest_scanned_phase2,
+ &src->ll_fid_latest_scanned_phase2);
}
static void lfsck_layout_cpu_to_le(struct lfsck_layout *des,
cpu_to_le64(src->ll_objs_repaired[i]);
des->ll_objs_skipped = cpu_to_le64(src->ll_objs_skipped);
des->ll_bitmap_size = cpu_to_le32(src->ll_bitmap_size);
+ fid_cpu_to_le(&des->ll_fid_latest_scanned_phase2,
+ &src->ll_fid_latest_scanned_phase2);
}
/**
struct dt_object *obj = com->lc_obj;
struct lfsck_assistant_data *lad = com->lc_data;
struct lfsck_layout *lo = com->lc_file_ram;
- cfs_bitmap_t *bitmap = lad->lad_bitmap;
+ struct cfs_bitmap *bitmap = lad->lad_bitmap;
loff_t pos = com->lc_file_size;
ssize_t size;
__u32 nbits;
if (nbits > bitmap->size) {
__u32 new_bits = bitmap->size;
- cfs_bitmap_t *new_bitmap;
+ struct cfs_bitmap *new_bitmap;
while (new_bits < nbits)
new_bits <<= 1;
struct lfsck_layout *lo = com->lc_file_disk;
struct thandle *th;
struct dt_device *dev = lfsck_obj2dev(obj);
- cfs_bitmap_t *bitmap = NULL;
+ struct cfs_bitmap *bitmap = NULL;
loff_t pos;
ssize_t size = com->lc_file_size;
__u32 nbits = 0;
lo->ll_status = LS_INIT;
down_write(&com->lc_sem);
rc = lfsck_layout_store(env, com);
+ if (rc == 0 && com->lc_lfsck->li_master)
+ rc = lfsck_load_sub_trace_files(env, com,
+ &dt_lfsck_layout_dangling_features, LFSCK_LAYOUT, true);
up_write(&com->lc_sem);
return rc;
log:
CDEBUG(D_LFSCK, "%s: layout LFSCK will create LAST_ID for <seq> "
- LPX64": rc = %d\n",
+ "%#llx: rc = %d\n",
lfsck_lfsck2name(lfsck), fid_seq(lfsck_dto2fid(obj)), rc);
return rc;
lo->ll_flags |= LF_CRASHED_LASTID;
CDEBUG(D_LFSCK, "%s: layout LFSCK finds crashed "
- "LAST_ID file (1) for the sequence "LPX64
- ", old value "LPU64", known value "LPU64"\n",
+ "LAST_ID file (1) for the sequence %#llx"
+ ", old value %llu, known value %llu\n",
lfsck_lfsck2name(lfsck), lls->lls_seq,
lastid, lls->lls_lastid);
}
continue;
CDEBUG(D_LFSCK, "%s: layout LFSCK will sync the LAST_ID for "
- "<seq> "LPX64" as <oid> "LPU64"\n",
+ "<seq> %#llx as <oid> %llu\n",
lfsck_lfsck2name(lfsck), lls->lls_seq, lls->lls_lastid);
if (bk->lb_param & LPF_DRYRUN) {
if (IS_ERR(th)) {
rc1 = PTR_ERR(th);
CDEBUG(D_LFSCK, "%s: layout LFSCK failed to store "
- "the LAST_ID for <seq> "LPX64"(1): rc = %d\n",
+ "the LAST_ID for <seq> %#llx(1): rc = %d\n",
lfsck_lfsck2name(com->lc_lfsck),
lls->lls_seq, rc1);
continue;
if (rc != 0) {
rc1 = rc;
CDEBUG(D_LFSCK, "%s: layout LFSCK failed to store "
- "the LAST_ID for <seq> "LPX64"(2): rc = %d\n",
+ "the LAST_ID for <seq> %#llx(2): rc = %d\n",
lfsck_lfsck2name(com->lc_lfsck),
lls->lls_seq, rc1);
}
lo->ll_flags |= LF_CRASHED_LASTID;
CDEBUG(D_LFSCK, "%s: layout LFSCK cannot find the "
- "LAST_ID file for sequence "LPX64"\n",
+ "LAST_ID file for sequence %#llx\n",
lfsck_lfsck2name(lfsck), lls->lls_seq);
if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_DELAY4) &&
lo->ll_flags |= LF_CRASHED_LASTID;
CDEBUG(D_LFSCK, "%s: layout LFSCK finds invalid "
- "LAST_ID file for the sequence "LPX64
+ "LAST_ID file for the sequence %#llx"
": rc = %d\n",
lfsck_lfsck2name(lfsck), lls->lls_seq, rc);
}
lo->ll_pos_first_inconsistent = cookie;
CDEBUG(D_LFSCK, "%s: layout LFSCK hit first non-repaired "
- "inconsistency at the pos ["LPU64"]\n",
+ "inconsistency at the pos [%llu]\n",
lfsck_lfsck2name(lfsck),
lo->ll_pos_first_inconsistent);
}
{
int rc;
+ /* XXX: If there is something worng or it needs to repair nothing,
+ * then notify the lower to stop the modification. Currently,
+ * we use th_result for such purpose, that may be replaced by
+ * some rollback mechanism in the future. */
handle->th_result = result;
rc = dt_trans_stop(env, dev, handle);
- if (rc > 0)
- rc = 0;
- else if (rc == 0)
- rc = 1;
+ if (result != 0)
+ return result > 0 ? 0 : result;
+
+ return rc == 0 ? 1 : rc;
+}
+
+static int lfsck_layout_ins_dangling_rec(const struct lu_env *env,
+ struct lfsck_component *com,
+ const struct lu_fid *pfid,
+ const struct lu_fid *cfid,
+ __u32 ea_off, __u32 ost_idx)
+{
+ struct lu_fid *key = &lfsck_env_info(env)->lti_fid3;
+ struct lu_fid *rec = &lfsck_env_info(env)->lti_fid4;
+ struct dt_device *dev;
+ struct dt_object *obj;
+ struct thandle *th = NULL;
+ int idx;
+ int rc = 0;
+ ENTRY;
+
+ idx = lfsck_sub_trace_file_fid2idx(pfid);
+ obj = com->lc_sub_trace_objs[idx].lsto_obj;
+ dev = lfsck_obj2dev(obj);
+ fid_cpu_to_be(key, pfid);
+ key->f_ver = cpu_to_be32(ea_off);
+ fid_cpu_to_be(rec, cfid);
+ rec->f_ver = cpu_to_be32(ost_idx);
+
+ mutex_lock(&com->lc_sub_trace_objs[idx].lsto_mutex);
+
+ th = dt_trans_create(env, dev);
+ if (IS_ERR(th))
+ GOTO(unlock, rc = PTR_ERR(th));
+
+ rc = dt_declare_insert(env, obj,
+ (const struct dt_rec *)rec,
+ (const struct dt_key *)key, th);
+ if (rc)
+ GOTO(unlock, rc);
+
+ rc = dt_trans_start_local(env, dev, th);
+ if (rc)
+ GOTO(unlock, rc);
+
+ rc = dt_insert(env, obj, (const struct dt_rec *)rec,
+ (const struct dt_key *)key, th, 1);
+
+ GOTO(unlock, rc);
+
+unlock:
+ if (th != NULL && !IS_ERR(th))
+ dt_trans_stop(env, dev, th);
+
+ mutex_unlock(&com->lc_sub_trace_objs[idx].lsto_mutex);
+
+ CDEBUG(D_LFSCK, "%s: insert the paris "DFID" => "DFID", ea_off = %u, "
+ "ost_idx = %u, into the trace file for further dangling check: "
+ "rc = %d\n", lfsck_lfsck2name(com->lc_lfsck),
+ PFID(pfid), PFID(cfid), ea_off, ost_idx, rc);
+
+ return rc;
+}
+
+static int lfsck_layout_del_dangling_rec(const struct lu_env *env,
+ struct lfsck_component *com,
+ const struct lu_fid *fid,
+ __u32 ea_off)
+{
+ struct lu_fid *key = &lfsck_env_info(env)->lti_fid3;
+ struct dt_device *dev;
+ struct dt_object *obj;
+ struct thandle *th = NULL;
+ int idx;
+ int rc = 0;
+ ENTRY;
+
+ idx = lfsck_sub_trace_file_fid2idx(fid);
+ obj = com->lc_sub_trace_objs[idx].lsto_obj;
+ dev = lfsck_obj2dev(obj);
+ fid_cpu_to_be(key, fid);
+ key->f_ver = cpu_to_be32(ea_off);
+
+ mutex_lock(&com->lc_sub_trace_objs[idx].lsto_mutex);
+
+ th = dt_trans_create(env, dev);
+ if (IS_ERR(th))
+ GOTO(unlock, rc = PTR_ERR(th));
+
+ rc = dt_declare_delete(env, obj, (const struct dt_key *)key, th);
+ if (rc)
+ GOTO(unlock, rc);
+
+ rc = dt_trans_start_local(env, dev, th);
+ if (rc)
+ GOTO(unlock, rc);
+
+ rc = dt_delete(env, obj, (const struct dt_key *)key, th);
+
+ GOTO(unlock, rc);
+
+unlock:
+ if (th != NULL && !IS_ERR(th))
+ dt_trans_stop(env, dev, th);
+
+ mutex_unlock(&com->lc_sub_trace_objs[idx].lsto_mutex);
+
+ CDEBUG(D_LFSCK, "%s: delete the dangling record for "DFID
+ ", ea_off = %u from the trace file: rc = %d\n",
+ lfsck_lfsck2name(com->lc_lfsck), PFID(fid), ea_off, rc);
return rc;
}
struct lfsck_thread_info *info = lfsck_env_info(env);
struct dt_insert_rec *dtrec = &info->lti_dt_rec;
char *name = info->lti_key;
- struct lu_attr *la = &info->lti_la;
+ struct lu_attr *la = &info->lti_la2;
struct dt_object_format *dof = &info->lti_dof;
struct lfsck_instance *lfsck = com->lc_lfsck;
struct lu_fid *pfid = &rec->lor_fid;
if (rc != -ENOENT)
GOTO(unlock, rc);
- rc = linkea_data_new(&ldata,
- &lfsck_env_info(env)->lti_linkea_buf);
- if (rc != 0)
- GOTO(unlock, rc);
-
pname = lfsck_name_get_const(env, name, strlen(name));
- rc = linkea_add_buf(&ldata, pname, lfsck_dto2fid(lfsck->li_lpf_obj));
+ rc = linkea_links_new(&ldata, &lfsck_env_info(env)->lti_linkea_buf,
+ pname, lfsck_dto2fid(lfsck->li_lpf_obj));
if (rc != 0)
GOTO(unlock, rc);
{
struct lfsck_thread_info *info = lfsck_env_info(env);
struct lu_attr *la = &info->lti_la;
- ldlm_policy_data_t *policy = &info->lti_policy;
+ union ldlm_policy_data *policy = &info->lti_policy;
struct ldlm_res_id *resid = &info->lti_resid;
struct lfsck_instance *lfsck = com->lc_lfsck;
struct dt_device *dev = lfsck->li_bottom;
int rc = 0;
ENTRY;
+ while (CFS_FAIL_TIMEOUT(OBD_FAIL_LFSCK_DELAY3, cfs_fail_val)) {
+ if (unlikely(!thread_is_running(&com->lc_lfsck->li_thread)))
+ RETURN(0);
+ }
+
ostid_le_to_cpu(&slot->l_ost_oi, oi);
rc = ostid_to_fid(cfid2, oi, ost_idx2);
if (rc != 0)
if (!S_ISREG(lu_object_attr(&parent->do_lu)))
GOTO(put, rc = -EISDIR);
+ /* The orphan OST-object claims to be the parent's stripe, then
+ * related dangling record in the trace file is meaningless. */
+ rc = lfsck_layout_del_dangling_rec(env, com, pfid, ea_off);
+ if (rc != 0 && rc != -ENOENT)
+ GOTO(put, rc);
+
rc = lfsck_layout_recreate_lovea(env, com, ltd, rec, parent, cfid,
ltd->ltd_index, ea_off);
if (unlikely(IS_ERR(obj)))
GOTO(log, rc = PTR_ERR(obj));
- rc = obj->do_ops->do_index_try(env, obj, &dt_lfsck_orphan_features);
+ rc = obj->do_ops->do_index_try(env, obj,
+ &dt_lfsck_layout_orphan_features);
if (rc != 0)
GOTO(put, rc);
return rc > 0 ? 0 : rc;
}
-/* For the MDT-object with dangling reference, we need to repare the
- * inconsistency according to the LFSCK sponsor's requirement:
+/**
+ * Repair the MDT-object with dangling LOV EA reference.
+ *
+ * we need to repair the inconsistency according to the users' requirement:
*
* 1) Keep the inconsistency there and report the inconsistency case,
* then give the chance to the application to find related issues,
* and the users can make the decision about how to handle it with
* more human knownledge. (by default)
*
- * 2) Re-create the missing OST-object with the FID/owner information. */
-static int lfsck_layout_repair_dangling(const struct lu_env *env,
- struct lfsck_component *com,
- struct dt_object *parent,
- struct lfsck_layout_req *llr,
- struct lu_attr *la)
+ * 2) Re-create the missing OST-object with the FID/owner information.
+ *
+ * \param[in] env pointer to the thread context
+ * \param[in] com the layout LFSCK component
+ * \param[in] parent the MDT-object with dangling LOV EA reference
+ * \param[in] child the OST-object to be created
+ * \param[in] ea_off the offset of the OST-object in the LOV EA
+ * \param[in] ost_idx the index of OST on which the OST-object resides
+ *
+ * \retval +1 for repair successfully
+ * \retval 0 for did nothing
+ * \retval negative error number on failure
+ */
+static int __lfsck_layout_repair_dangling(const struct lu_env *env,
+ struct lfsck_component *com,
+ struct dt_object *parent,
+ struct dt_object *child,
+ __u32 ea_off, __u32 ost_idx, bool log)
{
- struct lfsck_thread_info *info = lfsck_env_info(env);
- struct filter_fid *pfid = &info->lti_new_pfid;
- struct dt_object_format *dof = &info->lti_dof;
- struct dt_object *child = llr->llr_child;
- struct dt_device *dev = lfsck_obj2dev(child);
- const struct lu_fid *tfid = lu_object_fid(&parent->do_lu);
- struct thandle *handle;
- struct lu_buf *buf;
- struct lustre_handle lh = { 0 };
- int rc;
- bool create;
+ struct lfsck_thread_info *info = lfsck_env_info(env);
+ struct filter_fid *ff = &info->lti_new_pfid;
+ struct dt_object_format *dof = &info->lti_dof;
+ struct lu_attr *la = &info->lti_la;
+ struct lfsck_instance *lfsck = com->lc_lfsck;
+ struct dt_device *dev = lfsck_obj2dev(child);
+ const struct lu_fid *pfid = lfsck_dto2fid(parent);
+ const struct lu_fid *cfid = lfsck_dto2fid(child);
+ struct thandle *handle;
+ struct lu_buf *buf;
+ struct lustre_handle lh = { 0 };
+ int rc;
ENTRY;
- if (com->lc_lfsck->li_bookmark_ram.lb_param & LPF_CREATE_OSTOBJ)
- create = true;
- else
- create = false;
-
- if (!create)
+ if (!(lfsck->li_bookmark_ram.lb_param & LPF_CREATE_OSTOBJ))
GOTO(log, rc = 1);
- rc = lfsck_ibits_lock(env, com->lc_lfsck, parent, &lh,
+ rc = lfsck_ibits_lock(env, lfsck, parent, &lh,
MDS_INODELOCK_LAYOUT | MDS_INODELOCK_XATTR,
LCK_EX);
if (rc != 0)
la->la_valid = LA_TYPE | LA_MODE | LA_UID | LA_GID |
LA_ATIME | LA_MTIME | LA_CTIME;
memset(dof, 0, sizeof(*dof));
- pfid->ff_parent.f_seq = cpu_to_le64(tfid->f_seq);
- pfid->ff_parent.f_oid = cpu_to_le32(tfid->f_oid);
+ ff->ff_parent.f_seq = cpu_to_le64(pfid->f_seq);
+ ff->ff_parent.f_oid = cpu_to_le32(pfid->f_oid);
/* Currently, the filter_fid::ff_parent::f_ver is not the real parent
* MDT-object's FID::f_ver, instead it is the OST-object index in its
* parent MDT-object's layout EA. */
- pfid->ff_parent.f_stripe_idx = cpu_to_le32(llr->llr_lov_idx);
- buf = lfsck_buf_get(env, pfid, sizeof(struct filter_fid));
+ ff->ff_parent.f_stripe_idx = cpu_to_le32(ea_off);
+ buf = lfsck_buf_get(env, ff, sizeof(struct filter_fid));
handle = dt_trans_create(env, dev);
if (IS_ERR(handle))
dt_read_lock(env, parent, 0);
if (unlikely(lfsck_is_dead_obj(parent)))
- GOTO(unlock2, rc = 1);
+ GOTO(unlock2, rc = 0);
+
+ if (lfsck->li_bookmark_ram.lb_param & LPF_DELAY_CREATE_OSTOBJ) {
+ struct ost_id *oi = &info->lti_oi;
+ struct lu_fid *tfid = &info->lti_fid2;
+ struct lu_buf *lovea = &info->lti_big_buf;
+ struct lov_mds_md_v1 *lmm;
+ struct lov_ost_data_v1 *objs;
+ __u32 magic;
+ int count;
+ int idx2;
+
+ rc = lfsck_layout_get_lovea(env, parent, lovea);
+ if (rc <= 0)
+ GOTO(unlock2, rc);
+
+ lmm = lovea->lb_buf;
+ rc = lfsck_layout_verify_header(lmm);
+ if (unlikely(rc != 0))
+ GOTO(unlock2, rc);
+
+ count = le16_to_cpu(lmm->lmm_stripe_count);
+ /* Someone changed the LOV EA, do nothing. */
+ if (count <= ea_off)
+ GOTO(unlock2, rc = 0);
+
+ /* Currently, we only support LOV_MAGIC_V1/LOV_MAGIC_V3 which
+ * has been verified in lfsck_layout_verify_header() already.
+ * If some new magic introduced in the future, then the layout
+ * LFSCK needs to be updated also. */
+ magic = le32_to_cpu(lmm->lmm_magic);
+ if (magic == LOV_MAGIC_V1) {
+ objs = &lmm->lmm_objects[ea_off];
+ } else {
+ LASSERT(magic == LOV_MAGIC_V3);
+
+ objs = &((struct lov_mds_md_v3 *)lmm)->\
+ lmm_objects[ea_off];
+ }
+
+ ostid_le_to_cpu(&objs->l_ost_oi, oi);
+ idx2 = le32_to_cpu(objs->l_ost_idx);
+ rc = ostid_to_fid(tfid, oi, idx2);
+ /* Someone changed the LOV EA, do nothing. */
+ if (rc != 0 || !lu_fid_eq(tfid, cfid))
+ GOTO(unlock2, rc);
+ }
rc = dt_create(env, child, la, NULL, dof, handle);
if (rc != 0)
lfsck_ibits_unlock(&lh, LCK_EX);
log:
- CDEBUG(D_LFSCK, "%s: layout LFSCK assistant found dangling "
- "reference for: parent "DFID", child "DFID", OST-index %u, "
- "stripe-index %u, owner %u/%u. %s: rc = %d\n",
- lfsck_lfsck2name(com->lc_lfsck), PFID(lfsck_dto2fid(parent)),
- PFID(lfsck_dto2fid(child)), llr->llr_ost_idx,
- llr->llr_lov_idx, la->la_uid, la->la_gid,
- create ? "Create the lost OST-object as required" :
- "Keep the MDT-object there by default", rc);
+ if (rc != 0 && log)
+ CDEBUG(D_LFSCK, "%s: layout LFSCK assistant found "
+ "dangling reference for: parent "DFID", child "
+ DFID", ea_off %u, ost_idx %u, %s: rc = %d\n",
+ lfsck_lfsck2name(lfsck), PFID(pfid), PFID(cfid),
+ ea_off, ost_idx,
+ (lfsck->li_bookmark_ram.lb_param & LPF_CREATE_OSTOBJ) ?
+ "Create the lost OST-object as required" :
+ "Keep the MDT-object there by default", rc);
+
+ return rc;
+}
+
+/**
+ * Repair the MDT-object with dangling LOV EA reference.
+ *
+ * Prepare parameters and call __lfsck_layout_repair_dangling()
+ * to repair the dangling LOV EA reference.
+ *
+ * \param[in] env pointer to the thread context
+ * \param[in] com the layout LFSCK component
+ * \param[in] pfid the MDT-object's FID
+ * \param[in] cfid the FID for the OST-object to be created
+ * \param[in] ea_off the offset of the OST-object in the LOV EA
+ * \param[in] ost_idx the index of OST on which the OST-object resides
+ *
+ * \retval +1 for repair successfully
+ * \retval 0 for did nothing
+ * \retval negative error number on failure
+ */
+static int lfsck_layout_repair_dangling(const struct lu_env *env,
+ struct lfsck_component *com,
+ const struct lu_fid *pfid,
+ const struct lu_fid *cfid,
+ __u32 ea_off, __u32 ost_idx)
+{
+ struct lfsck_instance *lfsck = com->lc_lfsck;
+ struct dt_object *parent = NULL;
+ struct dt_object *child = NULL;
+ struct lfsck_tgt_desc *ltd;
+ int rc;
+ ENTRY;
+
+ parent = lfsck_object_find_bottom(env, lfsck, pfid);
+ if (IS_ERR(parent))
+ GOTO(log, rc = PTR_ERR(parent));
+
+ /* The MDT-object has been removed. */
+ if (dt_object_exists(parent) == 0)
+ GOTO(log, rc = 0);
+
+ ltd = lfsck_ltd2tgt(&lfsck->li_ost_descs, ost_idx);
+ if (unlikely(ltd == NULL))
+ GOTO(log, rc = -ENODEV);
+
+ child = lfsck_object_find_by_dev(env, ltd->ltd_tgt, cfid);
+ if (IS_ERR(child))
+ GOTO(log, rc = PTR_ERR(child));
+
+ /* The OST-object has been created. */
+ if (unlikely(dt_object_exists(child) != 0))
+ GOTO(log, rc = 0);
+
+ rc = __lfsck_layout_repair_dangling(env, com, parent, child,
+ ea_off, ost_idx, false);
+
+ GOTO(log, rc);
+
+log:
+ if (child != NULL && !IS_ERR(child))
+ lfsck_object_put(env, child);
+
+ if (parent != NULL && !IS_ERR(parent))
+ lfsck_object_put(env, parent);
+
+ if (rc != 0)
+ CDEBUG(D_LFSCK, "%s: layout LFSCK assistant found "
+ "dangling reference for: parent "DFID", child "
+ DFID", ea_off %u, ost_idx %u, %s: rc = %d\n",
+ lfsck_lfsck2name(lfsck), PFID(pfid), PFID(cfid),
+ ea_off, ost_idx,
+ (lfsck->li_bookmark_ram.lb_param & LPF_CREATE_OSTOBJ) ?
+ "Create the lost OST-object as required" :
+ "Keep the MDT-object there by default", rc);
return rc;
}
lfsck_ibits_unlock(&lh, LCK_EX);
log:
- CDEBUG(D_LFSCK, "%s: layout LFSCK assistant repaired unmatched "
- "MDT-OST pair for: parent "DFID", child "DFID", OST-index %u, "
- "stripe-index %u, owner %u/%u: rc = %d\n",
- lfsck_lfsck2name(com->lc_lfsck), PFID(lfsck_dto2fid(parent)),
- PFID(lfsck_dto2fid(child)), llr->llr_ost_idx, llr->llr_lov_idx,
- la->la_uid, la->la_gid, rc);
+ if (rc != 0)
+ CDEBUG(D_LFSCK, "%s: layout LFSCK assistant repaired "
+ "unmatched MDT-OST pair for: parent "DFID
+ ", child "DFID", OST-index %u, stripe-index %u, "
+ "owner %u/%u: rc = %d\n",
+ lfsck_lfsck2name(com->lc_lfsck),
+ PFID(lfsck_dto2fid(parent)),
+ PFID(lfsck_dto2fid(child)),
+ llr->llr_ost_idx, llr->llr_lov_idx,
+ la->la_uid, la->la_gid, rc);
return rc;
}
if (child != NULL)
lfsck_object_put(env, child);
- CDEBUG(D_LFSCK, "%s: layout LFSCK assistant repaired multiple "
- "references for: parent "DFID", OST-index %u, stripe-index %u, "
- "owner %u/%u: rc = %d\n", lfsck_lfsck2name(lfsck), PFID(pfid),
- llr->llr_ost_idx, llr->llr_lov_idx, la->la_uid, la->la_gid, rc);
+ if (rc != 0)
+ CDEBUG(D_LFSCK, "%s: layout LFSCK assistant repaired "
+ "multiple references for: parent "DFID", OST-index %u, "
+ "stripe-index %u, owner %u/%u: rc = %d\n",
+ lfsck_lfsck2name(lfsck), PFID(pfid), llr->llr_ost_idx,
+ llr->llr_lov_idx, la->la_uid, la->la_gid, rc);
return rc;
}
struct lfsck_component *com,
struct dt_object *parent,
struct lfsck_layout_req *llr,
- struct lu_attr *la)
+ struct lu_attr *pla,
+ const struct lu_attr *cla)
{
struct lfsck_thread_info *info = lfsck_env_info(env);
- struct lu_attr *tla = &info->lti_la;
+ struct lu_attr *tla = &info->lti_la2;
struct dt_object *child = llr->llr_child;
struct dt_device *dev = lfsck_obj2dev(child);
struct thandle *handle;
int rc;
ENTRY;
+ tla->la_uid = pla->la_uid;
+ tla->la_gid = pla->la_gid;
+ tla->la_valid = LA_UID | LA_GID;
handle = dt_trans_create(env, dev);
if (IS_ERR(handle))
GOTO(log, rc = PTR_ERR(handle));
- tla->la_uid = la->la_uid;
- tla->la_gid = la->la_gid;
- tla->la_valid = LA_UID | LA_GID;
rc = dt_declare_attr_set(env, child, tla, handle);
if (rc != 0)
GOTO(stop, rc);
GOTO(unlock, rc = 1);
/* Get the latest parent's owner. */
- rc = dt_attr_get(env, parent, la);
+ rc = dt_attr_get(env, parent, pla);
if (rc != 0)
GOTO(unlock, rc);
/* Some others chown/chgrp during the LFSCK, needs to do nothing. */
- if (unlikely(tla->la_uid != la->la_uid ||
- tla->la_gid != la->la_gid))
- GOTO(unlock, rc = 1);
-
- rc = dt_attr_set(env, child, tla, handle);
+ if (unlikely(tla->la_uid != pla->la_uid ||
+ tla->la_gid != pla->la_gid))
+ rc = 1;
+ else
+ rc = dt_attr_set(env, child, tla, handle);
GOTO(unlock, rc);
rc = lfsck_layout_trans_stop(env, dev, handle, rc);
log:
- CDEBUG(D_LFSCK, "%s: layout LFSCK assistant repaired inconsistent "
- "file owner for: parent "DFID", child "DFID", OST-index %u, "
- "stripe-index %u, owner %u/%u: rc = %d\n",
- lfsck_lfsck2name(com->lc_lfsck), PFID(lfsck_dto2fid(parent)),
- PFID(lfsck_dto2fid(child)), llr->llr_ost_idx, llr->llr_lov_idx,
- la->la_uid, la->la_gid, rc);
+ if (rc != 0)
+ CDEBUG(D_LFSCK, "%s: layout LFSCK assistant repaired "
+ "inconsistent file owner for: parent "DFID", child "DFID
+ ", OST-index %u, stripe-index %u, old owner %u/%u, "
+ "new owner %u/%u: rc = %d\n",
+ lfsck_lfsck2name(com->lc_lfsck),
+ PFID(lfsck_dto2fid(parent)), PFID(lfsck_dto2fid(child)),
+ llr->llr_ost_idx, llr->llr_lov_idx,
+ cla->la_uid, cla->la_gid, tla->la_uid, tla->la_gid, rc);
return rc;
}
__u16 count;
ENTRY;
- if (fid_is_zero(pfid)) {
- /* client never wrote. */
- if (cla->la_size == 0 && cla->la_blocks == 0) {
- struct lu_attr *pla = &lso->lso_attr;
-
- /* Someone may has changed the owner after the @pla
- * pre-loaded. It can be handled when repairs owner
- * inside lfsck_layout_repair_owner(). */
- if (unlikely(cla->la_uid != pla->la_uid ||
- cla->la_gid != pla->la_gid))
- RETURN(LLIT_INCONSISTENT_OWNER);
-
- RETURN(0);
- }
-
- RETURN(LLIT_UNMATCHED_PAIR);
- }
-
if (unlikely(!fid_is_sane(pfid)))
RETURN(LLIT_UNMATCHED_PAIR);
if (lu_fid_eq(pfid, &lso->lso_fid)) {
- if (llr->llr_lov_idx == idx)
+ if (likely(llr->llr_lov_idx == idx))
RETURN(0);
RETURN(LLIT_UNMATCHED_PAIR);
if (IS_ERR(tobj))
RETURN(PTR_ERR(tobj));
- if (dt_object_exists(tobj) == 0 ||
- lfsck_is_dead_obj(tobj))
- GOTO(out, rc = LLIT_UNMATCHED_PAIR);
-
- if (!S_ISREG(lfsck_object_type(tobj)))
+ if (dt_object_exists(tobj) == 0 || lfsck_is_dead_obj(tobj) ||
+ !S_ISREG(lfsck_object_type(tobj)))
GOTO(out, rc = LLIT_UNMATCHED_PAIR);
/* Load the tobj's layout EA, in spite of it is a local MDT-object or
if (lso->lso_dead)
RETURN(0);
+ CFS_FAIL_TIMEOUT(OBD_FAIL_LFSCK_ASSISTANT_DIRECT, cfs_fail_val);
+
rc = dt_attr_get(env, child, cla);
if (rc == -ENOENT) {
parent = lfsck_assistant_object_load(env, lfsck, lso);
lfsck_buf_init(&buf, pea, sizeof(struct filter_fid_old));
rc = dt_xattr_get(env, child, &buf, XATTR_NAME_FID);
- if (unlikely(rc >= 0 && rc != sizeof(struct filter_fid_old) &&
+ if (unlikely(rc > 0 && rc != sizeof(struct filter_fid_old) &&
rc != sizeof(struct filter_fid))) {
type = LLIT_UNMATCHED_PAIR;
goto repair;
if (rc < 0 && rc != -ENODATA)
GOTO(out, rc);
- if (rc == -ENODATA) {
- fid_zero(pfid);
- } else {
- fid_le_to_cpu(pfid, &pea->ff_parent);
- /* Currently, the filter_fid::ff_parent::f_ver is not the
- * real parent MDT-object's FID::f_ver, instead it is the
- * OST-object index in its parent MDT-object's layout EA. */
- idx = pfid->f_stripe_idx;
- pfid->f_ver = 0;
- }
+ if (rc == 0 || rc == -ENODATA)
+ GOTO(check_owner, rc = 0);
+ fid_le_to_cpu(pfid, &pea->ff_parent);
+ /* Currently, the filter_fid::ff_parent::f_ver is not the
+ * real parent MDT-object's FID::f_ver, instead it is the
+ * OST-object index in its parent MDT-object's layout EA. */
+ idx = pfid->f_stripe_idx;
+ pfid->f_ver = 0;
rc = lfsck_layout_check_parent(env, com, lso, pfid,
lu_object_fid(&child->do_lu),
cla, llr, &buf, idx);
if (rc < 0)
GOTO(out, rc);
+check_owner:
/* Someone may has changed the owner after the parent attr pre-loaded.
* It can be handled later inside the lfsck_layout_repair_owner(). */
if (unlikely(cla->la_uid != pla->la_uid ||
switch (type) {
case LLIT_DANGLING:
- rc = lfsck_layout_repair_dangling(env, com, parent, llr, pla);
+ if (bk->lb_param & LPF_DELAY_CREATE_OSTOBJ)
+ rc = lfsck_layout_ins_dangling_rec(env, com,
+ lfsck_dto2fid(parent), lfsck_dto2fid(child),
+ llr->llr_lov_idx, llr->llr_ost_idx);
+ else
+ rc = __lfsck_layout_repair_dangling(env, com, parent,
+ llr->llr_child, llr->llr_lov_idx,
+ llr->llr_ost_idx, true);
break;
case LLIT_UNMATCHED_PAIR:
rc = lfsck_layout_repair_unmatched_pair(env, com, parent,
llr, pla, &buf);
break;
case LLIT_INCONSISTENT_OWNER:
- rc = lfsck_layout_repair_owner(env, com, parent, llr, pla);
+ rc = lfsck_layout_repair_owner(env, com, parent, llr, pla, cla);
break;
default:
rc = 0;
} else {
lfsck_layout_record_failure(env, lfsck, lo);
}
- } else if (rc > 0) {
+ } else if (rc > 0 && (type != LLIT_DANGLING ||
+ !(bk->lb_param & LPF_DELAY_CREATE_OSTOBJ))) {
LASSERTF(type > LLIT_NONE && type <= LLIT_MAX,
"unknown type = %d\n", type);
return rc;
}
+static int
+lfsck_layout_double_scan_one_trace_file(const struct lu_env *env,
+ struct lfsck_component *com,
+ struct dt_object *obj, bool first)
+{
+ struct lfsck_instance *lfsck = com->lc_lfsck;
+ struct ptlrpc_thread *thread = &lfsck->li_thread;
+ struct lfsck_bookmark *bk = &lfsck->li_bookmark_ram;
+ struct lfsck_layout *lo = com->lc_file_ram;
+ const struct dt_it_ops *iops = &obj->do_index_ops->dio_it;
+ struct dt_it *di;
+ struct dt_key *key;
+ struct lu_fid *pfid = &lfsck_env_info(env)->lti_fid3;
+ struct lu_fid *cfid = &lfsck_env_info(env)->lti_fid4;
+ __u32 ea_off;
+ __u32 ost_idx;
+ int rc;
+ ENTRY;
+
+ di = iops->init(env, obj, 0);
+ if (IS_ERR(di))
+ RETURN(PTR_ERR(di));
+
+ if (first)
+ fid_cpu_to_be(pfid, &lo->ll_fid_latest_scanned_phase2);
+ else
+ fid_zero(pfid);
+ rc = iops->get(env, di, (const struct dt_key *)pfid);
+ if (rc < 0)
+ GOTO(fini, rc);
+
+ if (first) {
+ /* The start one either has been processed or does not exist,
+ * skip it. */
+ rc = iops->next(env, di);
+ if (rc != 0)
+ GOTO(put, rc);
+ }
+
+ do {
+ if (CFS_FAIL_TIMEOUT(OBD_FAIL_LFSCK_DELAY3, cfs_fail_val) &&
+ unlikely(!thread_is_running(thread)))
+ GOTO(put, rc = 0);
+
+ key = iops->key(env, di);
+ if (IS_ERR(key)) {
+ rc = PTR_ERR(key);
+ if (rc == -ENOENT)
+ GOTO(put, rc = 1);
+
+ goto checkpoint;
+ }
+
+ fid_be_to_cpu(pfid, (const struct lu_fid *)key);
+ ea_off = pfid->f_ver;
+ pfid->f_ver = 0;
+ if (!fid_is_sane(pfid)) {
+ rc = 0;
+ goto checkpoint;
+ }
+
+ rc = iops->rec(env, di, (struct dt_rec *)cfid, 0);
+ if (rc == 0) {
+ fid_be_to_cpu(cfid, cfid);
+ ost_idx = cfid->f_ver;
+ cfid->f_ver = 0;
+ if (!fid_is_sane(cfid)) {
+ rc = 0;
+ goto checkpoint;
+ }
+
+ rc = lfsck_layout_repair_dangling(env, com, pfid, cfid,
+ ea_off, ost_idx);
+ }
+
+checkpoint:
+ down_write(&com->lc_sem);
+ com->lc_new_checked++;
+ com->lc_new_scanned++;
+ if (rc >= 0)
+ lo->ll_fid_latest_scanned_phase2 = *pfid;
+
+ if (rc > 0)
+ lo->ll_objs_repaired[LLIT_DANGLING - 1]++;
+ else if (rc < 0)
+ lo->ll_objs_failed_phase2++;
+ up_write(&com->lc_sem);
+
+ if (rc < 0 && bk->lb_param & LPF_FAILOUT)
+ GOTO(put, rc);
+
+ if (unlikely(cfs_time_beforeq(com->lc_time_next_checkpoint,
+ cfs_time_current())) &&
+ com->lc_new_checked != 0) {
+ down_write(&com->lc_sem);
+ lo->ll_run_time_phase2 +=
+ cfs_duration_sec(cfs_time_current() +
+ HALF_SEC - com->lc_time_last_checkpoint);
+ lo->ll_time_last_checkpoint = cfs_time_current_sec();
+ lo->ll_objs_checked_phase2 += com->lc_new_checked;
+ com->lc_new_checked = 0;
+ lfsck_layout_store(env, com);
+ up_write(&com->lc_sem);
+
+ com->lc_time_last_checkpoint = cfs_time_current();
+ com->lc_time_next_checkpoint =
+ com->lc_time_last_checkpoint +
+ cfs_time_seconds(LFSCK_CHECKPOINT_INTERVAL);
+ }
+
+ lfsck_control_speed_by_self(com);
+ if (unlikely(!thread_is_running(thread)))
+ GOTO(put, rc = 0);
+
+ rc = iops->next(env, di);
+ } while (rc == 0);
+
+ GOTO(put, rc);
+
+put:
+ iops->put(env, di);
+
+fini:
+ iops->fini(env, di);
+
+ return rc;
+}
+
static int lfsck_layout_assistant_handler_p2(const struct lu_env *env,
struct lfsck_component *com)
{
struct lfsck_tgt_desc,
ltd_layout_phase_list);
list_del_init(<d->ltd_layout_phase_list);
- if (bk->lb_param & LPF_ALL_TGT) {
+ if (bk->lb_param & LPF_OST_ORPHAN) {
spin_unlock(<ds->ltd_lock);
rc = lfsck_layout_scan_orphan(env, com, ltd);
if (rc != 0 && bk->lb_param & LPF_FAILOUT)
rc = 0;
spin_unlock(<ds->ltd_lock);
+ if (rc == 1 && bk->lb_param & LPF_OST_ORPHAN) {
+ struct lfsck_layout *lo = com->lc_file_ram;
+ int i;
+
+ com->lc_new_checked = 0;
+ com->lc_new_scanned = 0;
+ com->lc_time_last_checkpoint = cfs_time_current();
+ com->lc_time_next_checkpoint = com->lc_time_last_checkpoint +
+ cfs_time_seconds(LFSCK_CHECKPOINT_INTERVAL);
+
+ i = lfsck_sub_trace_file_fid2idx(
+ &lo->ll_fid_latest_scanned_phase2);
+ rc = lfsck_layout_double_scan_one_trace_file(env, com,
+ com->lc_sub_trace_objs[i].lsto_obj, true);
+ while (rc > 0 && ++i < LFSCK_STF_COUNT)
+ rc = lfsck_layout_double_scan_one_trace_file(env, com,
+ com->lc_sub_trace_objs[i].lsto_obj, false);
+
+ CDEBUG(D_LFSCK, "%s: layout LFSCK phase2 scan dangling stop "
+ "at the No. %d trace file: rc = %d\n",
+ lfsck_lfsck2name(lfsck), i, rc);
+ }
+
CDEBUG(D_LFSCK, "%s: layout LFSCK phase2 scan stop: rc = %d\n",
lfsck_lfsck2name(lfsck), rc);
bool done = false;
if (rc != 0) {
- /* It is quite probably caused by target crash,
- * to make the LFSCK can go ahead, assume that
- * the target finished the LFSCK prcoessing. */
- done = true;
+ /* It is probably caused by network trouble, or target crash,
+ * it will try several times (depends on the obd_timeout, and
+ * will not less than 3 times). But to make the LFSCK can go
+ * ahead, we should not try for ever. After some try but still
+ * hit failure, it will assume that the target exit the LFSCK
+ * prcoessing and stop try. */
+ if (rc == -ENOTCONN || rc == -ESHUTDOWN) {
+ int max_try = max_t(int, obd_timeout / 30, 3);
+
+ if (++(llst->llst_failures) > max_try)
+ done = true;
+ } else {
+ done = true;
+ }
} else {
+ llst->llst_failures = 0;
lr = req_capsule_server_get(&req->rq_pill, &RMF_LFSCK_REPLY);
if (lr->lr_status != LS_SCANNING_PHASE1 &&
lr->lr_status != LS_SCANNING_PHASE2)
if (done) {
CDEBUG(D_LFSCK, "%s: layout LFSCK slave gets the MDT %x "
- "status %d\n", lfsck_lfsck2name(com->lc_lfsck),
- llst->llst_index, lr != NULL ? lr->lr_status : rc);
+ "status %d, failures_try %d\n", lfsck_lfsck2name(com->lc_lfsck),
+ llst->llst_index, lr != NULL ? lr->lr_status : rc,
+ llst->llst_failures);
lfsck_layout_llst_del(llsd, llst);
}
llsaa->llsaa_com = lfsck_component_get(com);
llsaa->llsaa_llst = llst;
req->rq_interpret_reply = lfsck_layout_slave_async_interpret;
+ req->rq_allow_intr = 1;
ptlrpc_set_add_req(set, req);
RETURN(0);
tmp = req_capsule_client_get(&req->rq_pill, &RMF_LFSCK_REQUEST);
*tmp = *lr;
ptlrpc_request_set_replen(req);
+ req->rq_allow_intr = 1;
ptlrpc_set_add_req(set, req);
RETURN(0);
}
rc = lfsck_layout_store(env, com);
+ if (rc == 0 && com->lc_lfsck->li_master)
+ rc = lfsck_load_sub_trace_files(env, com,
+ &dt_lfsck_layout_dangling_features, LFSCK_LAYOUT, true);
up_write(&com->lc_sem);
CDEBUG(D_LFSCK, "%s: layout LFSCK reset: rc = %d\n",
up_write(&com->lc_sem);
CDEBUG(D_LFSCK, "%s: layout LFSCK master checkpoint at the pos ["
- LPU64"]: rc = %d\n", lfsck_lfsck2name(lfsck),
- lfsck->li_pos_current.lp_oit_cookie, rc);
+ "%llu], status = %d: rc = %d\n", lfsck_lfsck2name(lfsck),
+ lfsck->li_pos_current.lp_oit_cookie, lo->ll_status, rc);
return rc;
}
up_write(&com->lc_sem);
CDEBUG(D_LFSCK, "%s: layout LFSCK slave checkpoint at the pos ["
- LPU64"]: rc = %d\n", lfsck_lfsck2name(lfsck),
- lfsck->li_pos_current.lp_oit_cookie, rc);
+ "%llu], status = %d: rc = %d\n", lfsck_lfsck2name(lfsck),
+ lfsck->li_pos_current.lp_oit_cookie, lo->ll_status, rc);
return rc;
}
}
CDEBUG(D_LFSCK, "%s: layout LFSCK slave prep done, start pos ["
- LPU64"]\n", lfsck_lfsck2name(lfsck),
+ "%llu]\n", lfsck_lfsck2name(lfsck),
com->lc_pos_start.lp_oit_cookie);
return rc;
log:
CDEBUG(D_LFSCK, "%s: layout LFSCK master prep done, start pos ["
- LPU64"]\n", lfsck_lfsck2name(com->lc_lfsck),
+ "%llu]\n", lfsck_lfsck2name(com->lc_lfsck),
com->lc_pos_start.lp_oit_cookie);
return 0;
goto next;
}
- rc = dt_declare_attr_get(env, cobj);
- if (rc != 0)
- goto next;
+ if (!OBD_FAIL_CHECK(OBD_FAIL_LFSCK_ASSISTANT_DIRECT)) {
+ rc = dt_declare_attr_get(env, cobj);
+ if (rc != 0)
+ goto next;
- rc = dt_declare_xattr_get(env, cobj, &buf, XATTR_NAME_FID);
- if (rc != 0)
- goto next;
+ rc = dt_declare_xattr_get(env, cobj, &buf,
+ XATTR_NAME_FID);
+ if (rc != 0)
+ goto next;
+ }
if (lso == NULL) {
struct lu_attr *attr = &info->lti_la;
rc = dt_attr_get(env, parent, attr);
- if (rc != 0) {
- rc = PTR_ERR(lso);
+ if (rc != 0)
goto next;
- }
lso = lfsck_assistant_object_init(env,
lfsck_dto2fid(parent), attr,
rc = lfsck_layout_lastid_load(env, com, lls);
if (rc != 0) {
CDEBUG(D_LFSCK, "%s: layout LFSCK failed to "
- "load LAST_ID for "LPX64": rc = %d\n",
+ "load LAST_ID for %#llx: rc = %d\n",
lfsck_lfsck2name(com->lc_lfsck), seq, rc);
lo->ll_objs_failed_phase1++;
OBD_FREE_PTR(lls);
rc = lfsck_layout_lastid_reload(env, com, lls);
if (unlikely(rc != 0)) {
CDEBUG(D_LFSCK, "%s: layout LFSCK failed to "
- "reload LAST_ID for "LPX64": rc = %d\n",
+ "reload LAST_ID for %#llx: rc = %d\n",
lfsck_lfsck2name(com->lc_lfsck),
lls->lls_seq, rc);
lo->ll_flags |= LF_CRASHED_LASTID;
CDEBUG(D_LFSCK, "%s: layout LFSCK finds crashed "
- "LAST_ID file (2) for the sequence "LPX64
- ", old value "LPU64", known value "LPU64"\n",
+ "LAST_ID file (2) for the sequence %#llx"
+ ", old value %llu, known value %llu\n",
lfsck_lfsck2name(lfsck), lls->lls_seq,
lls->lls_lastid, oid);
}
int rc;
bool done = false;
+ down_write(&com->lc_sem);
rc = lfsck_layout_lastid_store(env, com);
if (rc != 0)
result = rc;
LASSERT(lfsck->li_out_notify != NULL);
- down_write(&com->lc_sem);
spin_lock(&lfsck->li_lock);
if (!init)
lo->ll_pos_last_checkpoint =
return rc;
}
-static int lfsck_layout_dump(const struct lu_env *env,
- struct lfsck_component *com, struct seq_file *m)
+static void lfsck_layout_dump(const struct lu_env *env,
+ 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 rc;
down_read(&com->lc_sem);
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));
-
- rc = lfsck_bits_dump(m, lo->ll_flags, lfsck_flags_names, "flags");
- if (rc < 0)
- goto out;
+ "magic: %#x\n"
+ "version: %d\n"
+ "status: %s\n",
+ lo->ll_magic,
+ bk->lb_version,
+ lfsck_status2name(lo->ll_status));
- rc = lfsck_bits_dump(m, bk->lb_param, lfsck_param_names, "param");
- if (rc < 0)
- goto out;
+ lfsck_bits_dump(m, lo->ll_flags, lfsck_flags_names, "flags");
- rc = lfsck_time_dump(m, lo->ll_time_last_complete,
- "last_completed");
- if (rc < 0)
- goto out;
+ lfsck_bits_dump(m, bk->lb_param, lfsck_param_names, "param");
- rc = lfsck_time_dump(m, lo->ll_time_latest_start,
- "latest_start");
- if (rc < 0)
- goto out;
+ lfsck_time_dump(m, lo->ll_time_last_complete, "last_completed");
- rc = lfsck_time_dump(m, lo->ll_time_last_checkpoint,
- "last_checkpoint");
- if (rc < 0)
- goto out;
+ lfsck_time_dump(m, lo->ll_time_latest_start, "latest_start");
- 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);
+ lfsck_time_dump(m, lo->ll_time_last_checkpoint, "last_checkpoint");
+
+ seq_printf(m, "latest_start_position: %llu\n"
+ "last_checkpoint_position: %llu\n"
+ "first_failure_position: %llu\n",
+ lo->ll_pos_latest_start,
+ lo->ll_pos_last_checkpoint,
+ lo->ll_pos_first_inconsistent);
seq_printf(m, "success_count: %u\n"
- "repaired_dangling: "LPU64"\n"
- "repaired_unmatched_pair: "LPU64"\n"
- "repaired_multiple_referenced: "LPU64"\n"
- "repaired_orphan: "LPU64"\n"
- "repaired_inconsistent_owner: "LPU64"\n"
- "repaired_others: "LPU64"\n"
- "skipped: "LPU64"\n"
- "failed_phase1: "LPU64"\n"
- "failed_phase2: "LPU64"\n",
- lo->ll_success_count,
- lo->ll_objs_repaired[LLIT_DANGLING - 1],
- lo->ll_objs_repaired[LLIT_UNMATCHED_PAIR - 1],
- lo->ll_objs_repaired[LLIT_MULTIPLE_REFERENCED - 1],
- lo->ll_objs_repaired[LLIT_ORPHAN - 1],
- lo->ll_objs_repaired[LLIT_INCONSISTENT_OWNER - 1],
- lo->ll_objs_repaired[LLIT_OTHERS - 1],
- lo->ll_objs_skipped,
- lo->ll_objs_failed_phase1,
- lo->ll_objs_failed_phase2);
+ "repaired_dangling: %llu\n"
+ "repaired_unmatched_pair: %llu\n"
+ "repaired_multiple_referenced: %llu\n"
+ "repaired_orphan: %llu\n"
+ "repaired_inconsistent_owner: %llu\n"
+ "repaired_others: %llu\n"
+ "skipped: %llu\n"
+ "failed_phase1: %llu\n"
+ "failed_phase2: %llu\n",
+ lo->ll_success_count,
+ lo->ll_objs_repaired[LLIT_DANGLING - 1],
+ lo->ll_objs_repaired[LLIT_UNMATCHED_PAIR - 1],
+ lo->ll_objs_repaired[LLIT_MULTIPLE_REFERENCED - 1],
+ lo->ll_objs_repaired[LLIT_ORPHAN - 1],
+ lo->ll_objs_repaired[LLIT_INCONSISTENT_OWNER - 1],
+ lo->ll_objs_repaired[LLIT_OTHERS - 1],
+ lo->ll_objs_skipped,
+ lo->ll_objs_failed_phase1,
+ lo->ll_objs_failed_phase2);
if (lo->ll_status == LS_SCANNING_PHASE1) {
__u64 pos;
- const struct dt_it_ops *iops;
cfs_duration_t duration = cfs_time_current() -
lfsck->li_time_last_checkpoint;
__u64 checked = lo->ll_objs_checked_phase1 +
do_div(new_checked, duration);
if (rtime != 0)
do_div(speed, rtime);
- 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: N/A\n"
- "real-time_speed_phase1: "LPU64" items/sec\n"
- "real-time_speed_phase2: N/A\n",
- checked,
- lo->ll_objs_checked_phase2,
- rtime,
- lo->ll_run_time_phase2,
- speed,
- new_checked);
-
- LASSERT(lfsck->li_di_oit != NULL);
-
- iops = &lfsck->li_obj_oit->do_index_ops->dio_it;
-
- /* The low layer otable-based iteration position may NOT
- * exactly match the layout-based directory traversal
- * cookie. Generally, it is not a serious issue. But the
- * caller should NOT make assumption on that. */
- pos = iops->store(env, lfsck->li_di_oit);
- if (!lfsck->li_current_oit_processed)
- pos--;
- seq_printf(m, "current_position: "LPU64"\n", pos);
+ seq_printf(m, "checked_phase1: %llu\n"
+ "checked_phase2: %llu\n"
+ "run_time_phase1: %u seconds\n"
+ "run_time_phase2: %u seconds\n"
+ "average_speed_phase1: %llu items/sec\n"
+ "average_speed_phase2: N/A\n"
+ "real-time_speed_phase1: %llu items/sec\n"
+ "real-time_speed_phase2: N/A\n",
+ checked,
+ lo->ll_objs_checked_phase2,
+ rtime,
+ lo->ll_run_time_phase2,
+ speed,
+ new_checked);
+
+ if (likely(lfsck->li_di_oit)) {
+ const struct dt_it_ops *iops =
+ &lfsck->li_obj_oit->do_index_ops->dio_it;
+
+ /* The low layer otable-based iteration position may NOT
+ * exactly match the layout-based directory traversal
+ * cookie. Generally, it is not a serious issue. But the
+ * caller should NOT make assumption on that. */
+ pos = iops->store(env, lfsck->li_di_oit);
+ if (!lfsck->li_current_oit_processed)
+ pos--;
+ } else {
+ pos = lo->ll_pos_last_checkpoint;
+ }
+ seq_printf(m, "current_position: %llu\n", pos);
} else if (lo->ll_status == LS_SCANNING_PHASE2) {
cfs_duration_t duration = cfs_time_current() -
com->lc_time_last_checkpoint;
do_div(speed1, lo->ll_run_time_phase1);
if (rtime != 0)
do_div(speed2, rtime);
- 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;
-
+ seq_printf(m, "checked_phase1: %llu\n"
+ "checked_phase2: %llu\n"
+ "run_time_phase1: %u seconds\n"
+ "run_time_phase2: %u seconds\n"
+ "average_speed_phase1: %llu items/sec\n"
+ "average_speed_phase2: %llu items/sec\n"
+ "real-time_speed_phase1: N/A\n"
+ "real-time_speed_phase2: %llu 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));
} else {
__u64 speed1 = lo->ll_objs_checked_phase1;
__u64 speed2 = lo->ll_objs_checked_phase2;
do_div(speed1, lo->ll_run_time_phase1);
if (lo->ll_run_time_phase2 != 0)
do_div(speed2, lo->ll_run_time_phase2);
- seq_printf(m, "checked_phase1: "LPU64"\n"
- "checked_phase2: "LPU64"\n"
+ seq_printf(m, "checked_phase1: %llu\n"
+ "checked_phase2: %llu\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"
+ "average_speed_phase1: %llu items/sec\n"
+ "average_speed_phase2: %llu objs/sec\n"
"real-time_speed_phase1: N/A\n"
"real-time_speed_phase2: N/A\n"
"current_position: N/A\n",
speed1,
speed2);
}
-out:
- up_read(&com->lc_sem);
- return rc;
+ up_read(&com->lc_sem);
}
static int lfsck_layout_master_double_scan(const struct lu_env *env,
LASSERT(llsd != NULL);
+ down_write(&com->lc_sem);
list_for_each_entry_safe(lls, next, &llsd->llsd_seq_list,
lls_list) {
list_del_init(&lls->lls_list);
lfsck_object_put(env, lls->lls_lastid_obj);
OBD_FREE_PTR(lls);
}
+ up_write(&com->lc_sem);
spin_lock(&llsd->llsd_lock);
while (!list_empty(&llsd->llsd_master_list)) {
RETURN(0);
}
+static void lfsck_layout_repaired(struct lfsck_layout *lo, __u64 *count)
+{
+ int i;
+
+ for (i = 0; i < LLIT_MAX; i++)
+ *count += lo->ll_objs_repaired[i];
+}
+
+static int lfsck_layout_query_all(const struct lu_env *env,
+ struct lfsck_component *com,
+ __u32 *mdts_count, __u32 *osts_count,
+ __u64 *repaired)
+{
+ struct lfsck_layout *lo = com->lc_file_ram;
+ struct lfsck_tgt_descs *ltds;
+ struct lfsck_tgt_desc *ltd;
+ int idx;
+ int rc;
+ ENTRY;
+
+ rc = lfsck_query_all(env, com);
+ if (rc != 0)
+ RETURN(rc);
+
+ ltds = &com->lc_lfsck->li_mdt_descs;
+ down_read(<ds->ltd_rw_sem);
+ cfs_foreach_bit(ltds->ltd_tgts_bitmap, idx) {
+ ltd = lfsck_ltd2tgt(ltds, idx);
+ LASSERT(ltd != NULL);
+
+ mdts_count[ltd->ltd_layout_status]++;
+ *repaired += ltd->ltd_layout_repaired;
+ }
+ up_read(<ds->ltd_rw_sem);
+
+ ltds = &com->lc_lfsck->li_ost_descs;
+ down_read(<ds->ltd_rw_sem);
+ cfs_foreach_bit(ltds->ltd_tgts_bitmap, idx) {
+ ltd = lfsck_ltd2tgt(ltds, idx);
+ LASSERT(ltd != NULL);
+
+ osts_count[ltd->ltd_layout_status]++;
+ *repaired += ltd->ltd_layout_repaired;
+ }
+ up_read(<ds->ltd_rw_sem);
+
+ down_read(&com->lc_sem);
+ mdts_count[lo->ll_status]++;
+ lfsck_layout_repaired(lo, repaired);
+ up_read(&com->lc_sem);
+
+ RETURN(0);
+}
+
static int lfsck_layout_query(const struct lu_env *env,
- struct lfsck_component *com)
+ struct lfsck_component *com,
+ struct lfsck_request *req,
+ struct lfsck_reply *rep,
+ struct lfsck_query *que, int idx)
{
struct lfsck_layout *lo = com->lc_file_ram;
+ int rc = 0;
+
+ if (que != NULL) {
+ LASSERT(com->lc_lfsck->li_master);
+
+ rc = lfsck_layout_query_all(env, com,
+ que->lu_mdts_count[idx],
+ que->lu_osts_count[idx],
+ &que->lu_repaired[idx]);
+ } else {
+ down_read(&com->lc_sem);
+ rep->lr_status = lo->ll_status;
+ if (req->lr_flags & LEF_QUERY_ALL)
+ lfsck_layout_repaired(lo, &rep->lr_repaired);
+ up_read(&com->lc_sem);
+ }
- return lo->ll_status;
+ return rc;
}
/* with lfsck::li_lock held */
struct lfsck_assistant_data *lad = com->lc_data;
struct lfsck_layout_req *llr;
+ if (((struct lfsck_layout *)(com->lc_file_ram))->ll_status !=
+ LS_SCANNING_PHASE1)
+ return;
+
if (list_empty(&lad->lad_req_list))
return;
struct lfsck_layout *lo;
struct dt_object *root = NULL;
struct dt_object *obj;
+ int i;
int rc;
ENTRY;
LFSCK_LAYOUT);
if (com->lc_data == NULL)
GOTO(out, rc = -ENOMEM);
+
+ for (i = 0; i < LFSCK_STF_COUNT; i++)
+ mutex_init(&com->lc_sub_trace_objs[i].lsto_mutex);
} else {
struct lfsck_layout_slave_data *llsd;
rc = lfsck_layout_reset(env, com, true);
else if (rc == -ENOENT)
rc = lfsck_layout_init(env, com);
+ else if (lfsck->li_master)
+ rc = lfsck_load_sub_trace_files(env, com,
+ &dt_lfsck_layout_dangling_features,
+ LFSCK_LAYOUT, false);
if (rc != 0)
GOTO(out, rc);
LASSERT(llst != NULL);
if (hash != llst->llst_hash) {
- CDEBUG(D_LFSCK, "%s: the given hash "LPU64" for orphan "
+ CDEBUG(D_LFSCK, "%s: the given hash %llu for orphan "
"iteration does not match the one when fini "
- LPU64", to be reset.\n",
+ "%llu, to be reset.\n",
lfsck_lfsck2name(it->loi_com->lc_lfsck), hash,
llst->llst_hash);
fid_zero(&llst->llst_fid);