* [PATCH v2 1/8] ext2: mark s_next_generation as guarded by s_next_gen_lock
2026-08-11 16:03 [PATCH v2 0/8] Support Clang context analysis for ext2 Timothy Day
@ 2026-08-11 16:03 ` Timothy Day
2026-08-11 16:03 ` [PATCH v2 2/8] ext2: annotate ext2_update_dynamic_rev() as requiring s_lock Timothy Day
` (8 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Timothy Day @ 2026-08-11 16:03 UTC (permalink / raw)
To: linux-ext4
Cc: Jan Kara, Marco Elver, Theodore Tso, linux-fsdevel, linux-kernel,
Timothy Day
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@thelustrecollective.com>
---
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
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v2 2/8] ext2: annotate ext2_update_dynamic_rev() as requiring s_lock
2026-08-11 16:03 [PATCH v2 0/8] Support Clang context analysis for ext2 Timothy Day
2026-08-11 16:03 ` [PATCH v2 1/8] ext2: mark s_next_generation as guarded by s_next_gen_lock Timothy Day
@ 2026-08-11 16:03 ` Timothy Day
2026-08-11 16:03 ` [PATCH v2 3/8] ext2: mark statfs overhead cache as guarded by s_lock Timothy Day
` (7 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Timothy Day @ 2026-08-11 16:03 UTC (permalink / raw)
To: linux-ext4
Cc: Jan Kara, Marco Elver, Theodore Tso, linux-fsdevel, linux-kernel,
Timothy Day
ext2_update_dynamic_rev() modifies several fields within
'struct ext2_super_block' and is already documented as requiring
s_lock. Express that with __must_hold() for Clang's context analysis.
Both callers ext2_xattr_update_super_block() and __ext2_write_inode()
already hold s_lock.
Signed-off-by: Timothy Day <timday@thelustrecollective.com>
---
fs/ext2/ext2.h | 3 ++-
fs/ext2/super.c | 1 +
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index e851d2a6be66..c8bf2e69675d 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -760,7 +760,8 @@ extern __printf(3, 4)
void ext2_error(struct super_block *, const char *, const char *, ...);
extern __printf(3, 4)
void ext2_msg(struct super_block *, const char *, const char *, ...);
-extern void ext2_update_dynamic_rev (struct super_block *sb);
+extern void ext2_update_dynamic_rev(struct super_block *sb)
+ __must_hold(&EXT2_SB(sb)->s_lock);
extern void ext2_sync_super(struct super_block *sb, struct ext2_super_block *es,
int wait);
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index b8bb1f88a620..5bf63943828b 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -127,6 +127,7 @@ void ext2_msg(struct super_block *sb, const char *prefix,
* This must be called with sbi->s_lock held.
*/
void ext2_update_dynamic_rev(struct super_block *sb)
+ __must_hold(&EXT2_SB(sb)->s_lock)
{
struct ext2_super_block *es = EXT2_SB(sb)->s_es;
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v2 3/8] ext2: mark statfs overhead cache as guarded by s_lock
2026-08-11 16:03 [PATCH v2 0/8] Support Clang context analysis for ext2 Timothy Day
2026-08-11 16:03 ` [PATCH v2 1/8] ext2: mark s_next_generation as guarded by s_next_gen_lock Timothy Day
2026-08-11 16:03 ` [PATCH v2 2/8] ext2: annotate ext2_update_dynamic_rev() as requiring s_lock Timothy Day
@ 2026-08-11 16:03 ` Timothy Day
2026-08-11 16:03 ` [PATCH v2 4/8] ext2: mark s_mount_state " Timothy Day
` (6 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Timothy Day @ 2026-08-11 16:03 UTC (permalink / raw)
To: linux-ext4
Cc: Jan Kara, Marco Elver, Theodore Tso, linux-fsdevel, linux-kernel,
Timothy Day
s_overhead_last and s_blocks_last cache the filesystem overhead
computation and are only ever accessed in ext2_statfs() under s_lock.
Annotate them with __guarded_by() for Clang's context analysis.
Signed-off-by: Timothy Day <timday@thelustrecollective.com>
---
fs/ext2/ext2.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index c8bf2e69675d..ecca898653eb 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -77,8 +77,8 @@ struct ext2_sb_info {
unsigned long s_gdb_count; /* Number of group descriptor blocks */
unsigned long s_desc_per_block; /* Number of group descriptors per block */
unsigned long s_groups_count; /* Number of groups in the fs */
- unsigned long s_overhead_last; /* Last calculated overhead */
- unsigned long s_blocks_last; /* Last seen block count */
+ unsigned long s_overhead_last __guarded_by(&s_lock); /* Last calculated overhead */
+ unsigned long s_blocks_last __guarded_by(&s_lock); /* Last seen block count */
struct buffer_head * s_sbh; /* Buffer containing the super block */
struct ext2_super_block * s_es; /* Pointer to the super block in the buffer */
struct buffer_head ** s_group_desc;
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v2 4/8] ext2: mark s_mount_state as guarded by s_lock
2026-08-11 16:03 [PATCH v2 0/8] Support Clang context analysis for ext2 Timothy Day
` (2 preceding siblings ...)
2026-08-11 16:03 ` [PATCH v2 3/8] ext2: mark statfs overhead cache as guarded by s_lock Timothy Day
@ 2026-08-11 16:03 ` Timothy Day
2026-08-11 16:03 ` [PATCH v2 5/8] ext2: annotate ext2_init_block_alloc_info() as requiring truncate_mutex Timothy Day
` (5 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Timothy Day @ 2026-08-11 16:03 UTC (permalink / raw)
To: linux-ext4
Cc: Jan Kara, Marco Elver, Theodore Tso, linux-fsdevel, linux-kernel,
Timothy Day
s_mount_state tracks the filesystem's mount/error state and is protected
by s_lock everywhere it is accessed. Annotate it with __guarded_by() for
Clang's context analysis.
ext2_setup_super() reads s_mount_state and is called with s_lock held
from the remount path, so annotate it with __must_hold().
There are two accesses (the initial read in ext2_fill_super() and the
setup_super() call) in the mount flow. This is before the superblock
is live, so no concurrent access should be possible. Convert the
spinlock initialization to use guard(spinlock_init) to prevent
warnings on the writes later in initialization.
Signed-off-by: Timothy Day <timday@thelustrecollective.com>
---
fs/ext2/ext2.h | 2 +-
fs/ext2/super.c | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index ecca898653eb..4c30d6f5c972 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -86,7 +86,7 @@ struct ext2_sb_info {
unsigned long s_sb_block;
kuid_t s_resuid;
kgid_t s_resgid;
- unsigned short s_mount_state;
+ unsigned short s_mount_state __guarded_by(&s_lock);
unsigned short s_pad;
int s_addr_per_block_bits;
int s_desc_per_block_bits;
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 5bf63943828b..0fa7914e5f04 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -633,6 +633,7 @@ static int ext2_parse_param(struct fs_context *fc, struct fs_parameter *param)
static int ext2_setup_super (struct super_block * sb,
struct ext2_super_block * es,
int read_only)
+ __must_hold(&EXT2_SB(sb)->s_lock)
{
int res = 0;
struct ext2_sb_info *sbi = EXT2_SB(sb);
@@ -894,7 +895,7 @@ static int ext2_fill_super(struct super_block *sb, struct fs_context *fc)
sb->s_fs_info = sbi;
sbi->s_sb_block = sb_block;
- spin_lock_init(&sbi->s_lock);
+ guard(spinlock_init)(&EXT2_SB(sb)->s_lock);
ret = -EINVAL;
/*
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v2 5/8] ext2: annotate ext2_init_block_alloc_info() as requiring truncate_mutex
2026-08-11 16:03 [PATCH v2 0/8] Support Clang context analysis for ext2 Timothy Day
` (3 preceding siblings ...)
2026-08-11 16:03 ` [PATCH v2 4/8] ext2: mark s_mount_state " Timothy Day
@ 2026-08-11 16:03 ` Timothy Day
2026-08-11 16:03 ` [PATCH v2 6/8] ext2: annotate block-mapping helpers " Timothy Day
` (4 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Timothy Day @ 2026-08-11 16:03 UTC (permalink / raw)
To: linux-ext4
Cc: Jan Kara, Marco Elver, Theodore Tso, linux-fsdevel, linux-kernel,
Timothy Day
ext2_init_block_alloc_info() sets up the inode's block reservation info
and is already documented as needing truncate_mutex protection. Express
that with __must_hold() for Clang's context analysis.
Both callers (ext2_get_blocks() and ext2_ioctl()) already hold
truncate_mutex.
Signed-off-by: Timothy Day <timday@thelustrecollective.com>
---
fs/ext2/balloc.c | 1 +
fs/ext2/ext2.h | 3 ++-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c
index adf0f31fbddd..53c91cb38bde 100644
--- a/fs/ext2/balloc.c
+++ b/fs/ext2/balloc.c
@@ -414,6 +414,7 @@ static inline int rsv_is_empty(struct ext2_reserve_window *rsv)
* Needs truncate_mutex protection prior to calling this function.
*/
void ext2_init_block_alloc_info(struct inode *inode)
+ __must_hold(&EXT2_I(inode)->truncate_mutex)
{
struct ext2_inode_info *ei = EXT2_I(inode);
struct ext2_block_alloc_info *block_i;
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index 4c30d6f5c972..b6ae29b2e6ec 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -710,7 +710,8 @@ extern struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb,
struct buffer_head ** bh);
extern void ext2_discard_reservation (struct inode *);
extern int ext2_should_retry_alloc(struct super_block *sb, int *retries);
-extern void ext2_init_block_alloc_info(struct inode *);
+extern void ext2_init_block_alloc_info(struct inode *inode)
+ __must_hold(&EXT2_I(inode)->truncate_mutex);
extern void ext2_rsv_window_add(struct super_block *sb, struct ext2_reserve_window_node *rsv);
/* dir.c */
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v2 6/8] ext2: annotate block-mapping helpers as requiring truncate_mutex
2026-08-11 16:03 [PATCH v2 0/8] Support Clang context analysis for ext2 Timothy Day
` (4 preceding siblings ...)
2026-08-11 16:03 ` [PATCH v2 5/8] ext2: annotate ext2_init_block_alloc_info() as requiring truncate_mutex Timothy Day
@ 2026-08-11 16:03 ` Timothy Day
2026-08-11 16:03 ` [PATCH v2 7/8] ext2: annotate s_rsv_window_root as requiring s_rsv_window_lock Timothy Day
` (3 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Timothy Day @ 2026-08-11 16:03 UTC (permalink / raw)
To: linux-ext4
Cc: Jan Kara, Marco Elver, Theodore Tso, linux-fsdevel, linux-kernel,
Timothy Day
The indirect-block mapping helpers in inode.c all run under the
inode's truncate_mutex.
ext2_find_goal(), ext2_alloc_blocks(), ext2_alloc_branch() and
ext2_splice_branch() are reached only from ext2_get_blocks() while
it holds the mutex. ext2_find_shared(), ext2_free_data() and
ext2_free_branches() are called from __ext2_truncate_blocks() while
it holds the mutex.
Add __must_hold() annotations for the Clang's context analysis to reflect
this.
Signed-off-by: Timothy Day <timday@thelustrecollective.com>
---
fs/ext2/inode.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 29808629cce5..f0be5236d04e 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -329,6 +329,7 @@ static ext2_fsblk_t ext2_find_near(struct inode *inode, Indirect *ind)
static inline ext2_fsblk_t ext2_find_goal(struct inode *inode, long block,
Indirect *partial)
+ __must_hold(&EXT2_I(inode)->truncate_mutex)
{
struct ext2_block_alloc_info *block_i;
@@ -399,6 +400,7 @@ ext2_blks_to_allocate(Indirect * branch, int k, unsigned long blks,
static int ext2_alloc_blocks(struct inode *inode,
ext2_fsblk_t goal, int indirect_blks, int blks,
ext2_fsblk_t new_blocks[4], int *err)
+ __must_hold(&EXT2_I(inode)->truncate_mutex)
{
int target, i;
unsigned long count = 0;
@@ -479,6 +481,7 @@ static int ext2_alloc_blocks(struct inode *inode,
static int ext2_alloc_branch(struct inode *inode,
int indirect_blks, int *blks, ext2_fsblk_t goal,
int *offsets, Indirect *branch)
+ __must_hold(&EXT2_I(inode)->truncate_mutex)
{
int blocksize = inode->i_sb->s_blocksize;
int i, n = 0;
@@ -560,6 +563,7 @@ static int ext2_alloc_branch(struct inode *inode,
*/
static void ext2_splice_branch(struct inode *inode,
long block, Indirect *where, int num, int blks)
+ __must_hold(&EXT2_I(inode)->truncate_mutex)
{
int i;
struct ext2_block_alloc_info *block_i;
@@ -1002,6 +1006,7 @@ static Indirect *ext2_find_shared(struct inode *inode,
int offsets[4],
Indirect chain[4],
__le32 *top)
+ __must_hold(&EXT2_I(inode)->truncate_mutex)
{
Indirect *partial, *p;
int k, err;
@@ -1057,6 +1062,7 @@ static Indirect *ext2_find_shared(struct inode *inode,
* appropriately.
*/
static inline void ext2_free_data(struct inode *inode, __le32 *p, __le32 *q)
+ __must_hold(&EXT2_I(inode)->truncate_mutex)
{
ext2_fsblk_t block_to_free = 0, count = 0;
ext2_fsblk_t nr;
@@ -1097,6 +1103,7 @@ static inline void ext2_free_data(struct inode *inode, __le32 *p, __le32 *q)
* appropriately.
*/
static void ext2_free_branches(struct inode *inode, __le32 *p, __le32 *q, int depth)
+ __must_hold(&EXT2_I(inode)->truncate_mutex)
{
struct buffer_head * bh;
ext2_fsblk_t nr;
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v2 7/8] ext2: annotate s_rsv_window_root as requiring s_rsv_window_lock
2026-08-11 16:03 [PATCH v2 0/8] Support Clang context analysis for ext2 Timothy Day
` (5 preceding siblings ...)
2026-08-11 16:03 ` [PATCH v2 6/8] ext2: annotate block-mapping helpers " Timothy Day
@ 2026-08-11 16:03 ` Timothy Day
2026-08-11 16:03 ` [PATCH v2 8/8] ext2: enable context analysis support for ext2 filesystem Timothy Day
` (2 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Timothy Day @ 2026-08-11 16:03 UTC (permalink / raw)
To: linux-ext4
Cc: Jan Kara, Marco Elver, Theodore Tso, linux-fsdevel, linux-kernel,
Timothy Day
The per-filesystem reservation window rb-tree (s_rsv_window_root) is
protected by s_rsv_window_lock. Mark the s_rsv_window_root field
with __guarded_by() for Clang's context analysis.
The helpers (ext2_rsv_window_add, rsv_window_remove, and
find_next_reservable_window) that mutate or walk the tree are all
called with the s_rsv_window_lock held. Annotate these helpers
with __must_hold().
The accesses in ext2_fill_super() are before the superblock is live.
Since no concurrent access should be possible, s_rsv_window_lock
is not taken. Convert the spinlock initialization to use
scoped_guard(spinlock_init, ...) and place the writes under the
guard to prevent warnings.
Signed-off-by: Timothy Day <timday@thelustrecollective.com>
---
fs/ext2/balloc.c | 3 +++
fs/ext2/ext2.h | 5 +++--
fs/ext2/super.c | 27 ++++++++++++++-------------
3 files changed, 20 insertions(+), 15 deletions(-)
diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c
index 53c91cb38bde..80acc1e19387 100644
--- a/fs/ext2/balloc.c
+++ b/fs/ext2/balloc.c
@@ -334,6 +334,7 @@ search_reserve_window(struct rb_root *root, ext2_fsblk_t goal)
*/
void ext2_rsv_window_add(struct super_block *sb,
struct ext2_reserve_window_node *rsv)
+ __must_hold(&EXT2_SB(sb)->s_rsv_window_lock)
{
struct rb_root *root = &EXT2_SB(sb)->s_rsv_window_root;
struct rb_node *node = &rsv->rsv_node;
@@ -373,6 +374,7 @@ void ext2_rsv_window_add(struct super_block *sb,
*/
static void rsv_window_remove(struct super_block *sb,
struct ext2_reserve_window_node *rsv)
+ __must_hold(&EXT2_SB(sb)->s_rsv_window_lock)
{
rsv->rsv_start = EXT2_RESERVE_WINDOW_NOT_ALLOCATED;
rsv->rsv_end = EXT2_RESERVE_WINDOW_NOT_ALLOCATED;
@@ -759,6 +761,7 @@ static int find_next_reservable_window(
struct super_block * sb,
ext2_fsblk_t start_block,
ext2_fsblk_t last_block)
+ __must_hold(&EXT2_SB(sb)->s_rsv_window_lock)
{
struct rb_node *next;
struct ext2_reserve_window_node *rsv, *prev;
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index b6ae29b2e6ec..404f4223a6bd 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -102,7 +102,7 @@ struct ext2_sb_info {
struct blockgroup_lock *s_blockgroup_lock;
/* root of the per fs reservation window tree */
spinlock_t s_rsv_window_lock;
- struct rb_root s_rsv_window_root;
+ struct rb_root s_rsv_window_root __guarded_by(&s_rsv_window_lock);
struct ext2_reserve_window_node s_rsv_window_head;
/*
* s_lock protects against concurrent modifications of s_mount_state,
@@ -712,7 +712,8 @@ extern void ext2_discard_reservation (struct inode *);
extern int ext2_should_retry_alloc(struct super_block *sb, int *retries);
extern void ext2_init_block_alloc_info(struct inode *inode)
__must_hold(&EXT2_I(inode)->truncate_mutex);
-extern void ext2_rsv_window_add(struct super_block *sb, struct ext2_reserve_window_node *rsv);
+extern void ext2_rsv_window_add(struct super_block *sb, struct ext2_reserve_window_node *rsv)
+ __must_hold(&EXT2_SB(sb)->s_rsv_window_lock);
/* dir.c */
int ext2_add_link(struct dentry *, struct inode *);
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 0fa7914e5f04..b7f042e42009 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -1131,19 +1131,20 @@ static int ext2_fill_super(struct super_block *sb, struct fs_context *fc)
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;
- /*
- * Add a single, static dummy reservation to the start of the
- * reservation window list --- it gives us a placeholder for
- * append-at-start-of-list which makes the allocation logic
- * _much_ simpler.
- */
- sbi->s_rsv_window_head.rsv_start = EXT2_RESERVE_WINDOW_NOT_ALLOCATED;
- sbi->s_rsv_window_head.rsv_end = EXT2_RESERVE_WINDOW_NOT_ALLOCATED;
- sbi->s_rsv_window_head.rsv_alloc_hit = 0;
- sbi->s_rsv_window_head.rsv_goal_size = 0;
- ext2_rsv_window_add(sb, &sbi->s_rsv_window_head);
+ scoped_guard(spinlock_init, &EXT2_SB(sb)->s_rsv_window_lock) {
+ sbi->s_rsv_window_root = RB_ROOT;
+ /*
+ * Add a single, static dummy reservation to the start of the
+ * reservation window list --- it gives us a placeholder for
+ * append-at-start-of-list which makes the allocation logic
+ * _much_ simpler.
+ */
+ sbi->s_rsv_window_head.rsv_start = EXT2_RESERVE_WINDOW_NOT_ALLOCATED;
+ sbi->s_rsv_window_head.rsv_end = EXT2_RESERVE_WINDOW_NOT_ALLOCATED;
+ sbi->s_rsv_window_head.rsv_alloc_hit = 0;
+ sbi->s_rsv_window_head.rsv_goal_size = 0;
+ ext2_rsv_window_add(sb, &sbi->s_rsv_window_head);
+ }
err = percpu_counter_init(&sbi->s_freeblocks_counter,
ext2_count_free_blocks(sb), GFP_KERNEL);
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH v2 8/8] ext2: enable context analysis support for ext2 filesystem
2026-08-11 16:03 [PATCH v2 0/8] Support Clang context analysis for ext2 Timothy Day
` (6 preceding siblings ...)
2026-08-11 16:03 ` [PATCH v2 7/8] ext2: annotate s_rsv_window_root as requiring s_rsv_window_lock Timothy Day
@ 2026-08-11 16:03 ` Timothy Day
2026-08-12 11:14 ` [PATCH v2 0/8] Support Clang context analysis for ext2 Marco Elver
2026-08-18 9:58 ` Jan Kara
9 siblings, 0 replies; 16+ messages in thread
From: Timothy Day @ 2026-08-11 16:03 UTC (permalink / raw)
To: linux-ext4
Cc: Jan Kara, Marco Elver, Theodore Tso, linux-fsdevel, linux-kernel,
Timothy Day
Update ext2 Makefile to support context analysis [1].
[1] https://docs.kernel.org/dev-tools/context-analysis.html
Signed-off-by: Timothy Day <timday@thelustrecollective.com>
---
fs/ext2/Makefile | 2 ++
1 file changed, 2 insertions(+)
diff --git a/fs/ext2/Makefile b/fs/ext2/Makefile
index 8860948ef9ca..33db2e9dc908 100644
--- a/fs/ext2/Makefile
+++ b/fs/ext2/Makefile
@@ -3,6 +3,8 @@
# Makefile for the linux ext2-filesystem routines.
#
+CONTEXT_ANALYSIS := y
+
obj-$(CONFIG_EXT2_FS) += ext2.o
ext2-y := balloc.o dir.o file.o ialloc.o inode.o \
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* Re: [PATCH v2 0/8] Support Clang context analysis for ext2
2026-08-11 16:03 [PATCH v2 0/8] Support Clang context analysis for ext2 Timothy Day
` (7 preceding siblings ...)
2026-08-11 16:03 ` [PATCH v2 8/8] ext2: enable context analysis support for ext2 filesystem Timothy Day
@ 2026-08-12 11:14 ` Marco Elver
2026-08-18 9:58 ` Jan Kara
9 siblings, 0 replies; 16+ messages in thread
From: Marco Elver @ 2026-08-12 11:14 UTC (permalink / raw)
To: Timothy Day
Cc: linux-ext4, Jan Kara, Theodore Tso, linux-fsdevel, linux-kernel
On Tue, 11 Aug 2026 at 18:04, Timothy Day
<timday@thelustrecollective.com> wrote:
>
> This description is mostly copied from v1:
>
> This series adds annotations for Clang's context analysis to ext2.
> Clang context analysis was recently added in a series by Marco
> Elver [1]. This allows the compiler to validate different
> locking patterns at compile time.
>
> This series enables context analysis, fixes pre-existing warnings,
> and adds new annotations. It is inspired by similar series in the
> block layer (NVMe host driver, for example [2]).
>
> I'm starting with ext2 since it's smaller and simpler compared to
> ext4/btrfs/etc. After ext2, I'd be interested in converting the
> other filesystems and infrastructure code in fs/. I think the ultimate
> goal would be to enable this by default across all of fs/.
>
> The series was built and tested with Clang 23 with
> CONFIG_WARN_CONTEXT_ANALYSIS enabled. I based on 7.2-rc7.
>
> Thanks!
>
> Changes from v1:
>
> * A false positive has been fixed in Clang [3] and ported to Clang 23.
> Hence, the first patch (silencing that false positive) has been dropped.
> * Use guard() and scoped_guard() instead of context_unsafe(), when
> possible, to express that certain fields are being protected by a newly
> initialized lock during init.
Acked-by: Marco Elver <elver@google.com>
But ultimately up to maintainers. Also, thanks for helping improve the
Clang side (FWIW, Clang 23 will release August 23)!
> Link to v1: https://lore.kernel.org/linux-fsdevel/20260712165610.366474-1-timday@thelustrecollective.com/
>
> [1] https://lore.kernel.org/lkml/20251219154418.3592607-1-elver@google.com/
> [2] https://lore.kernel.org/all/20260706141452.3008233-1-nilay@linux.ibm.com/
> [3] https://github.com/llvm/llvm-project/pull/209796
>
> Timothy Day (8):
> ext2: mark s_next_generation as guarded by s_next_gen_lock
> ext2: annotate ext2_update_dynamic_rev() as requiring s_lock
> ext2: mark statfs overhead cache as guarded by s_lock
> ext2: mark s_mount_state as guarded by s_lock
> ext2: annotate ext2_init_block_alloc_info() as requiring
> truncate_mutex
> ext2: annotate block-mapping helpers as requiring truncate_mutex
> ext2: annotate s_rsv_window_root as requiring s_rsv_window_lock
> ext2: enable context analysis support for ext2 filesystem
>
> fs/ext2/Makefile | 2 ++
> fs/ext2/balloc.c | 4 ++++
> fs/ext2/ext2.h | 19 +++++++++++--------
> fs/ext2/inode.c | 7 +++++++
> fs/ext2/super.c | 35 +++++++++++++++++++----------------
> 5 files changed, 43 insertions(+), 24 deletions(-)
>
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [PATCH v2 0/8] Support Clang context analysis for ext2
2026-08-11 16:03 [PATCH v2 0/8] Support Clang context analysis for ext2 Timothy Day
` (8 preceding siblings ...)
2026-08-12 11:14 ` [PATCH v2 0/8] Support Clang context analysis for ext2 Marco Elver
@ 2026-08-18 9:58 ` Jan Kara
2026-09-03 7:27 ` Nathan Chancellor
9 siblings, 1 reply; 16+ messages in thread
From: Jan Kara @ 2026-08-18 9:58 UTC (permalink / raw)
To: Timothy Day
Cc: linux-ext4, Jan Kara, Marco Elver, Theodore Tso, linux-fsdevel,
linux-kernel
Hello!
On Tue 11-08-26 12:03:28, Timothy Day wrote:
> This description is mostly copied from v1:
>
> This series adds annotations for Clang's context analysis to ext2.
> Clang context analysis was recently added in a series by Marco
> Elver [1]. This allows the compiler to validate different
> locking patterns at compile time.
>
> This series enables context analysis, fixes pre-existing warnings,
> and adds new annotations. It is inspired by similar series in the
> block layer (NVMe host driver, for example [2]).
>
> I'm starting with ext2 since it's smaller and simpler compared to
> ext4/btrfs/etc. After ext2, I'd be interested in converting the
> other filesystems and infrastructure code in fs/. I think the ultimate
> goal would be to enable this by default across all of fs/.
>
> The series was built and tested with Clang 23 with
> CONFIG_WARN_CONTEXT_ANALYSIS enabled. I based on 7.2-rc7.
Thanks for the patches! They look good to me. Once the merge window is over
I'll queue them to my tree. The only thing I'm not fully sure is how much I
like the spinlock_init scoped guards - they looked quite confusing to me at
the first sight (as much as I understand the convenience, conceptually how
can initialization of a global lock be scoped?). I'll sleep over it, maybe
I'll change them to just spinlock_init() + scoped_guard for the lock itself
or maybe I'll get used to them. Anyway, no action on your side needed :).
Honza
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [PATCH v2 0/8] Support Clang context analysis for ext2
2026-08-18 9:58 ` Jan Kara
@ 2026-09-03 7:27 ` Nathan Chancellor
2026-09-03 10:34 ` Marco Elver
0 siblings, 1 reply; 16+ messages in thread
From: Nathan Chancellor @ 2026-09-03 7:27 UTC (permalink / raw)
To: Jan Kara
Cc: Timothy Day, linux-ext4, Jan Kara, Marco Elver, Theodore Tso,
linux-fsdevel, linux-kernel
On Tue, Aug 18, 2026 at 11:58:20AM +0200, Jan Kara wrote:
> On Tue 11-08-26 12:03:28, Timothy Day wrote:
> > This description is mostly copied from v1:
> >
> > This series adds annotations for Clang's context analysis to ext2.
> > Clang context analysis was recently added in a series by Marco
> > Elver [1]. This allows the compiler to validate different
> > locking patterns at compile time.
> >
> > This series enables context analysis, fixes pre-existing warnings,
> > and adds new annotations. It is inspired by similar series in the
> > block layer (NVMe host driver, for example [2]).
> >
> > I'm starting with ext2 since it's smaller and simpler compared to
> > ext4/btrfs/etc. After ext2, I'd be interested in converting the
> > other filesystems and infrastructure code in fs/. I think the ultimate
> > goal would be to enable this by default across all of fs/.
> >
> > The series was built and tested with Clang 23 with
> > CONFIG_WARN_CONTEXT_ANALYSIS enabled. I based on 7.2-rc7.
>
> Thanks for the patches! They look good to me. Once the merge window is over
> I'll queue them to my tree. The only thing I'm not fully sure is how much I
> like the spinlock_init scoped guards - they looked quite confusing to me at
> the first sight (as much as I understand the convenience, conceptually how
> can initialization of a global lock be scoped?). I'll sleep over it, maybe
> I'll change them to just spinlock_init() + scoped_guard for the lock itself
> or maybe I'll get used to them. Anyway, no action on your side needed :).
This series is now in -next, where I see the following warnings (or errors with
CONFIG_WERROR=y / W=e) with various configurations, such as ARCH=arm
allmodconfig, when building with LLVM 23.1.0
fs/ext2/xattr.c:825:6: error: rw_semaphore 'EXT2_I().xattr_sem' is not held on every path through here [-Werror,-Wthread-safety-analysis]
825 | if (WARN_ON_ONCE(!down_write_trylock(&EXT2_I(inode)->xattr_sem)))
| ^
include/asm-generic/bug.h:180:2: note: expanded from macro 'WARN_ON_ONCE'
180 | DO_ONCE_LITE_IF(condition, WARN_ON, 1)
| ^
include/linux/once_lite.h:30:7: note: expanded from macro 'DO_ONCE_LITE_IF'
30 | if (__ONCE_LITE_IF(__ret_do_once)) \
| ^
include/linux/once_lite.h:23:3: note: expanded from macro '__ONCE_LITE_IF'
23 | unlikely(__ret_once); \
| ^
include/linux/compiler.h:77:22: note: expanded from macro 'unlikely'
77 | # define unlikely(x) __builtin_expect(!!(x), 0)
| ^
fs/ext2/xattr.c:825:20: note: rw_semaphore acquired here
825 | if (WARN_ON_ONCE(!down_write_trylock(&EXT2_I(inode)->xattr_sem)))
| ^
fs/ext2/super.c:1149:3: error: calling function 'ext2_rsv_window_add' requires holding spinlock 'EXT2_SB(sb).s_rsv_window_lock' exclusively [-Werror,-Wthread-safety-precise]
1149 | ext2_rsv_window_add(sb, &sbi->s_rsv_window_head);
| ^
fs/ext2/super.c:1149:3: note: found near match '_res->s_rsv_window_lock'
--
Cheers,
Nathan
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [PATCH v2 0/8] Support Clang context analysis for ext2
2026-09-03 7:27 ` Nathan Chancellor
@ 2026-09-03 10:34 ` Marco Elver
2026-09-03 11:06 ` Jan Kara
0 siblings, 1 reply; 16+ messages in thread
From: Marco Elver @ 2026-09-03 10:34 UTC (permalink / raw)
To: Nathan Chancellor
Cc: Jan Kara, Timothy Day, linux-ext4, Jan Kara, Theodore Tso,
linux-fsdevel, linux-kernel
On Thu, 3 Sept 2026 at 09:28, Nathan Chancellor <nathan@kernel.org> wrote:
> On Tue, Aug 18, 2026 at 11:58:20AM +0200, Jan Kara wrote:
> > On Tue 11-08-26 12:03:28, Timothy Day wrote:
> > > This description is mostly copied from v1:
> > >
> > > This series adds annotations for Clang's context analysis to ext2.
> > > Clang context analysis was recently added in a series by Marco
> > > Elver [1]. This allows the compiler to validate different
> > > locking patterns at compile time.
> > >
> > > This series enables context analysis, fixes pre-existing warnings,
> > > and adds new annotations. It is inspired by similar series in the
> > > block layer (NVMe host driver, for example [2]).
> > >
> > > I'm starting with ext2 since it's smaller and simpler compared to
> > > ext4/btrfs/etc. After ext2, I'd be interested in converting the
> > > other filesystems and infrastructure code in fs/. I think the ultimate
> > > goal would be to enable this by default across all of fs/.
> > >
> > > The series was built and tested with Clang 23 with
> > > CONFIG_WARN_CONTEXT_ANALYSIS enabled. I based on 7.2-rc7.
> >
> > Thanks for the patches! They look good to me. Once the merge window is over
> > I'll queue them to my tree. The only thing I'm not fully sure is how much I
> > like the spinlock_init scoped guards - they looked quite confusing to me at
> > the first sight (as much as I understand the convenience, conceptually how
> > can initialization of a global lock be scoped?). I'll sleep over it, maybe
> > I'll change them to just spinlock_init() + scoped_guard for the lock itself
> > or maybe I'll get used to them. Anyway, no action on your side needed :).
>
> This series is now in -next, where I see the following warnings (or errors with
> CONFIG_WERROR=y / W=e) with various configurations, such as ARCH=arm
> allmodconfig, when building with LLVM 23.1.0
>
> fs/ext2/xattr.c:825:6: error: rw_semaphore 'EXT2_I().xattr_sem' is not held on every path through here [-Werror,-Wthread-safety-analysis]
> 825 | if (WARN_ON_ONCE(!down_write_trylock(&EXT2_I(inode)->xattr_sem)))
> | ^
> include/asm-generic/bug.h:180:2: note: expanded from macro 'WARN_ON_ONCE'
> 180 | DO_ONCE_LITE_IF(condition, WARN_ON, 1)
> | ^
> include/linux/once_lite.h:30:7: note: expanded from macro 'DO_ONCE_LITE_IF'
> 30 | if (__ONCE_LITE_IF(__ret_do_once)) \
> | ^
> include/linux/once_lite.h:23:3: note: expanded from macro '__ONCE_LITE_IF'
> 23 | unlikely(__ret_once); \
> | ^
> include/linux/compiler.h:77:22: note: expanded from macro 'unlikely'
> 77 | # define unlikely(x) __builtin_expect(!!(x), 0)
> | ^
> fs/ext2/xattr.c:825:20: note: rw_semaphore acquired here
> 825 | if (WARN_ON_ONCE(!down_write_trylock(&EXT2_I(inode)->xattr_sem)))
> | ^
This one can be fixed with (should also be a bit more efficient):
https://lore.kernel.org/all/20260903101843.3462767-1-elver@google.com/
> fs/ext2/super.c:1149:3: error: calling function 'ext2_rsv_window_add' requires holding spinlock 'EXT2_SB(sb).s_rsv_window_lock' exclusively [-Werror,-Wthread-safety-precise]
> 1149 | ext2_rsv_window_add(sb, &sbi->s_rsv_window_head);
> | ^
> fs/ext2/super.c:1149:3: note: found near match '_res->s_rsv_window_lock'
sbi was just allocated, and EXT2_SB(sb) and sbi are pointing to the
same object (unless I misread the code), but the compiler can't tell
since aliases can't be tracked through non-local objects. So that
scoped_guard could just become:
scoped_guard(spinlock, &EXT2_SB(sb)->s_rsv_window_lock) {
...
But I'll leave that to Jan and Tim.
Thanks,
-- Marco
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [PATCH v2 0/8] Support Clang context analysis for ext2
2026-09-03 10:34 ` Marco Elver
@ 2026-09-03 11:06 ` Jan Kara
2026-09-03 12:06 ` Marco Elver
0 siblings, 1 reply; 16+ messages in thread
From: Jan Kara @ 2026-09-03 11:06 UTC (permalink / raw)
To: Marco Elver
Cc: Nathan Chancellor, Jan Kara, Timothy Day, linux-ext4, Jan Kara,
Theodore Tso, linux-fsdevel, linux-kernel
On Thu 03-09-26 12:34:34, Marco Elver wrote:
> On Thu, 3 Sept 2026 at 09:28, Nathan Chancellor <nathan@kernel.org> wrote:
> > fs/ext2/super.c:1149:3: error: calling function 'ext2_rsv_window_add' requires holding spinlock 'EXT2_SB(sb).s_rsv_window_lock' exclusively [-Werror,-Wthread-safety-precise]
> > 1149 | ext2_rsv_window_add(sb, &sbi->s_rsv_window_head);
> > | ^
> > fs/ext2/super.c:1149:3: note: found near match '_res->s_rsv_window_lock'
>
> sbi was just allocated, and EXT2_SB(sb) and sbi are pointing to the
> same object (unless I misread the code), but the compiler can't tell
> since aliases can't be tracked through non-local objects. So that
> scoped_guard could just become:
>
> scoped_guard(spinlock, &EXT2_SB(sb)->s_rsv_window_lock) {
> ...
>
> But I'll leave that to Jan and Tim.
Yes, at the beginning of ext4_fill_super() we do:
sbi = kzalloc_obj(*sbi);
...
sb->s_fs_info = sbi;
and EXT2_SB(sb) is just sb->s_fs_info. Are you saying that clang is not
able to infer that sb->s_fs_info and sbi are still pointing to the same
memory later in the function where we do scoped_guard()?
Honza
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [PATCH v2 0/8] Support Clang context analysis for ext2
2026-09-03 11:06 ` Jan Kara
@ 2026-09-03 12:06 ` Marco Elver
2026-09-03 12:43 ` Jan Kara
0 siblings, 1 reply; 16+ messages in thread
From: Marco Elver @ 2026-09-03 12:06 UTC (permalink / raw)
To: Jan Kara
Cc: Nathan Chancellor, Timothy Day, linux-ext4, Jan Kara,
Theodore Tso, linux-fsdevel, linux-kernel
On Thu, 3 Sept 2026 at 13:06, Jan Kara <jack@suse.cz> wrote:
>
> On Thu 03-09-26 12:34:34, Marco Elver wrote:
> > On Thu, 3 Sept 2026 at 09:28, Nathan Chancellor <nathan@kernel.org> wrote:
> > > fs/ext2/super.c:1149:3: error: calling function 'ext2_rsv_window_add' requires holding spinlock 'EXT2_SB(sb).s_rsv_window_lock' exclusively [-Werror,-Wthread-safety-precise]
> > > 1149 | ext2_rsv_window_add(sb, &sbi->s_rsv_window_head);
> > > | ^
> > > fs/ext2/super.c:1149:3: note: found near match '_res->s_rsv_window_lock'
> >
> > sbi was just allocated, and EXT2_SB(sb) and sbi are pointing to the
> > same object (unless I misread the code), but the compiler can't tell
> > since aliases can't be tracked through non-local objects. So that
> > scoped_guard could just become:
> >
> > scoped_guard(spinlock, &EXT2_SB(sb)->s_rsv_window_lock) {
> > ...
> >
> > But I'll leave that to Jan and Tim.
>
> Yes, at the beginning of ext4_fill_super() we do:
>
> sbi = kzalloc_obj(*sbi);
> ...
> sb->s_fs_info = sbi;
>
> and EXT2_SB(sb) is just sb->s_fs_info. Are you saying that clang is not
> able to infer that sb->s_fs_info and sbi are still pointing to the same
> memory later in the function where we do scoped_guard()?
Yes - alias tracking is only done through local aliases. sb is
non-local, along with additional member indirection; unfortunately,
the C language doesn't give us the guarantees that it wasn't modified
somewhere in between, say after a function call (this rule is applied
also for local aliases if clang sees that they "escape" their local
scope via non-const pointer to pointer).
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [PATCH v2 0/8] Support Clang context analysis for ext2
2026-09-03 12:06 ` Marco Elver
@ 2026-09-03 12:43 ` Jan Kara
0 siblings, 0 replies; 16+ messages in thread
From: Jan Kara @ 2026-09-03 12:43 UTC (permalink / raw)
To: Marco Elver
Cc: Jan Kara, Nathan Chancellor, Timothy Day, linux-ext4, Jan Kara,
Theodore Tso, linux-fsdevel, linux-kernel
On Thu 03-09-26 14:06:22, Marco Elver wrote:
> On Thu, 3 Sept 2026 at 13:06, Jan Kara <jack@suse.cz> wrote:
> >
> > On Thu 03-09-26 12:34:34, Marco Elver wrote:
> > > On Thu, 3 Sept 2026 at 09:28, Nathan Chancellor <nathan@kernel.org> wrote:
> > > > fs/ext2/super.c:1149:3: error: calling function 'ext2_rsv_window_add' requires holding spinlock 'EXT2_SB(sb).s_rsv_window_lock' exclusively [-Werror,-Wthread-safety-precise]
> > > > 1149 | ext2_rsv_window_add(sb, &sbi->s_rsv_window_head);
> > > > | ^
> > > > fs/ext2/super.c:1149:3: note: found near match '_res->s_rsv_window_lock'
> > >
> > > sbi was just allocated, and EXT2_SB(sb) and sbi are pointing to the
> > > same object (unless I misread the code), but the compiler can't tell
> > > since aliases can't be tracked through non-local objects. So that
> > > scoped_guard could just become:
> > >
> > > scoped_guard(spinlock, &EXT2_SB(sb)->s_rsv_window_lock) {
> > > ...
> > >
> > > But I'll leave that to Jan and Tim.
> >
> > Yes, at the beginning of ext4_fill_super() we do:
> >
> > sbi = kzalloc_obj(*sbi);
> > ...
> > sb->s_fs_info = sbi;
> >
> > and EXT2_SB(sb) is just sb->s_fs_info. Are you saying that clang is not
> > able to infer that sb->s_fs_info and sbi are still pointing to the same
> > memory later in the function where we do scoped_guard()?
>
> Yes - alias tracking is only done through local aliases. sb is
> non-local, along with additional member indirection; unfortunately,
> the C language doesn't give us the guarantees that it wasn't modified
> somewhere in between, say after a function call (this rule is applied
> also for local aliases if clang sees that they "escape" their local
> scope via non-const pointer to pointer).
Hrm, ok, understood (but still it's annoying ;)). I've pushed out the patch
with the suggested fixup.
Honza
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 16+ messages in thread