From 91fbcee9555982cbf8482808b7a93e4fe452fefa Mon Sep 17 00:00:00 2001 From: Bobi Jam Date: Mon, 24 Jun 2024 14:18:51 +0800 Subject: [PATCH] LU-17970 ldlm: add lock match flag LDLM_MATCH_SKIP_UNUSED Add lock match flag LDLM_MATCH_SKIP_UNUSED to skip match unused lock. Signed-off-by: Bobi Jam Change-Id: I31d8f051b837a5b00cee6f2bc1ad9782acc62892 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/55508 Reviewed-by: Sebastien Buisson Reviewed-by: Andreas Dilger Reviewed-by: Oleg Drokin Tested-by: jenkins Tested-by: Maloo --- lustre/include/lustre_dlm.h | 8 +++++--- lustre/include/obd.h | 1 + lustre/include/obd_class.h | 2 ++ lustre/ldlm/ldlm_lock.c | 20 ++++++++++++++++++-- lustre/llite/dir.c | 2 +- lustre/llite/file.c | 14 ++++++++------ lustre/llite/llite_internal.h | 3 ++- lustre/llite/namei.c | 7 ++++--- lustre/lmv/lmv_obd.c | 7 ++++--- lustre/mdc/mdc_dev.c | 12 ++++++------ lustre/mdc/mdc_internal.h | 4 +++- lustre/mdc/mdc_locks.c | 10 ++++++---- lustre/mdt/mdt_io.c | 4 ++-- lustre/osc/osc_object.c | 2 +- lustre/osc/osc_request.c | 6 +++--- 15 files changed, 66 insertions(+), 36 deletions(-) diff --git a/lustre/include/lustre_dlm.h b/lustre/include/lustre_dlm.h index adaa82f..b81803e 100644 --- a/lustre/include/lustre_dlm.h +++ b/lustre/include/lustre_dlm.h @@ -1023,6 +1023,7 @@ enum ldlm_match_flags { LDLM_MATCH_AST_ANY = BIT(2), LDLM_MATCH_RIGHT = BIT(3), LDLM_MATCH_GROUP = BIT(4), + LDLM_MATCH_SKIP_UNUSED = BIT(5), }; #ifdef HAVE_INTERVAL_TREE_CACHED @@ -1641,18 +1642,19 @@ enum ldlm_mode ldlm_lock_match_with_skip(struct ldlm_namespace *ns, enum ldlm_type type, union ldlm_policy_data *policy, enum ldlm_mode mode, - struct lustre_handle *lh, - enum ldlm_match_flags match_flags); + enum ldlm_match_flags match_flags, + struct lustre_handle *lh); static inline enum ldlm_mode ldlm_lock_match(struct ldlm_namespace *ns, __u64 flags, const struct ldlm_res_id *res_id, enum ldlm_type type, union ldlm_policy_data *policy, enum ldlm_mode mode, + enum ldlm_match_flags m_flags, struct lustre_handle *lh) { return ldlm_lock_match_with_skip(ns, flags, 0, res_id, type, policy, - mode, lh, 0); + mode, m_flags, lh); } struct ldlm_lock *search_itree(struct ldlm_resource *res, struct ldlm_match_data *data); diff --git a/lustre/include/obd.h b/lustre/include/obd.h index 4572f9b..3ea36fa 100644 --- a/lustre/include/obd.h +++ b/lustre/include/obd.h @@ -1358,6 +1358,7 @@ struct md_ops { enum ldlm_type type, union ldlm_policy_data *policy, enum ldlm_mode mode, + enum ldlm_match_flags match_flags, struct lustre_handle *lockh); int (*m_cancel_unused)(struct obd_export *exp, const struct lu_fid *fid, diff --git a/lustre/include/obd_class.h b/lustre/include/obd_class.h index c6ea0e4..b2b21f8 100644 --- a/lustre/include/obd_class.h +++ b/lustre/include/obd_class.h @@ -1839,6 +1839,7 @@ static inline enum ldlm_mode md_lock_match(struct obd_export *exp, __u64 flags, enum ldlm_type type, union ldlm_policy_data *policy, enum ldlm_mode mode, + enum ldlm_match_flags match_flags, struct lustre_handle *lockh) { int rc; @@ -1850,6 +1851,7 @@ static inline enum ldlm_mode md_lock_match(struct obd_export *exp, __u64 flags, return exp->exp_obd->obd_type->typ_md_ops->m_lock_match(exp, flags, fid, type, policy, mode, + match_flags, lockh); } diff --git a/lustre/ldlm/ldlm_lock.c b/lustre/ldlm/ldlm_lock.c index 08c6b5a..06d0c3e 100644 --- a/lustre/ldlm/ldlm_lock.c +++ b/lustre/ldlm/ldlm_lock.c @@ -1185,6 +1185,10 @@ static bool lock_matches(struct ldlm_lock *lock, void *vdata) lock->l_readers == 0 && lock->l_writers == 0) return false; + if (data->lmd_match & LDLM_MATCH_SKIP_UNUSED && + lock->l_readers == 0 && lock->l_writers == 0) + return false; + if (!(lock->l_req_mode & *data->lmd_mode)) return false; @@ -1389,6 +1393,18 @@ EXPORT_SYMBOL(ldlm_lock_allow_match); * If 'flags' contains LDLM_FL_TEST_LOCK, then don't actually reference a lock, * just tell us if we would have matched. * + * If @match_flags contains LDLM_MATCH_UNREF, then we don't match unreferenced + * locks + * If @match_flags contains LDLM_MATCH_AST, then we don't match lock without + * ast_data + * If @match_flags contains LDLM_MATCH_AST_ANY, then we'd match lock with + * ast_data + * If @match_flags contains LDLM_MATCH_RIGHT, then we'd match extent lock at + * the right region for the desired lock + * If @match_flags contains LDLM_MATCH_GROUP, then we'd match group lock + * If @match_flags contains LDLM_MATCH_SKIP_UNUSED, then we don't match any + * unused locks + * * \retval 1 if it finds an already-existing lock that is compatible; in this * case, lockh is filled in with a addref()ed lock * @@ -1402,8 +1418,8 @@ enum ldlm_mode ldlm_lock_match_with_skip(struct ldlm_namespace *ns, enum ldlm_type type, union ldlm_policy_data *policy, enum ldlm_mode mode, - struct lustre_handle *lockh, - enum ldlm_match_flags match_flags) + enum ldlm_match_flags match_flags, + struct lustre_handle *lockh) { struct ldlm_match_data data = { .lmd_old = NULL, diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index 9a55e15..c8ac8ed 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -360,7 +360,7 @@ static int ll_readdir(struct file *filp, void *cookie, filldir_t filldir) struct obd_export *exp = ll_i2mdexp(i_dir); enum mds_ibits_locks ibits = MDS_INODELOCK_LOOKUP; - if (ll_have_md_lock(exp, i_dir, &ibits, LCK_MINMODE)) + if (ll_have_md_lock(exp, i_dir, &ibits, LCK_MINMODE, 0)) pfid = *ll_inode2fid(i_dir); } dput(parent); diff --git a/lustre/llite/file.c b/lustre/llite/file.c index a3803ff..c6f777c 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -397,7 +397,7 @@ static int ll_md_close(struct inode *inode, struct file *file) /* LU-4398: do not cache write open lock if the file has exec bit */ if ((lockmode == LCK_CW && inode->i_mode & 0111) || !md_lock_match(ll_i2mdexp(inode), flags, ll_inode2fid(inode), - LDLM_IBITS, &policy, lockmode, &lockh)) + LDLM_IBITS, &policy, lockmode, 0, &lockh)) rc = ll_md_real_close(inode, lfd->fd_omode); out: @@ -5874,12 +5874,14 @@ ll_file_noflock(struct file *file, int cmd, struct file_lock *file_lock) * - if found clear the common lock bits in *bits * - the bits not found, are kept in *bits * \param inode [IN] - * \param bits [IN] searched lock bits [IN] - * \param l_req_mode [IN] searched lock mode + * \param bits [IN] searched lock bits [IN] + * \param l_req_mode [IN] searched lock mode + * \param match_flags [IN] match flags * \retval boolean, true iff all bits are found */ int ll_have_md_lock(struct obd_export *exp, struct inode *inode, - enum mds_ibits_locks *bits, enum ldlm_mode l_req_mode) + enum mds_ibits_locks *bits, enum ldlm_mode l_req_mode, + enum ldlm_match_flags match_flags) { struct lustre_handle lockh; union ldlm_policy_data policy; @@ -5904,7 +5906,7 @@ int ll_have_md_lock(struct obd_export *exp, struct inode *inode, continue; if (md_lock_match(exp, flags, fid, LDLM_IBITS, &policy, mode, - &lockh)) { + match_flags, &lockh)) { struct ldlm_lock *lock; lock = ldlm_handle2lock(&lockh); @@ -5933,7 +5935,7 @@ enum ldlm_mode ll_take_md_lock(struct inode *inode, __u64 bits, CDEBUG(D_INFO, "trying to match res "DFID"\n", PFID(fid)); rc = md_lock_match(ll_i2mdexp(inode), LDLM_FL_BLOCK_GRANTED|flags, - fid, LDLM_IBITS, &policy, mode, lockh); + fid, LDLM_IBITS, &policy, mode, 0, lockh); RETURN(rc); } diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index ca2a985..8455e2d 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -1384,7 +1384,8 @@ extern const struct inode_operations ll_file_inode_operations; const struct file_operations *ll_select_file_operations(struct ll_sb_info *sbi); extern int ll_have_md_lock(struct obd_export *exp, struct inode *inode, enum mds_ibits_locks *bits, - enum ldlm_mode l_req_mode); + enum ldlm_mode l_req_mode, + enum ldlm_match_flags match_flags); extern enum ldlm_mode ll_take_md_lock(struct inode *inode, __u64 bits, struct lustre_handle *lockh, __u64 flags, enum ldlm_mode mode); diff --git a/lustre/llite/namei.c b/lustre/llite/namei.c index 1861563..41c74b0 100644 --- a/lustre/llite/namei.c +++ b/lustre/llite/namei.c @@ -284,7 +284,7 @@ static void ll_lock_cancel_bits(struct ldlm_lock *lock, */ if (bits & MDS_INODELOCK_OPEN) ll_have_md_lock(lock->l_conn_export, inode, &bits, - lock->l_req_mode); + lock->l_req_mode, 0); if (bits & MDS_INODELOCK_OPEN) { fmode_t fmode; @@ -312,7 +312,8 @@ static void ll_lock_cancel_bits(struct ldlm_lock *lock, if (bits & (MDS_INODELOCK_LOOKUP | MDS_INODELOCK_UPDATE | MDS_INODELOCK_LAYOUT | MDS_INODELOCK_PERM | MDS_INODELOCK_DOM)) - ll_have_md_lock(lock->l_conn_export, inode, &bits, LCK_MINMODE); + ll_have_md_lock(lock->l_conn_export, inode, &bits, LCK_MINMODE, + 0); if (bits & MDS_INODELOCK_DOM) { rc = ll_dom_lock_cancel(inode, lock); @@ -462,7 +463,7 @@ static int ll_md_need_convert(struct ldlm_lock *lock) unlock_res_and_lock(lock); inode = ll_inode_from_resource_lock(lock); - ll_have_md_lock(lock->l_conn_export, inode, &bits, mode); + ll_have_md_lock(lock->l_conn_export, inode, &bits, mode, 0); iput(inode); return !!(bits); } diff --git a/lustre/lmv/lmv_obd.c b/lustre/lmv/lmv_obd.c index 68d6c6d..b83ebe9 100644 --- a/lustre/lmv/lmv_obd.c +++ b/lustre/lmv/lmv_obd.c @@ -3944,7 +3944,8 @@ static enum ldlm_mode lmv_lock_match(struct obd_export *exp, __u64 flags, const struct lu_fid *fid, enum ldlm_type type, union ldlm_policy_data *policy, - enum ldlm_mode mode, struct lustre_handle *lockh) + enum ldlm_mode mode, enum ldlm_match_flags match_flags, + struct lustre_handle *lockh) { struct obd_device *obd = exp->exp_obd; struct lmv_obd *lmv = &obd->u.lmv; @@ -3975,7 +3976,7 @@ lmv_lock_match(struct obd_export *exp, __u64 flags, if (!tgt || !tgt->ltd_exp || !tgt->ltd_active) continue; rc = md_lock_match(tgt->ltd_exp, flags, fid, type, - policy, mode, lockh); + policy, mode, match_flags, lockh); if (rc) break; } @@ -3983,7 +3984,7 @@ lmv_lock_match(struct obd_export *exp, __u64 flags, tgt = lmv_fid2tgt(lmv, fid); if (!IS_ERR(tgt) && tgt->ltd_exp && tgt->ltd_active) rc = md_lock_match(tgt->ltd_exp, flags, fid, type, - policy, mode, lockh); + policy, mode, match_flags, lockh); } CDEBUG(D_INODE, "Lock match for "DFID": %d\n", PFID(fid), rc); diff --git a/lustre/mdc/mdc_dev.c b/lustre/mdc/mdc_dev.c index 894f259..3370884 100644 --- a/lustre/mdc/mdc_dev.c +++ b/lustre/mdc/mdc_dev.c @@ -80,8 +80,8 @@ static int mdc_dom_lock_match(const struct lu_env *env, struct obd_export *exp, union ldlm_policy_data *policy, enum ldlm_mode mode, __u64 *flags, struct osc_object *obj, - struct lustre_handle *lockh, - enum ldlm_match_flags match_flags) + enum ldlm_match_flags match_flags, + struct lustre_handle *lockh) { struct obd_device *obd = exp->exp_obd; __u64 lflags = *flags; @@ -90,7 +90,7 @@ static int mdc_dom_lock_match(const struct lu_env *env, struct obd_export *exp, ENTRY; rc = ldlm_lock_match_with_skip(obd->obd_namespace, lflags, 0, - res_id, type, policy, mode, lockh, match_flags); + res_id, type, policy, mode, match_flags, lockh); if (rc == 0 || lflags & LDLM_FL_TEST_LOCK) RETURN(rc); @@ -156,7 +156,7 @@ again: * writers can share a single PW lock. */ mode = mdc_dom_lock_match(env, osc_export(obj), resname, LDLM_IBITS, policy, LCK_PR | LCK_PW | LCK_GROUP, &flags, - obj, &lockh, match_flags); + obj, match_flags, &lockh); if (mode != 0) { lock = ldlm_handle2lock(&lockh); /* RACE: the lock is cancelled so let's try again */ @@ -722,7 +722,7 @@ static int mdc_enqueue_send(const struct lu_env *env, struct obd_export *exp, match_flags = LDLM_MATCH_GROUP; mode = ldlm_lock_match_with_skip(obd->obd_namespace, search_flags, 0, res_id, einfo->ei_type, policy, mode, - &lockh, match_flags); + match_flags, &lockh); if (mode) { struct ldlm_lock *matched; @@ -1540,7 +1540,7 @@ static int mdc_object_fiemap(const struct lu_env *env, struct cl_object *obj, flags = LDLM_FL_BLOCK_GRANTED | LDLM_FL_LVB_READY; mode = mdc_dom_lock_match(env, exp, resid, LDLM_IBITS, policy, LCK_PR | LCK_PW | LCK_GROUP, - &flags, osc, &lockh, 0); + &flags, osc, 0, &lockh); fmkey->lfik_oa.o_valid |= OBD_MD_FLFLAGS; if (mode) { /* lock is cached on client */ fmkey->lfik_oa.o_flags &= ~OBD_FL_SRVLOCK; diff --git a/lustre/mdc/mdc_internal.h b/lustre/mdc/mdc_internal.h index 6ccb55f..cc91848 100644 --- a/lustre/mdc/mdc_internal.h +++ b/lustre/mdc/mdc_internal.h @@ -129,7 +129,9 @@ int mdc_batch_add(struct obd_export *exp, struct lu_batch *bh, enum ldlm_mode mdc_lock_match(struct obd_export *exp, __u64 flags, const struct lu_fid *fid, enum ldlm_type type, union ldlm_policy_data *policy, - enum ldlm_mode mode, struct lustre_handle *lockh); + enum ldlm_mode mode, + enum ldlm_match_flags match_flags, + struct lustre_handle *lockh); #define MDC_CHANGELOG_DEV_COUNT LMV_MAX_STRIPE_COUNT diff --git a/lustre/mdc/mdc_locks.c b/lustre/mdc/mdc_locks.c index 8500ae1..7baba2a 100644 --- a/lustre/mdc/mdc_locks.c +++ b/lustre/mdc/mdc_locks.c @@ -125,7 +125,9 @@ int mdc_set_lock_data(struct obd_export *exp, const struct lustre_handle *lockh, enum ldlm_mode mdc_lock_match(struct obd_export *exp, __u64 flags, const struct lu_fid *fid, enum ldlm_type type, union ldlm_policy_data *policy, - enum ldlm_mode mode, struct lustre_handle *lockh) + enum ldlm_mode mode, + enum ldlm_match_flags match_flags, + struct lustre_handle *lockh) { struct ldlm_res_id res_id; enum ldlm_mode rc; @@ -135,7 +137,7 @@ enum ldlm_mode mdc_lock_match(struct obd_export *exp, __u64 flags, /* LU-4405: Clear bits not supported by server */ policy->l_inodebits.bits &= exp_connect_ibits(exp); rc = ldlm_lock_match(class_exp2obd(exp)->obd_namespace, flags, - &res_id, type, policy, mode, lockh); + &res_id, type, policy, mode, match_flags, lockh); RETURN(rc); } @@ -1368,7 +1370,7 @@ static int mdc_finish_intent_lock(struct obd_export *exp, memcpy(&old_lock, lockh, sizeof(*lockh)); if (ldlm_lock_match(NULL, LDLM_FL_BLOCK_GRANTED, NULL, - LDLM_IBITS, &policy, LCK_NL, &old_lock)) { + LDLM_IBITS, &policy, LCK_NL, 0, &old_lock)) { ldlm_lock_decref_and_cancel(lockh, it->it_lock_mode); memcpy(lockh, &old_lock, sizeof(old_lock)); it->it_lock_handle = lockh->cookie; @@ -1436,7 +1438,7 @@ int mdc_revalidate_lock(struct obd_export *exp, struct lookup_intent *it, mode = mdc_lock_match(exp, LDLM_FL_BLOCK_GRANTED, fid, LDLM_IBITS, &policy, - LCK_CR | LCK_CW | LCK_PR | LCK_PW, + LCK_CR | LCK_CW | LCK_PR | LCK_PW, 0, &lockh); } diff --git a/lustre/mdt/mdt_io.c b/lustre/mdt/mdt_io.c index 55ebde6..12fc055 100644 --- a/lustre/mdt/mdt_io.c +++ b/lustre/mdt/mdt_io.c @@ -1373,7 +1373,7 @@ static int mdt_do_glimpse(const struct lu_env *env, struct ldlm_namespace *ns, policy.l_inodebits.bits = MDS_INODELOCK_DOM; mode = ldlm_lock_match(ns, LDLM_FL_TEST_LOCK, &res->lr_name, LDLM_IBITS, &policy, - LCK_PW, &lockh); + LCK_PW, 0, &lockh); /* There is no PW lock on this object; finished. */ if (mode == 0) @@ -1695,7 +1695,7 @@ bool mdt_dom_client_has_lock(struct mdt_thread_info *info, lm = (open_flags & MDS_FMODE_WRITE) ? LCK_PW : LCK_PR | LCK_PW; mode = ldlm_lock_match(mdt->mdt_namespace, LDLM_FL_BLOCK_GRANTED | LDLM_FL_TEST_LOCK, res_id, LDLM_IBITS, policy, - lm, &lockh); + lm, 0, &lockh); /* There is no other PW lock on this object; finished. */ if (mode == 0) diff --git a/lustre/osc/osc_object.c b/lustre/osc/osc_object.c index 4c09079..a6b63f6 100644 --- a/lustre/osc/osc_object.c +++ b/lustre/osc/osc_object.c @@ -263,7 +263,7 @@ static int osc_object_fiemap(const struct lu_env *env, struct cl_object *obj, mode = ldlm_lock_match(exp->exp_obd->obd_namespace, LDLM_FL_BLOCK_GRANTED | LDLM_FL_LVB_READY, &resid, LDLM_EXTENT, &policy, - LCK_PR | LCK_PW, &lockh); + LCK_PR | LCK_PW, 0, &lockh); fmkey->lfik_oa.o_valid |= OBD_MD_FLFLAGS; if (mode) { /* lock is cached on client */ fmkey->lfik_oa.o_flags &= ~OBD_FL_SRVLOCK; diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index 69bf928..88e193a 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -3173,7 +3173,7 @@ int osc_enqueue_base(struct obd_export *exp, struct ldlm_res_id *res_id, match_flags = LDLM_MATCH_GROUP; mode = ldlm_lock_match_with_skip(obd->obd_namespace, search_flags, 0, res_id, einfo->ei_type, policy, mode, - &lockh, match_flags); + match_flags, &lockh); if (mode) { struct ldlm_lock *matched; @@ -3280,8 +3280,8 @@ int osc_match_base(const struct lu_env *env, struct obd_export *exp, /* Next, search for already existing extent locks that will cover us */ rc = ldlm_lock_match_with_skip(obd->obd_namespace, lflags, 0, - res_id, type, policy, mode, lockh, - match_flags); + res_id, type, policy, mode, + match_flags, lockh); if (rc == 0 || lflags & LDLM_FL_TEST_LOCK) RETURN(rc); -- 1.8.3.1