From 19654ba88080438cd572c5298e2bb258cba9cac0 Mon Sep 17 00:00:00 2001 From: roy Date: Mon, 29 Jun 2026 00:44:06 +0800 Subject: [PATCH] Rework directory block enumeration accounting __file_lookup() and simplefs_remove_from_dir() bound their block walks differently, and neither skips directory blocks that hold no files. Bound both inner loops by nr_bi_files, decrement it only after a block is scanned, and skip blocks whose nr_files is zero. In simplefs_try_remove_entry(), zero the freed slot's nr_blk and drop the now redundant blk_nr_files guard. --- inode.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/inode.c b/inode.c index dacc95f..27acd7d 100644 --- a/inode.c +++ b/inode.c @@ -162,7 +162,6 @@ static int __file_lookup(struct inode *dir, if (!eblock->extents[_ei].ee_start) continue; - nr_ei_files -= eblock->extents[_ei].nr_files; /* Iterate blocks in extent */ int nr_bi_files = eblock->extents[_ei].nr_files; for (idx_bi = 0; nr_bi_files; _bi++, idx_bi++) { @@ -176,7 +175,10 @@ static int __file_lookup(struct inode *dir, dblock = (struct simplefs_dir_block *) (*ret_bi_bh)->b_data; /* Search file in ei_block */ - nr_bi_files -= dblock->nr_files; + if (dblock->nr_files == 0) { + RELEASE_BUFFER_HEAD(*ret_bi_bh); + continue; + } for (_fi = 0; _fi < SIMPLEFS_FILES_PER_BLOCK;) { f = &dblock->files[_fi]; if (f->inode && !strncmp(f->filename, dentry->d_name.name, @@ -188,8 +190,10 @@ static int __file_lookup(struct inode *dir, } _fi += dblock->files[_fi].nr_blk; } + nr_bi_files -= dblock->nr_files; RELEASE_BUFFER_HEAD(*ret_bi_bh); } + nr_ei_files -= eblock->extents[_ei].nr_files; _bi = 0; } file_search_end: @@ -468,9 +472,8 @@ static bool simplefs_try_remove_entry(struct simplefs_dir_block *dblock, const char *name) { int fi, i; - int blk_nr_files = dblock->nr_files; - for (fi = 0; blk_nr_files && fi < SIMPLEFS_FILES_PER_BLOCK;) { + for (fi = 0; fi < SIMPLEFS_FILES_PER_BLOCK;) { if (dblock->files[fi].inode) { if (dblock->files[fi].inode == ino && !strcmp(dblock->files[fi].filename, name)) { @@ -479,6 +482,7 @@ static bool simplefs_try_remove_entry(struct simplefs_dir_block *dblock, for (i = fi - 1; i >= 0; i--) { if (dblock->files[i].inode != 0 || i == 0) { dblock->files[i].nr_blk += dblock->files[fi].nr_blk; + dblock->files[fi].nr_blk = 0; break; } } @@ -487,7 +491,6 @@ static bool simplefs_try_remove_entry(struct simplefs_dir_block *dblock, eblock->nr_files--; return true; } - blk_nr_files--; } fi += dblock->files[fi].nr_blk; } @@ -692,10 +695,10 @@ static int simplefs_remove_from_dir(struct inode *dir, CHECK_AND_SET_RING_INDEX(ei, SIMPLEFS_MAX_EXTENTS); if (eblock->extents[ei].ee_start) { - dir_nr_files -= eblock->extents[ei].nr_files; + int nr_bi_files = eblock->extents[ei].nr_files; + dir_nr_files -= nr_bi_files; /* simplefs_extent */ - for (idx_bi = 0; idx_bi < eblock->extents[ei].ee_len; - bi++, idx_bi++) { + for (idx_bi = 0; nr_bi_files; bi++, idx_bi++) { CHECK_AND_SET_RING_INDEX(bi, eblock->extents[ei].ee_len); bh2 = sb_bread(sb, eblock->extents[ei].ee_start + bi); if (!bh2) { @@ -704,6 +707,10 @@ static int simplefs_remove_from_dir(struct inode *dir, } /* simplefs_dir_block */ dirblk = (struct simplefs_dir_block *) bh2->b_data; + if (dirblk->nr_files == 0) { + RELEASE_BUFFER_HEAD(bh2); + continue; + } if (simplefs_try_remove_entry(dirblk, eblock, ei, inode->i_ino, dentry->d_name.name)) { mark_buffer_dirty(bh2); @@ -712,6 +719,7 @@ static int simplefs_remove_from_dir(struct inode *dir, *ret_ei = ei; goto found_data; } + nr_bi_files -= dirblk->nr_files; RELEASE_BUFFER_HEAD(bh2); } }