[PATCH v2 1/8] ext2: mark s_next_generation as guarded by s_next_gen_lock

From: Timothy Day

Date: Tue Aug 11 2026 - 12:05:11 EST


s_next_generation is only ever modified while holding s_next_gen_lock
(in ext2_new_inode()), so annotate it with __guarded_by() for Clang's
context analysis.

The only other write is the initialisation in ext2_fill_super(), which
runs before the superblock is live. No concurrent access should be
possible. Convert the spinlock initialization to use
scoped_guard(spinlock_init, ...) and place the write under the guard
to prevent a warning.

Signed-off-by: Timothy Day <timday@xxxxxxxxxxxxxxxxxxxxxxx>
---
fs/ext2/ext2.h | 2 +-
fs/ext2/super.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index 79f7b395258c..e851d2a6be66 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -93,7 +93,7 @@ struct ext2_sb_info {
int s_inode_size;
int s_first_ino;
spinlock_t s_next_gen_lock;
- u32 s_next_generation;
+ u32 s_next_generation __guarded_by(&s_next_gen_lock);
unsigned long s_dir_count;
u8 *s_debts;
struct percpu_counter s_freeblocks_counter;
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 3999f8f3b156..b8bb1f88a620 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -1125,8 +1125,8 @@ static int ext2_fill_super(struct super_block *sb, struct fs_context *fc)
goto failed_mount2;
}
sbi->s_gdb_count = db_count;
- sbi->s_next_generation = get_random_u32();
- spin_lock_init(&sbi->s_next_gen_lock);
+ scoped_guard(spinlock_init, &sbi->s_next_gen_lock)
+ sbi->s_next_generation = get_random_u32();

/* per filesystem reservation list head & lock */
spin_lock_init(&sbi->s_rsv_window_lock);
--
2.43.0