From 1d18700e987c62bb446d4c71c3d830940502e5a2 Mon Sep 17 00:00:00 2001 From: Fan Yong Date: Mon, 8 Oct 2012 15:35:55 +0800 Subject: [PATCH] LU-2041 oi: keep oi mapping cache consistency Sometimes the local ID of the per RPC thread OI mappig cache may be changed, but the FID of such OI mapping cache has not been updated, which will cause the RPC thread finds some unexpected object with the given FID, should be fixed. Move osd_device::osd_scrub::os_no_scrub to osd_device::od_noscrub. Signed-off-by: Fan Yong Change-Id: Idbc46cd70b136b7ffc2528331d5593fbac725900 Reviewed-on: http://review.whamcloud.com/4207 Tested-by: Hudson Reviewed-by: Andreas Dilger Tested-by: Maloo Reviewed-by: Liang Zhen Reviewed-by: Oleg Drokin --- lustre/osd-ldiskfs/osd_handler.c | 73 ++++++++++++++++++++------------------- lustre/osd-ldiskfs/osd_internal.h | 7 ++-- lustre/osd-ldiskfs/osd_lproc.c | 4 +-- lustre/osd-ldiskfs/osd_scrub.c | 15 ++++---- lustre/osd-ldiskfs/osd_scrub.h | 1 - lustre/tests/sanity-scrub.sh | 2 +- 6 files changed, 51 insertions(+), 51 deletions(-) diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c index f27fd30..060e1aa 100644 --- a/lustre/osd-ldiskfs/osd_handler.c +++ b/lustre/osd-ldiskfs/osd_handler.c @@ -366,12 +366,10 @@ osd_iget_verify(struct osd_thread_info *info, struct osd_device *dev, return inode; rc = osd_get_lma(inode, &info->oti_obj_dentry, lma); + if (rc == -ENODATA) + return inode; + if (rc != 0) { - if (rc == -ENODATA) { - CDEBUG(D_LFSCK, "inconsistent obj: NULL, %lu, "DFID"\n", - inode->i_ino, PFID(fid)); - rc = -EREMCHG; - } iput(inode); return ERR_PTR(rc); } @@ -380,7 +378,7 @@ osd_iget_verify(struct osd_thread_info *info, struct osd_device *dev, CDEBUG(D_LFSCK, "inconsistent obj: "DFID", %lu, "DFID"\n", PFID(&lma->lma_self_fid), inode->i_ino, PFID(fid)); iput(inode); - return ERR_PTR(EREMCHG); + return ERR_PTR(-EREMCHG); } return inode; } @@ -411,26 +409,27 @@ static int osd_fid_lookup(const struct lu_env *env, struct osd_object *obj, info = osd_oti_get(env); LASSERT(info); oic = &info->oti_cache; - id = &oic->oic_lid; if (OBD_FAIL_CHECK(OBD_FAIL_OST_ENOENT)) RETURN(-ENOENT); - if (fid_is_norm(fid)) { - /* Search order: 1. per-thread cache. */ - if (lu_fid_eq(fid, &oic->oic_fid)) { - goto iget; - } else if (!cfs_list_empty(&scrub->os_inconsistent_items)) { - /* Search order: 2. OI scrub pending list. */ - result = osd_oii_lookup(dev, fid, id); - if (result == 0) - goto iget; - } + /* Search order: 1. per-thread cache. */ + if (lu_fid_eq(fid, &oic->oic_fid)) { + id = &oic->oic_lid; + goto iget; + } - if (sf->sf_flags & SF_INCONSISTENT) - verify = 1; + id = &info->oti_id; + if (!cfs_list_empty(&scrub->os_inconsistent_items)) { + /* Search order: 2. OI scrub pending list. */ + result = osd_oii_lookup(dev, fid, id); + if (result == 0) + goto iget; } + if (sf->sf_flags & SF_INCONSISTENT) + verify = 1; + /* * Objects are created as locking anchors or place holders for objects * yet to be created. No need to osd_oi_lookup() at here because FID @@ -470,7 +469,7 @@ iget: trigger: if (thread_is_running(&scrub->os_thread)) { result = -EINPROGRESS; - } else if (!scrub->os_no_scrub) { + } else if (!dev->od_noscrub) { result = osd_scrub_start(dev); LCONSOLE_ERROR("%.16s: trigger OI scrub by RPC " "for "DFID", rc = %d [1]\n", @@ -3327,7 +3326,7 @@ static int osd_ea_add_rec(const struct lu_env *env, struct osd_object *pobj, return rc; } -static int +static void osd_consistency_check(struct osd_thread_info *oti, struct osd_device *dev, struct osd_idmap_cache *oic) { @@ -3338,13 +3337,16 @@ osd_consistency_check(struct osd_thread_info *oti, struct osd_device *dev, int rc; ENTRY; + if (!fid_is_norm(fid) && !fid_is_igif(fid)) + RETURN_EXIT; + again: rc = osd_oi_lookup(oti, dev, fid, id); if (rc != 0 && rc != -ENOENT) - RETURN(rc); + RETURN_EXIT; if (rc == 0 && osd_id_eq(id, &oic->oic_lid)) - RETURN(0); + RETURN_EXIT; if (thread_is_running(&scrub->os_thread)) { rc = osd_oii_insert(dev, oic, rc == -ENOENT); @@ -3355,10 +3357,10 @@ again: if (unlikely(rc == -EAGAIN)) goto again; - RETURN(rc); + RETURN_EXIT; } - if (!scrub->os_no_scrub && ++once == 1) { + if (!dev->od_noscrub && ++once == 1) { CDEBUG(D_LFSCK, "Trigger OI scrub by RPC for "DFID"\n", PFID(fid)); rc = osd_scrub_start(dev); @@ -3370,7 +3372,7 @@ again: goto again; } - RETURN(rc = -EREMCHG); + EXIT; } /** @@ -3423,7 +3425,7 @@ static int osd_ea_lookup_rec(const struct lu_env *env, struct osd_object *obj, rc = osd_ea_fid_get(env, obj, ino, fid, &oic->oic_lid); else osd_id_gen(&oic->oic_lid, ino, OSD_OII_NOGEN); - if (rc != 0 || !fid_is_norm(fid)) { + if (rc != 0) { fid_zero(&oic->oic_fid); GOTO(out, rc); } @@ -3433,7 +3435,7 @@ static int osd_ea_lookup_rec(const struct lu_env *env, struct osd_object *obj, (sf->sf_flags & SF_INCONSISTENT || ldiskfs_test_bit(osd_oi_fid2idx(dev, fid), sf->sf_oi_bitmap))) - rc = osd_consistency_check(oti, dev, oic); + osd_consistency_check(oti, dev, oic); } else { rc = -ENOENT; } @@ -4130,8 +4132,10 @@ static inline int osd_it_ea_rec(const struct lu_env *env, if (!fid_is_sane(fid)) { rc = osd_ea_fid_get(env, obj, ino, fid, &oic->oic_lid); - if (rc != 0) + if (rc != 0) { + fid_zero(&oic->oic_fid); RETURN(rc); + } } else { osd_id_gen(&oic->oic_lid, ino, OSD_OII_NOGEN); } @@ -4140,16 +4144,11 @@ static inline int osd_it_ea_rec(const struct lu_env *env, it->oie_dirent->oied_name, it->oie_dirent->oied_namelen, it->oie_dirent->oied_type, attr); - if (!fid_is_norm(fid)) { - fid_zero(&oic->oic_fid); - RETURN(0); - } - oic->oic_fid = *fid; if ((scrub->os_pos_current <= ino) && (sf->sf_flags & SF_INCONSISTENT || ldiskfs_test_bit(osd_oi_fid2idx(dev, fid), sf->sf_oi_bitmap))) - rc = osd_consistency_check(oti, dev, oic); + osd_consistency_check(oti, dev, oic); RETURN(rc); } @@ -4219,7 +4218,6 @@ static int osd_index_ea_lookup(const struct lu_env *env, struct dt_object *dt, return -EACCES; rc = osd_ea_lookup_rec(env, obj, rec, key); - if (rc == 0) rc = +1; RETURN(rc); @@ -4375,6 +4373,9 @@ static int osd_mount(const struct lu_env *env, lsi = s2lsi(lmi->lmi_sb); ldd = lsi->lsi_ldd; + if (get_mount_flags(lmi->lmi_sb) & LMD_FLG_NOSCRUB) + o->od_noscrub = 1; + if (ldd->ldd_flags & LDD_F_IAM_DIR) { o->od_iop_mode = 0; LCONSOLE_WARN("%s: OSD: IAM mode enabled\n", dev); diff --git a/lustre/osd-ldiskfs/osd_internal.h b/lustre/osd-ldiskfs/osd_internal.h index eeb57db..4130727 100644 --- a/lustre/osd-ldiskfs/osd_internal.h +++ b/lustre/osd-ldiskfs/osd_internal.h @@ -280,11 +280,8 @@ struct osd_device { struct obd_statfs od_statfs; cfs_spinlock_t od_osfs_lock; - /** - * The following flag indicates, if it is interop mode or not. - * It will be initialized, using mount param. - */ - __u32 od_iop_mode; + unsigned int od_iop_mode:1, + od_noscrub:1; struct fsfilt_operations *od_fsops; diff --git a/lustre/osd-ldiskfs/osd_lproc.c b/lustre/osd-ldiskfs/osd_lproc.c index dea02f3..9009dc6 100644 --- a/lustre/osd-ldiskfs/osd_lproc.c +++ b/lustre/osd-ldiskfs/osd_lproc.c @@ -370,7 +370,7 @@ static int lprocfs_osd_rd_auto_scrub(char *page, char **start, off_t off, return -EINPROGRESS; *eof = 1; - return snprintf(page, count, "%d\n", !dev->od_scrub.os_no_scrub); + return snprintf(page, count, "%d\n", !dev->od_noscrub); } static int lprocfs_osd_wr_auto_scrub(struct file *file, const char *buffer, @@ -387,7 +387,7 @@ static int lprocfs_osd_wr_auto_scrub(struct file *file, const char *buffer, if (rc) return rc; - dev->od_scrub.os_no_scrub = !val; + dev->od_noscrub = !val; return count; } diff --git a/lustre/osd-ldiskfs/osd_scrub.c b/lustre/osd-ldiskfs/osd_scrub.c index 762ea07..8f57596 100644 --- a/lustre/osd-ldiskfs/osd_scrub.c +++ b/lustre/osd-ldiskfs/osd_scrub.c @@ -385,12 +385,15 @@ iget: GOTO(out, rc = -ENOMEM); } - if (ops == DTO_INDEX_UPDATE) + if (ops == DTO_INDEX_UPDATE) { rc = iam_update(jh, bag, (const struct iam_key *)oi_fid, (struct iam_rec *)oi_id, ipd); - else + } else { rc = iam_insert(jh, bag, (const struct iam_key *)oi_fid, (struct iam_rec *)oi_id, ipd); + if (rc == -EEXIST) + rc = 1; + } osd_ipd_put(info->oti_env, bag, ipd); ldiskfs_journal_stop(jh); if (rc == 0) { @@ -403,11 +406,13 @@ iget: GOTO(out, rc); out: - if (rc != 0) { + if (rc < 0) { sf->sf_items_failed++; if (sf->sf_pos_first_inconsistent == 0 || sf->sf_pos_first_inconsistent > lid->oii_ino) sf->sf_pos_first_inconsistent = lid->oii_ino; + } else { + rc = 0; } if (ops == DTO_INDEX_INSERT) { @@ -1042,8 +1047,6 @@ int osd_scrub_setup(const struct lu_env *env, struct osd_device *dev) cfs_init_rwsem(&scrub->os_rwsem); cfs_spin_lock_init(&scrub->os_lock); CFS_INIT_LIST_HEAD(&scrub->os_inconsistent_items); - if (get_mount_flags(dev->od_mount->lmi_sb) & LMD_FLG_NOSCRUB) - scrub->os_no_scrub = 1; push_ctxt(&saved, ctxt, NULL); filp = filp_open(osd_scrub_name, O_RDWR | O_CREAT, 0644); @@ -1107,7 +1110,7 @@ int osd_scrub_setup(const struct lu_env *env, struct osd_device *dev) } } - if (rc == 0 && !scrub->os_no_scrub && + if (rc == 0 && !dev->od_noscrub && ((sf->sf_status == SS_PAUSED) || (sf->sf_status == SS_CRASHED && sf->sf_flags & (SF_RECREATED | SF_INCONSISTENT | SF_AUTO)) || diff --git a/lustre/osd-ldiskfs/osd_scrub.h b/lustre/osd-ldiskfs/osd_scrub.h index c012d6b..2437772 100644 --- a/lustre/osd-ldiskfs/osd_scrub.h +++ b/lustre/osd-ldiskfs/osd_scrub.h @@ -198,7 +198,6 @@ struct osd_scrub { * found by RPC prior */ os_waiting:1, /* Waiting for scan window. */ os_full_speed:1, /* run w/o speed limit */ - os_no_scrub:1, /* NOT auto trigger OI scrub*/ os_paused:1; /* The scrub is paused. */ }; diff --git a/lustre/tests/sanity-scrub.sh b/lustre/tests/sanity-scrub.sh index 1b2c6cd..a40335d 100644 --- a/lustre/tests/sanity-scrub.sh +++ b/lustre/tests/sanity-scrub.sh @@ -122,7 +122,7 @@ test_1b() { local FLAGS=$($SHOW_SCRUB | awk '/^flags/ { print $2 }') [ "$FLAGS" == "recreated" ] || - error "(3) Expect 'recreated', but got '$STATUS'" + error "(3) Expect 'recreated', but got '$FLAGS'" $START_SCRUB || error "(4) Fail to start OI scrub!" sleep 3 -- 1.8.3.1