Re: [PATCH v1 0/9] Support Clang context analysis for ext2

From: Timothy Day

Date: Tue Jul 14 2026 - 14:11:42 EST


On Tue, 14 Jul 2026 19:27:38 +0200, Jan Kara wrote:
> On Sun 12-07-26 12:56:01, Timothy Day wrote:
> > 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-rc2 (since the
> > minimum Clang version was recently bumped to 23 in 7.2+ [3]).
> >
> > I'd appreciate reviews and suggestions. I'm especially interested in
> > suggestions on how we can make this easier to enable for other
> > filesystems.
> >
> > Thanks!
>
> Overall this looks sane to me and I kind of like the documentation value of
> __guarded_by and __must_hold annotations. The context_unsafe annotations
> are a bit annoying but I can live with that for now. Just one question: do
> I understand right that the compiler verifies whether the lock is held when
> entering the function marked with __must_hold? So if we get the annotation
> wrong, the compiler will tell us?

Yeah, the compiler will tell us if we got it wrong (so long as you have
CONFIG_WARN_CONTEXT_ANALYSIS=y and Clang 23+). Here's some examples of fake
or wrong mutexes:

PATCH:

diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index f0be5236d04e0..66bcb0c63887f 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -329,7 +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)
+ __must_hold(&EXT2_I(inode)->veryrealmutex)
{
struct ext2_block_alloc_info *block_i;

ERROR:

linux/fs/ext2/inode.c:332:30: error: no member named 'veryrealmutex' in 'struct ext2_inode_info'
332 | __must_hold(&EXT2_I(inode)->veryrealmutex)
| ~~~~~~~~~~~~~ ^

PATCH:

diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index 404f4223a6bdc..dc1f17709aaf6 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -667,6 +667,7 @@ struct ext2_inode_info {
* ext2_reserve_window_node.
*/
struct mutex truncate_mutex;
+ struct mutex real_truncate_mutex;
struct inode vfs_inode;
struct list_head i_orphan; /* unlinked but open inodes */
#ifdef CONFIG_QUOTA
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index f0be5236d04e0..d530fbe50d274 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -329,7 +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)
+ __must_hold(&EXT2_I(inode)->real_truncate_mutex)
{
struct ext2_block_alloc_info *block_i;

ERROR:

linux/fs/ext2/inode.c:726:9: error: calling function 'ext2_find_goal' requires holding \
mutex 'EXT2_I(inode).real_truncate_mutex' exclusively [-Werror,-Wthread-safety-analysis]
726 | goal = ext2_find_goal(inode, iblock, partial);
| ^


Tim Day