* improve the discard / reset zones code in mkfs
@ 2025-10-29 9:07 Christoph Hellwig
2025-10-29 9:07 ` [PATCH 1/4] mkfs: move clearing LIBXFS_DIRECT into check_device_type Christoph Hellwig
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: Christoph Hellwig @ 2025-10-29 9:07 UTC (permalink / raw)
To: Andrey Albershteyn; +Cc: Darrick J . Wong, linux-xfs
Hi all,
this series refactors the discard and reset zones code in mkfs a
bit, and then allows discarding for the data device even when
the RT devices sits on a zones where discard doesn't make much
sense.
Note: this sits on top of the "improve a few messages in mkfs and
xfs_copy" series sent a while ago.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/4] mkfs: move clearing LIBXFS_DIRECT into check_device_type
2025-10-29 9:07 improve the discard / reset zones code in mkfs Christoph Hellwig
@ 2025-10-29 9:07 ` Christoph Hellwig
2025-10-29 15:38 ` Darrick J. Wong
2025-10-29 9:07 ` [PATCH 2/4] libxfs: cleanup get_topology Christoph Hellwig
` (2 subsequent siblings)
3 siblings, 1 reply; 9+ messages in thread
From: Christoph Hellwig @ 2025-10-29 9:07 UTC (permalink / raw)
To: Andrey Albershteyn; +Cc: Darrick J . Wong, linux-xfs
Keep it close to the block device vs regular file logic and remove
the checks for each device in the caller.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
mkfs/xfs_mkfs.c | 27 ++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index cb7c20e3aa18..3ccd37920321 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -1330,6 +1330,7 @@ nr_cpus(void)
static void
check_device_type(
+ struct cli_params *cli,
struct libxfs_dev *dev,
bool no_size,
bool dry_run,
@@ -1375,6 +1376,13 @@ check_device_type(
dev->isfile = 1;
else if (!dry_run)
dev->create = 1;
+
+ /*
+ * Explicitly disable direct IO for image files so we don't
+ * error out on sector size mismatches between the new
+ * filesystem and the underlying host filesystem.
+ */
+ cli->xi->flags &= ~LIBXFS_DIRECT;
return;
}
@@ -2378,21 +2386,14 @@ validate_sectorsize(
* Before anything else, verify that we are correctly operating on
* files or block devices and set the control parameters correctly.
*/
- check_device_type(&cli->xi->data, !cli->dsize, dry_run, "data", "d");
+ check_device_type(cli, &cli->xi->data, !cli->dsize, dry_run,
+ "data", "d");
if (!cli->loginternal)
- check_device_type(&cli->xi->log, !cli->logsize, dry_run, "log",
- "l");
+ check_device_type(cli, &cli->xi->log, !cli->logsize, dry_run,
+ "log", "l");
if (cli->xi->rt.name)
- check_device_type(&cli->xi->rt, !cli->rtsize, dry_run, "RT",
- "r");
-
- /*
- * Explicitly disable direct IO for image files so we don't error out on
- * sector size mismatches between the new filesystem and the underlying
- * host filesystem.
- */
- if (cli->xi->data.isfile || cli->xi->log.isfile || cli->xi->rt.isfile)
- cli->xi->flags &= ~LIBXFS_DIRECT;
+ check_device_type(cli, &cli->xi->rt, !cli->rtsize, dry_run,
+ "RT", "r");
memset(ft, 0, sizeof(*ft));
get_topology(cli->xi, ft, force_overwrite);
--
2.47.3
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/4] libxfs: cleanup get_topology
2025-10-29 9:07 improve the discard / reset zones code in mkfs Christoph Hellwig
2025-10-29 9:07 ` [PATCH 1/4] mkfs: move clearing LIBXFS_DIRECT into check_device_type Christoph Hellwig
@ 2025-10-29 9:07 ` Christoph Hellwig
2025-10-29 15:39 ` Darrick J. Wong
2025-10-29 9:07 ` [PATCH 3/4] mkfs: remove duplicate struct libxfs_init arguments Christoph Hellwig
2025-10-29 9:07 ` [PATCH 4/4] mkfs: split zone reset from discard Christoph Hellwig
3 siblings, 1 reply; 9+ messages in thread
From: Christoph Hellwig @ 2025-10-29 9:07 UTC (permalink / raw)
To: Andrey Albershteyn; +Cc: Darrick J . Wong, linux-xfs
Add a libxfs_ prefix to the name, clear the structure in the helper
instead of in the callers, and use a bool to pass a boolean argument.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
libxfs/topology.c | 9 +++++----
libxfs/topology.h | 7 ++-----
mkfs/xfs_mkfs.c | 3 +--
repair/sb.c | 3 +--
4 files changed, 9 insertions(+), 13 deletions(-)
diff --git a/libxfs/topology.c b/libxfs/topology.c
index 7764687beac0..366165719c84 100644
--- a/libxfs/topology.c
+++ b/libxfs/topology.c
@@ -224,7 +224,7 @@ static void
blkid_get_topology(
const char *device,
struct device_topology *dt,
- int force_overwrite)
+ bool force_overwrite)
{
blkid_topology tp;
blkid_probe pr;
@@ -317,7 +317,7 @@ static void
get_device_topology(
struct libxfs_dev *dev,
struct device_topology *dt,
- int force_overwrite)
+ bool force_overwrite)
{
struct stat st;
@@ -364,11 +364,12 @@ get_device_topology(
}
void
-get_topology(
+libxfs_get_topology(
struct libxfs_init *xi,
struct fs_topology *ft,
- int force_overwrite)
+ bool force_overwrite)
{
+ memset(ft, 0, sizeof(*ft));
get_device_topology(&xi->data, &ft->data, force_overwrite);
get_device_topology(&xi->rt, &ft->rt, force_overwrite);
get_device_topology(&xi->log, &ft->log, force_overwrite);
diff --git a/libxfs/topology.h b/libxfs/topology.h
index f0ca65f3576e..3688d56b542f 100644
--- a/libxfs/topology.h
+++ b/libxfs/topology.h
@@ -25,11 +25,8 @@ struct fs_topology {
struct device_topology log;
};
-void
-get_topology(
- struct libxfs_init *xi,
- struct fs_topology *ft,
- int force_overwrite);
+void libxfs_get_topology(struct libxfs_init *xi, struct fs_topology *ft,
+ bool force_overwrite);
extern void
calc_default_ag_geometry(
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 3ccd37920321..0ba7798eccf6 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -2395,8 +2395,7 @@ validate_sectorsize(
check_device_type(cli, &cli->xi->rt, !cli->rtsize, dry_run,
"RT", "r");
- memset(ft, 0, sizeof(*ft));
- get_topology(cli->xi, ft, force_overwrite);
+ libxfs_get_topology(cli->xi, ft, force_overwrite);
/* set configured sector sizes in preparation for checks */
if (!cli->sectorsize) {
diff --git a/repair/sb.c b/repair/sb.c
index 0e4827e04678..ee1cc63fae64 100644
--- a/repair/sb.c
+++ b/repair/sb.c
@@ -184,8 +184,7 @@ guess_default_geometry(
uint64_t dblocks;
int multidisk;
- memset(&ft, 0, sizeof(ft));
- get_topology(x, &ft, 1);
+ libxfs_get_topology(x, &ft, true);
/*
* get geometry from get_topology result.
--
2.47.3
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 3/4] mkfs: remove duplicate struct libxfs_init arguments
2025-10-29 9:07 improve the discard / reset zones code in mkfs Christoph Hellwig
2025-10-29 9:07 ` [PATCH 1/4] mkfs: move clearing LIBXFS_DIRECT into check_device_type Christoph Hellwig
2025-10-29 9:07 ` [PATCH 2/4] libxfs: cleanup get_topology Christoph Hellwig
@ 2025-10-29 9:07 ` Christoph Hellwig
2025-10-29 15:39 ` Darrick J. Wong
2025-10-29 9:07 ` [PATCH 4/4] mkfs: split zone reset from discard Christoph Hellwig
3 siblings, 1 reply; 9+ messages in thread
From: Christoph Hellwig @ 2025-10-29 9:07 UTC (permalink / raw)
To: Andrey Albershteyn; +Cc: Darrick J . Wong, linux-xfs
The libxfs_init structure instance is pointed to by cli_params, so use
that were it already exists instead of passing an additional argument.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
mkfs/xfs_mkfs.c | 49 ++++++++++++++++++++++---------------------------
1 file changed, 22 insertions(+), 27 deletions(-)
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 0ba7798eccf6..09a69af31be5 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -4005,8 +4005,7 @@ ddev_is_solidstate(
static void
calc_concurrency_ag_geometry(
struct mkfs_params *cfg,
- struct cli_params *cli,
- struct libxfs_init *xi)
+ struct cli_params *cli)
{
uint64_t try_agsize;
uint64_t def_agsize;
@@ -4074,11 +4073,10 @@ out:
static void
calculate_initial_ag_geometry(
struct mkfs_params *cfg,
- struct cli_params *cli,
- struct libxfs_init *xi)
+ struct cli_params *cli)
{
if (cli->data_concurrency > 0) {
- calc_concurrency_ag_geometry(cfg, cli, xi);
+ calc_concurrency_ag_geometry(cfg, cli);
} else if (cli->agsize) { /* User-specified AG size */
cfg->agsize = getnum(cli->agsize, &dopts, D_AGSIZE);
@@ -4099,8 +4097,9 @@ _("agsize (%s) not a multiple of fs blk size (%d)\n"),
cfg->agcount = cli->agcount;
cfg->agsize = cfg->dblocks / cfg->agcount +
(cfg->dblocks % cfg->agcount != 0);
- } else if (cli->data_concurrency == -1 && ddev_is_solidstate(xi)) {
- calc_concurrency_ag_geometry(cfg, cli, xi);
+ } else if (cli->data_concurrency == -1 &&
+ ddev_is_solidstate(cli->xi)) {
+ calc_concurrency_ag_geometry(cfg, cli);
} else {
calc_default_ag_geometry(cfg->blocklog, cfg->dblocks,
cfg->dsunit, &cfg->agsize,
@@ -4360,8 +4359,7 @@ rtdev_is_solidstate(
static void
calc_concurrency_rtgroup_geometry(
struct mkfs_params *cfg,
- struct cli_params *cli,
- struct libxfs_init *xi)
+ struct cli_params *cli)
{
uint64_t try_rgsize;
uint64_t def_rgsize;
@@ -4468,8 +4466,7 @@ _("realtime group count (%llu) must be less than the maximum (%u)\n"),
static void
calculate_rtgroup_geometry(
struct mkfs_params *cfg,
- struct cli_params *cli,
- struct libxfs_init *xi)
+ struct cli_params *cli)
{
if (!cli->sb_feat.metadir) {
cfg->rgcount = 0;
@@ -4510,8 +4507,9 @@ _("rgsize (%s) not a multiple of fs blk size (%d)\n"),
cfg->rgsize = cfg->rtblocks;
cfg->rgcount = 0;
} else if (cli->rtvol_concurrency > 0 ||
- (cli->rtvol_concurrency == -1 && rtdev_is_solidstate(xi))) {
- calc_concurrency_rtgroup_geometry(cfg, cli, xi);
+ (cli->rtvol_concurrency == -1 &&
+ rtdev_is_solidstate(cli->xi))) {
+ calc_concurrency_rtgroup_geometry(cfg, cli);
} else if (is_power_of_2(cfg->rtextblocks)) {
cfg->rgsize = calc_rgsize_extsize_power(cfg);
cfg->rgcount = cfg->rtblocks / cfg->rgsize +
@@ -4538,7 +4536,6 @@ 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;
@@ -4547,7 +4544,8 @@ adjust_nr_zones(
if (zt->rt.nr_zones)
max_zones = zt->rt.nr_zones;
else
- max_zones = DTOBT(xi->rt.size, cfg->blocklog) / cfg->rgsize;
+ max_zones = DTOBT(cli->xi->rt.size, cfg->blocklog) /
+ cfg->rgsize;
if (!cli->rgcount)
cfg->rgcount += XFS_RESERVED_ZONES;
@@ -4576,7 +4574,6 @@ static void
calculate_zone_geometry(
struct mkfs_params *cfg,
struct cli_params *cli,
- struct libxfs_init *xi,
struct zone_topology *zt)
{
if (cfg->rtblocks == 0) {
@@ -4645,7 +4642,7 @@ _("rgsize (%s) not a multiple of fs blk size (%d)\n"),
}
if (cli->rtsize || cli->rgcount)
- adjust_nr_zones(cfg, cli, xi, zt);
+ adjust_nr_zones(cfg, cli, zt);
if (cfg->rgcount < XFS_MIN_ZONES) {
fprintf(stderr,
@@ -4984,7 +4981,6 @@ static uint64_t
calc_concurrency_logblocks(
struct mkfs_params *cfg,
struct cli_params *cli,
- struct libxfs_init *xi,
unsigned int max_tx_bytes)
{
uint64_t log_bytes;
@@ -4992,7 +4988,7 @@ calc_concurrency_logblocks(
unsigned int new_logblocks;
if (cli->log_concurrency < 0) {
- if (!ddev_is_solidstate(xi))
+ if (!ddev_is_solidstate(cli->xi))
goto out;
cli->log_concurrency = nr_cpus();
@@ -5160,7 +5156,6 @@ static void
calculate_log_size(
struct mkfs_params *cfg,
struct cli_params *cli,
- struct libxfs_init *xi,
struct xfs_mount *mp)
{
struct xfs_sb *sbp = &mp->m_sb;
@@ -5225,8 +5220,8 @@ _("external log device size %lld blocks too small, must be at least %lld blocks\
if (cfg->lsunit) {
uint64_t max_logblocks;
- max_logblocks = min(DTOBT(xi->log.size, cfg->blocklog),
- XFS_MAX_LOG_BLOCKS);
+ max_logblocks = min(XFS_MAX_LOG_BLOCKS,
+ DTOBT(cli->xi->log.size, cfg->blocklog));
align_log_size(cfg, cfg->lsunit, max_logblocks);
}
@@ -5261,7 +5256,7 @@ _("max log size %d smaller than min log size %d, filesystem is too small\n"),
if (cli->log_concurrency != 0)
cfg->logblocks = calc_concurrency_logblocks(cfg, cli,
- xi, max_tx_bytes);
+ max_tx_bytes);
/* But don't go below a reasonable size */
cfg->logblocks = max(cfg->logblocks,
@@ -6135,12 +6130,12 @@ main(
* dependent on device sizes. Once calculated, make sure everything
* aligns to device geometry correctly.
*/
- calculate_initial_ag_geometry(&cfg, &cli, &xi);
+ calculate_initial_ag_geometry(&cfg, &cli);
align_ag_geometry(&cfg, &ft);
if (cfg.sb_feat.zoned)
- calculate_zone_geometry(&cfg, &cli, &xi, &zt);
+ calculate_zone_geometry(&cfg, &cli, &zt);
else
- calculate_rtgroup_geometry(&cfg, &cli, &xi);
+ calculate_rtgroup_geometry(&cfg, &cli);
calculate_imaxpct(&cfg, &cli);
@@ -6164,7 +6159,7 @@ main(
* With the mount set up, we can finally calculate the log size
* constraints and do default size calculations and final validation
*/
- calculate_log_size(&cfg, &cli, &xi, mp);
+ calculate_log_size(&cfg, &cli, mp);
finish_superblock_setup(&cfg, mp, sbp);
--
2.47.3
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 4/4] mkfs: split zone reset from discard
2025-10-29 9:07 improve the discard / reset zones code in mkfs Christoph Hellwig
` (2 preceding siblings ...)
2025-10-29 9:07 ` [PATCH 3/4] mkfs: remove duplicate struct libxfs_init arguments Christoph Hellwig
@ 2025-10-29 9:07 ` Christoph Hellwig
2025-10-29 15:40 ` Darrick J. Wong
3 siblings, 1 reply; 9+ messages in thread
From: Christoph Hellwig @ 2025-10-29 9:07 UTC (permalink / raw)
To: Andrey Albershteyn; +Cc: Darrick J . Wong, linux-xfs
Zone reset is a mandatory part of creating a file system on a zoned
device, unlike discard, which can be skipped. It also is implemented
a bit different, so just split the handling. This also means that we
can now support the -K option to skip discard on the data section for
zoned file systems.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
mkfs/xfs_mkfs.c | 112 +++++++++++++++++++++++-------------------------
1 file changed, 53 insertions(+), 59 deletions(-)
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 09a69af31be5..cd4f3ba4a549 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -1607,34 +1607,6 @@ discard_blocks(int fd, uint64_t nsectors, int quiet)
printf("Done.\n");
}
-static void
-reset_zones(
- struct mkfs_params *cfg,
- int fd,
- uint64_t start_sector,
- uint64_t nsectors,
- int quiet)
-{
- struct blk_zone_range range = {
- .sector = start_sector,
- .nr_sectors = nsectors,
- };
-
- if (!quiet) {
- printf("Resetting zones...");
- fflush(stdout);
- }
-
- if (ioctl(fd, BLKRESETZONE, &range) < 0) {
- if (!quiet)
- printf(" FAILED (%d)\n", -errno);
- exit(1);
- }
-
- if (!quiet)
- printf("Done.\n");
-}
-
static __attribute__((noreturn)) void
illegal_option(
const char *value,
@@ -3780,41 +3752,66 @@ discard_devices(
struct zone_topology *zt,
int quiet)
{
- /*
- * This function has to be called after libxfs has been initialized.
- */
-
if (!xi->data.isfile) {
uint64_t nsectors = xi->data.size;
- if (cfg->rtstart && zt->data.nr_zones) {
- /*
- * Note that the zone reset here includes the LBA range
- * for the data device.
- *
- * This is because doing a single zone reset all on the
- * entire device (which the kernel automatically does
- * for us for a full device range) is a lot faster than
- * resetting each zone individually and resetting
- * the conventional zones used for the data device is a
- * no-op.
- */
- reset_zones(cfg, xi->data.fd, 0,
- cfg->rtstart + xi->rt.size, quiet);
+ if (cfg->rtstart && zt->data.nr_zones)
nsectors -= cfg->rtstart;
- }
discard_blocks(xi->data.fd, nsectors, quiet);
}
- if (xi->rt.dev && !xi->rt.isfile) {
- if (zt->rt.nr_zones)
- reset_zones(cfg, xi->rt.fd, 0, xi->rt.size, quiet);
- else
- discard_blocks(xi->rt.fd, xi->rt.size, quiet);
- }
+ if (xi->rt.dev && !xi->rt.isfile && !zt->rt.nr_zones)
+ discard_blocks(xi->rt.fd, xi->rt.size, quiet);
if (xi->log.dev && xi->log.dev != xi->data.dev && !xi->log.isfile)
discard_blocks(xi->log.fd, xi->log.size, quiet);
}
+static void
+reset_zones(
+ struct mkfs_params *cfg,
+ struct libxfs_dev *dev,
+ uint64_t size,
+ bool quiet)
+{
+ struct blk_zone_range range = {
+ .nr_sectors = size,
+ };
+
+ if (!quiet) {
+ printf("Resetting zones...");
+ fflush(stdout);
+ }
+ if (ioctl(dev->fd, BLKRESETZONE, &range) < 0) {
+ if (!quiet)
+ printf(" FAILED (%d)\n", -errno);
+ exit(1);
+ }
+ if (!quiet)
+ printf("Done.\n");
+}
+
+static void
+reset_devices(
+ struct mkfs_params *cfg,
+ struct libxfs_init *xi,
+ struct zone_topology *zt,
+ int quiet)
+{
+ /*
+ * Note that the zone reset here includes the conventional zones used
+ * for the data device.
+ *
+ * It is done that way because doing a single zone reset all on the
+ * entire device (which the kernel automatically does for us for a full
+ * device range) is a lot faster than resetting each zone individually
+ * and resetting the conventional zones used for the data device is a
+ * no-op.
+ */
+ if (!xi->data.isfile && zt->data.nr_zones && cfg->rtstart)
+ reset_zones(cfg, &xi->data, cfg->rtstart + xi->rt.size, quiet);
+ if (xi->rt.dev && !xi->rt.isfile && zt->rt.nr_zones)
+ reset_zones(cfg, &xi->rt, xi->rt.size, quiet);
+}
+
static void
validate_datadev(
struct mkfs_params *cfg,
@@ -6196,13 +6193,10 @@ main(
/*
* All values have been validated, discard the old device layout.
*/
- if (cli.sb_feat.zoned && !discard) {
- fprintf(stderr,
- _("-K not support for zoned file systems.\n"));
- return 1;
- }
if (discard && !dry_run)
- discard_devices(&cfg, &xi, &zt, quiet);
+ discard_devices(&cfg, cli.xi, &zt, quiet);
+ if (cli.sb_feat.zoned && !dry_run)
+ reset_devices(&cfg, cli.xi, &zt, quiet);
/*
* we need the libxfs buffer cache from here on in.
--
2.47.3
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 1/4] mkfs: move clearing LIBXFS_DIRECT into check_device_type
2025-10-29 9:07 ` [PATCH 1/4] mkfs: move clearing LIBXFS_DIRECT into check_device_type Christoph Hellwig
@ 2025-10-29 15:38 ` Darrick J. Wong
0 siblings, 0 replies; 9+ messages in thread
From: Darrick J. Wong @ 2025-10-29 15:38 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Andrey Albershteyn, linux-xfs
On Wed, Oct 29, 2025 at 10:07:29AM +0100, Christoph Hellwig wrote:
> Keep it close to the block device vs regular file logic and remove
> the checks for each device in the caller.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
I guess it makes sense to move the clearing of LIBXFS_DIRECT to where we
determine that one of the device paths pointed to a regular file...
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
--D
> ---
> mkfs/xfs_mkfs.c | 27 ++++++++++++++-------------
> 1 file changed, 14 insertions(+), 13 deletions(-)
>
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index cb7c20e3aa18..3ccd37920321 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -1330,6 +1330,7 @@ nr_cpus(void)
>
> static void
> check_device_type(
> + struct cli_params *cli,
> struct libxfs_dev *dev,
> bool no_size,
> bool dry_run,
> @@ -1375,6 +1376,13 @@ check_device_type(
> dev->isfile = 1;
> else if (!dry_run)
> dev->create = 1;
> +
> + /*
> + * Explicitly disable direct IO for image files so we don't
> + * error out on sector size mismatches between the new
> + * filesystem and the underlying host filesystem.
> + */
> + cli->xi->flags &= ~LIBXFS_DIRECT;
> return;
> }
>
> @@ -2378,21 +2386,14 @@ validate_sectorsize(
> * Before anything else, verify that we are correctly operating on
> * files or block devices and set the control parameters correctly.
> */
> - check_device_type(&cli->xi->data, !cli->dsize, dry_run, "data", "d");
> + check_device_type(cli, &cli->xi->data, !cli->dsize, dry_run,
> + "data", "d");
> if (!cli->loginternal)
> - check_device_type(&cli->xi->log, !cli->logsize, dry_run, "log",
> - "l");
> + check_device_type(cli, &cli->xi->log, !cli->logsize, dry_run,
> + "log", "l");
> if (cli->xi->rt.name)
> - check_device_type(&cli->xi->rt, !cli->rtsize, dry_run, "RT",
> - "r");
> -
> - /*
> - * Explicitly disable direct IO for image files so we don't error out on
> - * sector size mismatches between the new filesystem and the underlying
> - * host filesystem.
> - */
> - if (cli->xi->data.isfile || cli->xi->log.isfile || cli->xi->rt.isfile)
> - cli->xi->flags &= ~LIBXFS_DIRECT;
> + check_device_type(cli, &cli->xi->rt, !cli->rtsize, dry_run,
> + "RT", "r");
>
> memset(ft, 0, sizeof(*ft));
> get_topology(cli->xi, ft, force_overwrite);
> --
> 2.47.3
>
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/4] libxfs: cleanup get_topology
2025-10-29 9:07 ` [PATCH 2/4] libxfs: cleanup get_topology Christoph Hellwig
@ 2025-10-29 15:39 ` Darrick J. Wong
0 siblings, 0 replies; 9+ messages in thread
From: Darrick J. Wong @ 2025-10-29 15:39 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Andrey Albershteyn, linux-xfs
On Wed, Oct 29, 2025 at 10:07:30AM +0100, Christoph Hellwig wrote:
> Add a libxfs_ prefix to the name, clear the structure in the helper
> instead of in the callers, and use a bool to pass a boolean argument.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Looks good,
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
--D
> ---
> libxfs/topology.c | 9 +++++----
> libxfs/topology.h | 7 ++-----
> mkfs/xfs_mkfs.c | 3 +--
> repair/sb.c | 3 +--
> 4 files changed, 9 insertions(+), 13 deletions(-)
>
> diff --git a/libxfs/topology.c b/libxfs/topology.c
> index 7764687beac0..366165719c84 100644
> --- a/libxfs/topology.c
> +++ b/libxfs/topology.c
> @@ -224,7 +224,7 @@ static void
> blkid_get_topology(
> const char *device,
> struct device_topology *dt,
> - int force_overwrite)
> + bool force_overwrite)
> {
> blkid_topology tp;
> blkid_probe pr;
> @@ -317,7 +317,7 @@ static void
> get_device_topology(
> struct libxfs_dev *dev,
> struct device_topology *dt,
> - int force_overwrite)
> + bool force_overwrite)
> {
> struct stat st;
>
> @@ -364,11 +364,12 @@ get_device_topology(
> }
>
> void
> -get_topology(
> +libxfs_get_topology(
> struct libxfs_init *xi,
> struct fs_topology *ft,
> - int force_overwrite)
> + bool force_overwrite)
> {
> + memset(ft, 0, sizeof(*ft));
> get_device_topology(&xi->data, &ft->data, force_overwrite);
> get_device_topology(&xi->rt, &ft->rt, force_overwrite);
> get_device_topology(&xi->log, &ft->log, force_overwrite);
> diff --git a/libxfs/topology.h b/libxfs/topology.h
> index f0ca65f3576e..3688d56b542f 100644
> --- a/libxfs/topology.h
> +++ b/libxfs/topology.h
> @@ -25,11 +25,8 @@ struct fs_topology {
> struct device_topology log;
> };
>
> -void
> -get_topology(
> - struct libxfs_init *xi,
> - struct fs_topology *ft,
> - int force_overwrite);
> +void libxfs_get_topology(struct libxfs_init *xi, struct fs_topology *ft,
> + bool force_overwrite);
>
> extern void
> calc_default_ag_geometry(
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index 3ccd37920321..0ba7798eccf6 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -2395,8 +2395,7 @@ validate_sectorsize(
> check_device_type(cli, &cli->xi->rt, !cli->rtsize, dry_run,
> "RT", "r");
>
> - memset(ft, 0, sizeof(*ft));
> - get_topology(cli->xi, ft, force_overwrite);
> + libxfs_get_topology(cli->xi, ft, force_overwrite);
>
> /* set configured sector sizes in preparation for checks */
> if (!cli->sectorsize) {
> diff --git a/repair/sb.c b/repair/sb.c
> index 0e4827e04678..ee1cc63fae64 100644
> --- a/repair/sb.c
> +++ b/repair/sb.c
> @@ -184,8 +184,7 @@ guess_default_geometry(
> uint64_t dblocks;
> int multidisk;
>
> - memset(&ft, 0, sizeof(ft));
> - get_topology(x, &ft, 1);
> + libxfs_get_topology(x, &ft, true);
>
> /*
> * get geometry from get_topology result.
> --
> 2.47.3
>
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 3/4] mkfs: remove duplicate struct libxfs_init arguments
2025-10-29 9:07 ` [PATCH 3/4] mkfs: remove duplicate struct libxfs_init arguments Christoph Hellwig
@ 2025-10-29 15:39 ` Darrick J. Wong
0 siblings, 0 replies; 9+ messages in thread
From: Darrick J. Wong @ 2025-10-29 15:39 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Andrey Albershteyn, linux-xfs
On Wed, Oct 29, 2025 at 10:07:31AM +0100, Christoph Hellwig wrote:
> The libxfs_init structure instance is pointed to by cli_params, so use
> that were it already exists instead of passing an additional argument.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Yay fewer args,
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
--D
> ---
> mkfs/xfs_mkfs.c | 49 ++++++++++++++++++++++---------------------------
> 1 file changed, 22 insertions(+), 27 deletions(-)
>
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index 0ba7798eccf6..09a69af31be5 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -4005,8 +4005,7 @@ ddev_is_solidstate(
> static void
> calc_concurrency_ag_geometry(
> struct mkfs_params *cfg,
> - struct cli_params *cli,
> - struct libxfs_init *xi)
> + struct cli_params *cli)
> {
> uint64_t try_agsize;
> uint64_t def_agsize;
> @@ -4074,11 +4073,10 @@ out:
> static void
> calculate_initial_ag_geometry(
> struct mkfs_params *cfg,
> - struct cli_params *cli,
> - struct libxfs_init *xi)
> + struct cli_params *cli)
> {
> if (cli->data_concurrency > 0) {
> - calc_concurrency_ag_geometry(cfg, cli, xi);
> + calc_concurrency_ag_geometry(cfg, cli);
> } else if (cli->agsize) { /* User-specified AG size */
> cfg->agsize = getnum(cli->agsize, &dopts, D_AGSIZE);
>
> @@ -4099,8 +4097,9 @@ _("agsize (%s) not a multiple of fs blk size (%d)\n"),
> cfg->agcount = cli->agcount;
> cfg->agsize = cfg->dblocks / cfg->agcount +
> (cfg->dblocks % cfg->agcount != 0);
> - } else if (cli->data_concurrency == -1 && ddev_is_solidstate(xi)) {
> - calc_concurrency_ag_geometry(cfg, cli, xi);
> + } else if (cli->data_concurrency == -1 &&
> + ddev_is_solidstate(cli->xi)) {
> + calc_concurrency_ag_geometry(cfg, cli);
> } else {
> calc_default_ag_geometry(cfg->blocklog, cfg->dblocks,
> cfg->dsunit, &cfg->agsize,
> @@ -4360,8 +4359,7 @@ rtdev_is_solidstate(
> static void
> calc_concurrency_rtgroup_geometry(
> struct mkfs_params *cfg,
> - struct cli_params *cli,
> - struct libxfs_init *xi)
> + struct cli_params *cli)
> {
> uint64_t try_rgsize;
> uint64_t def_rgsize;
> @@ -4468,8 +4466,7 @@ _("realtime group count (%llu) must be less than the maximum (%u)\n"),
> static void
> calculate_rtgroup_geometry(
> struct mkfs_params *cfg,
> - struct cli_params *cli,
> - struct libxfs_init *xi)
> + struct cli_params *cli)
> {
> if (!cli->sb_feat.metadir) {
> cfg->rgcount = 0;
> @@ -4510,8 +4507,9 @@ _("rgsize (%s) not a multiple of fs blk size (%d)\n"),
> cfg->rgsize = cfg->rtblocks;
> cfg->rgcount = 0;
> } else if (cli->rtvol_concurrency > 0 ||
> - (cli->rtvol_concurrency == -1 && rtdev_is_solidstate(xi))) {
> - calc_concurrency_rtgroup_geometry(cfg, cli, xi);
> + (cli->rtvol_concurrency == -1 &&
> + rtdev_is_solidstate(cli->xi))) {
> + calc_concurrency_rtgroup_geometry(cfg, cli);
> } else if (is_power_of_2(cfg->rtextblocks)) {
> cfg->rgsize = calc_rgsize_extsize_power(cfg);
> cfg->rgcount = cfg->rtblocks / cfg->rgsize +
> @@ -4538,7 +4536,6 @@ 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;
> @@ -4547,7 +4544,8 @@ adjust_nr_zones(
> if (zt->rt.nr_zones)
> max_zones = zt->rt.nr_zones;
> else
> - max_zones = DTOBT(xi->rt.size, cfg->blocklog) / cfg->rgsize;
> + max_zones = DTOBT(cli->xi->rt.size, cfg->blocklog) /
> + cfg->rgsize;
>
> if (!cli->rgcount)
> cfg->rgcount += XFS_RESERVED_ZONES;
> @@ -4576,7 +4574,6 @@ static void
> calculate_zone_geometry(
> struct mkfs_params *cfg,
> struct cli_params *cli,
> - struct libxfs_init *xi,
> struct zone_topology *zt)
> {
> if (cfg->rtblocks == 0) {
> @@ -4645,7 +4642,7 @@ _("rgsize (%s) not a multiple of fs blk size (%d)\n"),
> }
>
> if (cli->rtsize || cli->rgcount)
> - adjust_nr_zones(cfg, cli, xi, zt);
> + adjust_nr_zones(cfg, cli, zt);
>
> if (cfg->rgcount < XFS_MIN_ZONES) {
> fprintf(stderr,
> @@ -4984,7 +4981,6 @@ static uint64_t
> calc_concurrency_logblocks(
> struct mkfs_params *cfg,
> struct cli_params *cli,
> - struct libxfs_init *xi,
> unsigned int max_tx_bytes)
> {
> uint64_t log_bytes;
> @@ -4992,7 +4988,7 @@ calc_concurrency_logblocks(
> unsigned int new_logblocks;
>
> if (cli->log_concurrency < 0) {
> - if (!ddev_is_solidstate(xi))
> + if (!ddev_is_solidstate(cli->xi))
> goto out;
>
> cli->log_concurrency = nr_cpus();
> @@ -5160,7 +5156,6 @@ static void
> calculate_log_size(
> struct mkfs_params *cfg,
> struct cli_params *cli,
> - struct libxfs_init *xi,
> struct xfs_mount *mp)
> {
> struct xfs_sb *sbp = &mp->m_sb;
> @@ -5225,8 +5220,8 @@ _("external log device size %lld blocks too small, must be at least %lld blocks\
> if (cfg->lsunit) {
> uint64_t max_logblocks;
>
> - max_logblocks = min(DTOBT(xi->log.size, cfg->blocklog),
> - XFS_MAX_LOG_BLOCKS);
> + max_logblocks = min(XFS_MAX_LOG_BLOCKS,
> + DTOBT(cli->xi->log.size, cfg->blocklog));
> align_log_size(cfg, cfg->lsunit, max_logblocks);
> }
>
> @@ -5261,7 +5256,7 @@ _("max log size %d smaller than min log size %d, filesystem is too small\n"),
>
> if (cli->log_concurrency != 0)
> cfg->logblocks = calc_concurrency_logblocks(cfg, cli,
> - xi, max_tx_bytes);
> + max_tx_bytes);
>
> /* But don't go below a reasonable size */
> cfg->logblocks = max(cfg->logblocks,
> @@ -6135,12 +6130,12 @@ main(
> * dependent on device sizes. Once calculated, make sure everything
> * aligns to device geometry correctly.
> */
> - calculate_initial_ag_geometry(&cfg, &cli, &xi);
> + calculate_initial_ag_geometry(&cfg, &cli);
> align_ag_geometry(&cfg, &ft);
> if (cfg.sb_feat.zoned)
> - calculate_zone_geometry(&cfg, &cli, &xi, &zt);
> + calculate_zone_geometry(&cfg, &cli, &zt);
> else
> - calculate_rtgroup_geometry(&cfg, &cli, &xi);
> + calculate_rtgroup_geometry(&cfg, &cli);
>
> calculate_imaxpct(&cfg, &cli);
>
> @@ -6164,7 +6159,7 @@ main(
> * With the mount set up, we can finally calculate the log size
> * constraints and do default size calculations and final validation
> */
> - calculate_log_size(&cfg, &cli, &xi, mp);
> + calculate_log_size(&cfg, &cli, mp);
>
> finish_superblock_setup(&cfg, mp, sbp);
>
> --
> 2.47.3
>
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 4/4] mkfs: split zone reset from discard
2025-10-29 9:07 ` [PATCH 4/4] mkfs: split zone reset from discard Christoph Hellwig
@ 2025-10-29 15:40 ` Darrick J. Wong
0 siblings, 0 replies; 9+ messages in thread
From: Darrick J. Wong @ 2025-10-29 15:40 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Andrey Albershteyn, linux-xfs
On Wed, Oct 29, 2025 at 10:07:32AM +0100, Christoph Hellwig wrote:
> Zone reset is a mandatory part of creating a file system on a zoned
> device, unlike discard, which can be skipped. It also is implemented
> a bit different, so just split the handling. This also means that we
> can now support the -K option to skip discard on the data section for
> zoned file systems.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Nice feature improvement! ;)
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
--D
> ---
> mkfs/xfs_mkfs.c | 112 +++++++++++++++++++++++-------------------------
> 1 file changed, 53 insertions(+), 59 deletions(-)
>
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index 09a69af31be5..cd4f3ba4a549 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -1607,34 +1607,6 @@ discard_blocks(int fd, uint64_t nsectors, int quiet)
> printf("Done.\n");
> }
>
> -static void
> -reset_zones(
> - struct mkfs_params *cfg,
> - int fd,
> - uint64_t start_sector,
> - uint64_t nsectors,
> - int quiet)
> -{
> - struct blk_zone_range range = {
> - .sector = start_sector,
> - .nr_sectors = nsectors,
> - };
> -
> - if (!quiet) {
> - printf("Resetting zones...");
> - fflush(stdout);
> - }
> -
> - if (ioctl(fd, BLKRESETZONE, &range) < 0) {
> - if (!quiet)
> - printf(" FAILED (%d)\n", -errno);
> - exit(1);
> - }
> -
> - if (!quiet)
> - printf("Done.\n");
> -}
> -
> static __attribute__((noreturn)) void
> illegal_option(
> const char *value,
> @@ -3780,41 +3752,66 @@ discard_devices(
> struct zone_topology *zt,
> int quiet)
> {
> - /*
> - * This function has to be called after libxfs has been initialized.
> - */
> -
> if (!xi->data.isfile) {
> uint64_t nsectors = xi->data.size;
>
> - if (cfg->rtstart && zt->data.nr_zones) {
> - /*
> - * Note that the zone reset here includes the LBA range
> - * for the data device.
> - *
> - * This is because doing a single zone reset all on the
> - * entire device (which the kernel automatically does
> - * for us for a full device range) is a lot faster than
> - * resetting each zone individually and resetting
> - * the conventional zones used for the data device is a
> - * no-op.
> - */
> - reset_zones(cfg, xi->data.fd, 0,
> - cfg->rtstart + xi->rt.size, quiet);
> + if (cfg->rtstart && zt->data.nr_zones)
> nsectors -= cfg->rtstart;
> - }
> discard_blocks(xi->data.fd, nsectors, quiet);
> }
> - if (xi->rt.dev && !xi->rt.isfile) {
> - if (zt->rt.nr_zones)
> - reset_zones(cfg, xi->rt.fd, 0, xi->rt.size, quiet);
> - else
> - discard_blocks(xi->rt.fd, xi->rt.size, quiet);
> - }
> + if (xi->rt.dev && !xi->rt.isfile && !zt->rt.nr_zones)
> + discard_blocks(xi->rt.fd, xi->rt.size, quiet);
> if (xi->log.dev && xi->log.dev != xi->data.dev && !xi->log.isfile)
> discard_blocks(xi->log.fd, xi->log.size, quiet);
> }
>
> +static void
> +reset_zones(
> + struct mkfs_params *cfg,
> + struct libxfs_dev *dev,
> + uint64_t size,
> + bool quiet)
> +{
> + struct blk_zone_range range = {
> + .nr_sectors = size,
> + };
> +
> + if (!quiet) {
> + printf("Resetting zones...");
> + fflush(stdout);
> + }
> + if (ioctl(dev->fd, BLKRESETZONE, &range) < 0) {
> + if (!quiet)
> + printf(" FAILED (%d)\n", -errno);
> + exit(1);
> + }
> + if (!quiet)
> + printf("Done.\n");
> +}
> +
> +static void
> +reset_devices(
> + struct mkfs_params *cfg,
> + struct libxfs_init *xi,
> + struct zone_topology *zt,
> + int quiet)
> +{
> + /*
> + * Note that the zone reset here includes the conventional zones used
> + * for the data device.
> + *
> + * It is done that way because doing a single zone reset all on the
> + * entire device (which the kernel automatically does for us for a full
> + * device range) is a lot faster than resetting each zone individually
> + * and resetting the conventional zones used for the data device is a
> + * no-op.
> + */
> + if (!xi->data.isfile && zt->data.nr_zones && cfg->rtstart)
> + reset_zones(cfg, &xi->data, cfg->rtstart + xi->rt.size, quiet);
> + if (xi->rt.dev && !xi->rt.isfile && zt->rt.nr_zones)
> + reset_zones(cfg, &xi->rt, xi->rt.size, quiet);
> +}
> +
> static void
> validate_datadev(
> struct mkfs_params *cfg,
> @@ -6196,13 +6193,10 @@ main(
> /*
> * All values have been validated, discard the old device layout.
> */
> - if (cli.sb_feat.zoned && !discard) {
> - fprintf(stderr,
> - _("-K not support for zoned file systems.\n"));
> - return 1;
> - }
> if (discard && !dry_run)
> - discard_devices(&cfg, &xi, &zt, quiet);
> + discard_devices(&cfg, cli.xi, &zt, quiet);
> + if (cli.sb_feat.zoned && !dry_run)
> + reset_devices(&cfg, cli.xi, &zt, quiet);
>
> /*
> * we need the libxfs buffer cache from here on in.
> --
> 2.47.3
>
>
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2025-10-29 15:40 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-29 9:07 improve the discard / reset zones code in mkfs Christoph Hellwig
2025-10-29 9:07 ` [PATCH 1/4] mkfs: move clearing LIBXFS_DIRECT into check_device_type Christoph Hellwig
2025-10-29 15:38 ` Darrick J. Wong
2025-10-29 9:07 ` [PATCH 2/4] libxfs: cleanup get_topology Christoph Hellwig
2025-10-29 15:39 ` Darrick J. Wong
2025-10-29 9:07 ` [PATCH 3/4] mkfs: remove duplicate struct libxfs_init arguments Christoph Hellwig
2025-10-29 15:39 ` Darrick J. Wong
2025-10-29 9:07 ` [PATCH 4/4] mkfs: split zone reset from discard Christoph Hellwig
2025-10-29 15:40 ` Darrick J. Wong
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).