rename_tmp_log(): on SCLD_VANISHED, retry
[gitweb.git] / refs.c
diff --git a/refs.c b/refs.c
index bbcdc88e418efd8b681fd59d0fe0ad9fefd8a34e..703b5a2f457e0b931cada8fc39c235ada8e48c0b 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -2530,16 +2530,23 @@ int delete_ref(const char *refname, const unsigned char *sha1, int delopt)
 
 static int rename_tmp_log(const char *newrefname)
 {
-       int attempts_remaining = 3;
+       int attempts_remaining = 4;
 
  retry:
-       if (safe_create_leading_directories(git_path("logs/%s", newrefname))) {
+       switch (safe_create_leading_directories(git_path("logs/%s", newrefname))) {
+       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);
                return -1;
        }
 
        if (rename(git_path(TMP_RENAMED_LOG), git_path("logs/%s", newrefname))) {
-               if (errno==EISDIR || errno==ENOTDIR) {
+               if ((errno==EISDIR || errno==ENOTDIR) && --attempts_remaining > 0) {
                        /*
                         * rename(a, b) when b is an existing
                         * directory ought to result in ISDIR, but