From: Fan Yong Date: Wed, 21 Oct 2015 02:43:49 +0000 (+0800) Subject: LU-6861 scrub: only trigger full OI scrub when necessary X-Git-Tag: 2.8.55~66 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=76b4684a576ea423561fafb5fdb5f6f762e6b3e0 LU-6861 scrub: only trigger full OI scrub when necessary Generally, scanning the whole device for OI scrub routine check may takes some long time. If the whole system only contains several bad OI mappings, then it is not worth to trigger OI scrub automatically with full speed when some bad OI mapping is auto-detected. Instead, we can make the OI scrub to fix the found bad OI mappings only, and if more and more bad OI mappings are found as to exceeds some given threshold that can be adjusted via some proc interface, then the OI scrub will run with full speed to scan whole device. Our current OI scrub auto-trigger control mechanism can avoid most of unnecessary whole-device based scanning. But it missed one case that the FID lookup for remote MDT-object and may cause unexpected whole-device based OI scrub. This patch is for handle such corner. Fix the sanity-scrub.sh test_4a, test_4b, and test_4c to search for "prior_updated" and not "updated_prior" in the scrub status file. Signed-off-by: James Nunez Signed-off-by: Fan Yong Change-Id: I776c44b1dbc7357817d42d9b1ff6011226fe292b Reviewed-on: http://review.whamcloud.com/16951 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Alex Zhuravlev Reviewed-by: Oleg Drokin --- diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c index c7c8ecf..681897f 100644 --- a/lustre/osd-ldiskfs/osd_handler.c +++ b/lustre/osd-ldiskfs/osd_handler.c @@ -779,9 +779,9 @@ static int osd_fid_lookup(const struct lu_env *env, struct osd_object *obj, struct osd_scrub *scrub; struct scrub_file *sf; int result; - int saved = 0; - bool cached = true; - bool triggered = false; + int rc1 = 0; + bool cached = true; + bool remote = false; ENTRY; LINVRNT(osd_invariant(obj)); @@ -847,29 +847,6 @@ iget: if (result == -EREMCHG) { trigger: - if (unlikely(triggered)) - GOTO(out, result = saved); - - triggered = true; - if (thread_is_running(&scrub->os_thread)) { - result = -EINPROGRESS; - } else if (!dev->od_noscrub) { - result = osd_scrub_start(dev, SS_AUTO_FULL | - SS_CLEAR_DRYRUN | SS_CLEAR_FAILOUT); - LCONSOLE_WARN("%.16s: trigger OI scrub by RPC " - "for "DFID", rc = %d [1]\n", - osd_name(dev), PFID(fid), result); - if (result == 0 || result == -EALREADY) - result = -EINPROGRESS; - else - result = -EREMCHG; - } else { - result = -EREMCHG; - } - - if (fid_is_on_ost(info, dev, fid, OI_CHECK_FLD)) - GOTO(out, result); - /* We still have chance to get the valid inode: for the * object which is referenced by remote name entry, the * object on the local MDT will be linked under the dir @@ -885,18 +862,54 @@ trigger: * only happened for the RPC from other MDT during the * OI scrub, or for the client side RPC with FID only, * such as FID to path, or from old connected client. */ - saved = result; - result = osd_lookup_in_remote_parent(info, dev, - fid, id); - if (result == 0) { - cached = true; - goto iget; + if (!remote && + !fid_is_on_ost(info, dev, fid, OI_CHECK_FLD)) { + rc1 = osd_lookup_in_remote_parent(info, dev, + fid, id); + if (rc1 == 0) { + remote = true; + cached = true; + goto iget; + } } - result = saved; + if (thread_is_running(&scrub->os_thread)) { + if (remote) { + osd_add_oi_cache(info, dev, id, fid); + osd_oii_insert(dev, oic, true); + } else { + result = -EINPROGRESS; + } + } else if (!dev->od_noscrub) { + __u32 flags = SS_CLEAR_DRYRUN | + SS_CLEAR_FAILOUT; + + flags |= (remote ? SS_AUTO_PARTIAL : + SS_AUTO_FULL); + rc1 = osd_scrub_start(dev, flags); + LCONSOLE_WARN("%.16s: trigger OI scrub by RPC " + "for the "DFID" with flags 0x%x," + " rc = %d\n", osd_name(dev), + PFID(fid), flags, rc1); + if (rc1 == 0 || rc1 == -EALREADY) { + result = -EINPROGRESS; + if (remote) { + osd_add_oi_cache(info, dev, id, + fid); + osd_oii_insert(dev, oic, true); + } + } else { + result = -EREMCHG; + } + } else { + result = -EREMCHG; + } } GOTO(out, result); + } else if (remote) { + result = 0; + goto trigger; } obj->oo_inode = inode; @@ -2621,7 +2634,8 @@ static int __osd_oi_insert(const struct lu_env *env, struct osd_object *obj, osd_trans_exec_op(env, th, OSD_OT_INSERT); osd_id_gen(id, obj->oo_inode->i_ino, obj->oo_inode->i_generation); - rc = osd_oi_insert(info, osd, fid, id, oh->ot_handle, OI_CHECK_FLD); + rc = osd_oi_insert(info, osd, fid, id, oh->ot_handle, + OI_CHECK_FLD, NULL); osd_trans_exec_check(env, th, OSD_OT_INSERT); return rc; diff --git a/lustre/osd-ldiskfs/osd_oi.c b/lustre/osd-ldiskfs/osd_oi.c index 3517c0d..a57e21a 100644 --- a/lustre/osd-ldiskfs/osd_oi.c +++ b/lustre/osd-ldiskfs/osd_oi.c @@ -670,7 +670,7 @@ static int osd_oi_iam_refresh(struct osd_thread_info *oti, struct osd_oi *oi, int osd_oi_insert(struct osd_thread_info *info, struct osd_device *osd, const struct lu_fid *fid, const struct osd_inode_id *id, - handle_t *th, enum oi_check_flags flags) + handle_t *th, enum oi_check_flags flags, bool *exist) { struct lu_fid *oi_fid = &info->oti_fid2; struct osd_inode_id *oi_id = &info->oti_id2; @@ -742,6 +742,9 @@ update: (const struct dt_key *)oi_fid, th, false); if (rc != 0) return rc; + + if (exist != NULL) + *exist = true; } if (unlikely(fid_seq(fid) == FID_SEQ_LOCAL_FILE)) diff --git a/lustre/osd-ldiskfs/osd_oi.h b/lustre/osd-ldiskfs/osd_oi.h index 6d5fae3..e278411 100644 --- a/lustre/osd-ldiskfs/osd_oi.h +++ b/lustre/osd-ldiskfs/osd_oi.h @@ -147,7 +147,7 @@ int osd_oi_lookup(struct osd_thread_info *info, struct osd_device *osd, enum oi_check_flags flags); int osd_oi_insert(struct osd_thread_info *info, struct osd_device *osd, const struct lu_fid *fid, const struct osd_inode_id *id, - handle_t *th, enum oi_check_flags flags); + handle_t *th, enum oi_check_flags flags, bool *exist); int osd_oi_delete(struct osd_thread_info *info, struct osd_device *osd, const struct lu_fid *fid, handle_t *th, enum oi_check_flags flags); diff --git a/lustre/osd-ldiskfs/osd_scrub.c b/lustre/osd-ldiskfs/osd_scrub.c index 7236a21..8c0c5ec 100644 --- a/lustre/osd-ldiskfs/osd_scrub.c +++ b/lustre/osd-ldiskfs/osd_scrub.c @@ -98,7 +98,7 @@ static int osd_scrub_refresh_mapping(struct osd_thread_info *info, const struct lu_fid *fid, const struct osd_inode_id *id, int ops, bool force, - enum oi_check_flags flags) + enum oi_check_flags flags, bool *exist) { handle_t *th; int rc; @@ -128,7 +128,7 @@ static int osd_scrub_refresh_mapping(struct osd_thread_info *info, } break; case DTO_INDEX_INSERT: - rc = osd_oi_insert(info, dev, fid, id, th, flags); + rc = osd_oi_insert(info, dev, fid, id, th, flags, exist); if (unlikely(rc == -EEXIST)) { rc = 1; /* XXX: There are trouble things when adding OI @@ -467,9 +467,9 @@ osd_scrub_check_update(struct osd_thread_info *info, struct osd_device *dev, struct osd_inconsistent_item *oii = NULL; struct inode *inode = NULL; int ops = DTO_INDEX_UPDATE; - int idx; int rc; bool converted = false; + bool exist = false; ENTRY; down_write(&scrub->os_rwsem); @@ -549,7 +549,6 @@ iget: if (!scrub->os_partial_scan) scrub->os_full_speed = 1; - idx = osd_oi_fid2idx(dev, fid); switch (val) { case SCRUB_NEXT_NOLMA: sf->sf_flags |= SF_UPGRADE; @@ -567,9 +566,6 @@ iget: case SCRUB_NEXT_OSTOBJ_OLD: break; default: - sf->sf_flags |= SF_RECREATED; - if (unlikely(!ldiskfs_test_bit(idx, sf->sf_oi_bitmap))) - ldiskfs_set_bit(idx, sf->sf_oi_bitmap); break; } } else if (osd_id_eq(lid, lid2)) { @@ -600,12 +596,21 @@ iget: rc = osd_scrub_refresh_mapping(info, dev, fid, lid, ops, false, (val == SCRUB_NEXT_OSTOBJ || - val == SCRUB_NEXT_OSTOBJ_OLD) ? OI_KNOWN_ON_OST : 0); + val == SCRUB_NEXT_OSTOBJ_OLD) ? OI_KNOWN_ON_OST : 0, + &exist); if (rc == 0) { if (scrub->os_in_prior) sf->sf_items_updated_prior++; else sf->sf_items_updated++; + + if (ops == DTO_INDEX_INSERT && val == 0 && !exist) { + int idx = osd_oi_fid2idx(dev, fid); + + sf->sf_flags |= SF_RECREATED; + if (unlikely(!ldiskfs_test_bit(idx, sf->sf_oi_bitmap))) + ldiskfs_set_bit(idx, sf->sf_oi_bitmap); + } } GOTO(out, rc); @@ -629,7 +634,7 @@ out: DTO_INDEX_DELETE, false, (val == SCRUB_NEXT_OSTOBJ || val == SCRUB_NEXT_OSTOBJ_OLD) ? - OI_KNOWN_ON_OST : 0); + OI_KNOWN_ON_OST : 0, NULL); up_write(&scrub->os_rwsem); if (inode != NULL && !IS_ERR(inode)) @@ -1862,7 +1867,7 @@ osd_ios_scan_one(struct osd_thread_info *info, struct osd_device *dev, RETURN(rc); rc = osd_scrub_refresh_mapping(info, dev, &tfid, id, - DTO_INDEX_INSERT, true, 0); + DTO_INDEX_INSERT, true, 0, NULL); if (rc > 0) rc = 0; @@ -1882,7 +1887,7 @@ osd_ios_scan_one(struct osd_thread_info *info, struct osd_device *dev, } rc = osd_scrub_refresh_mapping(info, dev, &tfid, id, - DTO_INDEX_UPDATE, true, 0); + DTO_INDEX_UPDATE, true, 0, NULL); if (rc > 0) rc = 0; @@ -2346,7 +2351,7 @@ static int osd_initial_OI_scrub(struct osd_thread_info *info, else if (PTR_ERR(child) == -ENOENT) osd_scrub_refresh_mapping(info, dev, &map->olm_fid, NULL, DTO_INDEX_DELETE, - true, 0); + true, 0, NULL); map++; } diff --git a/lustre/tests/sanity-scrub.sh b/lustre/tests/sanity-scrub.sh index f45cba9..2000ed8 100644 --- a/lustre/tests/sanity-scrub.sh +++ b/lustre/tests/sanity-scrub.sh @@ -430,7 +430,7 @@ test_4a() { local -a updated0 for n in $(seq $MDSCOUNT); do updated0[$n]=$(scrub_status $n | - awk '/^sf_items_updated_prior/ { print $2 }') + awk '/^prior_updated/ { print $2 }') done scrub_check_data2 sanity-scrub.sh 9 @@ -439,7 +439,7 @@ test_4a() { local -a updated1 for n in $(seq $MDSCOUNT); do updated1[$n]=$(scrub_status $n | - awk '/^sf_items_updated_prior/ { print $2 }') + awk '/^prior_updated/ { print $2 }') [ ${updated0[$n]} -eq ${updated1[$n]} ] || error "(10) NOT auto trigger full scrub as expected" done @@ -465,7 +465,7 @@ test_4b() { local -a updated0 for n in $(seq $MDSCOUNT); do updated0[$n]=$(scrub_status $n | - awk '/^sf_items_updated_prior/ { print $2 }') + awk '/^prior_updated/ { print $2 }') done scrub_check_data2 sanity-scrub.sh 9 @@ -477,7 +477,7 @@ test_4b() { local -a updated1 for n in $(seq $MDSCOUNT); do updated1[$n]=$(scrub_status $n | - awk '/^sf_items_updated_prior/ { print $2 }') + awk '/^prior_updated/ { print $2 }') [ ${updated0[$n]} -lt ${updated1[$n]} ] || error "(12) Auto trigger full scrub unexpectedly" done @@ -493,7 +493,7 @@ test_4b() { for n in $(seq $MDSCOUNT); do updated0[$n]=$(scrub_status $n | - awk '/^sf_items_updated_prior/ { print $2 }') + awk '/^prior_updated/ { print $2 }') [ ${updated0[$n]} -gt ${updated1[$n]} ] || error "(16) Auto trigger full scrub unexpectedly" done @@ -505,7 +505,7 @@ test_4b() { for n in $(seq $MDSCOUNT); do updated1[$n]=$(scrub_status $n | - awk '/^sf_items_updated_prior/ { print $2 }') + awk '/^prior_updated/ { print $2 }') [ ${updated0[$n]} -eq ${updated1[$n]} ] || error "(18) NOT auto trigger full scrub as expected" done @@ -531,7 +531,7 @@ test_4c() { local -a updated0 for n in $(seq $MDSCOUNT); do updated0[$n]=$(scrub_status $n | - awk '/^sf_items_updated_prior/ { print $2 }') + awk '/^prior_updated/ { print $2 }') done scrub_check_data2 sanity-scrub.sh 9 @@ -543,7 +543,7 @@ test_4c() { local -a updated1 for n in $(seq $MDSCOUNT); do updated1[$n]=$(scrub_status $n | - awk '/^sf_items_updated_prior/ { print $2 }') + awk '/^prior_updated/ { print $2 }') [ ${updated0[$n]} -lt ${updated1[$n]} ] || error "(12) Auto trigger full scrub unexpectedly" done @@ -559,7 +559,7 @@ test_4c() { for n in $(seq $MDSCOUNT); do updated0[$n]=$(scrub_status $n | - awk '/^sf_items_updated_prior/ { print $2 }') + awk '/^prior_updated/ { print $2 }') [ ${updated0[$n]} -gt ${updated1[$n]} ] || error "(16) Auto trigger full scrub unexpectedly" done @@ -571,7 +571,7 @@ test_4c() { for n in $(seq $MDSCOUNT); do updated1[$n]=$(scrub_status $n | - awk '/^sf_items_updated_prior/ { print $2 }') + awk '/^prior_updated/ { print $2 }') [ ${updated0[$n]} -eq ${updated1[$n]} ] || error "(18) NOT auto trigger full scrub as expected" done