reftable: don't second-guess errors from flock interface

The `flock` interface is implemented as part of "reftable/system.c" and
thus needs to be implemented by the integrator between the reftable
library and its parent code base. As such, we cannot rely on any
specific implementation thereof.

Regardless of that, users of the `flock` subsystem rely on `errno` being
set to specific values. This is fragile and not documented anywhere and
doesn't really make for a good interface.

Refactor the code so that the implementations themselves are expected to
return reftable-specific error codes. Our implementation of the `flock`
subsystem already knows to do this for all error paths except one.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
main
Patrick Steinhardt 2025-08-12 11:54:21 +02:00 committed by Junio C Hamano
parent 54d25de3ea
commit 8fd7a0ebe1
3 changed files with 12 additions and 31 deletions

View File

@ -698,14 +698,9 @@ static int reftable_stack_init_addition(struct reftable_addition *add,


err = flock_acquire(&add->tables_list_lock, st->list_file, err = flock_acquire(&add->tables_list_lock, st->list_file,
st->opts.lock_timeout_ms); st->opts.lock_timeout_ms);
if (err < 0) { if (err < 0)
if (errno == EEXIST) {
err = REFTABLE_LOCK_ERROR;
} else {
err = REFTABLE_IO_ERROR;
}
goto done; goto done;
}
if (st->opts.default_permissions) { if (st->opts.default_permissions) {
if (chmod(add->tables_list_lock.path, if (chmod(add->tables_list_lock.path,
st->opts.default_permissions) < 0) { st->opts.default_permissions) < 0) {
@ -1212,13 +1207,8 @@ static int stack_compact_range(struct reftable_stack *st,
* which are part of the user-specified range. * which are part of the user-specified range.
*/ */
err = flock_acquire(&tables_list_lock, st->list_file, st->opts.lock_timeout_ms); err = flock_acquire(&tables_list_lock, st->list_file, st->opts.lock_timeout_ms);
if (err < 0) { if (err < 0)
if (errno == EEXIST)
err = REFTABLE_LOCK_ERROR;
else
err = REFTABLE_IO_ERROR;
goto done; goto done;
}


/* /*
* Check whether the stack is up-to-date. We unfortunately cannot * Check whether the stack is up-to-date. We unfortunately cannot
@ -1272,7 +1262,7 @@ static int stack_compact_range(struct reftable_stack *st,
* tables, otherwise there would be nothing to compact. * tables, otherwise there would be nothing to compact.
* In that case, we return a lock error to our caller. * In that case, we return a lock error to our caller.
*/ */
if (errno == EEXIST && last - (i - 1) >= 2 && if (err == REFTABLE_LOCK_ERROR && last - (i - 1) >= 2 &&
flags & STACK_COMPACT_RANGE_BEST_EFFORT) { flags & STACK_COMPACT_RANGE_BEST_EFFORT) {
err = 0; err = 0;
/* /*
@ -1284,13 +1274,9 @@ static int stack_compact_range(struct reftable_stack *st,
*/ */
first = (i - 1) + 1; first = (i - 1) + 1;
break; break;
} else if (errno == EEXIST) {
err = REFTABLE_LOCK_ERROR;
goto done;
} else {
err = REFTABLE_IO_ERROR;
goto done;
} }

goto done;
} }


/* /*
@ -1299,11 +1285,9 @@ static int stack_compact_range(struct reftable_stack *st,
* of tables. * of tables.
*/ */
err = flock_close(&table_locks[nlocks++]); err = flock_close(&table_locks[nlocks++]);
if (err < 0) { if (err < 0)
err = REFTABLE_IO_ERROR;
goto done; goto done;
} }
}


/* /*
* We have locked all tables in our range and can thus release the * We have locked all tables in our range and can thus release the
@ -1334,13 +1318,8 @@ static int stack_compact_range(struct reftable_stack *st,
* the new table. * the new table.
*/ */
err = flock_acquire(&tables_list_lock, st->list_file, st->opts.lock_timeout_ms); err = flock_acquire(&tables_list_lock, st->list_file, st->opts.lock_timeout_ms);
if (err < 0) { if (err < 0)
if (errno == EEXIST)
err = REFTABLE_LOCK_ERROR;
else
err = REFTABLE_IO_ERROR;
goto done; goto done;
}


if (st->opts.default_permissions) { if (st->opts.default_permissions) {
if (chmod(tables_list_lock.path, if (chmod(tables_list_lock.path,

View File

@ -72,7 +72,7 @@ int flock_acquire(struct reftable_flock *l, const char *target_path,
reftable_free(lockfile); reftable_free(lockfile);
if (errno == EEXIST) if (errno == EEXIST)
return REFTABLE_LOCK_ERROR; return REFTABLE_LOCK_ERROR;
return -1; return REFTABLE_IO_ERROR;
} }


l->fd = get_lock_file_fd(lockfile); l->fd = get_lock_file_fd(lockfile);

View File

@ -81,7 +81,9 @@ struct reftable_flock {
* to acquire the lock. If `timeout_ms` is 0 we don't wait, if it is negative * to acquire the lock. If `timeout_ms` is 0 we don't wait, if it is negative
* we block indefinitely. * we block indefinitely.
* *
* Retrun 0 on success, a reftable error code on error. * Retrun 0 on success, a reftable error code on error. Specifically,
* `REFTABLE_LOCK_ERROR` should be returned in case the target path is already
* locked.
*/ */
int flock_acquire(struct reftable_flock *l, const char *target_path, int flock_acquire(struct reftable_flock *l, const char *target_path,
long timeout_ms); long timeout_ms);