git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v3 7/8] reftable: add code to facilitate consistency checks

From
Patrick Steinhardt <ps@pks.im>
Date
Sep 24, 2025, 05:54 UTC
Message-ID
<aNOHqEq5qxXrOCX7@pks.im>
In-Reply-To
<20250918-228-reftable-introduce-consistency-checks-v3-7-271af03eb34d@gmail.com>
On Thu, Sep 18, 2025 at 10:11:48AM +0200, Karthik Nayak wrote:
Show 22 quoted lines
> diff --git a/reftable/fsck.c b/reftable/fsck.c
> new file mode 100644
> index 0000000000..785e4b43e8
> --- /dev/null
> +++ b/reftable/fsck.c
> @@ -0,0 +1,112 @@
> +#include "basics.h"
> +#include "reftable-fsck.h"
> +#include "stack.h"
> +
> +static bool valid_table_name(const char *name, uint64_t *min_update_index,
> +			     uint64_t *max_update_index)
> +{
> +	const char *ptr = name;
> +	char *endptr;
> +
> +	/* strtoull doesn't set errno on success */
> +	errno = 0;
> +
> +	*min_update_index = strtoull(ptr, &endptr, 16);
> +	if (errno == EINVAL)
> +		return false;

strtoull may also return ERANGE. In general, shouldn't we abort whenever errno is non-zero here?

> +	ptr = endptr;
> +
> +	if (strncmp(ptr, "-", 1))
> +		return false;
Better:
    if (*ptr != '-')
        return false;
Show 18 quoted lines
> +	ptr++;
> +
> +	*max_update_index = strtoull(ptr, &endptr, 16);
> +	if (errno == EINVAL)
> +		return false;
> +	ptr = endptr;
> +
> +	if (*ptr != '-')
> +		return false;
> +	ptr++;
> +
> +	strtoul(ptr, &endptr, 16);
> +	if (errno == EINVAL)
> +		return false;
> +	ptr = endptr;
> +
> +	if (strcmp(ptr, ".ref") && strcmp(ptr, ".log"))
> +		return false;

Yup, makes sense. We don't do so ourselves, but in theory it is possible for tables to have a ".log" suffix. If so, they are expected to only contain reflog records.

Show 8 quoted lines
> +	return true;
> +}
> +
> +static int stack_check_all_files_in_dir(struct reftable_stack *stack,
> +					reftable_fsck_report_fn report_fn,
> +					void *cb_data)
> +{
> +	DIR *dir = opendir(stack->reftable_dir);

I think it would make sense to move this function call close to the conditional.

Show 25 quoted lines
> +	struct reftable_fsck_info info;
> +	struct dirent *d = NULL;
> +	uint64_t min, max;
> +	int err = 0;
> +
> +	if (!dir)
> +		return 0;
> +
> +	while ((d = readdir(dir))) {
> +		if (!strcmp(d->d_name, "tables.list"))
> +			continue;
> +
> +		if ((d->d_name[0] == '.' &&
> +		     (d->d_name[1] == '\0' ||
> +		      (d->d_name[1] == '.' && d->d_name[2] == '\0'))))
> +			continue;
> +
> +		if (d->d_type == DT_REG) {
> +			if (!valid_table_name(d->d_name, &min, &max)) {
> +				info.error = REFTABLE_FSCK_ERROR_TABLE_NAME;
> +				info.msg = "file with invalid table name";
> +				info.path = d->d_name;
> +
> +				err |= report_fn(&info, cb_data);
> +			}

One problem with this is that this is racy with concurrent writers. We don't recognize the "tables.list.lock" file, and neither do we recognize "0x*-0x*.{ref,log}.temp.XXXXXX"-style files.

Would it be a better approach be to instead go through table names as loaded by the stack? The reftable code already knows to prune unknown files anyway, so I don't think we should scan for any other files.

Show 19 quoted lines
> +		} else {
> +			info.error = REFTABLE_FSCK_ERROR_INVALID_FILE_TYPE;
> +			info.msg = "file with unexpected type";
> +			info.path = d->d_name;
> +
> +			err |= report_fn(&info, cb_data);
> +		}
> +	}
> +
> +	closedir(dir);
> +	return err;
> +}
> +
> +static int stack_checks(struct reftable_stack *stack,
> +			reftable_fsck_report_fn report_fn,
> +			void *cb_data)
> +{
> +	struct reftable_buf msg = REFTABLE_BUF_INIT;
> +	char **names = NULL;
This variable is unused.
> +	int err = 0;
> +
> +	if (stack == NULL)
> +		goto out;
Why should someone ever pass a `NULL` stack?
Show 15 quoted lines
> +	err |= stack_check_all_files_in_dir(stack, report_fn, cb_data);
> +
> +out:
> +	free_names(names);
> +	reftable_buf_release(&msg);
> +	return err;
> +}
> +
> +int reftable_fsck_check(struct reftable_stack *stack,
> +			reftable_fsck_report_fn report_fn,
> +			reftable_fsck_verbose_fn verbose_fn,
> +			void *cb_data)
> +{
> +	verbose_fn("Checking reftable: stack checks", cb_data);
> +	return stack_checks(stack, report_fn, cb_data);
Nit: having this extra function call to `stack_checks()` feels a bit
weird as it could just as well be inlined. Is this preparing for a
future change?
Show 19 quoted lines
> +}
> diff --git a/reftable/reftable-fsck.h b/reftable/reftable-fsck.h
> new file mode 100644
> index 0000000000..5e13ac9f02
> --- /dev/null
> +++ b/reftable/reftable-fsck.h
> @@ -0,0 +1,42 @@
> +#ifndef REFTABLE_FSCK_H
> +#define REFTABLE_FSCK_H
> +
> +#include "reftable-stack.h"
> +
> +enum reftable_fsck_error {
> +	/* Non regular file in the reftable directory */
> +	REFTABLE_FSCK_ERROR_INVALID_FILE_TYPE = 0,
> +	/* Invalid table name */
> +	REFTABLE_FSCK_ERROR_TABLE_NAME,
> +	/* Used for bounds checking, must be last */
> +	REFTABLE_FSCK_MAX_VALUE
Let's add a trailing comma here.
Patrick
Previous: Karthik NayakNext: Karthik Nayak
Message 36 of 64 in “refs/reftable: add fsck checks”
  1. 0/5 refs/reftable: add fsck checksKarthik Nayak, Aug 19, 2025
  2. 1/5 fsck: order 'fsck_msg_type' alphabeticallyKarthik Nayak, Aug 19, 2025
  3. 2/5 refs/reftable: add fsck check for checking the table nameKarthik Nayak, Aug 19, 2025
  4. shejialuoAug 26, 2025
  5. Karthik NayakSep 1, 2025
  6. shejialuoSep 3, 2025
  7. 3/5 refs/reftable: add fsck check for number of tablesKarthik Nayak, Aug 19, 2025
  8. shejialuoAug 26, 2025
  9. Karthik NayakSep 1, 2025
  10. shejialuoAug 26, 2025
  11. Karthik NayakSep 1, 2025
  12. 4/5 refs/reftable: add fsck check for trailing newlineKarthik Nayak, Aug 19, 2025
  13. 5/5 refs/reftable: add fsck check for incorrect update indexKarthik Nayak, Aug 19, 2025
  14. shejialuoAug 26, 2025
  15. Karthik NayakSep 1, 2025
  16. 0/8 refs/reftable: add consistency checksKarthik Nayak, Sep 18, 2025
  17. 1/8 refs: remove unused headersKarthik Nayak, Sep 18, 2025
  18. 2/8 refs: move consistency check msg to generic layerKarthik Nayak, Sep 18, 2025
  19. 3/8 reftable: check for trailing newline in 'tables.list'Karthik Nayak, Sep 18, 2025
  20. Junio C HamanoSep 18, 2025
  21. Karthik NayakSep 23, 2025
  22. Patrick SteinhardtSep 24, 2025
  23. Karthik NayakSep 24, 2025
  24. Kristoffer HaugsbakkSep 24, 2025
  25. Karthik NayakSep 24, 2025
  26. 5/8 Documentation/fsck-msgids: remove duplicate msg idKarthik Nayak, Sep 18, 2025
  27. 4/8 reftable: ensure tables in a stack use sequential update indicesKarthik Nayak, Sep 18, 2025
  28. Patrick SteinhardtSep 24, 2025
  29. Karthik NayakSep 24, 2025
  30. Junio C HamanoSep 24, 2025
  31. Karthik NayakSep 24, 2025
  32. Patrick SteinhardtSep 25, 2025
  33. Junio C HamanoSep 25, 2025
  34. 6/8 fsck: order 'fsck_msg_type' alphabeticallyKarthik Nayak, Sep 18, 2025
  35. 7/8 reftable: add code to facilitate consistency checksKarthik Nayak, Sep 18, 2025
  36. Patrick SteinhardtSep 24, 2025
  37. Karthik NayakSep 24, 2025
  38. Patrick SteinhardtSep 25, 2025
  39. 8/8 refs/reftable: add fsck check for checking the table nameKarthik Nayak, Sep 18, 2025
  40. Patrick SteinhardtSep 24, 2025
  41. Karthik NayakSep 24, 2025
  42. 0/7 refs/reftable: add consistency checksKarthik Nayak, Oct 6, 2025
  43. 1/7 refs: remove unused headersKarthik Nayak, Oct 6, 2025
  44. 2/7 refs: move consistency check msg to generic layerKarthik Nayak, Oct 6, 2025
  45. 3/7 reftable: check for trailing newline in 'tables.list'Karthik Nayak, Oct 6, 2025
  46. 4/7 Documentation/fsck-msgids: remove duplicate msg idKarthik Nayak, Oct 6, 2025
  47. 5/7 fsck: order 'fsck_msg_type' alphabeticallyKarthik Nayak, Oct 6, 2025
  48. 6/7 reftable: add code to facilitate consistency checksKarthik Nayak, Oct 6, 2025
  49. 7/7 refs/reftable: add fsck check for checking the table nameKarthik Nayak, Oct 6, 2025
  50. Jeff KingOct 7, 2025
  51. Karthik NayakOct 7, 2025
  52. Junio C HamanoOct 6, 2025
  53. Karthik NayakOct 7, 2025
  54. Junio C HamanoOct 7, 2025
  55. 0/7 refs/reftable: add consistency checksKarthik Nayak, Oct 7, 2025
  56. 1/7 refs: remove unused headersKarthik Nayak, Oct 7, 2025
  57. 2/7 refs: move consistency check msg to generic layerKarthik Nayak, Oct 7, 2025
  58. 3/7 reftable: check for trailing newline in 'tables.list'Karthik Nayak, Oct 7, 2025
  59. 4/7 Documentation/fsck-msgids: remove duplicate msg idKarthik Nayak, Oct 7, 2025
  60. 5/7 fsck: order 'fsck_msg_type' alphabeticallyKarthik Nayak, Oct 7, 2025
  61. 6/7 reftable: add code to facilitate consistency checksKarthik Nayak, Oct 7, 2025
  62. 7/7 refs/reftable: add fsck check for checking the table nameKarthik Nayak, Oct 7, 2025
  63. Patrick SteinhardtOct 7, 2025
  64. Junio C HamanoOct 7, 2025

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.