From 140b897187cdbbdbc593b85dbb8a3322a9c28c9c Mon Sep 17 00:00:00 2001 From: Fan Yong Date: Mon, 27 Jul 2015 09:02:57 +0800 Subject: [PATCH] LU-7109 lfsck: update OST-index in IDIF inside OSD Old IDIF used "0" as the OST index, that may cause compatibility issues when update. There is switch inside osd-ldiskfs for controlling whether convert old IDIF to new one. Once the real OST index became part of the IDIF and stored on disk (in LMA EA), then the OST cannot be downgraded. Because the conversion switch is inside osd-ldiskfs, the LFSCK should not update the IDIF-in-LMA, instead, leave it to be handled by OSD to avoid downgrading trouble. Signed-off-by: Fan Yong Change-Id: I9fee60ffabf732c0ab0734b1184e4e49638c9e88 Reviewed-on: http://review.whamcloud.com/16282 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Alex Zhuravlev Reviewed-by: Niu Yawei Reviewed-by: Oleg Drokin --- lustre/lfsck/lfsck_engine.c | 88 +++++++--------------------------------- lustre/osd-ldiskfs/osd_compat.c | 39 ++++++++++++++++++ lustre/osd-ldiskfs/osd_handler.c | 3 +- 3 files changed, 56 insertions(+), 74 deletions(-) diff --git a/lustre/lfsck/lfsck_engine.c b/lustre/lfsck/lfsck_engine.c index ba65343..62e8184 100644 --- a/lustre/lfsck/lfsck_engine.c +++ b/lustre/lfsck/lfsck_engine.c @@ -93,64 +93,6 @@ static void lfsck_di_dir_put(const struct lu_env *env, struct lfsck_instance *lf iops->put(env, di); } -static int lfsck_update_lma(const struct lu_env *env, - struct lfsck_instance *lfsck, struct dt_object *obj) -{ - struct lfsck_thread_info *info = lfsck_env_info(env); - struct lfsck_bookmark *bk = &lfsck->li_bookmark_ram; - struct dt_device *dev = lfsck_obj2dev(obj); - struct lustre_mdt_attrs *lma = &info->lti_lma; - struct lu_buf *buf; - struct thandle *th; - int fl; - int rc; - ENTRY; - - if (bk->lb_param & LPF_DRYRUN) - RETURN(0); - - buf = lfsck_buf_get(env, info->lti_lma_old, LMA_OLD_SIZE); - rc = dt_xattr_get(env, obj, buf, XATTR_NAME_LMA); - if (rc < 0) { - if (rc != -ENODATA) - RETURN(rc); - - fl = LU_XATTR_CREATE; - lustre_lma_init(lma, lfsck_dto2fid(obj), LMAC_FID_ON_OST, 0); - } else { - if (rc != LMA_OLD_SIZE && rc != sizeof(struct lustre_mdt_attrs)) - RETURN(-EINVAL); - - fl = LU_XATTR_REPLACE; - lustre_lma_swab(lma); - lustre_lma_init(lma, lfsck_dto2fid(obj), - lma->lma_compat | LMAC_FID_ON_OST, - lma->lma_incompat); - } - lustre_lma_swab(lma); - - th = dt_trans_create(env, dev); - if (IS_ERR(th)) - RETURN(PTR_ERR(th)); - - buf = lfsck_buf_get(env, lma, sizeof(*lma)); - rc = dt_declare_xattr_set(env, obj, buf, XATTR_NAME_LMA, fl, th); - if (rc != 0) - GOTO(stop, rc); - - rc = dt_trans_start_local(env, dev, th); - if (rc != 0) - GOTO(stop, rc); - - rc = dt_xattr_set(env, obj, buf, XATTR_NAME_LMA, fl, th); - - GOTO(stop, rc); - -stop: - dt_trans_stop(env, dev, th); - return rc; -} - static int lfsck_parent_fid(const struct lu_env *env, struct dt_object *obj, struct lu_fid *fid) { @@ -886,7 +828,6 @@ static int lfsck_master_oit_engine(const struct lu_env *env, do { struct dt_object *target; - bool update_lma = false; if (lfsck->li_di_dir != NULL) { rc = lfsck_master_dir_engine(env, lfsck); @@ -955,13 +896,23 @@ static int lfsck_master_oit_engine(const struct lu_env *env, LASSERT(!lfsck->li_master); - /* It is an old format device, update the LMA. */ if (idx != idx1) { struct ost_id *oi = &info->lti_oi; + if (unlikely(idx1 != 0)) { + CDEBUG(D_LFSCK, "%s: invalid IDIF "DFID + ", not match device index %u\n", + lfsck_lfsck2name(lfsck), + PFID(fid), idx); + + goto checkpoint; + } + + /* rebuild the IDIF with index to + * avoid double instances for the + * same object. */ fid_to_ostid(fid, oi); ostid_to_fid(fid, oi, idx); - update_lma = true; } } else if (!fid_is_norm(fid) && !fid_is_igif(fid) && !fid_is_last_id(fid) && @@ -1003,18 +954,9 @@ static int lfsck_master_oit_engine(const struct lu_env *env, goto checkpoint; } - if (dt_object_exists(target)) { - if (update_lma) { - rc = lfsck_update_lma(env, lfsck, target); - if (rc != 0) - CDEBUG(D_LFSCK, "%s: fail to update " - "LMA for "DFID": rc = %d\n", - lfsck_lfsck2name(lfsck), - PFID(lfsck_dto2fid(target)), rc); - } - if (rc == 0) - rc = lfsck_exec_oit(env, lfsck, target); - } + if (dt_object_exists(target)) + rc = lfsck_exec_oit(env, lfsck, target); + lfsck_object_put(env, target); if (rc != 0 && bk->lb_param & LPF_FAILOUT) RETURN(rc); diff --git a/lustre/osd-ldiskfs/osd_compat.c b/lustre/osd-ldiskfs/osd_compat.c index 2d78901..0c44850 100644 --- a/lustre/osd-ldiskfs/osd_compat.c +++ b/lustre/osd-ldiskfs/osd_compat.c @@ -586,6 +586,45 @@ static int osd_obj_update_entry(struct osd_thread_info *info, GOTO(out, rc = -EEXIST); } + if (fid_is_idif(fid) && fid_is_idif(oi_fid)) { + __u32 idx1 = fid_idif_ost_idx(fid); + __u32 idx2 = fid_idif_ost_idx(oi_fid); + struct ost_id *ostid = &info->oti_ostid; + struct lu_fid *tfid = &info->oti_fid3; + + LASSERTF(idx1 == 0 || idx1 == osd->od_index, + "invalid given FID "DFID", not match the " + "device index %u\n", PFID(fid), osd->od_index); + + if (idx1 != idx2) { + if (idx1 == 0 && idx2 == osd->od_index) { + fid_to_ostid(fid, ostid); + ostid_to_fid(tfid, ostid, idx2); + if (lu_fid_eq(tfid, oi_fid)) { + CERROR("%s: the FID "DFID" is used by " + "two objects(2): %u/%u %u/%u\n", + osd_name(osd), PFID(fid), + oi_id->oii_ino, oi_id->oii_gen, + id->oii_ino, id->oii_gen); + + GOTO(out, rc = -EEXIST); + } + } else if (idx2 == 0 && idx1 == osd->od_index) { + fid_to_ostid(oi_fid, ostid); + ostid_to_fid(tfid, ostid, idx1); + if (lu_fid_eq(tfid, fid)) { + CERROR("%s: the FID "DFID" is used by " + "two objects(2): %u/%u %u/%u\n", + osd_name(osd), PFID(fid), + oi_id->oii_ino, oi_id->oii_gen, + id->oii_ino, id->oii_gen); + + GOTO(out, rc = -EEXIST); + } + } + } + } + update: /* There may be temporary inconsistency: On one hand, the new * object may be referenced by multiple entries, which is out diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c index d62023d..aebd82f 100644 --- a/lustre/osd-ldiskfs/osd_handler.c +++ b/lustre/osd-ldiskfs/osd_handler.c @@ -455,7 +455,8 @@ int osd_get_idif(struct osd_thread_info *info, struct inode *inode, rc = 0; ostid_set_seq(ostid, le64_to_cpu(ff->ff_seq)); ostid_set_id(ostid, le64_to_cpu(ff->ff_objid)); - /* XXX: should use real OST index in the future. LU-3569 */ + /* XXX: use 0 as the index for compatibility, the caller will + * handle index related issues when necessarry. */ ostid_to_fid(fid, ostid, 0); } else if (rc == sizeof(struct filter_fid)) { rc = 1; -- 1.8.3.1