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 --- 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