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