* GPL HEADER END
*/
/*
- * Copyright (c) 2014, Intel Corporation.
+ * Copyright (c) 2014, 2017, Intel Corporation.
*/
/*
* lustre/lfsck/lfsck_striped_dir.c
#define DEBUG_SUBSYSTEM S_LFSCK
-#include <lustre/lustre_idl.h>
#include <lu_object.h>
#include <dt_object.h>
#include <md_object.h>
#include <lustre_lib.h>
#include <lustre_net.h>
#include <lustre_lmv.h>
-#include <lustre/lustre_user.h>
#include "lfsck_internal.h"
int lfsck_read_stripe_lmv(const struct lu_env *env, struct dt_object *obj,
struct lmv_mds_md_v1 *lmv)
{
+ struct lfsck_thread_info *info = lfsck_env_info(env);
+ struct lu_buf *buf = &info->lti_buf;
+ int size = sizeof(*lmv) + sizeof(struct lu_fid) * 2;
+ struct lmv_foreign_md *lfm;
int rc;
dt_read_lock(env, obj, 0);
- rc = dt_xattr_get(env, obj, lfsck_buf_get(env, lmv, sizeof(*lmv)),
- XATTR_NAME_LMV);
+ buf->lb_buf = lmv;
+ buf->lb_len = sizeof(*lmv);
+ rc = dt_xattr_get(env, obj, buf, XATTR_NAME_LMV);
+ if (unlikely(rc == -ERANGE)) {
+ buf = &info->lti_big_buf;
+ /* For the in-migration directory, its LMV EA contains
+ * not only the LMV header, but also the FIDs for both
+ * source and target. So the LMV EA size is larger.
+ * Or may be this is a foreign LMV */
+ rc = dt_xattr_get(env, obj, &LU_BUF_NULL, XATTR_NAME_LMV);
+ if (rc > sizeof(*lmv)) {
+ int rc1;
+
+ lu_buf_check_and_alloc(buf, rc);
+ rc1 = dt_xattr_get(env, obj, buf, XATTR_NAME_LMV);
+ if (rc != rc1)
+ rc = -EINVAL;
+ } else {
+ rc = -EINVAL;
+ }
+ }
dt_read_unlock(env, obj);
+
+ if (rc > 0 && rc > offsetof(typeof(*lfm), lfm_value) &&
+ *((__u32 *)buf->lb_buf) == LMV_MAGIC_FOREIGN) {
+ __u32 value_len;
+
+ lfm = buf->lb_buf;
+ value_len = le32_to_cpu(lfm->lfm_length);
+ CDEBUG(D_INFO,
+ "foreign LMV EA, magic %x, len %u, type %x, flags %x, for dir "DFID"\n",
+ le32_to_cpu(lfm->lfm_magic), value_len,
+ le32_to_cpu(lfm->lfm_type), le32_to_cpu(lfm->lfm_flags),
+ PFID(lfsck_dto2fid(obj)));
+
+ if (rc != value_len + offsetof(typeof(*lfm), lfm_value))
+ CDEBUG(D_LFSCK,
+ "foreign LMV EA internal size %u does not match EA full size %d for dir "DFID"\n",
+ value_len, rc, PFID(lfsck_dto2fid(obj)));
+
+ /* no further usage/decode of foreign LMV outside */
+ return -ENODATA;
+ }
+
+ if (rc == size) {
+ rc = sizeof(*lmv);
+ memcpy(lmv, buf->lb_buf, rc);
+ }
if (rc != sizeof(*lmv))
return rc > 0 ? -EINVAL : rc;
lfsck_lmv_put(env, llmv);
} else {
ns->ln_striped_dirs_repaired++;
+ llmv->ll_counted = 1;
spin_lock(&lfsck->li_lock);
list_add_tail(&llu->llu_link, &lfsck->li_list_lmv);
spin_unlock(&lfsck->li_lock);
lmv3->lmv_magic = LMV_MAGIC;
lmv3->lmv_master_mdt_index = pidx;
+ lmv3->lmv_layout_version++;
if (flags & LEF_SET_LMV_ALL) {
rc = lfsck_allow_regenerate_master_lmv(env, com, obj,
GOTO(out, rc);
}
+ CFS_FAIL_TIMEOUT(OBD_FAIL_LFSCK_ENGINE_DELAY, cfs_fail_val);
+
parent = lfsck_object_find_bottom(env, lfsck, pfid);
if (IS_ERR(parent)) {
rc = lfsck_namespace_trace_update(env, com, cfid,
RETURN(rc);
ns->ln_striped_dirs_scanned++;
- ns->ln_striped_dirs_repaired++;
+ if (!llmv->ll_counted)
+ ns->ln_striped_dirs_repaired++;
}
fld_range_set_mdt(range);
const struct lu_fid *cfid = &lslr->lslr_fid;
const struct lu_name *cname;
struct linkea_data ldata = { NULL };
- int len;
int rc1 = 0;
bool repair_linkea = false;
bool repair_lmvea = false;
if (fid_is_zero(cfid))
continue;
- len = snprintf(info->lti_tmpbuf, sizeof(info->lti_tmpbuf),
- DFID":%u", PFID(cfid), i);
- cname = lfsck_name_get_const(env, info->lti_tmpbuf, len);
- memcpy(lnr->lnr_name, info->lti_tmpbuf, len);
-
- obj = lfsck_object_find_bottom_nowait(env, lfsck, cfid);
+ lnr->lnr_fid = *cfid;
+ lnr->lnr_namelen = snprintf(lnr->lnr_name,
+ lnr->lnr_size - sizeof(*lnr),
+ DFID":%u", PFID(cfid), i);
+ cname = lfsck_name_get_const(env, lnr->lnr_name,
+ lnr->lnr_namelen);
+ obj = lfsck_object_find_bottom(env, lfsck, cfid);
if (IS_ERR(obj)) {
if (dir == NULL) {
dir = lfsck_assistant_object_load(env, lfsck,
break;
}
- rc1 = lfsck_links_read(env, obj, &ldata);
+ rc1 = lfsck_links_read_with_rec(env, obj, &ldata);
if (rc1 == -ENOENT) {
create = true;
goto repair;
if (repair_linkea) {
struct lustre_handle lh = { 0 };
- rc1 = linkea_data_new(&ldata, &info->lti_big_buf);
+ rc1 = linkea_links_new(&ldata, &info->lti_big_buf,
+ cname, lfsck_dto2fid(dir));
if (rc1 != 0)
goto next;
}
}
- rc1 = linkea_add_buf(&ldata, cname, lfsck_dto2fid(dir));
- if (rc1 != 0)
- goto next;
-
rc1 = lfsck_ibits_lock(env, lfsck, obj, &lh,
MDS_INODELOCK_UPDATE |
MDS_INODELOCK_XATTR, LCK_EX);
"%d "DFID" of the striped directory "DFID" with "
"dangling %s/%s, rename %s/%s, llinkea %s/%s, "
"repair_lmvea %s/%s: rc = %d\n", lfsck_lfsck2name(lfsck),
- i, PFID(cfid), PFID(&lnr->lnr_fid),
+ i, PFID(cfid), PFID(pfid),
create ? "yes" : "no", create_repaired ? "yes" : "no",
rename ? "yes" : "no", rename_repaired ? "yes" : "no",
repair_linkea ? "yes" : "no",
GOTO(out, rc);
}
- ltd = LTD_TGT(&lfsck->li_mdt_descs, shard_idx);
+ ltd = lfsck_ltd2tgt(&lfsck->li_mdt_descs, shard_idx);
if (unlikely(ltd == NULL)) {
CDEBUG(D_LFSCK, "%s: cannot talk with MDT %x which "
"did not join the namespace LFSCK\n",
dev = ltd->ltd_tgt;
}
- obj = lfsck_object_find_by_dev_nowait(env, dev, &lnr->lnr_fid);
+ obj = lfsck_object_find_by_dev(env, dev, &lnr->lnr_fid);
if (IS_ERR(obj)) {
if (lfsck_is_dead_obj(dir))
RETURN(0);