]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_mkfs: calculate zone overprovisioning when specifying size
authorChristoph Hellwig <hch@lst.de>
Mon, 14 Apr 2025 05:36:15 +0000 (07:36 +0200)
committerAndrey Albershteyn <aalbersh@kernel.org>
Tue, 29 Apr 2025 16:09:58 +0000 (18:09 +0200)
When size is specified for zoned file systems, calculate the required
over provisioning to back the requested capacity.

Signed-off-by: Hans Holmberg <hans.holmberg@wdc.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
mkfs/xfs_mkfs.c

index 7289c797a7247d7eb15f40ef8afba13556027883..8768fbb12cf1d07cb8f3ebf8b8595a191c157f28 100644 (file)
@@ -4422,6 +4422,49 @@ _("rgsize (%s) not a multiple of fs blk size (%d)\n"),
                        NBBY * (cfg->blocksize - sizeof(struct xfs_rtbuf_blkinfo)));
 }
 
+/*
+ * If we're creating a zoned filesystem and the user specified a size, add
+ * enough over-provisioning to be able to back the requested amount of
+ * writable space.
+ */
+static void
+adjust_nr_zones(
+       struct mkfs_params      *cfg,
+       struct cli_params       *cli,
+       struct libxfs_init      *xi,
+       struct zone_topology    *zt)
+{
+       uint64_t                new_rtblocks, slack;
+       unsigned int            max_zones;
+
+       if (zt->rt.nr_zones)
+               max_zones = zt->rt.nr_zones;
+       else
+               max_zones = DTOBT(xi->rt.size, cfg->blocklog) / cfg->rgsize;
+
+       if (!cli->rgcount)
+               cfg->rgcount += XFS_RESERVED_ZONES;
+       if (cfg->rgcount > max_zones) {
+               cfg->rgcount = max_zones;
+               fprintf(stderr,
+_("Warning: not enough zones for backing requested rt size due to\n"
+  "over-provisioning needs, writable size will be less than %s\n"),
+                       cli->rtsize);
+       }
+       new_rtblocks = (cfg->rgcount * cfg->rgsize);
+       slack = (new_rtblocks - cfg->rtblocks) % cfg->rgsize;
+
+       cfg->rtblocks = new_rtblocks;
+       cfg->rtextents = cfg->rtblocks / cfg->rtextblocks;
+
+       /*
+        * Add the slack to the end of the last zone to the reserved blocks.
+        * This ensures the visible user capacity is exactly the one that the
+        * user asked for.
+        */
+       cfg->rtreserved += (slack * cfg->blocksize);
+}
+
 static void
 calculate_zone_geometry(
        struct mkfs_params      *cfg,
@@ -4494,6 +4537,9 @@ _("rgsize (%s) not a multiple of fs blk size (%d)\n"),
                }
        }
 
+       if (cli->rtsize || cli->rgcount)
+               adjust_nr_zones(cfg, cli, xi, zt);
+
        if (cfg->rgcount < XFS_MIN_ZONES)  {
                fprintf(stderr,
 _("realtime group count (%llu) must be greater than the minimum zone count (%u)\n"),