[PATCH 1/5] f2fs: avoid underflow when counting free NIDs

From: Xinping Zhang

Date: Wed Aug 26 2026 - 17:39:49 EST


__count_free_nids() subtracts the retention threshold before checking
whether the cached count exceeds it. The operands are unsigned, so a
smaller cache wraps before the result is assigned to long.

The PAGE_SIZE-derived threshold happens to make this an unsigned long
subtraction, whose wrapped result becomes negative when converted to
long by supported toolchains. Do not rely on operand width or
unsigned-to-signed conversion. Compare values before subtracting.

Signed-off-by: Kelvin Zhang <zhangxp1998@xxxxxxxxx>
---
fs/f2fs/shrinker.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/shrinker.c b/fs/f2fs/shrinker.c
index 4f6bf5926de4..1fd0ee4f89a9 100644
--- a/fs/f2fs/shrinker.c
+++ b/fs/f2fs/shrinker.c
@@ -23,9 +23,10 @@ static unsigned long __count_nat_entries(struct
f2fs_sb_info *sbi)

static unsigned long __count_free_nids(struct f2fs_sb_info *sbi)
{
- long count = NM_I(sbi)->nid_cnt[FREE_NID] - MAX_FREE_NIDS;
+ unsigned long count = NM_I(sbi)->nid_cnt[FREE_NID];
+ unsigned long max = MAX_FREE_NIDS;

- return count > 0 ? count : 0;
+ return count > max ? count - max : 0;
}

static unsigned long __count_extent_cache(struct f2fs_sb_info *sbi,
--
2.53.0