Linux XFS filesystem development
 help / color / mirror / Atom feed
From: "Darrick J. Wong" <djwong@kernel.org>
To: Christoph Hellwig <hch@lst.de>
Cc: Andrey Albershteyn <aalbersh@kernel.org>, linux-xfs@vger.kernel.org
Subject: Re: [PATCH 1/2] growfs: support unit postfixes when specifying sizes
Date: Thu, 30 Jul 2026 08:49:52 -0700	[thread overview]
Message-ID: <20260730154952.GD3556460@frogsfrogsfrogs> (raw)
In-Reply-To: <20260730122841.2591200-2-hch@lst.de>

On Thu, Jul 30, 2026 at 02:28:15PM +0200, Christoph Hellwig wrote:
> Try using cvtnum to parse the sizes for the -D, -L and -R arguments,
> and only fall back to plain integer parsing and interpreting it as
> blocks when that fails.  This matches the mkfs UI and makes specifying
> a size significantly easier.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  growfs/xfs_growfs.c   | 30 +++++++++++++++++++++++++++---
>  man/man8/xfs_growfs.8 | 39 +++++++++++++++++++++++++++++++--------
>  2 files changed, 58 insertions(+), 11 deletions(-)
> 
> diff --git a/growfs/xfs_growfs.c b/growfs/xfs_growfs.c
> index 0d0b2ae3e739..6e65f037c5cb 100644
> --- a/growfs/xfs_growfs.c
> +++ b/growfs/xfs_growfs.c
> @@ -5,6 +5,7 @@
>   */
>  
>  #include "libxfs.h"
> +#include "libfrog/convert.h"
>  #include "libfrog/paths.h"
>  #include "libfrog/fsgeom.h"
>  
> @@ -31,6 +32,19 @@ Options:\n\
>  	exit(2);
>  }
>  
> +static long long
> +parse_size(
> +	struct xfs_fsop_geom	*geo,
> +	const char		*size_str)
> +{
> +	long long		size;
> +
> +	size = cvtnum(geo->blocksize, geo->sectsize, size_str);
> +	if (size == -1)
> +		return strtoll(size_str, NULL, 10);
> +	return size / geo->blocksize;

Hmmm.  Previously, "-D 12345" meant "grow to 12345 fsblocks", right?
However, cvtnum(, "12345") returns 12345, which is now divided by the
fsblock size and we'll "grow" the filesystem to 3x 4k fsblocks.  So I
don't think this quite works, though the ability to specify "-D 12345M"
is very appealing.

--D

> +}
> +
>  int
>  main(int argc, char **argv)
>  {
> @@ -55,6 +69,9 @@ main(int argc, char **argv)
>  	struct xfs_fsop_geom	ngeo;	/* new fs geometry */
>  	int			rflag;	/* -r flag */
>  	long long		rsize;	/* new rt size in fs blocks */
> +	const char		*dsize_str = NULL;
> +	const char		*lsize_str = NULL;
> +	const char		*rsize_str = NULL;
>  	int			xflag;	/* -x flag */
>  	char			*fname;	/* mount point name */
>  	char			*datadev; /* data device name */
> @@ -77,7 +94,7 @@ main(int argc, char **argv)
>  	while ((c = getopt(argc, argv, "dD:e:ilL:m:np:rR:t:xV")) != EOF) {
>  		switch (c) {
>  		case 'D':
> -			dsize = strtoll(optarg, NULL, 10);
> +			dsize_str = strdup(optarg);
>  			fallthrough;
>  		case 'd':
>  			dflag = 1;
> @@ -90,7 +107,7 @@ main(int argc, char **argv)
>  			lflag = iflag = 1;
>  			break;
>  		case 'L':
> -			lsize = strtoll(optarg, NULL, 10);
> +			lsize_str = strdup(optarg);
>  			fallthrough;
>  		case 'l':
>  			lflag = 1;
> @@ -106,7 +123,7 @@ main(int argc, char **argv)
>  			progname = optarg;
>  			break;
>  		case 'R':
> -			rsize = strtoll(optarg, NULL, 10);
> +			rsize_str = strdup(optarg);
>  			fallthrough;
>  		case 'r':
>  			rflag = 1;
> @@ -211,6 +228,13 @@ main(int argc, char **argv)
>  
>  	xfs_report_geom(&geo, datadev, logdev, rtdev);
>  
> +	if (dsize_str)
> +		dsize = parse_size(&geo, dsize_str);
> +	if (lsize_str)
> +		lsize = parse_size(&geo, lsize_str);
> +	if (rsize_str)
> +		rsize = parse_size(&geo, rsize_str);
> +
>  	if (geo.rtstart) {
>  		xfs_daddr_t rtstart = geo.rtstart * (geo.blocksize / BBSIZE);
>  
> diff --git a/man/man8/xfs_growfs.8 b/man/man8/xfs_growfs.8
> index 2e329fa61758..d6e5fe13e943 100644
> --- a/man/man8/xfs_growfs.8
> +++ b/man/man8/xfs_growfs.8
> @@ -57,6 +57,32 @@ The filesystem must be mounted to be grown (see
>  .BR mount (8)).
>  The existing contents of the filesystem are undisturbed, and the added space
>  becomes available for additional file storage.
> +The following lists possible multiplication suffixes for any argument specifying
> +sizes.
> +.RS
> +.PD 0
> +.HP
> +.BR s "\ \-\ multiply by sector size (default = 512, see " \-s
> +option below).
> +.HP
> +.BR b "\ \-\ multiply by filesystem block size (default = 4K, see " \-b
> +option below).
> +.HP
> +.BR k "\ \-\ multiply by one kilobyte (1,024 bytes)."
> +.HP
> +.BR m "\ \-\ multiply by one megabyte (1,048,576 bytes)."
> +.HP
> +.BR g "\ \-\ multiply by one gigabyte (1,073,741,824 bytes)."
> +.HP
> +.BR t "\ \-\ multiply by one terabyte (1,099,511,627,776 bytes)."
> +.HP
> +.BR p "\ \-\ multiply by one petabyte (1,024 terabytes)."
> +.HP
> +.BR e "\ \-\ multiply by one exabyte (1,048,576 terabytes)."
> +.PD
> +.RE
> +If no suffix is specified, the sizes are in file system blocks.
> +.RE
>  .SH OPTIONS
>  .TP
>  .BI "\-d | \-D " size
> @@ -67,9 +93,8 @@ option is given, the data section is changed to that
>  .IR size ,
>  otherwise the data section is grown to the largest size possible with the
>  .B \-d
> -option. The size is expressed in filesystem blocks. A filesystem with only
> -1 AG cannot be shrunk further, and a filesystem cannot be shrunk to the point
> -where it would only have 1 AG.
> +option. A filesystem with only 1 AG cannot be shrunk further, and a
> +filesystem cannot be shrunk to the point where it would only have 1 AG.
>  .B [NOTE: Only shrinking the last AG without removing it is implemented]
>  .TP
>  .B \-e
> @@ -90,8 +115,7 @@ shrunk, or moved. If the
>  .I size
>  option is given, the log section is changed to be that
>  .IR size ,
> -if possible. The size is expressed in filesystem blocks.
> -The size of an internal log must be smaller than the size
> +if possible. The size of an internal log must be smaller than the size
>  of an allocation group (this value is printed at
>  .BR mkfs (8)
>  time). If neither
> @@ -124,9 +148,8 @@ Specifies that the real-time section of the filesystem should be grown. If the
>  option is given, the real-time section is grown to that size, otherwise
>  the real-time section is grown to the largest size possible with the
>  .B \-r
> -option. The size is expressed in filesystem blocks.
> -The filesystem does not need to have contained a real-time section before
> -the
> +option. The filesystem does not need to have contained a real-time section
> +before the
>  .B xfs_growfs
>  operation.
>  .TP
> -- 
> 2.53.0
> 
> 

  reply	other threads:[~2026-07-30 15:49 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-30 12:28 make the size options to xfs_growfs a bit more useful v2 Christoph Hellwig
2026-07-30 12:28 ` [PATCH 1/2] growfs: support unit postfixes when specifying sizes Christoph Hellwig
2026-07-30 15:49   ` Darrick J. Wong [this message]
2026-07-30 12:28 ` [PATCH 2/2] growfs: clarify the man page a bit Christoph Hellwig
2026-07-30 15:44   ` Darrick J. Wong
  -- strict thread matches above, loose matches on Subject: below --
2026-07-30 12:25 make the size options to xfs_growfs a bit more useful Christoph Hellwig
2026-07-30 12:25 ` [PATCH 1/2] growfs: support unit postfixes when specifying sizes Christoph Hellwig

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260730154952.GD3556460@frogsfrogsfrogs \
    --to=djwong@kernel.org \
    --cc=aalbersh@kernel.org \
    --cc=hch@lst.de \
    --cc=linux-xfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox