From 3ad2eb7d456167d71bc4c0552e9a44af5e07fae9 Mon Sep 17 00:00:00 2001 From: Mikhail Pershin Date: Sat, 18 Aug 2018 21:50:53 +0300 Subject: [PATCH] LU-11270 mdt: better DOM data discard Discard DOM data when all object are put and unlocked. So current thread will wait for discard but resources are not blocked by it. Also cancel discard lock immediately. Patch also add missing part for lock prolongation for DoM locks and fix for tgt_blocking_ast() to don't miss a call to ldlm_server_blocking_ast() in case of lu_env_init() failure. Signed-off-by: Mikhail Pershin Change-Id: I09aaa08e28d2a280ca1f9939315311c45d0334b5 Reviewed-on: https://review.whamcloud.com/33026 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Oleg Drokin --- lustre/mdt/mdt_internal.h | 7 +++---- lustre/mdt/mdt_io.c | 36 ++++++++++++++++++++++++++++++++++-- lustre/mdt/mdt_open.c | 16 +++++++++++----- lustre/mdt/mdt_reint.c | 26 ++++++++++++++++++-------- lustre/target/tgt_handler.c | 4 ++-- lustre/tests/racer/file_create.sh | 2 +- 6 files changed, 69 insertions(+), 22 deletions(-) diff --git a/lustre/mdt/mdt_internal.h b/lustre/mdt/mdt_internal.h index ab71750..ffff9d6 100644 --- a/lustre/mdt/mdt_internal.h +++ b/lustre/mdt/mdt_internal.h @@ -1279,12 +1279,11 @@ void mdt_dom_obj_lvb_update(const struct lu_env *env, struct mdt_object *mo, bool increase_only); int mdt_dom_lvb_alloc(struct ldlm_resource *res); -static inline void mdt_dom_check_and_discard(struct mdt_thread_info *mti, +static inline bool mdt_dom_check_for_discard(struct mdt_thread_info *mti, struct mdt_object *mo) { - if (lu_object_is_dying(&mo->mot_header) && - S_ISREG(lu_object_attr(&mo->mot_obj))) - mdt_dom_discard_data(mti, mdt_object_fid(mo)); + return lu_object_is_dying(&mo->mot_header) && + S_ISREG(lu_object_attr(&mo->mot_obj)); } int mdt_dom_object_size(const struct lu_env *env, struct mdt_device *mdt, diff --git a/lustre/mdt/mdt_io.c b/lustre/mdt/mdt_io.c index 9569cb2..c5dc89f 100644 --- a/lustre/mdt/mdt_io.c +++ b/lustre/mdt/mdt_io.c @@ -78,6 +78,36 @@ static inline time64_t prolong_timeout(struct ptlrpc_request *req) req_timeout); } +static void mdt_dom_resource_prolong(struct ldlm_prolong_args *arg) +{ + struct ldlm_resource *res; + struct ldlm_lock *lock; + + ENTRY; + + res = ldlm_resource_get(arg->lpa_export->exp_obd->obd_namespace, NULL, + &arg->lpa_resid, LDLM_EXTENT, 0); + if (IS_ERR(res)) { + CDEBUG(D_DLMTRACE, + "Failed to get resource for resid %llu/%llu\n", + arg->lpa_resid.name[0], arg->lpa_resid.name[1]); + RETURN_EXIT; + } + + lock_res(res); + list_for_each_entry(lock, &res->lr_granted, l_res_link) { + if (ldlm_has_dom(lock)) { + LDLM_DEBUG(lock, "DOM lock to prolong "); + ldlm_lock_prolong_one(lock, arg); + break; + } + } + unlock_res(res); + ldlm_resource_putref(res); + + EXIT; +} + static void mdt_prolong_dom_lock(struct tgt_session_info *tsi, struct ldlm_prolong_args *data) { @@ -102,9 +132,11 @@ static void mdt_prolong_dom_lock(struct tgt_session_info *tsi, ldlm_lock_prolong_one(lock, data); lock->l_last_used = ktime_get(); LDLM_LOCK_PUT(lock); - RETURN_EXIT; + if (data->lpa_locks_cnt > 0) + RETURN_EXIT; } } + mdt_dom_resource_prolong(data); EXIT; } @@ -1200,7 +1232,7 @@ void mdt_dom_discard_data(struct mdt_thread_info *info, /* We only care about the side-effects, just drop the lock. */ if (rc == ELDLM_OK) - ldlm_lock_decref(&dom_lh, LCK_PW); + ldlm_lock_decref_and_cancel(&dom_lh, LCK_PW); } /* check if client has already DoM lock for given resource */ diff --git a/lustre/mdt/mdt_open.c b/lustre/mdt/mdt_open.c index 386b267..bf4dc12 100644 --- a/lustre/mdt/mdt_open.c +++ b/lustre/mdt/mdt_open.c @@ -2222,17 +2222,20 @@ int mdt_mfd_close(struct mdt_thread_info *info, struct mdt_file_data *mfd) struct mdt_object *o = mfd->mfd_object; struct md_object *next = mdt_object_child(o); struct md_attr *ma = &info->mti_attr; + struct lu_fid *ofid = &info->mti_tmp_fid1; int rc = 0; __u64 mode; __u64 intent; + bool discard = false; ENTRY; mode = mfd->mfd_mode; intent = ma->ma_attr_flags & MDS_CLOSE_INTENT; + *ofid = *mdt_object_fid(o); CDEBUG(D_INODE, "%s: close file "DFID" with intent: %llx\n", - mdt_obd_name(info->mti_mdt), PFID(mdt_object_fid(o)), intent); + mdt_obd_name(info->mti_mdt), PFID(ofid), intent); switch (intent) { case MDS_HSM_RELEASE: { @@ -2240,7 +2243,7 @@ int mdt_mfd_close(struct mdt_thread_info *info, struct mdt_file_data *mfd) if (rc < 0) { CDEBUG(D_HSM, "%s: File " DFID " release failed: %d\n", mdt_obd_name(info->mti_mdt), - PFID(mdt_object_fid(o)), rc); + PFID(ofid), rc); /* continue to close even error occurred. */ } break; @@ -2253,7 +2256,7 @@ int mdt_mfd_close(struct mdt_thread_info *info, struct mdt_file_data *mfd) CDEBUG(D_INODE, "%s: cannot swap layout of "DFID": rc = %d\n", mdt_obd_name(info->mti_mdt), - PFID(mdt_object_fid(o)), rc); + PFID(ofid), rc); /* continue to close even if error occurred. */ } break; @@ -2275,7 +2278,7 @@ int mdt_mfd_close(struct mdt_thread_info *info, struct mdt_file_data *mfd) CDEBUG(D_INODE, "%s: File " DFID " LSOM failed: rc = %d\n", mdt_obd_name(info->mti_mdt), - PFID(mdt_object_fid(o)), rc2); + PFID(ofid), rc2); /* continue to close even if error occured. */ } @@ -2307,7 +2310,7 @@ int mdt_mfd_close(struct mdt_thread_info *info, struct mdt_file_data *mfd) if (!MFD_CLOSED(mode)) { rc = mo_close(info->mti_env, next, ma, mode); - mdt_dom_check_and_discard(info, o); + discard = mdt_dom_check_for_discard(info, o); } /* adjust open and lease count */ @@ -2319,6 +2322,9 @@ int mdt_mfd_close(struct mdt_thread_info *info, struct mdt_file_data *mfd) mdt_mfd_free(mfd); mdt_object_put(info->mti_env, o); + if (discard) + mdt_dom_discard_data(info, ofid); + RETURN(rc); } diff --git a/lustre/mdt/mdt_reint.c b/lustre/mdt/mdt_reint.c index 62308a8..d2dfd3f 100644 --- a/lustre/mdt/mdt_reint.c +++ b/lustre/mdt/mdt_reint.c @@ -1029,7 +1029,7 @@ relock: if (rc) GOTO(out_stat, rc); } else { - discard = true; + discard = mdt_dom_check_for_discard(info, mc); } mdt_handle_last_unlink(info, mc, ma); @@ -1058,13 +1058,18 @@ out_stat: unlock_child: mdt_reint_striped_unlock(info, mc, child_lh, einfo, rc); put_child: - if (discard) - mdt_dom_check_and_discard(info, mc); mdt_object_put(info->mti_env, mc); unlock_parent: mdt_object_unlock(info, mp, parent_lh, rc); put_parent: mdt_object_put(info->mti_env, mp); + + /* discard is just a PW DOM lock to drop the data on a client + * no need to keep objects being get and locked, do that after all. + */ + if (discard) + mdt_dom_discard_data(info, child_fid); + return rc; } @@ -2173,7 +2178,7 @@ relock: mdt_counter_incr(req, LPROC_MDT_RENAME); if (mnew) { mdt_handle_last_unlink(info, mnew, ma); - discard = true; + discard = mdt_dom_check_for_discard(info, mnew); } mdt_rename_counter_tally(info, info->mti_mdt, req, @@ -2186,11 +2191,8 @@ relock: out_unlock_old: mdt_object_unlock(info, mold, lh_oldp, rc); out_put_new: - if (mnew != NULL) { - if (discard) - mdt_dom_check_and_discard(info, mnew); + if (mnew != NULL) mdt_object_put(info->mti_env, mnew); - } out_put_old: mdt_object_put(info->mti_env, mold); out_unlock_parents: @@ -2200,6 +2202,14 @@ out_put_tgtdir: mdt_object_put(info->mti_env, mtgtdir); out_put_srcdir: mdt_object_put(info->mti_env, msrcdir); + + /* If 'discard' is set then new_fid must exits. + * DOM data discard need neither object nor lock, + * so do this at the end. + */ + if (discard) + mdt_dom_discard_data(info, new_fid); + return rc; } diff --git a/lustre/target/tgt_handler.c b/lustre/target/tgt_handler.c index b3419ec..ed8c030 100644 --- a/lustre/target/tgt_handler.c +++ b/lustre/target/tgt_handler.c @@ -1270,7 +1270,7 @@ static int tgt_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc, rc = lu_env_init(&env, LCT_DT_THREAD); if (unlikely(rc != 0)) - RETURN(rc); + GOTO(err, rc); ost_fid_from_resid(&fid, &lock->l_resource->lr_name, tgt->lut_lsd.lsd_osd_index); @@ -1301,7 +1301,7 @@ err_put: err_env: lu_env_fini(&env); } - +err: rc = ldlm_server_blocking_ast(lock, desc, data, flag); RETURN(rc); } diff --git a/lustre/tests/racer/file_create.sh b/lustre/tests/racer/file_create.sh index 3b37858..2dba88a 100755 --- a/lustre/tests/racer/file_create.sh +++ b/lustre/tests/racer/file_create.sh @@ -1,7 +1,7 @@ #!/bin/bash trap 'kill $(jobs -p)' EXIT RACER_ENABLE_PFL=${RACER_ENABLE_PFL:-true} -RACER_ENABLE_DOM=${RACER_ENABLE_DOM:-false} +RACER_ENABLE_DOM=${RACER_ENABLE_DOM:-true} RACER_ENABLE_FLR=${RACER_ENABLE_FLR:-true} DIR=$1 MAX=$2 -- 1.8.3.1