diff mbox series

btrfs: zoned: fix full zone SB reading on ZNS

Message ID 1932c39db3905ca491009e9956afe511d7b4767c.1683656399.git.naohiro.aota@wdc.com (mailing list archive)
State New, archived
Headers show
Series btrfs: zoned: fix full zone SB reading on ZNS | expand

Commit Message

Naohiro Aota May 9, 2023, 6:29 p.m. UTC
When both of the superblock zones are full, we need to check which
superblock is newer. The calculation of last superblock position is wrong
as it does not consider zone_capacity. Fix it.

Fixes: 9658b72ef300 ("btrfs: zoned: locate superblock position using zone capacity")
CC: stable@vger.kernel.org # 6.1+
Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
---
 fs/btrfs/zoned.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

Comments

Johannes Thumshirn May 9, 2023, 9:10 p.m. UTC | #1
Looks good,
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
David Sterba May 9, 2023, 10:27 p.m. UTC | #2
On Tue, May 09, 2023 at 06:29:15PM +0000, Naohiro Aota wrote:
> When both of the superblock zones are full, we need to check which
> superblock is newer. The calculation of last superblock position is wrong
> as it does not consider zone_capacity. Fix it.
> 
> Fixes: 9658b72ef300 ("btrfs: zoned: locate superblock position using zone capacity")
> CC: stable@vger.kernel.org # 6.1+
> Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>

Added to misc-next, thanks.

> ---
>  fs/btrfs/zoned.c | 7 +++----
>  1 file changed, 3 insertions(+), 4 deletions(-)
> 
> diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c
> index e3fe02aae641..cd1fee22998c 100644
> --- a/fs/btrfs/zoned.c
> +++ b/fs/btrfs/zoned.c
> @@ -122,10 +122,9 @@ static int sb_write_pointer(struct block_device *bdev, struct blk_zone *zones,
>  		int i;
>  
>  		for (i = 0; i < BTRFS_NR_SB_LOG_ZONES; i++) {
> -			u64 bytenr;
> -
> -			bytenr = ((zones[i].start + zones[i].len)
> -				   << SECTOR_SHIFT) - BTRFS_SUPER_INFO_SIZE;
> +			u64 zone_end = (zones[i].start + zones[i].capacity) << SECTOR_SHIFT;
> +			u64 bytenr = ALIGN_DOWN(zone_end, BTRFS_SUPER_INFO_SIZE) -
> +				BTRFS_SUPER_INFO_SIZE;

I did a quick grep for 'zone.*len' as a wide search for potential
candidates of the same pattern but haven't spotted anything obvious.
With the ZNS support it may be useful to have a helper to read the zone
end in case the real blocks need to be considered, like here.
diff mbox series

Patch

diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c
index e3fe02aae641..cd1fee22998c 100644
--- a/fs/btrfs/zoned.c
+++ b/fs/btrfs/zoned.c
@@ -122,10 +122,9 @@  static int sb_write_pointer(struct block_device *bdev, struct blk_zone *zones,
 		int i;
 
 		for (i = 0; i < BTRFS_NR_SB_LOG_ZONES; i++) {
-			u64 bytenr;
-
-			bytenr = ((zones[i].start + zones[i].len)
-				   << SECTOR_SHIFT) - BTRFS_SUPER_INFO_SIZE;
+			u64 zone_end = (zones[i].start + zones[i].capacity) << SECTOR_SHIFT;
+			u64 bytenr = ALIGN_DOWN(zone_end, BTRFS_SUPER_INFO_SIZE) -
+				BTRFS_SUPER_INFO_SIZE;
 
 			page[i] = read_cache_page_gfp(mapping,
 					bytenr >> PAGE_SHIFT, GFP_NOFS);