lock_ref_sha1_basic(): on SCLD_VANISHED, retry
If safe_create_leading_directories() fails because a file along the path unexpectedly vanished, try again (up to 3 times). This can occur if another process is deleting directories at the same time as we are trying to make them. For example, "git pack-refs --all" tries to delete the loose refs and any empty directories that are left behind. If a pack-refs process is running, then it might delete a directory that we need to put a new loose reference in. If safe_create_leading_directories() thinks this might have happened, then take its advice and try again (maximum three attempts). Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
parent
18d37e860d
commit
c4c61c763e
11
refs.c
11
refs.c
|
|
@ -2039,6 +2039,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
|
||||||
int type, lflags;
|
int type, lflags;
|
||||||
int mustexist = (old_sha1 && !is_null_sha1(old_sha1));
|
int mustexist = (old_sha1 && !is_null_sha1(old_sha1));
|
||||||
int missing = 0;
|
int missing = 0;
|
||||||
|
int attempts_remaining = 3;
|
||||||
|
|
||||||
lock = xcalloc(1, sizeof(struct ref_lock));
|
lock = xcalloc(1, sizeof(struct ref_lock));
|
||||||
lock->lock_fd = -1;
|
lock->lock_fd = -1;
|
||||||
|
|
@ -2093,7 +2094,15 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
|
||||||
if ((flags & REF_NODEREF) && (type & REF_ISSYMREF))
|
if ((flags & REF_NODEREF) && (type & REF_ISSYMREF))
|
||||||
lock->force_write = 1;
|
lock->force_write = 1;
|
||||||
|
|
||||||
if (safe_create_leading_directories(ref_file)) {
|
retry:
|
||||||
|
switch (safe_create_leading_directories(ref_file)) {
|
||||||
|
case SCLD_OK:
|
||||||
|
break; /* success */
|
||||||
|
case SCLD_VANISHED:
|
||||||
|
if (--attempts_remaining > 0)
|
||||||
|
goto retry;
|
||||||
|
/* fall through */
|
||||||
|
default:
|
||||||
last_errno = errno;
|
last_errno = errno;
|
||||||
error("unable to create directory for %s", ref_file);
|
error("unable to create directory for %s", ref_file);
|
||||||
goto error_return;
|
goto error_return;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue