Re: [PATCH] xfs_io: changes to statx interface

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

 



On Tue, Mar 28, 2017 at 6:22 AM, David Howells <dhowells@xxxxxxxxxx> wrote:
> Eric Sandeen <sandeen@xxxxxxxxxxx> wrote:
>
>> Wire up the statx syscall to xfs_io.
>>
>> xfs_io> help statx
>> statx [-O | -m mask][-FDLA] -- extended information about the currently open file
>> ...
>
> I would like to make the attached changes, to make it more capable, except
> that xfs_io seems to precheck the "-m mask" argument somewhere:
>
>         [root@andromeda ~]# xfs_io -c statx -m all /dev/null
>         non-numeric mode -- all
>
> and interprets "-c" for itself on the command line:
>
>         [root@andromeda ~]# xfs_io -c statx -c /dev/null
>         command "/dev/null" not found

xfs_io -c "statx -c /dev/null"

is what you want

>
> though both these seem to work when used from xfs_io's command prompt.  I
> guess I should switch -c to -C and also -m to -M since it's not a file mode as
> I think the core is expecting.
>
> Also, how do you get xfs_io to tell you what fd it has opened from its own
> command prompt?  I would need to pass that to the -d flag as a dir fd.
>

See the output of 'file' command or the global var filetable.


> David
> ---
> commit 03e4ca1cdc59aaa362fdd51f079493a1f0da254c
> Author: David Howells <dhowells@xxxxxxxxxx>
> Date:   Tue Mar 28 10:42:23 2017 +0100
>
>     changes
>
> diff --git a/io/stat.c b/io/stat.c
> index a7aebcd..0b05ec9 100644
> --- a/io/stat.c
> +++ b/io/stat.c
> @@ -189,12 +189,14 @@ statx_help(void)
>  " Display extended file status.\n"
>  "\n"
>  " Options:\n"
> -" -m mask -- Specify the field mask for the statx call (default STATX_ALL)\n"
> +" -c -- Compare against fstat/fstatat on the same file/fd\n"
> +" -d dirfd -- Use a specific directory fd\n"
> +" -f -- Do fstat equivalent and operate on fd\n"
> +" -m mask -- Specify the field mask for the statx call (can also be 'basic' or 'all'; default STATX_ALL)\n"
>  " -A -- Suppress terminal automount traversal\n"
>  " -D -- Don't sync attributes with the server\n"
>  " -F -- Force the attributes to be sync'd with the server\n"
>  " -L -- Follow symlinks (statx link target)\n"
> -" -O -- Add only basic stats (STATX_BASIC_STATS) to default mask\n"
>  "\n"));
>  }
>
> @@ -227,6 +229,65 @@ dump_statx(struct statx *stx)
>  }
>
>  /*
> + * Compare the contents of a statx struct with that of a stat struct and check
> + * that they're the same.
> + */
> +static int
> +cmp_statx(const struct statx *stx, const struct stat *st)
> +{
> +       const char *what = NULL;
> +
> +#define cmp(x) \
> +       do {                                    \
> +               what = #x;              \
> +               if (stx->stx_##x != st->st_##x) \
> +                       goto mismatch;          \
> +       } while (0)
> +
> +       cmp(blksize);
> +       cmp(nlink);
> +       cmp(uid);
> +       cmp(gid);
> +       cmp(mode);
> +       cmp(ino);
> +       cmp(size);
> +       cmp(blocks);
> +
> +#define devcmp(x) \
> +       do {                                            \
> +               what = #x".major";                      \
> +               if (stx->stx_##x##_major != major(st->st_##x))  \
> +                       goto mismatch;                  \
> +               what = #x".minor";                      \
> +               if (stx->stx_##x##_minor != minor(st->st_##x))  \
> +                       goto mismatch;                  \
> +       } while (0)
> +
> +       devcmp(dev);
> +       devcmp(rdev);
> +
> +#define timecmp(x) \
> +       do {                                            \
> +               what = #x".tv_sec";                     \
> +               if (stx->stx_##x##time.tv_sec != st->st_##x##tim.tv_sec)        \
> +                       goto mismatch;                  \
> +               what = #x".tv_nsec";                    \
> +               if (stx->stx_##x##time.tv_nsec != st->st_##x##tim.tv_nsec)      \
> +                       goto mismatch;                  \
> +       } while (0)
> +
> +       timecmp(a);
> +       timecmp(c);
> +       timecmp(m);
> +
> +       return 0;
> +
> +mismatch:
> +       fprintf(stderr, "Mismatch between stat and statx output (%s)\n", what);
> +       return -1;
> +}
> +
> +/*
>   * options:
>   *     - input flags - query type
>   *     - output style for flags (and all else?) (chars vs. hex?)
> @@ -239,16 +300,31 @@ statx_f(
>  {
>         int             c;
>         struct statx    stx;
> +       struct stat     st;
>         int             atflag = AT_SYMLINK_NOFOLLOW;
> -       unsigned int    m_mask = 0;     /* mask requested with -m */
> -       int             Oflag = 0, mflag = 0;   /* -O or -m was used */
>         unsigned int    mask = STATX_ALL;
> +       int             use_fd = 0;
> +       int             dirfd = AT_FDCWD;
> +       int             compare = 0;
>
> -       while ((c = getopt(argc, argv, "m:FDLOA")) != EOF) {
> +       while ((c = getopt(argc, argv, "d:cfm:FDLA")) != EOF) {
>                 switch (c) {
> +               case 'c':
> +                       compare = 1;
> +                       break;
> +               case 'd':
> +                       dirfd = strtoul(optarg, NULL, 0);
> +                       break;
> +               case 'f':
> +                       use_fd = 1;
> +                       break;
>                 case 'm':
> -                       m_mask = atoi(optarg);
> -                       mflag = 1;
> +                       if (strcmp(optarg, "basic") == 0)
> +                               mask = STATX_BASIC_STATS;
> +                       else if (strcmp(optarg, "all") == 0)
> +                               mask = STATX_ALL;
> +                       else
> +                               mask = strtoul(optarg, NULL, 0);
>                         break;
>                 case 'F':
>                         atflag &= ~AT_STATX_SYNC_TYPE;
> @@ -261,10 +337,6 @@ statx_f(
>                 case 'L':
>                         atflag &= ~AT_SYMLINK_NOFOLLOW;
>                         break;
> -               case 'O':
> -                       mask = STATX_BASIC_STATS;
> -                       Oflag = 1;
> -                       break;
>                 case 'A':
>                         atflag |= AT_NO_AUTOMOUNT;
>                         break;
> @@ -273,23 +345,38 @@ statx_f(
>                 }
>         }
>
> -       if (Oflag && mflag) {
> -               printf("Cannot specify both -m mask and -O\n");
> -               return 0;
> +       memset(&stx, 0xbf, sizeof(stx));
> +
> +       if (use_fd) {
> +               if (statx(file->fd, NULL, atflag, mask, &stx) < 0) {
> +                       perror("statx");
> +                       return 0;
> +               }
> +       } else {
> +               if (statx(dirfd, file->name, atflag, mask, &stx) < 0) {
> +                       perror("statx");
> +                       return 0;
> +               }
>         }
>
> -       /* -m overrides any other mask options */
> -       if (mflag)
> -               mask = m_mask;
> +       if (compare) {
> +               if (use_fd) {
> +                       if (fstat(file->fd, &st) < 0) {
> +                               perror("fstat");
> +                               return 0;
> +                       }
> +               } else {
> +                       if (fstatat(dirfd, file->name, &st,
> +                                   atflag & ~AT_STATX_SYNC_TYPE) < 0) {
> +                               perror("fstatat");
> +                               return 0;
> +                       }
> +               }
>
> -       memset(&stx, 0xbf, sizeof(stx));
> -       if (statx(AT_FDCWD, file->name, atflag, mask, &stx) < 0) {
> -               perror("statx");
> -               return 0;
> +               cmp_statx(&stx, &st);
>         }
> -
> +
>         dump_statx(&stx);
> -
>         return 0;
>  }
>
--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[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