Re: [PATCH 2/2] xfs_io: make statx mask parsing more generally useful

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2025-04-15 22:22:51, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@xxxxxxxxxx>
> 
> Enhance the statx -m parsing to be more useful:
> 
> Add words for all the new STATX_* field flags added in the previous
> patch.
> 
> Allow "+" and "-" prefixes to add or remove flags from the mask.
> 
> Allow multiple arguments to be specified as a comma separated list.
> 
> Signed-off-by: "Darrick J. Wong" <djwong@xxxxxxxxxx>
> ---
>  io/stat.c         |  120 ++++++++++++++++++++++++++++++++++++++++++++++-------
>  man/man8/xfs_io.8 |   11 +++++
>  2 files changed, 116 insertions(+), 15 deletions(-)
> 
> diff --git a/io/stat.c b/io/stat.c
> index b37b1a12b8b2fd..ebc085845972c4 100644
> --- a/io/stat.c
> +++ b/io/stat.c
> @@ -321,10 +321,41 @@ _statx(
>  #endif
>  }
>  
> +struct statx_masks {
> +	const char	*name;
> +	unsigned int	mask;
> +};
> +
> +static const struct statx_masks statx_masks[] = {
> +	{"basic",		STATX_BASIC_STATS},
> +	{"all",			STATX_ALL},
> +
> +	{"type",		STATX_TYPE},
> +	{"mode",		STATX_MODE},
> +	{"nlink",		STATX_NLINK},
> +	{"uid",			STATX_UID},
> +	{"gid",			STATX_GID},
> +	{"atime",		STATX_ATIME},
> +	{"mtime",		STATX_MTIME},
> +	{"ctime",		STATX_CTIME},
> +	{"ino",			STATX_INO},
> +	{"size",		STATX_SIZE},
> +	{"blocks",		STATX_BLOCKS},
> +	{"btime",		STATX_BTIME},
> +	{"mnt_id",		STATX_MNT_ID},
> +	{"dioalign",		STATX_DIOALIGN},
> +	{"mnt_id_unique",	STATX_MNT_ID_UNIQUE},
> +	{"subvol",		STATX_SUBVOL},
> +	{"write_atomic",	STATX_WRITE_ATOMIC},
> +	{"dio_read_align",	STATX_DIO_READ_ALIGN},
> +};
> +
>  static void
>  statx_help(void)
>  {
> -        printf(_(
> +	unsigned int	i;
> +
> +	printf(_(
>  "\n"
>  " Display extended file status.\n"
>  "\n"
> @@ -333,9 +364,16 @@ statx_help(void)
>  " -r -- Print raw statx structure fields\n"
>  " -m mask -- Specify the field mask for the statx call\n"
>  "            (can also be 'basic' or 'all'; default STATX_ALL)\n"
this comment     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
then probably can go away, as it can be any of the above now

Otherwise, looks good to me
Reviewed-by: Andrey Albershteyn <aalbersh@xxxxxxxxxx>

> +" -m +mask -- Add this to the field mask for the statx call\n"
> +" -m -mask -- Remove this from the field mask for the statx call\n"
>  " -D -- Don't sync attributes with the server\n"
>  " -F -- Force the attributes to be sync'd with the server\n"
> -"\n"));
> +"\n"
> +"statx mask values: "));
> +
> +	for (i = 0; i < ARRAY_SIZE(statx_masks); i++)
> +		printf("%s%s", i == 0 ? "" : ", ", statx_masks[i].name);
> +	printf("\n");
>  }
>  
>  /* statx helper */
> @@ -376,6 +414,68 @@ dump_raw_statx(struct statx *stx)
>  	return 0;
>  }
>  
> +enum statx_mask_op {
> +	SET,
> +	REMOVE,
> +	ADD,
> +};
> +
> +static bool
> +parse_statx_masks(
> +	char			*optarg,
> +	unsigned int		*caller_mask)
> +{
> +	char			*arg = optarg;
> +	char			*word;
> +	unsigned int		i;
> +
> +	while ((word = strtok(arg, ",")) != NULL) {
> +		enum statx_mask_op op;
> +		unsigned int	mask;
> +		char		*p;
> +
> +		arg = NULL;
> +
> +		if (*word == '+') {
> +			op = ADD;
> +			word++;
> +		} else if (*word == '-') {
> +			op = REMOVE;
> +			word++;
> +		} else {
> +			op = SET;
> +		}
> +
> +		for (i = 0; i < ARRAY_SIZE(statx_masks); i++) {
> +			if (!strcmp(statx_masks[i].name, word)) {
> +				mask = statx_masks[i].mask;
> +				goto process_op;
> +			}
> +		}
> +
> +		mask = strtoul(word, &p, 0);
> +		if (!p || p == word) {
> +			printf( _("non-numeric mask -- %s\n"), word);
> +			return false;
> +		}
> +
> +process_op:
> +		switch (op) {
> +		case ADD:
> +			*caller_mask |= mask;
> +			continue;
> +		case REMOVE:
> +			*caller_mask &= ~mask;
> +			continue;
> +		case SET:
> +			*caller_mask = mask;
> +			continue;
> +		}
> +	}
> +
> +	return true;
> +}
> +
>  /*
>   * options:
>   * 	- input flags - query type
> @@ -388,7 +488,6 @@ statx_f(
>  	char		**argv)
>  {
>  	int		c, verbose = 0, raw = 0;
> -	char		*p;
>  	struct statx	stx;
>  	int		atflag = 0;
>  	unsigned int	mask = STATX_ALL;
> @@ -396,18 +495,9 @@ statx_f(
>  	while ((c = getopt(argc, argv, "m:rvFD")) != EOF) {
>  		switch (c) {
>  		case 'm':
> -			if (strcmp(optarg, "basic") == 0)
> -				mask = STATX_BASIC_STATS;
> -			else if (strcmp(optarg, "all") == 0)
> -				mask = STATX_ALL;
> -			else {
> -				mask = strtoul(optarg, &p, 0);
> -				if (!p || p == optarg) {
> -					printf(
> -				_("non-numeric mask -- %s\n"), optarg);
> -					exitcode = 1;
> -					return 0;
> -				}
> +			if (!parse_statx_masks(optarg, &mask)) {
> +				exitcode = 1;
> +				return 0;
>  			}
>  			break;
>  		case 'r':
> diff --git a/man/man8/xfs_io.8 b/man/man8/xfs_io.8
> index 726e25af272242..0e8e69a1fe0c22 100644
> --- a/man/man8/xfs_io.8
> +++ b/man/man8/xfs_io.8
> @@ -999,6 +999,17 @@ .SH FILE I/O COMMANDS
>  .B \-m <mask>
>  Specify a numeric field mask for the statx call.
>  .TP
> +.BI "\-m +" value
> +Add this value to the statx field value.
> +Values can be numeric, or they can be words describing the desired fields.
> +See the help command output for a list of recognized words.
> +.TP
> +.BI "\-m -" value
> +Remove this value from the statx field value.
> +.TP
> +.BI "\-m +" value ",-" value
> +Add and remove multiple values from the statx field value.
> +.TP
>  .B \-F
>  Force the attributes to be synced with the server.
>  .TP
> 

-- 
- Andrey





[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux