[PATCH v1 8/9] ext2: annotate s_rsv_window_root as requiring s_rsv_window_lock
From: Timothy Day
Date: Sun Jul 12 2026 - 13:01:42 EST
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. Hence, wrap these accesses in context_unsafe().
Signed-off-by: Timothy Day <timday@xxxxxxxxxxxxxxxxxxxxxxx>
---
fs/ext2/balloc.c | 3 +++
fs/ext2/ext2.h | 5 +++--
fs/ext2/super.c | 6 ++++--
3 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c
index 53c91cb38bdee..80acc1e193871 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 b6ae29b2e6ec1..404f4223a6bdc 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 a5a5285dd5784..693e59c1aba5a 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -1135,7 +1135,8 @@ static int ext2_fill_super(struct super_block *sb, struct fs_context *fc)
/* per filesystem reservation list head & lock */
spin_lock_init(&sbi->s_rsv_window_lock);
- sbi->s_rsv_window_root = RB_ROOT;
+ /* concurrent access is not possible before the mount completes */
+ context_unsafe(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
@@ -1146,7 +1147,8 @@ static int ext2_fill_super(struct super_block *sb, struct fs_context *fc)
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);
+ /* concurrent access is not possible before the mount completes */
+ context_unsafe(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.39.5