summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNaohiro Aota <naohiro.aota@wdc.com>2021-02-04 13:21:43 +0300
committerDavid Sterba <dsterba@suse.com>2021-02-09 04:32:19 +0300
commitd6639b35da2d742f9cbcdf8f49f87f2bde9fd479 (patch)
tree8275791ab2af12d5c781a66c23d4e0b4615eecaa
parent7365104236ade0bf22edd7724c8fd438b0342ee4 (diff)
downloadlinux-d6639b35da2d742f9cbcdf8f49f87f2bde9fd479.tar.xz
btrfs: zoned: use regular super block location on zone emulation
A zoned filesystem currently has a superblock at the beginning of the superblock logging zones if the zones are conventional. This difference in superblock position causes a chicken-and-egg problem for filesystems with emulated zones. Since the device is a regular (non-zoned) device, we cannot know if the filesystem is regular or zoned while reading the superblock. But, to load the superblock, we need to see if it is emulated zoned or not. Place the superblocks at the same location as they are on regular filesystem on regular devices to solve the problem. It is possible because it's ensured that all the superblock locations are at an (emulated) conventional zone on regular devices. Reviewed-by: Anand Jain <anand.jain@oracle.com> Reviewed-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com> Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r--fs/btrfs/zoned.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c
index 0b1b1f38a196..8b3868088c5e 100644
--- a/fs/btrfs/zoned.c
+++ b/fs/btrfs/zoned.c
@@ -552,7 +552,13 @@ int btrfs_sb_log_location(struct btrfs_device *device, int mirror, int rw,
struct btrfs_zoned_device_info *zinfo = device->zone_info;
u32 zone_num;
- if (!zinfo) {
+ /*
+ * For a zoned filesystem on a non-zoned block device, use the same
+ * super block locations as regular filesystem. Doing so, the super
+ * block can always be retrieved and the zoned flag of the volume
+ * detected from the super block information.
+ */
+ if (!bdev_is_zoned(device->bdev)) {
*bytenr_ret = btrfs_sb_offset(mirror);
return 0;
}