Whamcloud - gitweb
LU-15971 llite: match lock in corresponding namespace 43/47843/10
authorLai Siyao <lai.siyao@whamcloud.com>
Wed, 29 Jun 2022 15:51:47 +0000 (11:51 -0400)
committerOleg Drokin <green@whamcloud.com>
Wed, 1 Mar 2023 06:18:14 +0000 (06:18 +0000)
For remote object, LOOKUP lock is on parent MDT, so lmv_lock_match()
iterates all MDT namespaces to match locks. This is needed in places
where only LOOKUP ibit is matched, and the lock namespace is unknown.

Test-Parameters: mdscount=2 mdtcount=4 testlist=sanityn env=ONLY=109,ONLY_REPEAT=50
Signed-off-by: Lai Siyao <lai.siyao@whamcloud.com>
Change-Id: I32767f63f92a4df825ddacbf435bda8cfcfbbdd7
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/47843
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Qian Yingjin <qian@ddn.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/llite/dir.c
lustre/llite/file.c
lustre/llite/llite_internal.h
lustre/llite/namei.c
lustre/lmv/lmv_obd.c

index 58e0441..8df0b4c 100644 (file)
@@ -368,7 +368,8 @@ static int ll_readdir(struct file *filp, void *cookie, filldir_t filldir)
                        struct inode *parent =
                                file_dentry(filp)->d_parent->d_inode;
 
-                       if (ll_have_md_lock(parent, &ibits, LCK_MINMODE))
+                       if (ll_have_md_lock(ll_i2mdexp(parent), parent, &ibits,
+                                           LCK_MINMODE))
                                pfid = *ll_inode2fid(parent);
                }
 
index 2d70c2a..e254b0b 100644 (file)
@@ -5304,7 +5304,8 @@ ll_file_noflock(struct file *file, int cmd, struct file_lock *file_lock)
  * \param l_req_mode [IN] searched lock mode
  * \retval boolean, true iff all bits are found
  */
-int ll_have_md_lock(struct inode *inode, __u64 *bits, enum ldlm_mode l_req_mode)
+int ll_have_md_lock(struct obd_export *exp, struct inode *inode, __u64 *bits,
+                   enum ldlm_mode l_req_mode)
 {
        struct lustre_handle lockh;
        union ldlm_policy_data policy;
@@ -5328,8 +5329,8 @@ int ll_have_md_lock(struct inode *inode, __u64 *bits, enum ldlm_mode l_req_mode)
                if (policy.l_inodebits.bits == 0)
                        continue;
 
-               if (md_lock_match(ll_i2mdexp(inode), flags, fid, LDLM_IBITS,
-                                 &policy, mode, &lockh)) {
+               if (md_lock_match(exp, flags, fid, LDLM_IBITS, &policy, mode,
+                                 &lockh)) {
                        struct ldlm_lock *lock;
 
                        lock = ldlm_handle2lock(&lockh);
index 198271c..5ce54fc 100644 (file)
@@ -1169,8 +1169,8 @@ extern const struct address_space_operations ll_aops;
 /* llite/file.c */
 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 inode *inode, __u64 *bits,
-                          enum ldlm_mode l_req_mode);
+extern int ll_have_md_lock(struct obd_export *exp, struct inode *inode,
+                          __u64 *bits, enum ldlm_mode l_req_mode);
 extern enum ldlm_mode ll_take_md_lock(struct inode *inode, __u64 bits,
                                      struct lustre_handle *lockh, __u64 flags,
                                      enum ldlm_mode mode);
index 810b9e9..23feb46 100644 (file)
@@ -276,7 +276,8 @@ static void ll_lock_cancel_bits(struct ldlm_lock *lock, __u64 to_cancel)
        /* For OPEN locks we differentiate between lock modes
         * LCK_CR, LCK_CW, LCK_PR - bug 22891 */
        if (bits & MDS_INODELOCK_OPEN)
-               ll_have_md_lock(inode, &bits, lock->l_req_mode);
+               ll_have_md_lock(lock->l_conn_export, inode, &bits,
+                               lock->l_req_mode);
 
        if (bits & MDS_INODELOCK_OPEN) {
                fmode_t fmode;
@@ -304,7 +305,7 @@ static void ll_lock_cancel_bits(struct ldlm_lock *lock, __u64 to_cancel)
        if (bits & (MDS_INODELOCK_LOOKUP | MDS_INODELOCK_UPDATE |
                    MDS_INODELOCK_LAYOUT | MDS_INODELOCK_PERM |
                    MDS_INODELOCK_DOM))
-               ll_have_md_lock(inode, &bits, LCK_MINMODE);
+               ll_have_md_lock(lock->l_conn_export, inode, &bits, LCK_MINMODE);
 
        if (bits & MDS_INODELOCK_DOM) {
                rc =  ll_dom_lock_cancel(inode, lock);
@@ -449,7 +450,7 @@ 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(inode, &bits, mode);
+       ll_have_md_lock(lock->l_conn_export, inode, &bits, mode);
        iput(inode);
        return !!(bits);
 }
index e16d24c..945061f 100644 (file)
@@ -3618,41 +3618,47 @@ lmv_lock_match(struct obd_export *exp, __u64 flags,
 {
        struct obd_device *obd = exp->exp_obd;
        struct lmv_obd *lmv = &obd->u.lmv;
-       enum ldlm_mode rc;
        struct lu_tgt_desc *tgt;
-       int i;
+       __u64 bits = policy->l_inodebits.bits;
+       enum ldlm_mode rc = LCK_MINMODE;
        int index;
+       int i;
 
-       ENTRY;
-
-       CDEBUG(D_INODE, "Lock match for "DFID"\n", PFID(fid));
-
-       /*
-        * With DNE every object can have two locks in different namespaces:
+       /* only one bit is set */
+       LASSERT(bits && !(bits & (bits - 1)));
+       /* With DNE every object can have two locks in different namespaces:
         * lookup lock in space of MDT storing direntry and update/open lock in
         * space of MDT storing inode.  Try the MDT that the FID maps to first,
         * since this can be easily found, and only try others if that fails.
         */
-       for (i = 0, index = lmv_fid2tgt_index(lmv, fid);
-            i < lmv->lmv_mdt_descs.ltd_tgts_size;
-            i++, index = (index + 1) % lmv->lmv_mdt_descs.ltd_tgts_size) {
-               if (index < 0) {
-                       CDEBUG(D_HA, "%s: "DFID" is inaccessible: rc = %d\n",
-                              obd->obd_name, PFID(fid), index);
-                       index = 0;
+       if (bits == MDS_INODELOCK_LOOKUP) {
+               for (i = 0, index = lmv_fid2tgt_index(lmv, fid);
+                    i < lmv->lmv_mdt_descs.ltd_tgts_size; i++,
+                    index = (index + 1) % lmv->lmv_mdt_descs.ltd_tgts_size) {
+                       if (index < 0) {
+                               CDEBUG(D_HA,
+                                      "%s: "DFID" is inaccessible: rc = %d\n",
+                                      obd->obd_name, PFID(fid), index);
+                               index = 0;
+                       }
+                       tgt = lmv_tgt(lmv, index);
+                       if (!tgt || !tgt->ltd_exp || !tgt->ltd_active)
+                               continue;
+                       rc = md_lock_match(tgt->ltd_exp, flags, fid, type,
+                                          policy, mode, lockh);
+                       if (rc)
+                               break;
                }
-
-               tgt = lmv_tgt(lmv, index);
-               if (!tgt || !tgt->ltd_exp || !tgt->ltd_active)
-                       continue;
-
-               rc = md_lock_match(tgt->ltd_exp, flags, fid, type, policy, mode,
-                                  lockh);
-               if (rc)
-                       RETURN(rc);
+       } else {
+               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);
        }
 
-       RETURN(0);
+       CDEBUG(D_INODE, "Lock match for "DFID": %d\n", PFID(fid), rc);
+
+       return rc;
 }
 
 static int