Linux Btrfs filesystem development
 help / color / mirror / Atom feed
* [PATCH 0/2] btrfs-progs: zoned: check existence of SB zone, not LBA
@ 2023-10-12 14:19 Naohiro Aota
  2023-10-12 14:19 ` [PATCH 1/2] btrfs-progs: zoned: introduce sb_bytenr_to_sb_zone() Naohiro Aota
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Naohiro Aota @ 2023-10-12 14:19 UTC (permalink / raw)
  To: linux-btrfs; +Cc: Naohiro Aota

Running btrfs check can fail on a certain zoned decice setup (e.g,
zone size = 128MB, device size = 16GB):

(from generic/330)
yes|/usr/local/bin/btrfs check --repair --force /dev/nullb1
[1/7] checking root items
Fixed 0 roots.
[2/7] checking extents
ERROR: zoned: failed to read zone info of 4096 and 4097: Invalid argument
ERROR: failed to write super block for devid 1: write error: Input/output error
failed to write new super block err -5
failed to repair damaged filesystem, aborting

This happens because write_dev_supers() is comparing the original
superblock location vs the device size to check if it can write out a
superblock copy or not.

For the above example, since the first copy location (64MB) < device size
(16GB), it tries to write out the copy. But, the copy must be written into
zone 4096 (512G / zone size (128M) = 4096), which is out of the device.

To address the issue, this series introduces check_sb_location() to check
if a SB copy can be written out.

The patch 1 is a preparation to factor out logic of converting the original
superblock location to SB log writing superblock zone. And, the second one
implements check_sb_location() to write_dev_supers().

Naohiro Aota (2):
  btrfs-progs: zoned: introduce sb_bytenr_to_sb_zone()
  btrfs-progs: zoned: check SB zone existence properly

 kernel-shared/disk-io.c |  9 ++++++++-
 kernel-shared/zoned.c   | 36 ++++++++++++++++++++++++------------
 kernel-shared/zoned.h   |  6 ++++++
 3 files changed, 38 insertions(+), 13 deletions(-)

-- 
2.42.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/2] btrfs-progs: zoned: introduce sb_bytenr_to_sb_zone()
  2023-10-12 14:19 [PATCH 0/2] btrfs-progs: zoned: check existence of SB zone, not LBA Naohiro Aota
@ 2023-10-12 14:19 ` Naohiro Aota
  2023-10-12 14:19 ` [PATCH 2/2] btrfs-progs: zoned: check SB zone existence properly Naohiro Aota
  2023-10-12 16:25 ` [PATCH 0/2] btrfs-progs: zoned: check existence of SB zone, not LBA David Sterba
  2 siblings, 0 replies; 4+ messages in thread
From: Naohiro Aota @ 2023-10-12 14:19 UTC (permalink / raw)
  To: linux-btrfs; +Cc: Naohiro Aota

Introduce sb_bytenr_to_sb_zone(), which converts the original superblock
location to the zone number of superblock log writing.

Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
---
 kernel-shared/zoned.c | 28 ++++++++++++++++------------
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/kernel-shared/zoned.c b/kernel-shared/zoned.c
index 16e83f8b6331..206ad906c985 100644
--- a/kernel-shared/zoned.c
+++ b/kernel-shared/zoned.c
@@ -478,6 +478,21 @@ static int sb_log_location(int fd, struct blk_zone *zones, int rw, u64 *bytenr_r
 	return 0;
 }
 
+static u32 sb_bytenr_to_sb_zone(u64 bytenr, int zone_size_shift)
+{
+	int i, mirror = -1;
+
+	for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) {
+		if (bytenr == btrfs_sb_offset(i)) {
+			mirror = i;
+			break;
+		}
+	}
+	ASSERT(mirror != -1);
+
+	return sb_zone_number(zone_size_shift, mirror);
+}
+
 size_t btrfs_sb_io(int fd, void *buf, off_t offset, int rw)
 {
 	size_t count = BTRFS_SUPER_INFO_SIZE;
@@ -489,8 +504,6 @@ size_t btrfs_sb_io(int fd, void *buf, off_t offset, int rw)
 	u32 zone_num;
 	u32 zone_size_sector;
 	size_t rep_size;
-	int mirror = -1;
-	int i;
 	int ret;
 	size_t ret_sz;
 
@@ -532,16 +545,7 @@ size_t btrfs_sb_io(int fd, void *buf, off_t offset, int rw)
 
 	ASSERT(IS_ALIGNED(zone_size_sector, sb_size_sector));
 
-	for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) {
-		if (offset == btrfs_sb_offset(i)) {
-			mirror = i;
-			break;
-		}
-	}
-	ASSERT(mirror != -1);
-
-	zone_num = sb_zone_number(ilog2(zone_size_sector) + SECTOR_SHIFT,
-				  mirror);
+	zone_num = sb_bytenr_to_sb_zone(offset, ilog2(zone_size_sector) + SECTOR_SHIFT);
 
 	rep_size = sizeof(struct blk_zone_report) + sizeof(struct blk_zone) * 2;
 	rep = calloc(1, rep_size);
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] btrfs-progs: zoned: check SB zone existence properly
  2023-10-12 14:19 [PATCH 0/2] btrfs-progs: zoned: check existence of SB zone, not LBA Naohiro Aota
  2023-10-12 14:19 ` [PATCH 1/2] btrfs-progs: zoned: introduce sb_bytenr_to_sb_zone() Naohiro Aota
@ 2023-10-12 14:19 ` Naohiro Aota
  2023-10-12 16:25 ` [PATCH 0/2] btrfs-progs: zoned: check existence of SB zone, not LBA David Sterba
  2 siblings, 0 replies; 4+ messages in thread
From: Naohiro Aota @ 2023-10-12 14:19 UTC (permalink / raw)
  To: linux-btrfs; +Cc: Naohiro Aota

Currently, write_dev_supers() compares the superblock location vs the size
of the device to check if it can write the superblock. This is not correct
for a zoned device, whose superblock location is different than a regular
device.

Introduce check_sb_location() to check if the superblock zone exists for
the zoned case.

Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
---
 kernel-shared/disk-io.c | 9 ++++++++-
 kernel-shared/zoned.c   | 8 ++++++++
 kernel-shared/zoned.h   | 6 ++++++
 3 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/kernel-shared/disk-io.c b/kernel-shared/disk-io.c
index 1b1531c52ad7..a056f2ca0560 100644
--- a/kernel-shared/disk-io.c
+++ b/kernel-shared/disk-io.c
@@ -1998,6 +1998,13 @@ int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr,
 	return transid > 0 ? 0 : -1;
 }
 
+static bool check_sb_location(struct btrfs_device *device, u64 bytenr)
+{
+	if (!device->zone_info)
+		return bytenr + BTRFS_SUPER_INFO_SIZE <= device->total_bytes;
+	return btrfs_sb_zone_exists(device, bytenr);
+}
+
 static int write_dev_supers(struct btrfs_fs_info *fs_info,
 			    struct btrfs_super_block *sb,
 			    struct btrfs_device *device)
@@ -2048,7 +2055,7 @@ static int write_dev_supers(struct btrfs_fs_info *fs_info,
 
 	for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) {
 		bytenr = btrfs_sb_offset(i);
-		if (bytenr + BTRFS_SUPER_INFO_SIZE > device->total_bytes)
+		if (!check_sb_location(device, bytenr))
 			break;
 
 		btrfs_set_super_bytenr(sb, bytenr);
diff --git a/kernel-shared/zoned.c b/kernel-shared/zoned.c
index 206ad906c985..491d52eab942 100644
--- a/kernel-shared/zoned.c
+++ b/kernel-shared/zoned.c
@@ -1175,3 +1175,11 @@ int btrfs_check_zoned_mode(struct btrfs_fs_info *fs_info)
 out:
 	return ret;
 }
+
+bool btrfs_sb_zone_exists(struct btrfs_device *device, u64 bytenr)
+{
+	u32 zone_num = sb_bytenr_to_sb_zone(bytenr,
+					    ilog2(device->zone_info->zone_size));
+
+	return zone_num + 1 <= device->zone_info->nr_zones - 1;
+}
diff --git a/kernel-shared/zoned.h b/kernel-shared/zoned.h
index f4b0d5d06301..6eba86d266bf 100644
--- a/kernel-shared/zoned.h
+++ b/kernel-shared/zoned.h
@@ -153,6 +153,7 @@ int btrfs_reset_all_zones(int fd, struct btrfs_zoned_device_info *zinfo);
 int zero_zone_blocks(int fd, struct btrfs_zoned_device_info *zinfo, off_t start,
 		     size_t len);
 int btrfs_wipe_temporary_sb(struct btrfs_fs_devices *fs_devices);
+bool btrfs_sb_zone_exists(struct btrfs_device *device, u64 bytenr);
 
 #else
 
@@ -225,6 +226,11 @@ static inline bool zoned_profile_supported(u64 map_type, bool rst)
 	return false;
 }
 
+static inline bool btrfs_sb_zone_exists(struct btrfs_device *device, u64 bytenr)
+{
+	return true;
+}
+
 #endif /* BTRFS_ZONED */
 
 /*
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 0/2] btrfs-progs: zoned: check existence of SB zone, not LBA
  2023-10-12 14:19 [PATCH 0/2] btrfs-progs: zoned: check existence of SB zone, not LBA Naohiro Aota
  2023-10-12 14:19 ` [PATCH 1/2] btrfs-progs: zoned: introduce sb_bytenr_to_sb_zone() Naohiro Aota
  2023-10-12 14:19 ` [PATCH 2/2] btrfs-progs: zoned: check SB zone existence properly Naohiro Aota
@ 2023-10-12 16:25 ` David Sterba
  2 siblings, 0 replies; 4+ messages in thread
From: David Sterba @ 2023-10-12 16:25 UTC (permalink / raw)
  To: Naohiro Aota; +Cc: linux-btrfs

On Thu, Oct 12, 2023 at 11:19:28PM +0900, Naohiro Aota wrote:
> Running btrfs check can fail on a certain zoned decice setup (e.g,
> zone size = 128MB, device size = 16GB):
> 
> (from generic/330)
> yes|/usr/local/bin/btrfs check --repair --force /dev/nullb1
> [1/7] checking root items
> Fixed 0 roots.
> [2/7] checking extents
> ERROR: zoned: failed to read zone info of 4096 and 4097: Invalid argument
> ERROR: failed to write super block for devid 1: write error: Input/output error
> failed to write new super block err -5
> failed to repair damaged filesystem, aborting
> 
> This happens because write_dev_supers() is comparing the original
> superblock location vs the device size to check if it can write out a
> superblock copy or not.
> 
> For the above example, since the first copy location (64MB) < device size
> (16GB), it tries to write out the copy. But, the copy must be written into
> zone 4096 (512G / zone size (128M) = 4096), which is out of the device.

I've added the text above to changelog of patch 2 as it's relevant for
the change.

> To address the issue, this series introduces check_sb_location() to check
> if a SB copy can be written out.
> 
> The patch 1 is a preparation to factor out logic of converting the original
> superblock location to SB log writing superblock zone. And, the second one
> implements check_sb_location() to write_dev_supers().
> 
> Naohiro Aota (2):
>   btrfs-progs: zoned: introduce sb_bytenr_to_sb_zone()
>   btrfs-progs: zoned: check SB zone existence properly

Added to devel, thanks.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2023-10-12 16:32 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-10-12 14:19 [PATCH 0/2] btrfs-progs: zoned: check existence of SB zone, not LBA Naohiro Aota
2023-10-12 14:19 ` [PATCH 1/2] btrfs-progs: zoned: introduce sb_bytenr_to_sb_zone() Naohiro Aota
2023-10-12 14:19 ` [PATCH 2/2] btrfs-progs: zoned: check SB zone existence properly Naohiro Aota
2023-10-12 16:25 ` [PATCH 0/2] btrfs-progs: zoned: check existence of SB zone, not LBA David Sterba

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox