[PATCH] btrfs: protect sb_write_pointer() with invalidate lock

KangNing Liao posted 1 patch 3 days, 7 hours ago
fs/btrfs/zoned.c | 2 ++
1 file changed, 2 insertions(+)
[PATCH] btrfs: protect sb_write_pointer() with invalidate lock
Posted by KangNing Liao 3 days, 7 hours ago
sb_write_pointer() reads the super block from the block device page cache
using read_cache_page_gfp(). This has the same race with BLKBSZSET as the
one fixed by commit 3f29d661e568 ("btrfs: sync read disk super and set
block size").

Take the mapping invalidate lock around read_cache_page_gfp() to
serialize the read against block size changes.

Signed-off-by: KangNing Liao <lkangn.kernel@gmail.com>
---
 fs/btrfs/zoned.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c
index 16dd87aa06f2..5f75cf0e14b9 100644
--- a/fs/btrfs/zoned.c
+++ b/fs/btrfs/zoned.c
@@ -131,8 +131,10 @@ static int sb_write_pointer(struct block_device *bdev, struct blk_zone *zones,
 			u64 bytenr = ALIGN_DOWN(zone_end, BTRFS_SUPER_INFO_SIZE) -
 						BTRFS_SUPER_INFO_SIZE;
 
+			filemap_invalidate_lock(mapping);
 			page[i] = read_cache_page_gfp(mapping,
 					bytenr >> PAGE_SHIFT, GFP_NOFS);
+			filemap_invalidate_unlock(mapping);
 			if (IS_ERR(page[i])) {
 				if (i == 1)
 					btrfs_release_disk_super(super[0]);
-- 
2.54.0
Re: [PATCH] btrfs: protect sb_write_pointer() with invalidate lock
Posted by Qu Wenruo 2 days, 21 hours ago

在 2026/5/21 21:59, KangNing Liao 写道:
> sb_write_pointer() reads the super block from the block device page cache
> using read_cache_page_gfp(). This has the same race with BLKBSZSET as the
> one fixed by commit 3f29d661e568 ("btrfs: sync read disk super and set
> block size").
> 
> Take the mapping invalidate lock around read_cache_page_gfp() to
> serialize the read against block size changes.
> 
> Signed-off-by: KangNing Liao <lkangn.kernel@gmail.com>

Reviewed-by: Qu Wenruo <wqu@suse.com>

Thanks,
Qu

> ---
>   fs/btrfs/zoned.c | 2 ++
>   1 file changed, 2 insertions(+)
> 
> diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c
> index 16dd87aa06f2..5f75cf0e14b9 100644
> --- a/fs/btrfs/zoned.c
> +++ b/fs/btrfs/zoned.c
> @@ -131,8 +131,10 @@ static int sb_write_pointer(struct block_device *bdev, struct blk_zone *zones,
>   			u64 bytenr = ALIGN_DOWN(zone_end, BTRFS_SUPER_INFO_SIZE) -
>   						BTRFS_SUPER_INFO_SIZE;
>   
> +			filemap_invalidate_lock(mapping);
>   			page[i] = read_cache_page_gfp(mapping,
>   					bytenr >> PAGE_SHIFT, GFP_NOFS);
> +			filemap_invalidate_unlock(mapping);
>   			if (IS_ERR(page[i])) {
>   				if (i == 1)
>   					btrfs_release_disk_super(super[0]);