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

[PATCH v2 3/5] refs/reftable: add fsck check for number of tables

From
Karthik Nayak <karthik.188@gmail.com>
Date
Sep 2, 2025, 07:05 UTC
Message-ID
<20250902-228-reftable-introduce-consistency-checks-v2-3-4f96b3834779@gmail.com>
In-Reply-To
<20250902-228-reftable-introduce-consistency-checks-v2-0-4f96b3834779@gmail.com>

Introduce a reftable fsck check to check that the number of files in the reftable directory matches the number of files listed in 'tables.list'. We do this by iterating over the files in the reftable directory and counting all the files present excluding the 'tables.list'. This is also exposed over Git's fsck checks as a 'badReftableStackCount' error.

Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
---
 Documentation/fsck-msgids.adoc |  3 +++
 fsck.h                         |  1 +
 refs/reftable-backend.c        |  3 +++
 reftable/fsck.c                | 34 ++++++++++++++++++++++++++++++++++
 reftable/reftable-fsck.h       |  2 ++
 t/t0614-reftable-fsck.sh       | 20 ++++++++++++++++++++
 6 files changed, 63 insertions(+)
diff --git a/Documentation/fsck-msgids.adoc b/Documentation/fsck-msgids.adoc
index 784ddc0df5..707e2fc50a 100644
--- a/Documentation/fsck-msgids.adoc
+++ b/Documentation/fsck-msgids.adoc
@@ -38,6 +38,9 @@
 `badReferentName`::
 	(ERROR) The referent name of a symref is invalid.
 
+`badReftableStackCount`::
+	(ERROR) Mismatch in number of tables.
+
 `badReftableTableName`::
 	(ERROR) A reftable table has an invalid name.
 
diff --git a/fsck.h b/fsck.h
index 5901f944a1..256effc4f8 100644
--- a/fsck.h
+++ b/fsck.h
@@ -34,6 +34,7 @@ enum fsck_msg_type {
 	FUNC(BAD_PACKED_REF_HEADER, ERROR)                         \
 	FUNC(BAD_PARENT_SHA1, ERROR)                               \
 	FUNC(BAD_REFERENT_NAME, ERROR)                             \
+	FUNC(BAD_REFTABLE_STACK_COUNT, ERROR)                      \
 	FUNC(BAD_REFTABLE_TABLE_NAME, ERROR)                       \
 	FUNC(BAD_REF_CONTENT, ERROR)                               \
 	FUNC(BAD_REF_FILETYPE, ERROR)                              \
diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c
index c38c6422f8..59c39f9b52 100644
--- a/refs/reftable-backend.c
+++ b/refs/reftable-backend.c
@@ -2695,6 +2695,9 @@ static int reftable_fsck_error_handler(struct reftable_fsck_info *info,
 	case REFTABLE_FSCK_ERROR_TABLE_NAME:
 		msg_id = FSCK_MSG_BAD_REFTABLE_TABLE_NAME;
 		break;
+	case REFTABLE_FSCK_ERROR_STACK_COUNT:
+		msg_id = FSCK_MSG_BAD_REFTABLE_STACK_COUNT;
+		break;
 	default:
 		BUG("unknown fsck error: %d", info->error);
 	}
diff --git a/reftable/fsck.c b/reftable/fsck.c
index 4282b1413e..20e6bfb0f1 100644
--- a/reftable/fsck.c
+++ b/reftable/fsck.c
@@ -2,6 +2,28 @@
 #include "reftable-fsck.h"
 #include "stack.h"
 
+static int reftable_fsck_valid_stack_count(struct reftable_stack *st)
+{
+	DIR *dir = opendir(st->reftable_dir);
+	struct dirent *d = NULL;
+	unsigned int count = 0;
+
+	if (!dir)
+		return 0;
+
+	while ((d = readdir(dir))) {
+		if (!strcmp(d->d_name, "tables.list"))
+			continue;
+
+		if (d->d_type == DT_REG)
+			count++;
+	}
+
+	closedir(dir);
+
+	return count == st->tables_len;
+}
+
 int reftable_fsck_check(struct reftable_stack *stack,
 			reftable_fsck_report_fn report_fn,
 			reftable_fsck_verbose_fn verbose_fn,
@@ -47,6 +69,18 @@ int reftable_fsck_check(struct reftable_stack *stack,
 		}
 	}
 
+	verbose_fn("Checking reftable tables count", cb_data);
+
+	if (!reftable_fsck_valid_stack_count(stack)) {
+		struct reftable_fsck_info info = {
+			.error = REFTABLE_FSCK_ERROR_STACK_COUNT,
+			.path = "reftable/tables.list",
+			.msg = "mismatch in number of tables"
+		};
+
+		err = report_fn(&info, cb_data);
+	}
+
 out:
 	free_names(names);
 	return err;
diff --git a/reftable/reftable-fsck.h b/reftable/reftable-fsck.h
index 4cf0053234..beba1bdd1a 100644
--- a/reftable/reftable-fsck.h
+++ b/reftable/reftable-fsck.h
@@ -6,6 +6,8 @@
 enum reftable_fsck_error {
 	/* Invalid table name */
 	REFTABLE_FSCK_ERROR_TABLE_NAME = -1,
+	/* Incorrect number of tables present */
+	REFTABLE_FSCK_ERROR_STACK_COUNT = -2,
 };
 
 /* Represents an individual error encountered during the FSCK checks. */
diff --git a/t/t0614-reftable-fsck.sh b/t/t0614-reftable-fsck.sh
index 81d30df2d7..3a34a31890 100755
--- a/t/t0614-reftable-fsck.sh
+++ b/t/t0614-reftable-fsck.sh
@@ -55,4 +55,24 @@ test_expect_success 'table name should be checked' '
 	)
 '
 
+test_expect_success 'table count should be checked' '
+	test_when_finished "rm -rf repo" &&
+	git init repo &&
+	(
+		cd repo &&
+		git commit --allow-empty -m initial &&
+
+		git refs verify 2>err &&
+		test_must_be_empty err &&
+
+		touch .git/reftable/0x000000002812-0x000000002813-c830a596.ref &&
+
+		test_must_fail git refs verify 2>err &&
+		cat >expect <<-EOF &&
+		error: reftable/tables.list: badReftableStackCount: mismatch in number of tables
+		EOF
+		test_cmp expect err
+	)
+'
+
 test_done
-- 
2.50.1
Previous: Karthik NayakNext: Patrick Steinhardt
Message 10 of 18 in “refs/reftable: add fsck checks”
  1. 0/5 refs/reftable: add fsck checksKarthik Nayak, Sep 2, 2025
  2. 1/5 fsck: order 'fsck_msg_type' alphabeticallyKarthik Nayak, Sep 2, 2025
  3. Junio C HamanoSep 2, 2025
  4. Karthik NayakSep 8, 2025
  5. 2/5 refs/reftable: add fsck check for checking the table nameKarthik Nayak, Sep 2, 2025
  6. Patrick SteinhardtSep 3, 2025
  7. shejialuoSep 3, 2025
  8. Karthik NayakSep 9, 2025
  9. Karthik NayakSep 9, 2025
  10. 3/5 refs/reftable: add fsck check for number of tablesKarthik Nayak, Sep 2, 2025
  11. Patrick SteinhardtSep 3, 2025
  12. Karthik NayakSep 15, 2025
  13. 4/5 refs/reftable: add fsck check for trailing newlineKarthik Nayak, Sep 2, 2025
  14. Junio C HamanoSep 2, 2025
  15. Patrick SteinhardtSep 3, 2025
  16. 5/5 refs/reftable: add fsck check for incorrect update indexKarthik Nayak, Sep 2, 2025
  17. Junio C HamanoSep 2, 2025
  18. Karthik NayakSep 18, 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.