[PATCH v1 2/9] ext2: mark s_next_generation as guarded by s_next_gen_lock
From: Timothy Day
Date: Sun Jul 12 2026 - 12:58:20 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. Since the s_next_gen_lock isn't being taken in this
case, wrap it in context_unsafe().
Signed-off-by: Timothy Day <timday@xxxxxxxxxxxxxxxxxxxxxxx>
---
fs/ext2/ext2.h | 2 +-
fs/ext2/super.c | 4 +++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index 79f7b395258c2..e851d2a6be662 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 3999f8f3b156e..8c7f3772917bb 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -1125,9 +1125,11 @@ 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);
+ /* concurrent access is not possible before the mount completes */
+ context_unsafe(sbi->s_next_generation = get_random_u32());
+
/* per filesystem reservation list head & lock */
spin_lock_init(&sbi->s_rsv_window_lock);
sbi->s_rsv_window_root = RB_ROOT;
--
2.39.5