Whamcloud - gitweb
LU-10235 mdt: mdt_create: check EEXIST without lock
[fs/lustre-release.git] / lustre / mdt / mdt_reint.c
index 18323ce..e189d72 100644 (file)
@@ -406,34 +406,36 @@ static int mdt_create(struct mdt_thread_info *info)
        if (!mdt_object_exists(parent))
                GOTO(put_parent, rc = -ENOENT);
 
-       lh = &info->mti_lh[MDT_LH_PARENT];
-       mdt_lock_pdo_init(lh, LCK_PW, &rr->rr_name);
-       rc = mdt_object_lock(info, parent, lh, MDS_INODELOCK_UPDATE);
-       if (rc)
-               GOTO(put_parent, rc);
-
-       if (!mdt_object_remote(parent)) {
-               rc = mdt_version_get_check_save(info, parent, 0);
-               if (rc)
-                       GOTO(unlock_parent, rc);
-       }
-
        /*
-        * Check child name version during replay.
-        * During create replay a file may exist with same name.
+        * LU-10235: check if name exists locklessly first to avoid massive
+        * lock recalls on existing directories.
         */
        rc = mdt_lookup_version_check(info, parent, &rr->rr_name,
                                      &info->mti_tmp_fid1, 1);
        if (rc == 0)
-               GOTO(unlock_parent, rc = -EEXIST);
+               GOTO(put_parent, rc = -EEXIST);
 
        /* -ENOENT is expected here */
        if (rc != -ENOENT)
-               GOTO(unlock_parent, rc);
+               GOTO(put_parent, rc);
 
        /* save version of file name for replay, it must be ENOENT here */
        mdt_enoent_version_save(info, 1);
 
+       OBD_RACE(OBD_FAIL_MDS_CREATE_RACE);
+
+       lh = &info->mti_lh[MDT_LH_PARENT];
+       mdt_lock_pdo_init(lh, LCK_PW, &rr->rr_name);
+       rc = mdt_object_lock(info, parent, lh, MDS_INODELOCK_UPDATE);
+       if (rc)
+               GOTO(put_parent, rc);
+
+       if (!mdt_object_remote(parent)) {
+               rc = mdt_version_get_check_save(info, parent, 0);
+               if (rc)
+                       GOTO(unlock_parent, rc);
+       }
+
        child = mdt_object_new(info->mti_env, mdt, rr->rr_fid2);
        if (unlikely(IS_ERR(child)))
                GOTO(unlock_parent, rc = PTR_ERR(child));