Git fork

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>

authored by

Patrick Steinhardt and committed by
Junio C Hamano
8fd7a0eb 54d25de3

+12 -31
+8 -29
reftable/stack.c
··· 698 698 699 699 err = flock_acquire(&add->tables_list_lock, st->list_file, 700 700 st->opts.lock_timeout_ms); 701 - if (err < 0) { 702 - if (errno == EEXIST) { 703 - err = REFTABLE_LOCK_ERROR; 704 - } else { 705 - err = REFTABLE_IO_ERROR; 706 - } 701 + if (err < 0) 707 702 goto done; 708 - } 703 + 709 704 if (st->opts.default_permissions) { 710 705 if (chmod(add->tables_list_lock.path, 711 706 st->opts.default_permissions) < 0) { ··· 1212 1207 * which are part of the user-specified range. 1213 1208 */ 1214 1209 err = flock_acquire(&tables_list_lock, st->list_file, st->opts.lock_timeout_ms); 1215 - if (err < 0) { 1216 - if (errno == EEXIST) 1217 - err = REFTABLE_LOCK_ERROR; 1218 - else 1219 - err = REFTABLE_IO_ERROR; 1210 + if (err < 0) 1220 1211 goto done; 1221 - } 1222 1212 1223 1213 /* 1224 1214 * Check whether the stack is up-to-date. We unfortunately cannot ··· 1272 1262 * tables, otherwise there would be nothing to compact. 1273 1263 * In that case, we return a lock error to our caller. 1274 1264 */ 1275 - if (errno == EEXIST && last - (i - 1) >= 2 && 1265 + if (err == REFTABLE_LOCK_ERROR && last - (i - 1) >= 2 && 1276 1266 flags & STACK_COMPACT_RANGE_BEST_EFFORT) { 1277 1267 err = 0; 1278 1268 /* ··· 1284 1274 */ 1285 1275 first = (i - 1) + 1; 1286 1276 break; 1287 - } else if (errno == EEXIST) { 1288 - err = REFTABLE_LOCK_ERROR; 1289 - goto done; 1290 - } else { 1291 - err = REFTABLE_IO_ERROR; 1292 - goto done; 1293 1277 } 1278 + 1279 + goto done; 1294 1280 } 1295 1281 1296 1282 /* ··· 1299 1285 * of tables. 1300 1286 */ 1301 1287 err = flock_close(&table_locks[nlocks++]); 1302 - if (err < 0) { 1303 - err = REFTABLE_IO_ERROR; 1288 + if (err < 0) 1304 1289 goto done; 1305 - } 1306 1290 } 1307 1291 1308 1292 /* ··· 1334 1318 * the new table. 1335 1319 */ 1336 1320 err = flock_acquire(&tables_list_lock, st->list_file, st->opts.lock_timeout_ms); 1337 - if (err < 0) { 1338 - if (errno == EEXIST) 1339 - err = REFTABLE_LOCK_ERROR; 1340 - else 1341 - err = REFTABLE_IO_ERROR; 1321 + if (err < 0) 1342 1322 goto done; 1343 - } 1344 1323 1345 1324 if (st->opts.default_permissions) { 1346 1325 if (chmod(tables_list_lock.path,
+1 -1
reftable/system.c
··· 72 72 reftable_free(lockfile); 73 73 if (errno == EEXIST) 74 74 return REFTABLE_LOCK_ERROR; 75 - return -1; 75 + return REFTABLE_IO_ERROR; 76 76 } 77 77 78 78 l->fd = get_lock_file_fd(lockfile);
+3 -1
reftable/system.h
··· 81 81 * to acquire the lock. If `timeout_ms` is 0 we don't wait, if it is negative 82 82 * we block indefinitely. 83 83 * 84 - * Retrun 0 on success, a reftable error code on error. 84 + * Retrun 0 on success, a reftable error code on error. Specifically, 85 + * `REFTABLE_LOCK_ERROR` should be returned in case the target path is already 86 + * locked. 85 87 */ 86 88 int flock_acquire(struct reftable_flock *l, const char *target_path, 87 89 long timeout_ms);