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

[PATCH] fsck: do not loop infinitely when processing packs

From
brian m. carlson <sandals@crustytoothpaste.net>
Date
Feb 22, 2026, 18:37 UTC
Message-ID
<20260222183710.2963424-1-sandals@crustytoothpaste.net>

When we iterate over our packfiles in the fsck code, we do so twice. The first time, we count the number of objects in all of the packs together and later on, we iterate a second time, processing each pack and verifying its integrity.

This would normally work fine, but if we have two packs and we're processing the second, the verification process will open the pack to read from it, which will place it at the beginning of the most recently used list. Since this same list is used for iteration, the pack we most recently processed before this will then be behind the current pack in the linked list, so when we next process the list, we will go back to the first pack again and then loop forever. This also makes our progress indicator loop up to many thousands of percent, which is not only nonsensical, but a clear indication that something has gone wrong.

Solve this by skipping our MRU updates when we're iterating over packfiles, which avoids the reordering that causes problems.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
I realize that t1050 may seem like a bizarre place to put this test.
However, I was debugging my sha256-interop branch and why the final test
calling `git fsck` was failing, so I placed a `git fsck` earlier in the
test to double-check and discovered the problem.  Since we already have
a natural testcase here, I thought I'd just place the test where we
already know it will trigger the problem.
 packfile.h       | 16 ++++++++++++++--
 t/t1050-large.sh |  4 ++++
 2 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/packfile.h b/packfile.h
index acc5c55ad5..086d98c1a0 100644
--- a/packfile.h
+++ b/packfile.h
@@ -183,6 +183,7 @@ struct packfile_list_entry *packfile_store_get_packs(struct packfile_store *stor
 struct repo_for_each_pack_data {
 	struct odb_source *source;
 	struct packfile_list_entry *entry;
+	struct repository *repo;
 };
 
 static inline struct repo_for_each_pack_data repo_for_eack_pack_data_init(struct repository *repo)
@@ -191,8 +192,13 @@ static inline struct repo_for_each_pack_data repo_for_eack_pack_data_init(struct
 
 	odb_prepare_alternates(repo->objects);
 
+	data.repo = repo;
+
 	for (struct odb_source *source = repo->objects->sources; source; source = source->next) {
-		struct packfile_list_entry *entry = packfile_store_get_packs(source->packfiles);
+		struct packfile_list_entry *entry;
+
+		source->packfiles->skip_mru_updates = true;
+		entry = packfile_store_get_packs(source->packfiles);
 		if (!entry)
 			continue;
 		data.source = source;
@@ -212,7 +218,10 @@ static inline void repo_for_each_pack_data_next(struct repo_for_each_pack_data *
 		return;
 
 	for (source = data->source->next; source; source = source->next) {
-		struct packfile_list_entry *entry = packfile_store_get_packs(source->packfiles);
+		struct packfile_list_entry *entry;
+
+		source->packfiles->skip_mru_updates = true;
+		entry = packfile_store_get_packs(source->packfiles);
 		if (!entry)
 			continue;
 		data->source = source;
@@ -220,6 +229,9 @@ static inline void repo_for_each_pack_data_next(struct repo_for_each_pack_data *
 		return;
 	}
 
+	for (struct odb_source *source = data->repo->objects->sources; source; source = source->next)
+		source->packfiles->skip_mru_updates = false;
+
 	data->source = NULL;
 	data->entry = NULL;
 }
diff --git a/t/t1050-large.sh b/t/t1050-large.sh
index 5be273611a..75e75e627c 100755
--- a/t/t1050-large.sh
+++ b/t/t1050-large.sh
@@ -160,6 +160,10 @@ test_expect_success 'hash-object' '
 	git hash-object large1
 '
 
+test_expect_success 'fsck does not loop forever' '
+	git fsck
+'
+
 test_expect_success 'cat-file a large file' '
 	git cat-file blob :large1 >/dev/null
 '
Next: Junio C Hamano
Message 1 of 14 in “fsck: do not loop infinitely when processing packs”
  1. fsck: do not loop infinitely when processing packsbrian m. carlson, Feb 22, 2026
  2. Junio C HamanoFeb 22, 2026
  3. brian m. carlsonFeb 22, 2026
  4. Jeff KingFeb 23, 2026
  5. Patrick SteinhardtFeb 23, 2026
  6. Jeff KingFeb 23, 2026
  7. Patrick SteinhardtFeb 23, 2026
  8. Jeff KingFeb 23, 2026
  9. Junio C HamanoFeb 23, 2026
  10. Patrick SteinhardtFeb 23, 2026
  11. Jeff KingFeb 23, 2026
  12. Patrick SteinhardtFeb 23, 2026
  13. brian m. carlsonFeb 24, 2026
  14. Junio C HamanoFeb 24, 2026

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.