From: Darrick J. Wong Date: Tue, 20 Jan 2026 17:50:48 +0000 (-0800) Subject: mkfs: set rtstart from user-specified dblocks X-Git-Tag: v6.19.0~30 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=81bedc02de7d8651551358631e8f2eea0682f30e;p=xfsprogs-dev.git mkfs: set rtstart from user-specified dblocks generic/211 fails to format the disk on a system with an internal zoned device. Poking through the shell scripts, it's apparently doing this: # mkfs.xfs -d size=629145600 -r size=629145600 -b size=4096 -m metadir=1,autofsck=1,uquota,gquota,pquota, -r zoned=1 -d rtinherit=1 /dev/sdd size 629145600 specified for data subvolume is too large, maximum is 131072 blocks Strange -- we asked for 629M data and rt sections, the device is 20GB in size, but it claims insufficient space in the data subvolume. Further analysis shows that open_devices is setting rtstart to 1% of the size of the data volume (or no less than 300M) and rounding that up to the nearest power of two (512M). Hence the 131072 number. But wait, we said that we wanted a 629M data section. Let's set rtstart to the same value if the user didn't already provide one, instead of using the default value. Cc: linux-xfs@vger.kernel.org # v6.15.0 Fixes: 2e5a737a61d34e ("xfs_mkfs: support creating file system with zoned RT devices") Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index b3440772..a90160b2 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -3696,6 +3696,36 @@ _("log stripe unit (%d bytes) is too large (maximum is 256KiB)\n" } +static uint64_t +calc_rtstart( + const struct mkfs_params *cfg, + const struct libxfs_init *xi) +{ + uint64_t rt_target_size; + uint64_t rtstart = 1; + + if (cfg->dblocks) { + /* + * If the user specified the size of the data device but not + * the start of the internal rt device, set the internal rt + * volume to start at the end of the data device. + */ + return cfg->dblocks << (cfg->blocklog - BBSHIFT); + } + + /* + * By default reserve at 1% of the total capacity (rounded up to the + * next power of two) for metadata, but match the minimum we enforce + * elsewhere. This matches what SMR HDDs provide. + */ + rt_target_size = max((xi->data.size + 99) / 100, + BTOBB(300 * 1024 * 1024)); + + while (rtstart < rt_target_size) + rtstart <<= 1; + return rtstart; +} + static void open_devices( struct mkfs_params *cfg, @@ -3720,17 +3750,7 @@ open_devices( zt->rt.zone_capacity = zt->data.zone_capacity; zt->rt.nr_zones = zt->data.nr_zones - zt->data.nr_conv_zones; } else if (cfg->sb_feat.zoned && !cfg->rtstart && !xi->rt.dev) { - /* - * By default reserve at 1% of the total capacity (rounded up to - * the next power of two) for metadata, but match the minimum we - * enforce elsewhere. This matches what SMR HDDs provide. - */ - uint64_t rt_target_size = max((xi->data.size + 99) / 100, - BTOBB(300 * 1024 * 1024)); - - cfg->rtstart = 1; - while (cfg->rtstart < rt_target_size) - cfg->rtstart <<= 1; + cfg->rtstart = calc_rtstart(cfg, xi); } if (cfg->rtstart) {