Whamcloud - gitweb
LU-13437 mdt: rename misses remote LOOKUP lock revoke
[fs/lustre-release.git] / lustre / mdt / mdt_reint.c
index c64abaa..5d37de3 100644 (file)
@@ -789,6 +789,7 @@ static int mdt_reint_setattr(struct mdt_thread_info *info,
        struct ptlrpc_request *req = mdt_info_req(info);
        struct mdt_object *mo;
        struct mdt_body *repbody;
+       ktime_t kstart = ktime_get();
        int rc, rc2;
 
        ENTRY;
@@ -958,7 +959,8 @@ out_put:
        mdt_object_put(info->mti_env, mo);
 out:
        if (rc == 0)
-               mdt_counter_incr(req, LPROC_MDT_SETATTR);
+               mdt_counter_incr(req, LPROC_MDT_SETATTR,
+                                ktime_us_delta(ktime_get(), kstart));
 
        mdt_client_compatibility(info);
        rc2 = mdt_fix_reply(info);
@@ -971,6 +973,7 @@ static int mdt_reint_create(struct mdt_thread_info *info,
                            struct mdt_lock_handle *lhc)
 {
        struct ptlrpc_request   *req = mdt_info_req(info);
+       ktime_t                 kstart = ktime_get();
        int                     rc;
 
        ENTRY;
@@ -986,16 +989,12 @@ static int mdt_reint_create(struct mdt_thread_info *info,
 
        switch (info->mti_attr.ma_attr.la_mode & S_IFMT) {
        case S_IFDIR:
-               mdt_counter_incr(req, LPROC_MDT_MKDIR);
-               break;
        case S_IFREG:
        case S_IFLNK:
        case S_IFCHR:
        case S_IFBLK:
        case S_IFIFO:
        case S_IFSOCK:
-               /* Special file should stay on the same node as parent. */
-               mdt_counter_incr(req, LPROC_MDT_MKNOD);
                break;
        default:
                CERROR("%s: Unsupported mode %o\n",
@@ -1005,6 +1004,16 @@ static int mdt_reint_create(struct mdt_thread_info *info,
        }
 
        rc = mdt_create(info);
+       if (rc == 0) {
+               if ((info->mti_attr.ma_attr.la_mode & S_IFMT) == S_IFDIR)
+                       mdt_counter_incr(req, LPROC_MDT_MKDIR,
+                                        ktime_us_delta(ktime_get(), kstart));
+               else
+                       /* Special file should stay on the same node as parent*/
+                       mdt_counter_incr(req, LPROC_MDT_MKNOD,
+                                        ktime_us_delta(ktime_get(), kstart));
+       }
+
        RETURN(rc);
 }
 
@@ -1027,6 +1036,7 @@ static int mdt_reint_unlink(struct mdt_thread_info *info,
        __u64 lock_ibits;
        bool cos_incompat = false;
        int no_name = 0;
+       ktime_t kstart = ktime_get();
        int rc;
 
        ENTRY;
@@ -1216,7 +1226,8 @@ out_stat:
        if (ma->ma_valid & MA_INODE) {
                switch (ma->ma_attr.la_mode & S_IFMT) {
                case S_IFDIR:
-                       mdt_counter_incr(req, LPROC_MDT_RMDIR);
+                       mdt_counter_incr(req, LPROC_MDT_RMDIR,
+                                        ktime_us_delta(ktime_get(), kstart));
                        break;
                case S_IFREG:
                case S_IFLNK:
@@ -1224,7 +1235,8 @@ out_stat:
                case S_IFBLK:
                case S_IFIFO:
                case S_IFSOCK:
-                       mdt_counter_incr(req, LPROC_MDT_UNLINK);
+                       mdt_counter_incr(req, LPROC_MDT_UNLINK,
+                                        ktime_us_delta(ktime_get(), kstart));
                        break;
                default:
                        LASSERTF(0, "bad file type %o unlinking\n",
@@ -1260,6 +1272,7 @@ static int mdt_reint_link(struct mdt_thread_info *info,
        struct mdt_object       *mp;
        struct mdt_lock_handle  *lhs;
        struct mdt_lock_handle  *lhp;
+       ktime_t kstart = ktime_get();
        bool cos_incompat;
        int rc;
 
@@ -1356,7 +1369,8 @@ static int mdt_reint_link(struct mdt_thread_info *info,
                      mdt_object_child(ms), &rr->rr_name, ma);
 
        if (rc == 0)
-               mdt_counter_incr(req, LPROC_MDT_LINK);
+               mdt_counter_incr(req, LPROC_MDT_LINK,
+                                ktime_us_delta(ktime_get(), kstart));
 
        EXIT;
 unlock_source:
@@ -2435,6 +2449,71 @@ static int mdt_rename_determine_lock_order(struct mdt_thread_info *info,
 }
 
 /*
+ * lock rename source object.
+ *
+ * Both source and source parent may be remote, and source may be a remote
+ * object on source parent, to avoid overriding lock handle, store remote
+ * LOOKUP lock separately in @lhr.
+ *
+ * \retval     0 on success
+ * \retval     -ev negative errno upon error
+ */
+static int mdt_rename_source_lock(struct mdt_thread_info *info,
+                                 struct mdt_object *parent,
+                                 struct mdt_object *child,
+                                 struct mdt_lock_handle *lhc,
+                                 struct mdt_lock_handle *lhr,
+                                 __u64 ibits,
+                                 bool cos_incompat)
+{
+       int rc;
+
+       rc = mdt_is_remote_object(info, parent, child);
+       if (rc < 0)
+               return rc;
+
+       if (rc) {
+               /* enqueue remote LOOKUP lock from the parent MDT */
+               __u64 rmt_ibits = MDS_INODELOCK_LOOKUP;
+
+               if (mdt_object_remote(parent)) {
+                       rc = mdt_remote_object_lock(info, parent,
+                                                   mdt_object_fid(child),
+                                                   &lhr->mlh_rreg_lh,
+                                                   lhr->mlh_rreg_mode,
+                                                   rmt_ibits, false);
+                       if (rc != ELDLM_OK)
+                               return rc;
+               } else {
+                       LASSERT(mdt_object_remote(child));
+                       rc = mdt_object_local_lock(info, child, lhr,
+                                                  &rmt_ibits, 0, true);
+                       if (rc < 0)
+                               return rc;
+               }
+
+               ibits &= ~MDS_INODELOCK_LOOKUP;
+       }
+
+       if (mdt_object_remote(child)) {
+               rc = mdt_remote_object_lock(info, child, mdt_object_fid(child),
+                                           &lhc->mlh_rreg_lh,
+                                           lhc->mlh_rreg_mode,
+                                           ibits, false);
+               if (rc == ELDLM_OK)
+                       rc = 0;
+       } else {
+               rc = mdt_reint_object_lock(info, child, lhc, ibits,
+                                          cos_incompat);
+       }
+
+       if (!rc)
+               mdt_object_unlock(info, child, lhr, rc);
+
+       return rc;
+}
+
+/*
  * VBR: rename versions in reply: 0 - srcdir parent; 1 - tgtdir parent;
  * 2 - srcdir child; 3 - tgtdir child.
  * Update on disk version of srcdir child.
@@ -2454,12 +2533,14 @@ static int mdt_reint_rename(struct mdt_thread_info *info,
        struct mdt_lock_handle *lh_srcdirp;
        struct mdt_lock_handle *lh_tgtdirp;
        struct mdt_lock_handle *lh_oldp = NULL;
+       struct mdt_lock_handle *lh_rmt = NULL;
        struct mdt_lock_handle *lh_newp = NULL;
        struct lu_fid *old_fid = &info->mti_tmp_fid1;
        struct lu_fid *new_fid = &info->mti_tmp_fid2;
        __u64 lock_ibits;
        bool reverse = false, discard = false;
        bool cos_incompat;
+       ktime_t kstart = ktime_get();
        int rc;
 
        ENTRY;
@@ -2685,26 +2766,14 @@ relock:
                        GOTO(out_put_new, rc = -EISDIR);
 
                lh_oldp = &info->mti_lh[MDT_LH_OLD];
+               lh_rmt = &info->mti_lh[MDT_LH_RMT];
                mdt_lock_reg_init(lh_oldp, LCK_EX);
+               mdt_lock_reg_init(lh_rmt, LCK_EX);
                lock_ibits = MDS_INODELOCK_LOOKUP | MDS_INODELOCK_XATTR;
-               if (mdt_object_remote(msrcdir)) {
-                       /* Enqueue lookup lock from the parent MDT */
-                       rc = mdt_remote_object_lock(info, msrcdir,
-                                                   mdt_object_fid(mold),
-                                                   &lh_oldp->mlh_rreg_lh,
-                                                   lh_oldp->mlh_rreg_mode,
-                                                   MDS_INODELOCK_LOOKUP,
-                                                   false);
-                       if (rc != ELDLM_OK)
-                               GOTO(out_put_new, rc);
-
-                       lock_ibits &= ~MDS_INODELOCK_LOOKUP;
-               }
-
-               rc = mdt_reint_object_lock(info, mold, lh_oldp, lock_ibits,
-                                          cos_incompat);
-               if (rc != 0)
-                       GOTO(out_unlock_old, rc);
+               rc = mdt_rename_source_lock(info, msrcdir, mold, lh_oldp,
+                                           lh_rmt, lock_ibits, cos_incompat);
+               if (rc < 0)
+                       GOTO(out_put_new, rc);
 
                /* Check if @msrcdir is subdir of @mnew, before locking child
                 * to avoid reverse locking.
@@ -2727,39 +2796,38 @@ relock:
 
                lh_newp = &info->mti_lh[MDT_LH_NEW];
                mdt_lock_reg_init(lh_newp, LCK_EX);
-               rc = mdt_reint_object_lock(info, mnew, lh_newp,
-                                          MDS_INODELOCK_LOOKUP |
-                                          MDS_INODELOCK_UPDATE,
+               lock_ibits = MDS_INODELOCK_LOOKUP | MDS_INODELOCK_UPDATE;
+               if (mdt_object_remote(mtgtdir)) {
+                       rc = mdt_remote_object_lock(info, mtgtdir,
+                                                   mdt_object_fid(mnew),
+                                                   &lh_newp->mlh_rreg_lh,
+                                                   lh_newp->mlh_rreg_mode,
+                                                   MDS_INODELOCK_LOOKUP,
+                                                   false);
+                       if (rc != ELDLM_OK)
+                               GOTO(out_unlock_old, rc);
+
+                       lock_ibits &= ~MDS_INODELOCK_LOOKUP;
+               }
+               rc = mdt_reint_object_lock(info, mnew, lh_newp, lock_ibits,
                                           cos_incompat);
                if (rc != 0)
-                       GOTO(out_unlock_old, rc);
+                       GOTO(out_unlock_new, rc);
 
                /* get and save version after locking */
                mdt_version_get_save(info, mnew, 3);
-       } else if (rc != -EREMOTE && rc != -ENOENT) {
+       } else if (rc != -ENOENT) {
                GOTO(out_put_old, rc);
        } else {
                lh_oldp = &info->mti_lh[MDT_LH_OLD];
+               lh_rmt = &info->mti_lh[MDT_LH_RMT];
                mdt_lock_reg_init(lh_oldp, LCK_EX);
+               mdt_lock_reg_init(lh_rmt, LCK_EX);
                lock_ibits = MDS_INODELOCK_LOOKUP | MDS_INODELOCK_XATTR;
-               if (mdt_object_remote(msrcdir)) {
-                       /* Enqueue lookup lock from the parent MDT */
-                       rc = mdt_remote_object_lock(info, msrcdir,
-                                                   mdt_object_fid(mold),
-                                                   &lh_oldp->mlh_rreg_lh,
-                                                   lh_oldp->mlh_rreg_mode,
-                                                   MDS_INODELOCK_LOOKUP,
-                                                   false);
-                       if (rc != ELDLM_OK)
-                               GOTO(out_put_old, rc);
-
-                       lock_ibits &= ~MDS_INODELOCK_LOOKUP;
-               }
-
-               rc = mdt_reint_object_lock(info, mold, lh_oldp, lock_ibits,
-                                          cos_incompat);
+               rc = mdt_rename_source_lock(info, msrcdir, mold, lh_oldp,
+                                           lh_rmt, lock_ibits, cos_incompat);
                if (rc != 0)
-                       GOTO(out_unlock_old, rc);
+                       GOTO(out_put_old, rc);
 
                mdt_enoent_version_save(info, 3);
        }
@@ -2783,19 +2851,23 @@ relock:
 
        /* handle last link of tgt object */
        if (rc == 0) {
-               mdt_counter_incr(req, LPROC_MDT_RENAME);
+               mdt_counter_incr(req, LPROC_MDT_RENAME,
+                                ktime_us_delta(ktime_get(), kstart));
                if (mnew) {
                        mdt_handle_last_unlink(info, mnew, ma);
                        discard = mdt_dom_check_for_discard(info, mnew);
                }
                mdt_rename_counter_tally(info, info->mti_mdt, req,
-                                        msrcdir, mtgtdir);
+                                        msrcdir, mtgtdir,
+                                        ktime_us_delta(ktime_get(), kstart));
        }
 
        EXIT;
+out_unlock_new:
        if (mnew != NULL)
                mdt_object_unlock(info, mnew, lh_newp, rc);
 out_unlock_old:
+       mdt_object_unlock(info, NULL, lh_rmt, rc);
        mdt_object_unlock(info, mold, lh_oldp, rc);
 out_put_new:
        if (mnew && !discard)