Whamcloud - gitweb
LU-17970 ldlm: add lock match flag LDLM_MATCH_SKIP_UNUSED 08/55508/10
authorBobi Jam <bobijam@whamcloud.com>
Mon, 24 Jun 2024 06:18:51 +0000 (14:18 +0800)
committerOleg Drokin <green@whamcloud.com>
Thu, 2 Jan 2025 20:41:18 +0000 (20:41 +0000)
Add lock match flag LDLM_MATCH_SKIP_UNUSED to skip match unused lock.

Signed-off-by: Bobi Jam <bobijam@whamcloud.com>
Change-Id: I31d8f051b837a5b00cee6f2bc1ad9782acc62892
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/55508
Reviewed-by: Sebastien Buisson <sbuisson@ddn.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
15 files changed:
lustre/include/lustre_dlm.h
lustre/include/obd.h
lustre/include/obd_class.h
lustre/ldlm/ldlm_lock.c
lustre/llite/dir.c
lustre/llite/file.c
lustre/llite/llite_internal.h
lustre/llite/namei.c
lustre/lmv/lmv_obd.c
lustre/mdc/mdc_dev.c
lustre/mdc/mdc_internal.h
lustre/mdc/mdc_locks.c
lustre/mdt/mdt_io.c
lustre/osc/osc_object.c
lustre/osc/osc_request.c

index adaa82f..b81803e 100644 (file)
@@ -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);
index 4572f9b..3ea36fa 100644 (file)
@@ -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,
index c6ea0e4..b2b21f8 100644 (file)
@@ -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);
 }
 
index 08c6b5a..06d0c3e 100644 (file)
@@ -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,
index 9a55e15..c8ac8ed 100644 (file)
@@ -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);
index a3803ff..c6f777c 100644 (file)
@@ -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);
 }
index ca2a985..8455e2d 100644 (file)
@@ -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);
index 1861563..41c74b0 100644 (file)
@@ -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);
 }
index 68d6c6d..b83ebe9 100644 (file)
@@ -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);
index 894f259..3370884 100644 (file)
@@ -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;
index 6ccb55f..cc91848 100644 (file)
@@ -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
index 8500ae1..7baba2a 100644 (file)
@@ -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);
        }
 
index 55ebde6..12fc055 100644 (file)
@@ -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)
index 4c09079..a6b63f6 100644 (file)
@@ -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;
index 69bf928..88e193a 100644 (file)
@@ -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);