Message ID | 20250409075557.3535745-32-hch@lst.de (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | [01/45] xfs: generalize the freespace and reserved blocks handling | expand |
On Wed, Apr 09, 2025 at 09:55:34AM +0200, Christoph Hellwig wrote: > 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> > --- > mkfs/xfs_mkfs.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 46 insertions(+) > > diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c > index 133ede8d8483..6b5eb9eb140a 100644 > --- a/mkfs/xfs_mkfs.c > +++ b/mkfs/xfs_mkfs.c > @@ -4413,6 +4413,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, writeable size will be less than %s\n"), Nit: "writable", not "writeable" With that fixed, Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> --D > + 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, > @@ -4485,6 +4528,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"), > -- > 2.47.2 > >
On Wed, Apr 09, 2025 at 12:06:14PM -0700, Darrick J. Wong wrote: > > +_("Warning: not enough zones for backing requested rt size due to\n" > > + "over-provisioning needs, writeable size will be less than %s\n"), > > Nit: "writable", not "writeable" Fixed, thanks.
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index 133ede8d8483..6b5eb9eb140a 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -4413,6 +4413,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, writeable 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, @@ -4485,6 +4528,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"),