From fffef5c29e3bdf0f96168abc3d0488bad06f33bb Mon Sep 17 00:00:00 2001 From: Lai Siyao Date: Tue, 23 Oct 2018 19:17:20 +0800 Subject: [PATCH] LU-11418 mdd: delete name if orphan doesn't exist mdd_orphan_destroy() should delete name if orphan object doesn't exist, otherwise the orphan clean thread will try to destroy this orphan in dead loop. add sanity test_811. Signed-off-by: Lai Siyao Change-Id: Id22b2fab0ac87dfb81ca9f01d8ed0338f1b12120 Reviewed-on: https://review.whamcloud.com/33661 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Hongchao Zhang Reviewed-by: Oleg Drokin --- lustre/include/obd_support.h | 1 + lustre/mdd/mdd_orphans.c | 47 ++++++++++++++++++++++++++++---------------- lustre/tests/sanity.sh | 17 ++++++++++++++++ 3 files changed, 48 insertions(+), 17 deletions(-) diff --git a/lustre/include/obd_support.h b/lustre/include/obd_support.h index 3239ba8..60d7c9b 100644 --- a/lustre/include/obd_support.h +++ b/lustre/include/obd_support.h @@ -250,6 +250,7 @@ extern char obd_jobid_var[]; #define OBD_FAIL_MDS_TRACK_OVERFLOW 0x162 #define OBD_FAIL_MDS_LOV_CREATE_RACE 0x163 #define OBD_FAIL_MDS_HSM_CDT_DELAY 0x164 +#define OBD_FAIL_MDS_ORPHAN_DELETE 0x165 /* layout lock */ #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170 diff --git a/lustre/mdd/mdd_orphans.c b/lustre/mdd/mdd_orphans.c index 7b99a93..0b33f40 100644 --- a/lustre/mdd/mdd_orphans.c +++ b/lustre/mdd/mdd_orphans.c @@ -210,13 +210,13 @@ int mdd_orphan_declare_delete(const struct lu_env *env, struct mdd_object *obj, if (rc) return rc; + if (!mdd_object_exists(obj)) + return -ENOENT; + rc = mdo_declare_ref_del(env, obj, th); if (rc) return rc; - if (!lu_object_exists(&obj->mod_obj.mo_lu)) - return -ENOENT; - if (S_ISDIR(mdd_object_type(obj))) { rc = mdo_declare_ref_del(env, obj, th); if (rc) @@ -244,7 +244,7 @@ int mdd_orphan_delete(const struct lu_env *env, struct mdd_object *obj, struct mdd_device *mdd = mdo2mdd(&obj->mod_obj); struct dt_object *dor = mdd->mdd_orphans; struct dt_key *key; - int rc; + int rc = 0; ENTRY; @@ -257,12 +257,16 @@ int mdd_orphan_delete(const struct lu_env *env, struct mdd_object *obj, key = mdd_orphan_key_fill(env, mdo2fid(obj)); dt_write_lock(env, mdd->mdd_orphans, MOR_TGT_ORPHAN); + if (OBD_FAIL_CHECK(OBD_FAIL_MDS_ORPHAN_DELETE)) + goto ref_del; + rc = dt_delete(env, mdd->mdd_orphans, key, th); if (rc == -ENOENT) { key = mdd_orphan_key_fill_20(env, mdo2fid(obj)); rc = dt_delete(env, mdd->mdd_orphans, key, th); } +ref_del: if (!rc) { /* lov objects will be destroyed by caller */ mdo_ref_del(env, obj, th); @@ -286,6 +290,7 @@ static int mdd_orphan_destroy(const struct lu_env *env, struct mdd_object *obj, { struct thandle *th = NULL; struct mdd_device *mdd = mdo2mdd(&obj->mod_obj); + bool orphan_exists = true; int rc = 0; ENTRY; @@ -298,23 +303,31 @@ static int mdd_orphan_destroy(const struct lu_env *env, struct mdd_object *obj, RETURN(rc); } + mdd_write_lock(env, obj, MOR_TGT_CHILD); rc = mdd_orphan_declare_delete(env, obj, th); - if (rc) - GOTO(stop, rc); - - rc = mdo_declare_destroy(env, obj, th); - if (rc) - GOTO(stop, rc); + if (rc == -ENOENT) + orphan_exists = false; + else if (rc) + GOTO(unlock, rc); + + if (orphan_exists) { + rc = mdo_declare_destroy(env, obj, th); + if (rc) + GOTO(unlock, rc); + } rc = mdd_trans_start(env, mdd, th); if (rc) - GOTO(stop, rc); + GOTO(unlock, rc); - mdd_write_lock(env, obj, MOR_TGT_CHILD); if (likely(obj->mod_count == 0)) { dt_write_lock(env, mdd->mdd_orphans, MOR_TGT_ORPHAN); rc = dt_delete(env, mdd->mdd_orphans, key, th); - if (rc == 0) { + if (rc) { + CERROR("%s: could not delete orphan "DFID": rc = %d\n", + mdd2obd_dev(mdd)->obd_name, PFID(mdo2fid(obj)), + rc); + } else if (orphan_exists) { mdo_ref_del(env, obj, th); if (S_ISDIR(mdd_object_type(obj))) { mdo_ref_del(env, obj, th); @@ -322,15 +335,15 @@ static int mdd_orphan_destroy(const struct lu_env *env, struct mdd_object *obj, } rc = mdo_destroy(env, obj, th); } else { - CERROR("%s: could not delete orphan "DFID": rc = %d\n", - mdd2obd_dev(mdd)->obd_name, PFID(mdo2fid(obj)), - rc); + CWARN("%s: orphan %s "DFID" doesn't exist\n", + mdd2obd_dev(mdd)->obd_name, (char *)key, + PFID(mdo2fid(obj))); } dt_write_unlock(env, mdd->mdd_orphans); } +unlock: mdd_write_unlock(env, obj); -stop: rc = mdd_trans_stop(env, mdd, 0, th); RETURN(rc); diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 198646b..a378f38 100755 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -20069,6 +20069,23 @@ test_810() { } run_test 810 "partial page writes on ZFS (LU-11663)" +test_811() { + [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] && + skip "Need MDS version at least 2.11.56" + + #define OBD_FAIL_MDS_ORPHAN_DELETE 0x165 + do_facet mds1 $LCTL set_param fail_loc=0x165 + $MULTIOP $DIR/$tfile Ouc || error "multiop failed" + + stop mds1 + start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS + + sleep 5 + [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] || + error "MDD orphan cleanup thread not quit" +} +run_test 811 "orphan name stub can be cleaned up in startup" + # # tests that do cleanup/setup should be run at the end # -- 1.8.3.1