On 11/8/25 10:57, Chao Yu via Linux-f2fs-devel wrote:
On 2025/11/6 17:15, Yongpeng Yang wrote:
From: Yongpeng Yang <[email protected]>

When the block device reports max_open_zones == 0, sbi->max_open_zones
is initialized to UINT_MAX. In such cases, F2FS can still be mounted
successfully (as tested under qemu).
However, for SSDs, a device reporting max_open_zones == 0 should not be
mountable, while for SMR HDDs this is acceptable.
Fix this issue by handling max_open_zones == 0 properly:
- Disallow mounting on SSDs when max_open_zones == 0.
- For SMR HDDs, set max_open_zones to the total number of zones.
- Remove redundant zoned device checks.
- Add a sysfs entry to expose max_open_zones.

Fixes: 0f9b12142be1af("f2fs: fix zoned block device information initialization")
Signed-off-by: Yongpeng Yang <[email protected]>
---
  fs/f2fs/super.c | 36 +++++++++++++++++++++---------------
  fs/f2fs/sysfs.c |  2 ++
  2 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index c055032593b7..7349d9cd901b 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -4353,21 +4353,6 @@ static int init_blkz_info(struct f2fs_sb_info *sbi, int devi)
      unsigned int max_open_zones;
      int ret;
-    if (!f2fs_sb_has_blkzoned(sbi))
-        return 0;

init_blkz_info() should only be called if blkzoned feature is on?


Yes, init_blkz_info() is only called by f2fs_scan_devices(), and the
blkzoned feature has already been checked there. So there’s no need to
check it again.

-
-    if (bdev_is_zoned(FDEV(devi).bdev)) {
-        max_open_zones = bdev_max_open_zones(bdev);
-        if (max_open_zones && (max_open_zones < sbi->max_open_zones))
-            sbi->max_open_zones = max_open_zones;
-        if (sbi->max_open_zones < F2FS_OPTION(sbi).active_logs) {
-            f2fs_err(sbi,
-                "zoned: max open zones %u is too small, need at least %u open zones",
-                sbi->max_open_zones, F2FS_OPTION(sbi).active_logs);
-            return -EINVAL;
-        }
-    }
-
      zone_sectors = bdev_zone_sectors(bdev);
      if (sbi->blocks_per_blkz && sbi->blocks_per_blkz !=
                  SECTOR_TO_BLOCK(zone_sectors))
@@ -4378,6 +4363,27 @@ static int init_blkz_info(struct f2fs_sb_info *sbi, int devi)
      if (nr_sectors & (zone_sectors - 1))
          FDEV(devi).nr_blkz++;
+    max_open_zones = bdev_max_open_zones(bdev);
+    if (!max_open_zones) {
+        /*
+         * SSDs require max_open_zones > 0 to be mountable.

Do you mean we enabled blkzoned feature on a zoned SSD? Such SSD can report zeroed max_open_zones?
If so, can you please add more details in commit message?


Yes, I tested with a ZNS SSD emulated on qemu and set zoned.max_open to
0. f2fs with zns ssd and conventional ssd can be mounted normally, and
sbi->max_open_zones is UINT_MAX. I will add more explanations in the v2
patch.


+         * For HDDs, if max_open_zones is reported as 0, it doesn't matter,
+         * set it to FDEV(devi).nr_blkz.
+         */
+        if (bdev_nonrot(bdev)) {
+            f2fs_err(sbi, "zoned: SSD device %s without open zones", FDEV(devi).path);
+            return -EINVAL;
+        }
+        max_open_zones = FDEV(devi).nr_blkz;
+    }
+    sbi->max_open_zones = min_t(unsigned int, max_open_zones, sbi- >max_open_zones);
+    if (sbi->max_open_zones < F2FS_OPTION(sbi).active_logs) {
+        f2fs_err(sbi,
+            "zoned: max open zones %u is too small, need at least %u open zones",
+            sbi->max_open_zones, F2FS_OPTION(sbi).active_logs);
+        return -EINVAL;
+    }
+
      FDEV(devi).blkz_seq = f2fs_kvzalloc(sbi,
                      BITS_TO_LONGS(FDEV(devi).nr_blkz)
                      * sizeof(unsigned long),
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index 98d2cb60e806..d3d268c707a9 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -1210,6 +1210,7 @@ F2FS_SBI_GENERAL_RW_ATTR(last_age_weight);
  F2FS_SBI_GENERAL_RW_ATTR(max_read_extent_count);
  #ifdef CONFIG_BLK_DEV_ZONED
  F2FS_SBI_GENERAL_RO_ATTR(unusable_blocks_per_blkz);
+F2FS_SBI_GENERAL_RO_ATTR(max_open_zones);

Need to update manual page as well, what about adding this new sysfs entry in a
separated patch?

Thanks,


I agree, it makes more sense to split them. I’ll separate the patch and update manual page in v2.

Yongpeng,

  F2FS_SBI_GENERAL_RW_ATTR(blkzone_alloc_policy);
  #endif
  F2FS_SBI_GENERAL_RW_ATTR(carve_out);
@@ -1384,6 +1385,7 @@ static struct attribute *f2fs_attrs[] = {
  #endif
  #ifdef CONFIG_BLK_DEV_ZONED
      ATTR_LIST(unusable_blocks_per_blkz),
+    ATTR_LIST(max_open_zones),
      ATTR_LIST(blkzone_alloc_policy),
  #endif
  #ifdef CONFIG_F2FS_FS_COMPRESSION



_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel



_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

Reply via email to