From 172a186fa91dbb817cdda3829120e7217d711510 Mon Sep 17 00:00:00 2001 From: David Date: Tue, 2 Sep 2025 19:36:10 -0400 Subject: [PATCH 1/3] compact when dir count hits 0x3ff --- lfs.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lfs.c b/lfs.c index 624f43cc..ebfd695a 100644 --- a/lfs.c +++ b/lfs.c @@ -2333,6 +2333,10 @@ static int lfs_dir_relocatingcommit(lfs_t *lfs, lfs_mdir_t *dir, lfs->gdisk = lfs->gstate; lfs->gdelta = (lfs_gstate_t){0}; + if(dir->count == 0x3ff) + { + goto compact; + } goto fixmlist; } From f24ff9fb2568d769d3d679c84d6ea19e269867f8 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Thu, 25 Sep 2025 13:03:42 -0500 Subject: [PATCH 2/3] Moved dir->count check before commit, limited to < 0xff This matches the logic originally implemented in 48bd2bf, which was lost during the big no-recursion refactor 84da4c0. Other notes: - Checking >= 0xff matches the split logic during compaction (line 2158): end - split < 0xff - Grouping dir->erased || dir->count >= 0xff together makes it clear these share a common code path. - Checking for dir->count >= 0xff early avoids committing >8-bit ids to disk. The cat may already be out-of-the bag on this one, but opening the id space up to the full 10-bits should probably be on a non-patch release. Found by dschendt --- lfs.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lfs.c b/lfs.c index ebfd695a..401c60a2 100644 --- a/lfs.c +++ b/lfs.c @@ -2264,7 +2264,7 @@ static int lfs_dir_relocatingcommit(lfs_t *lfs, lfs_mdir_t *dir, } } - if (dir->erased) { + if (dir->erased || dir->count >= 0xff) { // try to commit struct lfs_commit commit = { .block = dir->pair[0], @@ -2333,10 +2333,6 @@ static int lfs_dir_relocatingcommit(lfs_t *lfs, lfs_mdir_t *dir, lfs->gdisk = lfs->gstate; lfs->gdelta = (lfs_gstate_t){0}; - if(dir->count == 0x3ff) - { - goto compact; - } goto fixmlist; } From 4cd2bfc2c12b981f891d4fa335ce7492cc9141f4 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Thu, 25 Sep 2025 15:22:19 -0500 Subject: [PATCH 3/3] Fixed inverted dir->count check logic Curiously, the logic from 48bd2bf was incorrect, and would allow a commit to be tried if erased _or_ dir->count was at risk of overflow. That is clearly wrong, we should only try to commit if both conditions are met... Found again by dschendt --- lfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lfs.c b/lfs.c index 401c60a2..aecace6c 100644 --- a/lfs.c +++ b/lfs.c @@ -2264,7 +2264,7 @@ static int lfs_dir_relocatingcommit(lfs_t *lfs, lfs_mdir_t *dir, } } - if (dir->erased || dir->count >= 0xff) { + if (dir->erased && dir->count < 0xff) { // try to commit struct lfs_commit commit = { .block = dir->pair[0],