shallow: verify shallow file after taking lock
Before writing the shallow file, we stat() the existing file to make sure it has not been updated since our operation began. However, we do not do so under a lock, so there is a possible race: 1. Process A takes the lock. 2. Process B calls check_shallow_file_for_update and finds no update. 3. Process A commits the lockfile. 4. Process B takes the lock, then overwrite's process A's changes. We can fix this by doing our check while we hold the lock. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Jeff King committed
Mar 14, 2014 at 23:47 UTC
7839632167bc6ceef20f28bd046f7001493b070f
1 file changed
+2
-2
shallow.c
+2
-2
@@ -263,9 +263,9 @@ void setup_alternate_shallow(struct lock_file *shallow_lock,
263
struct strbuf sb = STRBUF_INIT;
264
int fd;
265
266
- check_shallow_file_for_update();
266
fd = hold_lock_file_for_update(shallow_lock, git_path("shallow"),
267
LOCK_DIE_ON_ERROR);
268
+ check_shallow_file_for_update();
269
if (write_shallow_commits(&sb, 0, extra)) {
270
if (write_in_full(fd, sb.buf, sb.len) != sb.len)
271
die_errno("failed to write to %s",
@@ -310,9 +310,9 @@ void prune_shallow(int show_only)
310
strbuf_release(&sb);
311
return;
312
}
313
- check_shallow_file_for_update();
313
fd = hold_lock_file_for_update(&shallow_lock, git_path("shallow"),
314
LOCK_DIE_ON_ERROR);
315
+ check_shallow_file_for_update();
316
if (write_shallow_commits_1(&sb, 0, NULL, SEEN_ONLY)) {
317
if (write_in_full(fd, sb.buf, sb.len) != sb.len)
318
die_errno("failed to write to %s",