diff options
author | Michael Haggerty <mhagger@alum.mit.edu> | 2017-01-06 17:22:29 +0100 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2017-01-07 19:30:09 -0800 |
commit | 6a7f3631709cb68cdea4403c480a1a5d93100c47 (patch) | |
tree | ebdd9ee9820af1eec192ae7cae00f5b1af4f0697 | |
parent | lock_ref_sha1_basic(): use raceproof_create_file() (diff) | |
download | tgif-6a7f3631709cb68cdea4403c480a1a5d93100c47.tar.xz |
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>
-rw-r--r-- | refs/files-backend.c | 73 |
1 files changed, 30 insertions, 43 deletions
diff --git a/refs/files-backend.c b/refs/files-backend.c index 74de289f42..3f18a01b4a 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -2489,55 +2489,42 @@ out: */ #define TMP_RENAMED_LOG "logs/refs/.tmp-renamed-log" -static int rename_tmp_log(const char *newrefname) +static int rename_tmp_log_callback(const char *path, void *cb) { - int attempts_remaining = 4; - struct strbuf path = STRBUF_INIT; - int ret = -1; + int *true_errno = cb; - retry: - strbuf_reset(&path); - strbuf_git_path(&path, "logs/%s", newrefname); - switch (safe_create_leading_directories_const(path.buf)) { - case SCLD_OK: - break; /* success */ - case SCLD_VANISHED: - if (--attempts_remaining > 0) - goto retry; - /* fall through */ - default: - error("unable to create directory for %s", newrefname); - goto out; + if (rename(git_path(TMP_RENAMED_LOG), path)) { + /* + * rename(a, b) when b is an existing directory ought + * to result in ISDIR, but Solaris 5.8 gives ENOTDIR. + * Sheesh. Record the true errno for error reporting, + * but report EISDIR to raceproof_create_file() so + * that it knows to retry. + */ + *true_errno = errno; + if (errno == ENOTDIR) + errno = EISDIR; + return -1; + } else { + return 0; } +} - if (rename(git_path(TMP_RENAMED_LOG), path.buf)) { - if ((errno==EISDIR || errno==ENOTDIR) && --attempts_remaining > 0) { - /* - * rename(a, b) when b is an existing - * directory ought to result in ISDIR, but - * Solaris 5.8 gives ENOTDIR. Sheesh. - */ - if (remove_empty_directories(&path)) { - error("Directory not empty: logs/%s", newrefname); - goto out; - } - goto retry; - } else if (errno == ENOENT && --attempts_remaining > 0) { - /* - * Maybe another process just deleted one of - * the directories in the path to newrefname. - * Try again from the beginning. - */ - goto retry; - } else { +static int rename_tmp_log(const char *newrefname) +{ + char *path = git_pathdup("logs/%s", newrefname); + int ret, true_errno; + + ret = raceproof_create_file(path, rename_tmp_log_callback, &true_errno); + if (ret) { + if (errno == EISDIR) + error("Directory not empty: %s", path); + else error("unable to move logfile "TMP_RENAMED_LOG" to logs/%s: %s", - newrefname, strerror(errno)); - goto out; - } + newrefname, strerror(true_errno)); } - ret = 0; -out: - strbuf_release(&path); + + free(path); return ret; } |