[PATCH v2 11/17] lock_ref_sha1_basic(): if locking fails with ENOENT, retry
- From
Michael Haggerty <mhagger@alum.mit.edu>
- Date
- Jan 6, 2014, 13:45 UTC
- Message-ID
- <1389015935-21936-12-git-send-email-mhagger@alum.mit.edu>
- In-Reply-To
- <1389015935-21936-1-git-send-email-mhagger@alum.mit.edu>
If hold_lock_file_for_update() fails with errno==ENOENT, it might be because somebody else (for example, a pack-refs process) has just deleted one of the lockfile's ancestor directories. So if this condition is detected, try again (up to 3 times).
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> --- refs.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/refs.c b/refs.c index 6eb8a02..8a3d3ea 100644 --- a/refs.c +++ b/refs.c @@ -2081,7 +2081,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname, lock->lk = xcalloc(1, sizeof(struct lock_file)); - lflags = LOCK_DIE_ON_ERROR; + lflags = 0; if (flags & REF_NODEREF) { refname = orig_refname; lflags |= LOCK_NODEREF; @@ -2109,6 +2109,17 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname, } lock->lock_fd = hold_lock_file_for_update(lock->lk, ref_file, lflags); + if (lock->lock_fd < 0) { + if (errno == ENOENT && --attempts > 0) + /* + * Maybe somebody just deleted one of the + * directories leading to ref_file. Try + * again: + */ + goto retry; + else + unable_to_lock_index_die(ref_file, errno); + } return old_sha1 ? verify_lock(lock, old_sha1, mustexist) : lock; error_return:
-- 1.8.5.2