rename_tmp_log(): use raceproof_create_file()
Besides shortening the code, this saves an unnecessary call to safe_create_leading_directories_const() in almost all cases. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Reviewed-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Michael Haggerty committed
Jan 6, 2017 at 17:22 UTC
6a7f3631709cb68cdea4403c480a1a5d93100c47
1 file changed
+30
-43
refs/files-backend.c
+30
-43
@@ -2489,55 +2489,42 @@ out:
2489
*/
2490
#define TMP_RENAMED_LOG "logs/refs/.tmp-renamed-log"
2491
2492
-static int rename_tmp_log(const char *newrefname)
2492
+static int rename_tmp_log_callback(const char *path, void *cb)
2493
{
2494
- int attempts_remaining = 4;
2495
- struct strbuf path = STRBUF_INIT;
2496
- int ret = -1;
2494
+ int *true_errno = cb;
2495
2498
- retry:
2499
- strbuf_reset(&path);
2500
- strbuf_git_path(&path, "logs/%s", newrefname);
2501
- switch (safe_create_leading_directories_const(path.buf)) {
2502
- case SCLD_OK:
2503
- break; /* success */
2504
- case SCLD_VANISHED:
2505
- if (--attempts_remaining > 0)
2506
- goto retry;
2507
- /* fall through */
2508
- default:
2509
- error("unable to create directory for %s", newrefname);
2510
- goto out;
2496
+ if (rename(git_path(TMP_RENAMED_LOG), path)) {
2497
+ /*
2498
+ * rename(a, b) when b is an existing directory ought
2499
+ * to result in ISDIR, but Solaris 5.8 gives ENOTDIR.
2500
+ * Sheesh. Record the true errno for error reporting,
2501
+ * but report EISDIR to raceproof_create_file() so
2502
+ * that it knows to retry.
2503
+ */
2504
+ *true_errno = errno;
2505
+ if (errno == ENOTDIR)
2506
+ errno = EISDIR;
2507
+ return -1;
2508
+ } else {
2509
+ return 0;
2510
}
2511
+}
2512
2513
- if (rename(git_path(TMP_RENAMED_LOG), path.buf)) {
2514
- if ((errno==EISDIR || errno==ENOTDIR) && --attempts_remaining > 0) {
2515
- /*
2516
- * rename(a, b) when b is an existing
2517
- * directory ought to result in ISDIR, but
2518
- * Solaris 5.8 gives ENOTDIR. Sheesh.
2519
- */
2520
- if (remove_empty_directories(&path)) {
2521
- error("Directory not empty: logs/%s", newrefname);
2522
- goto out;
2523
- }
2524
- goto retry;
2525
- } else if (errno == ENOENT && --attempts_remaining > 0) {
2526
- /*
2527
- * Maybe another process just deleted one of
2528
- * the directories in the path to newrefname.
2529
- * Try again from the beginning.
2530
- */
2531
- goto retry;
2532
- } else {
2513
+static int rename_tmp_log(const char *newrefname)
2514
+{
2515
+ char *path = git_pathdup("logs/%s", newrefname);
2516
+ int ret, true_errno;
2517
+
2518
+ ret = raceproof_create_file(path, rename_tmp_log_callback, &true_errno);
2519
+ if (ret) {
2520
+ if (errno == EISDIR)
2521
+ error("Directory not empty: %s", path);
2522
+ else
2523
error("unable to move logfile "TMP_RENAMED_LOG" to logs/%s: %s",
2534
- newrefname, strerror(errno));
2535
- goto out;
2536
- }
2524
+ newrefname, strerror(true_errno));
2525
}
2538
- ret = 0;
2539
-out:
2540
- strbuf_release(&path);
2526
+
2527
+ free(path);
2528
return ret;
2529
}
2530