Besides shortening the code, this saves an unnecessary call to
safe_create_leading_directories_const() in almost all cases.

Signed-off-by: Michael Haggerty <mhag...@alum.mit.edu>
---
 refs/files-backend.c | 73 +++++++++++++++++++++-------------------------------
 1 file changed, 30 insertions(+), 43 deletions(-)

diff --git a/refs/files-backend.c b/refs/files-backend.c
index 74de289..3f18a01 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -2489,55 +2489,42 @@ static int files_delete_refs(struct ref_store 
*ref_store,
  */
 #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;
 }
 
-- 
2.9.3

Reply via email to