Skip to content

Commit 16684b6

Browse files
pks-tgitster
authored andcommitted
refs/reftable: always reload stacks when creating lock
When creating a new addition via either `reftable_stack_new_addition()` or its convenince wrapper `reftable_stack_add()` we: 1. Create the "tables.list.lock" file. 2. Verify that the current version of the "tables.list" file is up-to-date. 3. Write the new table records if so. By default, the second step would cause us to bail out if we see that there has been a concurrent write to the stack that made our in-memory copy of the stack out-of-date. This is a safety mechanism to not write records to the stack based on outdated information. The downside though is that concurrent writes may now cause us to bail out, which is not a good user experience. In addition, this isn't even necessary for us, as Git knows to perform all checks for the old state of references under the lock. (Well, in all except one case: when we expire the reflog we first create the log iterator before we create the lock, but this ordering is fixed as part of this commit.) Consequently, most writers pass the `REFTABLE_STACK_NEW_ADDITION_RELOAD` flag. The effect of this flag is that we reload the stack after having acquired the lock in case the stack is out-of-date. This plugs the race with concurrent writers, but we continue performing the verifications of the expected old state to catch actual conflicts in the references we are about to write. Adapt the remaining callsites that don't yet pass this flag to do so. While at it, drop a needless manual reload. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 8fd7a0e commit 16684b6

File tree

1 file changed

+12
-11
lines changed

1 file changed

+12
-11
lines changed

refs/reftable-backend.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,10 +1006,6 @@ static int prepare_transaction_update(struct write_transaction_table_arg **out,
10061006
if (!arg) {
10071007
struct reftable_addition *addition;
10081008

1009-
ret = reftable_stack_reload(be->stack);
1010-
if (ret)
1011-
return ret;
1012-
10131009
ret = reftable_stack_new_addition(&addition, be->stack,
10141010
REFTABLE_STACK_NEW_ADDITION_RELOAD);
10151011
if (ret) {
@@ -1960,7 +1956,8 @@ static int reftable_be_rename_ref(struct ref_store *ref_store,
19601956
ret = backend_for(&arg.be, refs, newrefname, &newrefname, 1);
19611957
if (ret)
19621958
goto done;
1963-
ret = reftable_stack_add(arg.be->stack, &write_copy_table, &arg, 0);
1959+
ret = reftable_stack_add(arg.be->stack, &write_copy_table, &arg,
1960+
REFTABLE_STACK_NEW_ADDITION_RELOAD);
19641961

19651962
done:
19661963
assert(ret != REFTABLE_API_ERROR);
@@ -1989,7 +1986,8 @@ static int reftable_be_copy_ref(struct ref_store *ref_store,
19891986
ret = backend_for(&arg.be, refs, newrefname, &newrefname, 1);
19901987
if (ret)
19911988
goto done;
1992-
ret = reftable_stack_add(arg.be->stack, &write_copy_table, &arg, 0);
1989+
ret = reftable_stack_add(arg.be->stack, &write_copy_table, &arg,
1990+
REFTABLE_STACK_NEW_ADDITION_RELOAD);
19931991

19941992
done:
19951993
assert(ret != REFTABLE_API_ERROR);
@@ -2360,7 +2358,8 @@ static int reftable_be_create_reflog(struct ref_store *ref_store,
23602358
goto done;
23612359
arg.stack = be->stack;
23622360

2363-
ret = reftable_stack_add(be->stack, &write_reflog_existence_table, &arg, 0);
2361+
ret = reftable_stack_add(be->stack, &write_reflog_existence_table, &arg,
2362+
REFTABLE_STACK_NEW_ADDITION_RELOAD);
23642363

23652364
done:
23662365
return ret;
@@ -2431,7 +2430,8 @@ static int reftable_be_delete_reflog(struct ref_store *ref_store,
24312430
return ret;
24322431
arg.stack = be->stack;
24332432

2434-
ret = reftable_stack_add(be->stack, &write_reflog_delete_table, &arg, 0);
2433+
ret = reftable_stack_add(be->stack, &write_reflog_delete_table, &arg,
2434+
REFTABLE_STACK_NEW_ADDITION_RELOAD);
24352435

24362436
assert(ret != REFTABLE_API_ERROR);
24372437
return ret;
@@ -2552,15 +2552,16 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store,
25522552
if (ret < 0)
25532553
goto done;
25542554

2555-
ret = reftable_stack_init_log_iterator(be->stack, &it);
2555+
ret = reftable_stack_new_addition(&add, be->stack,
2556+
REFTABLE_STACK_NEW_ADDITION_RELOAD);
25562557
if (ret < 0)
25572558
goto done;
25582559

2559-
ret = reftable_iterator_seek_log(&it, refname);
2560+
ret = reftable_stack_init_log_iterator(be->stack, &it);
25602561
if (ret < 0)
25612562
goto done;
25622563

2563-
ret = reftable_stack_new_addition(&add, be->stack, 0);
2564+
ret = reftable_iterator_seek_log(&it, refname);
25642565
if (ret < 0)
25652566
goto done;
25662567

0 commit comments

Comments
 (0)