#define OBD_FAIL_MDS_HSM_CDT_DELAY 0x164
#define OBD_FAIL_MDS_ORPHAN_DELETE 0x165
#define OBD_FAIL_MDS_RMFID_NET 0x166
+#define OBD_FAIL_MDS_CREATE_RACE 0x167
/* layout lock */
#define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
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));
}
run_test 42h "pdirops: mkdir vs readdir =============="
-# test 43: unlink and blocking operations
+# test 43: rmdir,mkdir won't return -EEXIST
test_43a() {
- pdo_lru_clear
- touch $DIR1/$tfile
-#define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK 0x145
- do_facet $SINGLEMDS lctl set_param fail_loc=0x80000145
- rm $DIR1/$tfile &
- PID1=$! ; pdo_sched
- mkdir $DIR2/$tfile &
- PID2=$! ; pdo_sched
- do_facet $SINGLEMDS lctl set_param fail_loc=0
- check_pdo_conflict $PID1 && { wait $PID1; error "mkdir isn't blocked"; }
- wait $PID2 ; [ $? -eq 0 ] || error "mkdir must succeed"
- rm -rf $DIR/$tfile*
+ for i in {1..1000}; do
+ mkdir $DIR1/$tdir || error "mkdir $tdir failed"
+ rmdir $DIR2/$tdir || error "rmdir $tdir failed"
+ done
return 0
}
-run_test 43a "pdirops: unlink vs mkdir =============="
+run_test 43a "rmdir,mkdir doesn't return -EEXIST =============="
test_43b() {
pdo_lru_clear
}
run_test 43i "pdirops: unlink vs remote mkdir"
+test_43j() {
+ [[ $MDS1_VERSION -lt $(version_code 2.13.52) ]] &&
+ skip "Need MDS version newer than 2.13.52"
+
+ for i in {1..100}; do
+#define OBD_FAIL_ONCE|OBD_FAIL_MDS_CREATE_RACE 0x167
+ do_facet $SINGLEMDS lctl set_param fail_loc=0x80000167
+ OK=0
+ mkdir $DIR1/$tdir &
+ PID1=$!
+ mkdir $DIR2/$tdir && ((OK++))
+ wait $PID1 && ((OK++))
+ (( OK == 1 )) || error "exactly one mkdir should succeed"
+
+ rmdir $DIR1/$tdir || error "rmdir failed"
+ done
+ return 0
+}
+run_test 43j "racy mkdir return EEXIST =============="
+
# test 44: rename tgt and blocking operations
test_44a() {
pdo_lru_clear
}
run_test 44i "pdirops: rename tgt vs remote mkdir"
-# test 45: rename src and blocking operations
+# test 45: rename,mkdir doesn't fail with -EEXIST
test_45a() {
- pdo_lru_clear
- touch $DIR1/$tfile
-#define OBD_FAIL_ONCE|OBD_FAIL_MDS_PDO_LOCK 0x145
- do_facet $SINGLEMDS lctl set_param fail_loc=0x80000145
- mv $DIR1/$tfile $DIR1/$tfile-2 &
- PID1=$! ; pdo_sched
- mkdir $DIR2/$tfile &
- PID2=$! ; pdo_sched
- do_facet $SINGLEMDS lctl set_param fail_loc=0
- check_pdo_conflict $PID1 && { wait $PID1; error "mkdir isn't blocked"; }
- wait $PID2 ; [ $? -eq 0 ] || error "mkdir must succeed"
- rm -rf $DIR/$tfile*
+ for i in {1..1000}; do
+ mkdir $DIR1/$tdir || error "mkdir $tdir failed"
+ mrename $DIR2/$tdir $DIR2/$tdir.$i > /dev/null ||
+ error "mrename to $tdir.$i failed"
+ done
+ rm -rf $DIR/$tdir*
return 0
}
-run_test 45a "pdirops: rename src vs mkdir =============="
+run_test 45a "rename,mkdir doesn't return -EEXIST =============="
test_45b() {
pdo_lru_clear