All of lore.kernel.org
 help / color / mirror / Atom feed
From: Anders Roxell <anders.roxell@linaro.org>
To: David Howells <dhowells@redhat.com>
Cc: viro@zeniv.linux.org.uk, torvalds@linux-foundation.org,
	ebiederm@xmission.com, linux-fsdevel@vger.kernel.org,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	mszeredi@redhat.com, Arnd Bergmann <arnd@arndb.de>
Subject: Re: [PATCH 34/34] vfs: Add a sample program for the new mount API [ver #12]
Date: Mon, 17 Dec 2018 15:12:52 +0100	[thread overview]
Message-ID: <CADYN=9KNL=6juu0WuHYPLu3bMNpVimUMWfFqmr5GbTrKPyOfVg@mail.gmail.com> (raw)
In-Reply-To: <153754768644.17872.4707695831889551662.stgit@warthog.procyon.org.uk>

On Fri, 21 Sep 2018 at 18:34, David Howells <dhowells@redhat.com> wrote:
>
> Add a sample program to demonstrate fsopen/fsmount/move_mount to mount
> something.
>
> Signed-off-by: David Howells <dhowells@redhat.com>

I was trying to build today linux-next tag next-20181217, I ran into
the build error below
when I was trying to build a allmodconfig kernel. I think this patch
triggers the build error.

In file included from /usr/include/x86_64-linux-gnu/sys/stat.h:446,
                 from ../samples/vfs/test-statx.c:28:
/usr/include/x86_64-linux-gnu/bits/statx.h:25:8: error: redefinition
of ‘struct statx_timestamp’
 struct statx_timestamp
        ^~~~~~~~~~~~~~~
In file included from ../samples/vfs/test-statx.c:26:
./usr/include/linux/stat.h:56:8: note: originally defined here
 struct statx_timestamp {
        ^~~~~~~~~~~~~~~
In file included from /usr/include/x86_64-linux-gnu/sys/stat.h:446,
                 from ../samples/vfs/test-statx.c:28:
/usr/include/x86_64-linux-gnu/bits/statx.h:36:8: error: redefinition
of ‘struct statx’
 struct statx
        ^~~~~
In file included from ../samples/vfs/test-statx.c:26:
./usr/include/linux/stat.h:99:8: note: originally defined here
 struct statx {
        ^~~~~
../samples/vfs/test-statx.c:40:9: error: conflicting types for ‘statx’
 ssize_t statx(int dfd, const char *filename, unsigned flags,
         ^~~~~
In file included from /usr/include/x86_64-linux-gnu/sys/stat.h:446,
                 from ../samples/vfs/test-statx.c:28:
/usr/include/x86_64-linux-gnu/bits/statx.h:87:5: note: previous
declaration of ‘statx’ was here
 int statx (int __dirfd, const char *__restrict __path, int __flags,
     ^~~~~
make[3]: *** [scripts/Makefile.host:90: samples/vfs/test-statx] Error 1
make[3]: Target '__build' not remade because of errors.
make[2]: *** [../scripts/Makefile.build:492: samples/vfs] Error 2
make[2]: Target '__build' not remade because of errors.
make[1]: *** [/srv/src/kernel/next/Makefile:1065: samples] Error 2
make[1]: Target 'bzImage' not remade because of errors.
make: *** [Makefile:152: sub-make] Error 2
make: Target 'bzImage' not remade because of errors.

My libc version:
$ dpkg -l libc6
ii  libc6:amd64    2.28-2       amd64        GNU C Library: Shared libraries

Any idea what I do wrong?

Cheers,
Anders

> ---
>
>  samples/Kconfig            |   10 +-
>  samples/Makefile           |    2
>  samples/statx/Makefile     |    7 -
>  samples/statx/test-statx.c |  258 --------------------------------------------
>  samples/vfs/Makefile       |   10 ++
>  samples/vfs/test-fsmount.c |  118 ++++++++++++++++++++
>  samples/vfs/test-statx.c   |  258 ++++++++++++++++++++++++++++++++++++++++++++
>  7 files changed, 393 insertions(+), 270 deletions(-)
>  delete mode 100644 samples/statx/Makefile
>  delete mode 100644 samples/statx/test-statx.c
>  create mode 100644 samples/vfs/Makefile
>  create mode 100644 samples/vfs/test-fsmount.c
>  create mode 100644 samples/vfs/test-statx.c
>
> diff --git a/samples/Kconfig b/samples/Kconfig
> index bd133efc1a56..8df1c012820f 100644
> --- a/samples/Kconfig
> +++ b/samples/Kconfig
> @@ -146,10 +146,12 @@ config SAMPLE_VFIO_MDEV_MBOCHS
>           Specifically it does *not* include any legacy vga stuff.
>           Device looks a lot like "qemu -device secondary-vga".
>
> -config SAMPLE_STATX
> -       bool "Build example extended-stat using code"
> -       depends on BROKEN
> +config SAMPLE_VFS
> +       bool "Build example programs that use new VFS system calls"
> +       depends on X86
>         help
> -         Build example userspace program to use the new extended-stat syscall.
> +         Build example userspace programs that use new VFS system calls such
> +         as mount API and statx().  Note that this is restricted to the x86
> +         arch whilst it accesses system calls that aren't yet in all arches.
>
>  endif # SAMPLES
> diff --git a/samples/Makefile b/samples/Makefile
> index bd601c038b86..c5a6175c2d3f 100644
> --- a/samples/Makefile
> +++ b/samples/Makefile
> @@ -3,4 +3,4 @@
>  obj-$(CONFIG_SAMPLES)  += kobject/ kprobes/ trace_events/ livepatch/ \
>                            hw_breakpoint/ kfifo/ kdb/ hidraw/ rpmsg/ seccomp/ \
>                            configfs/ connector/ v4l/ trace_printk/ \
> -                          vfio-mdev/ statx/ qmi/
> +                          vfio-mdev/ vfs/ qmi/
> diff --git a/samples/statx/Makefile b/samples/statx/Makefile
> deleted file mode 100644
> index 59df7c25a9d1..000000000000
> --- a/samples/statx/Makefile
> +++ /dev/null
> @@ -1,7 +0,0 @@
> -# List of programs to build
> -hostprogs-$(CONFIG_SAMPLE_STATX) := test-statx
> -
> -# Tell kbuild to always build the programs
> -always := $(hostprogs-y)
> -
> -HOSTCFLAGS_test-statx.o += -I$(objtree)/usr/include
> diff --git a/samples/statx/test-statx.c b/samples/statx/test-statx.c
> deleted file mode 100644
> index d4d77b09412c..000000000000
> --- a/samples/statx/test-statx.c
> +++ /dev/null
> @@ -1,258 +0,0 @@
> -/* Test the statx() system call.
> - *
> - * Note that the output of this program is intended to look like the output of
> - * /bin/stat where possible.
> - *
> - * Copyright (C) 2015 Red Hat, Inc. All Rights Reserved.
> - * Written by David Howells (dhowells@redhat.com)
> - *
> - * This program is free software; you can redistribute it and/or
> - * modify it under the terms of the GNU General Public Licence
> - * as published by the Free Software Foundation; either version
> - * 2 of the Licence, or (at your option) any later version.
> - */
> -
> -#define _GNU_SOURCE
> -#define _ATFILE_SOURCE
> -#include <stdio.h>
> -#include <stdlib.h>
> -#include <string.h>
> -#include <unistd.h>
> -#include <ctype.h>
> -#include <errno.h>
> -#include <time.h>
> -#include <sys/syscall.h>
> -#include <sys/types.h>
> -#include <linux/stat.h>
> -#include <linux/fcntl.h>
> -#include <sys/stat.h>
> -
> -#define AT_STATX_SYNC_TYPE     0x6000
> -#define AT_STATX_SYNC_AS_STAT  0x0000
> -#define AT_STATX_FORCE_SYNC    0x2000
> -#define AT_STATX_DONT_SYNC     0x4000
> -
> -static __attribute__((unused))
> -ssize_t statx(int dfd, const char *filename, unsigned flags,
> -             unsigned int mask, struct statx *buffer)
> -{
> -       return syscall(__NR_statx, dfd, filename, flags, mask, buffer);
> -}
> -
> -static void print_time(const char *field, struct statx_timestamp *ts)
> -{
> -       struct tm tm;
> -       time_t tim;
> -       char buffer[100];
> -       int len;
> -
> -       tim = ts->tv_sec;
> -       if (!localtime_r(&tim, &tm)) {
> -               perror("localtime_r");
> -               exit(1);
> -       }
> -       len = strftime(buffer, 100, "%F %T", &tm);
> -       if (len == 0) {
> -               perror("strftime");
> -               exit(1);
> -       }
> -       printf("%s", field);
> -       fwrite(buffer, 1, len, stdout);
> -       printf(".%09u", ts->tv_nsec);
> -       len = strftime(buffer, 100, "%z", &tm);
> -       if (len == 0) {
> -               perror("strftime2");
> -               exit(1);
> -       }
> -       fwrite(buffer, 1, len, stdout);
> -       printf("\n");
> -}
> -
> -static void dump_statx(struct statx *stx)
> -{
> -       char buffer[256], ft = '?';
> -
> -       printf("results=%x\n", stx->stx_mask);
> -
> -       printf(" ");
> -       if (stx->stx_mask & STATX_SIZE)
> -               printf(" Size: %-15llu", (unsigned long long)stx->stx_size);
> -       if (stx->stx_mask & STATX_BLOCKS)
> -               printf(" Blocks: %-10llu", (unsigned long long)stx->stx_blocks);
> -       printf(" IO Block: %-6llu", (unsigned long long)stx->stx_blksize);
> -       if (stx->stx_mask & STATX_TYPE) {
> -               switch (stx->stx_mode & S_IFMT) {
> -               case S_IFIFO:   printf("  FIFO\n");                     ft = 'p'; break;
> -               case S_IFCHR:   printf("  character special file\n");   ft = 'c'; break;
> -               case S_IFDIR:   printf("  directory\n");                ft = 'd'; break;
> -               case S_IFBLK:   printf("  block special file\n");       ft = 'b'; break;
> -               case S_IFREG:   printf("  regular file\n");             ft = '-'; break;
> -               case S_IFLNK:   printf("  symbolic link\n");            ft = 'l'; break;
> -               case S_IFSOCK:  printf("  socket\n");                   ft = 's'; break;
> -               default:
> -                       printf(" unknown type (%o)\n", stx->stx_mode & S_IFMT);
> -                       break;
> -               }
> -       } else {
> -               printf(" no type\n");
> -       }
> -
> -       sprintf(buffer, "%02x:%02x", stx->stx_dev_major, stx->stx_dev_minor);
> -       printf("Device: %-15s", buffer);
> -       if (stx->stx_mask & STATX_INO)
> -               printf(" Inode: %-11llu", (unsigned long long) stx->stx_ino);
> -       if (stx->stx_mask & STATX_NLINK)
> -               printf(" Links: %-5u", stx->stx_nlink);
> -       if (stx->stx_mask & STATX_TYPE) {
> -               switch (stx->stx_mode & S_IFMT) {
> -               case S_IFBLK:
> -               case S_IFCHR:
> -                       printf(" Device type: %u,%u",
> -                              stx->stx_rdev_major, stx->stx_rdev_minor);
> -                       break;
> -               }
> -       }
> -       printf("\n");
> -
> -       if (stx->stx_mask & STATX_MODE)
> -               printf("Access: (%04o/%c%c%c%c%c%c%c%c%c%c)  ",
> -                      stx->stx_mode & 07777,
> -                      ft,
> -                      stx->stx_mode & S_IRUSR ? 'r' : '-',
> -                      stx->stx_mode & S_IWUSR ? 'w' : '-',
> -                      stx->stx_mode & S_IXUSR ? 'x' : '-',
> -                      stx->stx_mode & S_IRGRP ? 'r' : '-',
> -                      stx->stx_mode & S_IWGRP ? 'w' : '-',
> -                      stx->stx_mode & S_IXGRP ? 'x' : '-',
> -                      stx->stx_mode & S_IROTH ? 'r' : '-',
> -                      stx->stx_mode & S_IWOTH ? 'w' : '-',
> -                      stx->stx_mode & S_IXOTH ? 'x' : '-');
> -       if (stx->stx_mask & STATX_UID)
> -               printf("Uid: %5d   ", stx->stx_uid);
> -       if (stx->stx_mask & STATX_GID)
> -               printf("Gid: %5d\n", stx->stx_gid);
> -
> -       if (stx->stx_mask & STATX_ATIME)
> -               print_time("Access: ", &stx->stx_atime);
> -       if (stx->stx_mask & STATX_MTIME)
> -               print_time("Modify: ", &stx->stx_mtime);
> -       if (stx->stx_mask & STATX_CTIME)
> -               print_time("Change: ", &stx->stx_ctime);
> -       if (stx->stx_mask & STATX_BTIME)
> -               print_time(" Birth: ", &stx->stx_btime);
> -
> -       if (stx->stx_attributes_mask) {
> -               unsigned char bits, mbits;
> -               int loop, byte;
> -
> -               static char attr_representation[64 + 1] =
> -                       /* STATX_ATTR_ flags: */
> -                       "????????"      /* 63-56 */
> -                       "????????"      /* 55-48 */
> -                       "????????"      /* 47-40 */
> -                       "????????"      /* 39-32 */
> -                       "????????"      /* 31-24        0x00000000-ff000000 */
> -                       "????????"      /* 23-16        0x00000000-00ff0000 */
> -                       "???me???"      /* 15- 8        0x00000000-0000ff00 */
> -                       "?dai?c??"      /*  7- 0        0x00000000-000000ff */
> -                       ;
> -
> -               printf("Attributes: %016llx (", stx->stx_attributes);
> -               for (byte = 64 - 8; byte >= 0; byte -= 8) {
> -                       bits = stx->stx_attributes >> byte;
> -                       mbits = stx->stx_attributes_mask >> byte;
> -                       for (loop = 7; loop >= 0; loop--) {
> -                               int bit = byte + loop;
> -
> -                               if (!(mbits & 0x80))
> -                                       putchar('.');   /* Not supported */
> -                               else if (bits & 0x80)
> -                                       putchar(attr_representation[63 - bit]);
> -                               else
> -                                       putchar('-');   /* Not set */
> -                               bits <<= 1;
> -                               mbits <<= 1;
> -                       }
> -                       if (byte)
> -                               putchar(' ');
> -               }
> -               printf(")\n");
> -       }
> -}
> -
> -static void dump_hex(unsigned long long *data, int from, int to)
> -{
> -       unsigned offset, print_offset = 1, col = 0;
> -
> -       from /= 8;
> -       to = (to + 7) / 8;
> -
> -       for (offset = from; offset < to; offset++) {
> -               if (print_offset) {
> -                       printf("%04x: ", offset * 8);
> -                       print_offset = 0;
> -               }
> -               printf("%016llx", data[offset]);
> -               col++;
> -               if ((col & 3) == 0) {
> -                       printf("\n");
> -                       print_offset = 1;
> -               } else {
> -                       printf(" ");
> -               }
> -       }
> -
> -       if (!print_offset)
> -               printf("\n");
> -}
> -
> -int main(int argc, char **argv)
> -{
> -       struct statx stx;
> -       int ret, raw = 0, atflag = AT_SYMLINK_NOFOLLOW;
> -
> -       unsigned int mask = STATX_ALL;
> -
> -       for (argv++; *argv; argv++) {
> -               if (strcmp(*argv, "-F") == 0) {
> -                       atflag &= ~AT_STATX_SYNC_TYPE;
> -                       atflag |= AT_STATX_FORCE_SYNC;
> -                       continue;
> -               }
> -               if (strcmp(*argv, "-D") == 0) {
> -                       atflag &= ~AT_STATX_SYNC_TYPE;
> -                       atflag |= AT_STATX_DONT_SYNC;
> -                       continue;
> -               }
> -               if (strcmp(*argv, "-L") == 0) {
> -                       atflag &= ~AT_SYMLINK_NOFOLLOW;
> -                       continue;
> -               }
> -               if (strcmp(*argv, "-O") == 0) {
> -                       mask &= ~STATX_BASIC_STATS;
> -                       continue;
> -               }
> -               if (strcmp(*argv, "-A") == 0) {
> -                       atflag |= AT_NO_AUTOMOUNT;
> -                       continue;
> -               }
> -               if (strcmp(*argv, "-R") == 0) {
> -                       raw = 1;
> -                       continue;
> -               }
> -
> -               memset(&stx, 0xbf, sizeof(stx));
> -               ret = statx(AT_FDCWD, *argv, atflag, mask, &stx);
> -               printf("statx(%s) = %d\n", *argv, ret);
> -               if (ret < 0) {
> -                       perror(*argv);
> -                       exit(1);
> -               }
> -
> -               if (raw)
> -                       dump_hex((unsigned long long *)&stx, 0, sizeof(stx));
> -
> -               dump_statx(&stx);
> -       }
> -       return 0;
> -}
> diff --git a/samples/vfs/Makefile b/samples/vfs/Makefile
> new file mode 100644
> index 000000000000..4ac9690fb3c4
> --- /dev/null
> +++ b/samples/vfs/Makefile
> @@ -0,0 +1,10 @@
> +# List of programs to build
> +hostprogs-$(CONFIG_SAMPLE_VFS) := \
> +       test-fsmount \
> +       test-statx
> +
> +# Tell kbuild to always build the programs
> +always := $(hostprogs-y)
> +
> +HOSTCFLAGS_test-fsmount.o += -I$(objtree)/usr/include
> +HOSTCFLAGS_test-statx.o += -I$(objtree)/usr/include
> diff --git a/samples/vfs/test-fsmount.c b/samples/vfs/test-fsmount.c
> new file mode 100644
> index 000000000000..74124025ade0
> --- /dev/null
> +++ b/samples/vfs/test-fsmount.c
> @@ -0,0 +1,118 @@
> +/* fd-based mount test.
> + *
> + * Copyright (C) 2017 Red Hat, Inc. All Rights Reserved.
> + * Written by David Howells (dhowells@redhat.com)
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public Licence
> + * as published by the Free Software Foundation; either version
> + * 2 of the Licence, or (at your option) any later version.
> + */
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <errno.h>
> +#include <fcntl.h>
> +#include <sys/prctl.h>
> +#include <sys/wait.h>
> +#include <linux/fs.h>
> +#include <linux/unistd.h>
> +
> +#define E(x) do { if ((x) == -1) { perror(#x); exit(1); } } while(0)
> +
> +static void check_messages(int fd)
> +{
> +       char buf[4096];
> +       int err, n;
> +
> +       err = errno;
> +
> +       for (;;) {
> +               n = read(fd, buf, sizeof(buf));
> +               if (n < 0)
> +                       break;
> +               n -= 2;
> +
> +               switch (buf[0]) {
> +               case 'e':
> +                       fprintf(stderr, "Error: %*.*s\n", n, n, buf + 2);
> +                       break;
> +               case 'w':
> +                       fprintf(stderr, "Warning: %*.*s\n", n, n, buf + 2);
> +                       break;
> +               case 'i':
> +                       fprintf(stderr, "Info: %*.*s\n", n, n, buf + 2);
> +                       break;
> +               }
> +       }
> +
> +       errno = err;
> +}
> +
> +static __attribute__((noreturn))
> +void mount_error(int fd, const char *s)
> +{
> +       check_messages(fd);
> +       fprintf(stderr, "%s: %m\n", s);
> +       exit(1);
> +}
> +
> +static inline int fsopen(const char *fs_name, unsigned int flags)
> +{
> +       return syscall(__NR_fsopen, fs_name, flags);
> +}
> +
> +static inline int fsmount(int fsfd, unsigned int flags, unsigned int ms_flags)
> +{
> +       return syscall(__NR_fsmount, fsfd, flags, ms_flags);
> +}
> +
> +static inline int fsconfig(int fsfd, unsigned int cmd,
> +                          const char *key, const void *val, int aux)
> +{
> +       return syscall(__NR_fsconfig, fsfd, cmd, key, val, aux);
> +}
> +
> +static inline int move_mount(int from_dfd, const char *from_pathname,
> +                            int to_dfd, const char *to_pathname,
> +                            unsigned int flags)
> +{
> +       return syscall(__NR_move_mount,
> +                      from_dfd, from_pathname,
> +                      to_dfd, to_pathname, flags);
> +}
> +
> +#define E_fsconfig(fd, cmd, key, val, aux)                             \
> +       do {                                                            \
> +               if (fsconfig(fd, cmd, key, val, aux) == -1)             \
> +                       mount_error(fd, key ?: "create");               \
> +       } while (0)
> +
> +int main(int argc, char *argv[])
> +{
> +       int fsfd, mfd;
> +
> +       /* Mount a publically available AFS filesystem */
> +       fsfd = fsopen("afs", 0);
> +       if (fsfd == -1) {
> +               perror("fsopen");
> +               exit(1);
> +       }
> +
> +       E_fsconfig(fsfd, FSCONFIG_SET_STRING, "source", "#grand.central.org:root.cell.", 0);
> +       E_fsconfig(fsfd, FSCONFIG_CMD_CREATE, NULL, NULL, 0);
> +
> +       mfd = fsmount(fsfd, 0, MS_RDONLY);
> +       if (mfd < 0)
> +               mount_error(fsfd, "fsmount");
> +       E(close(fsfd));
> +
> +       if (move_mount(mfd, "", AT_FDCWD, "/mnt", MOVE_MOUNT_F_EMPTY_PATH) < 0) {
> +               perror("move_mount");
> +               exit(1);
> +       }
> +
> +       E(close(mfd));
> +       exit(0);
> +}
> diff --git a/samples/vfs/test-statx.c b/samples/vfs/test-statx.c
> new file mode 100644
> index 000000000000..d4d77b09412c
> --- /dev/null
> +++ b/samples/vfs/test-statx.c
> @@ -0,0 +1,258 @@
> +/* Test the statx() system call.
> + *
> + * Note that the output of this program is intended to look like the output of
> + * /bin/stat where possible.
> + *
> + * Copyright (C) 2015 Red Hat, Inc. All Rights Reserved.
> + * Written by David Howells (dhowells@redhat.com)
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public Licence
> + * as published by the Free Software Foundation; either version
> + * 2 of the Licence, or (at your option) any later version.
> + */
> +
> +#define _GNU_SOURCE
> +#define _ATFILE_SOURCE
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <unistd.h>
> +#include <ctype.h>
> +#include <errno.h>
> +#include <time.h>
> +#include <sys/syscall.h>
> +#include <sys/types.h>
> +#include <linux/stat.h>
> +#include <linux/fcntl.h>
> +#include <sys/stat.h>
> +
> +#define AT_STATX_SYNC_TYPE     0x6000
> +#define AT_STATX_SYNC_AS_STAT  0x0000
> +#define AT_STATX_FORCE_SYNC    0x2000
> +#define AT_STATX_DONT_SYNC     0x4000
> +
> +static __attribute__((unused))
> +ssize_t statx(int dfd, const char *filename, unsigned flags,
> +             unsigned int mask, struct statx *buffer)
> +{
> +       return syscall(__NR_statx, dfd, filename, flags, mask, buffer);
> +}
> +
> +static void print_time(const char *field, struct statx_timestamp *ts)
> +{
> +       struct tm tm;
> +       time_t tim;
> +       char buffer[100];
> +       int len;
> +
> +       tim = ts->tv_sec;
> +       if (!localtime_r(&tim, &tm)) {
> +               perror("localtime_r");
> +               exit(1);
> +       }
> +       len = strftime(buffer, 100, "%F %T", &tm);
> +       if (len == 0) {
> +               perror("strftime");
> +               exit(1);
> +       }
> +       printf("%s", field);
> +       fwrite(buffer, 1, len, stdout);
> +       printf(".%09u", ts->tv_nsec);
> +       len = strftime(buffer, 100, "%z", &tm);
> +       if (len == 0) {
> +               perror("strftime2");
> +               exit(1);
> +       }
> +       fwrite(buffer, 1, len, stdout);
> +       printf("\n");
> +}
> +
> +static void dump_statx(struct statx *stx)
> +{
> +       char buffer[256], ft = '?';
> +
> +       printf("results=%x\n", stx->stx_mask);
> +
> +       printf(" ");
> +       if (stx->stx_mask & STATX_SIZE)
> +               printf(" Size: %-15llu", (unsigned long long)stx->stx_size);
> +       if (stx->stx_mask & STATX_BLOCKS)
> +               printf(" Blocks: %-10llu", (unsigned long long)stx->stx_blocks);
> +       printf(" IO Block: %-6llu", (unsigned long long)stx->stx_blksize);
> +       if (stx->stx_mask & STATX_TYPE) {
> +               switch (stx->stx_mode & S_IFMT) {
> +               case S_IFIFO:   printf("  FIFO\n");                     ft = 'p'; break;
> +               case S_IFCHR:   printf("  character special file\n");   ft = 'c'; break;
> +               case S_IFDIR:   printf("  directory\n");                ft = 'd'; break;
> +               case S_IFBLK:   printf("  block special file\n");       ft = 'b'; break;
> +               case S_IFREG:   printf("  regular file\n");             ft = '-'; break;
> +               case S_IFLNK:   printf("  symbolic link\n");            ft = 'l'; break;
> +               case S_IFSOCK:  printf("  socket\n");                   ft = 's'; break;
> +               default:
> +                       printf(" unknown type (%o)\n", stx->stx_mode & S_IFMT);
> +                       break;
> +               }
> +       } else {
> +               printf(" no type\n");
> +       }
> +
> +       sprintf(buffer, "%02x:%02x", stx->stx_dev_major, stx->stx_dev_minor);
> +       printf("Device: %-15s", buffer);
> +       if (stx->stx_mask & STATX_INO)
> +               printf(" Inode: %-11llu", (unsigned long long) stx->stx_ino);
> +       if (stx->stx_mask & STATX_NLINK)
> +               printf(" Links: %-5u", stx->stx_nlink);
> +       if (stx->stx_mask & STATX_TYPE) {
> +               switch (stx->stx_mode & S_IFMT) {
> +               case S_IFBLK:
> +               case S_IFCHR:
> +                       printf(" Device type: %u,%u",
> +                              stx->stx_rdev_major, stx->stx_rdev_minor);
> +                       break;
> +               }
> +       }
> +       printf("\n");
> +
> +       if (stx->stx_mask & STATX_MODE)
> +               printf("Access: (%04o/%c%c%c%c%c%c%c%c%c%c)  ",
> +                      stx->stx_mode & 07777,
> +                      ft,
> +                      stx->stx_mode & S_IRUSR ? 'r' : '-',
> +                      stx->stx_mode & S_IWUSR ? 'w' : '-',
> +                      stx->stx_mode & S_IXUSR ? 'x' : '-',
> +                      stx->stx_mode & S_IRGRP ? 'r' : '-',
> +                      stx->stx_mode & S_IWGRP ? 'w' : '-',
> +                      stx->stx_mode & S_IXGRP ? 'x' : '-',
> +                      stx->stx_mode & S_IROTH ? 'r' : '-',
> +                      stx->stx_mode & S_IWOTH ? 'w' : '-',
> +                      stx->stx_mode & S_IXOTH ? 'x' : '-');
> +       if (stx->stx_mask & STATX_UID)
> +               printf("Uid: %5d   ", stx->stx_uid);
> +       if (stx->stx_mask & STATX_GID)
> +               printf("Gid: %5d\n", stx->stx_gid);
> +
> +       if (stx->stx_mask & STATX_ATIME)
> +               print_time("Access: ", &stx->stx_atime);
> +       if (stx->stx_mask & STATX_MTIME)
> +               print_time("Modify: ", &stx->stx_mtime);
> +       if (stx->stx_mask & STATX_CTIME)
> +               print_time("Change: ", &stx->stx_ctime);
> +       if (stx->stx_mask & STATX_BTIME)
> +               print_time(" Birth: ", &stx->stx_btime);
> +
> +       if (stx->stx_attributes_mask) {
> +               unsigned char bits, mbits;
> +               int loop, byte;
> +
> +               static char attr_representation[64 + 1] =
> +                       /* STATX_ATTR_ flags: */
> +                       "????????"      /* 63-56 */
> +                       "????????"      /* 55-48 */
> +                       "????????"      /* 47-40 */
> +                       "????????"      /* 39-32 */
> +                       "????????"      /* 31-24        0x00000000-ff000000 */
> +                       "????????"      /* 23-16        0x00000000-00ff0000 */
> +                       "???me???"      /* 15- 8        0x00000000-0000ff00 */
> +                       "?dai?c??"      /*  7- 0        0x00000000-000000ff */
> +                       ;
> +
> +               printf("Attributes: %016llx (", stx->stx_attributes);
> +               for (byte = 64 - 8; byte >= 0; byte -= 8) {
> +                       bits = stx->stx_attributes >> byte;
> +                       mbits = stx->stx_attributes_mask >> byte;
> +                       for (loop = 7; loop >= 0; loop--) {
> +                               int bit = byte + loop;
> +
> +                               if (!(mbits & 0x80))
> +                                       putchar('.');   /* Not supported */
> +                               else if (bits & 0x80)
> +                                       putchar(attr_representation[63 - bit]);
> +                               else
> +                                       putchar('-');   /* Not set */
> +                               bits <<= 1;
> +                               mbits <<= 1;
> +                       }
> +                       if (byte)
> +                               putchar(' ');
> +               }
> +               printf(")\n");
> +       }
> +}
> +
> +static void dump_hex(unsigned long long *data, int from, int to)
> +{
> +       unsigned offset, print_offset = 1, col = 0;
> +
> +       from /= 8;
> +       to = (to + 7) / 8;
> +
> +       for (offset = from; offset < to; offset++) {
> +               if (print_offset) {
> +                       printf("%04x: ", offset * 8);
> +                       print_offset = 0;
> +               }
> +               printf("%016llx", data[offset]);
> +               col++;
> +               if ((col & 3) == 0) {
> +                       printf("\n");
> +                       print_offset = 1;
> +               } else {
> +                       printf(" ");
> +               }
> +       }
> +
> +       if (!print_offset)
> +               printf("\n");
> +}
> +
> +int main(int argc, char **argv)
> +{
> +       struct statx stx;
> +       int ret, raw = 0, atflag = AT_SYMLINK_NOFOLLOW;
> +
> +       unsigned int mask = STATX_ALL;
> +
> +       for (argv++; *argv; argv++) {
> +               if (strcmp(*argv, "-F") == 0) {
> +                       atflag &= ~AT_STATX_SYNC_TYPE;
> +                       atflag |= AT_STATX_FORCE_SYNC;
> +                       continue;
> +               }
> +               if (strcmp(*argv, "-D") == 0) {
> +                       atflag &= ~AT_STATX_SYNC_TYPE;
> +                       atflag |= AT_STATX_DONT_SYNC;
> +                       continue;
> +               }
> +               if (strcmp(*argv, "-L") == 0) {
> +                       atflag &= ~AT_SYMLINK_NOFOLLOW;
> +                       continue;
> +               }
> +               if (strcmp(*argv, "-O") == 0) {
> +                       mask &= ~STATX_BASIC_STATS;
> +                       continue;
> +               }
> +               if (strcmp(*argv, "-A") == 0) {
> +                       atflag |= AT_NO_AUTOMOUNT;
> +                       continue;
> +               }
> +               if (strcmp(*argv, "-R") == 0) {
> +                       raw = 1;
> +                       continue;
> +               }
> +
> +               memset(&stx, 0xbf, sizeof(stx));
> +               ret = statx(AT_FDCWD, *argv, atflag, mask, &stx);
> +               printf("statx(%s) = %d\n", *argv, ret);
> +               if (ret < 0) {
> +                       perror(*argv);
> +                       exit(1);
> +               }
> +
> +               if (raw)
> +                       dump_hex((unsigned long long *)&stx, 0, sizeof(stx));
> +
> +               dump_statx(&stx);
> +       }
> +       return 0;
> +}
>

  reply	other threads:[~2018-12-17 14:13 UTC|newest]

Thread overview: 110+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-21 16:30 [PATCH 00/34] VFS: Introduce filesystem context [ver #12] David Howells
2018-09-21 16:30 ` David Howells
2018-09-21 16:30 ` David Howells
2018-09-21 16:30 ` [PATCH 01/34] vfs: syscall: Add open_tree(2) to reference or clone a mount " David Howells
2018-10-21 16:41   ` Eric W. Biederman
2018-09-21 16:30 ` [PATCH 02/34] vfs: syscall: Add move_mount(2) to move mounts around " David Howells
2018-09-21 16:30 ` [PATCH 03/34] teach move_mount(2) to work with OPEN_TREE_CLONE " David Howells
2018-10-05 18:24   ` Alan Jenkins
2018-10-07 10:48     ` Alan Jenkins
2018-10-07 19:20       ` Alan Jenkins
2018-10-10 12:36       ` David Howells
2018-10-12 14:22         ` Alan Jenkins
2018-10-12 14:22           ` Alan Jenkins
2018-10-12 14:54         ` David Howells
2018-10-12 14:57           ` Alan Jenkins
2018-10-11  9:17       ` David Howells
2018-10-11 11:48         ` Alan Jenkins
2018-10-11 13:10         ` David Howells
2018-10-11 12:14       ` David Howells
2018-10-11 12:23         ` Alan Jenkins
2018-10-11 15:33       ` David Howells
2018-10-11 18:38         ` Eric W. Biederman
2018-10-11 20:17         ` David Howells
2018-10-13  6:06           ` Al Viro
2018-10-17 17:45       ` Alan Jenkins
2018-10-18 20:09     ` David Howells
2018-10-18 20:58     ` David Howells
2018-10-19 11:57     ` David Howells
2018-10-19 13:37     ` David Howells
2018-10-19 17:35       ` Alan Jenkins
2018-10-19 21:35       ` David Howells
2018-10-19 21:40       ` David Howells
2018-10-19 22:36       ` David Howells
2018-10-20  5:25         ` Al Viro
2018-10-20 11:06         ` Alan Jenkins
2018-10-20 11:48           ` Al Viro
2018-10-20 11:48             ` Al Viro
2018-10-20 12:26             ` Al Viro
2018-10-21  0:40         ` David Howells
2018-10-10 11:56   ` David Howells
2018-10-10 12:31   ` David Howells
2018-10-10 12:39     ` Alan Jenkins
2018-10-10 12:50   ` David Howells
2018-10-10 13:02   ` David Howells
2018-10-10 13:06     ` Alan Jenkins
2018-10-21 16:57   ` Eric W. Biederman
2018-10-23 11:19   ` Alan Jenkins
2018-10-23 16:22     ` Al Viro
2018-09-21 16:30 ` [PATCH 04/34] vfs: Suppress MS_* flag defs within the kernel unless explicitly enabled " David Howells
2018-09-21 16:30 ` [PATCH 05/34] vfs: Introduce the basic header for the new mount API's filesystem context " David Howells
2018-09-21 16:30 ` [PATCH 06/34] vfs: Introduce logging functions " David Howells
2018-09-21 16:31 ` [PATCH 07/34] vfs: Add configuration parser helpers " David Howells
2019-03-14  7:46   ` Geert Uytterhoeven
2019-03-14 10:27   ` David Howells
2019-03-14 10:49     ` Geert Uytterhoeven
2018-09-21 16:31 ` [PATCH 08/34] vfs: Add LSM hooks for the new mount API " David Howells
2018-09-21 16:31   ` David Howells
2018-09-21 16:31 ` [PATCH 09/34] vfs: Put security flags into the fs_context struct " David Howells
2018-09-21 16:31 ` [PATCH 10/34] selinux: Implement the new mount API LSM hooks " David Howells
2018-09-21 16:31   ` David Howells
2018-09-21 16:31 ` [PATCH 11/34] smack: Implement filesystem context security " David Howells
2018-09-21 16:31   ` David Howells
2018-09-21 16:31 ` [PATCH 12/34] apparmor: Implement security hooks for the new mount API " David Howells
2018-09-21 16:31   ` David Howells
2018-09-21 16:31 ` [PATCH 13/34] tomoyo: " David Howells
2018-09-21 16:31   ` David Howells
2018-09-21 16:32 ` [PATCH 14/34] vfs: Separate changing mount flags full remount " David Howells
2018-09-21 16:32 ` [PATCH 15/34] vfs: Implement a filesystem superblock creation/configuration context " David Howells
2018-09-21 16:32 ` [PATCH 16/34] vfs: Remove unused code after filesystem context changes " David Howells
2018-09-21 16:32 ` [PATCH 17/34] procfs: Move proc_fill_super() to fs/proc/root.c " David Howells
2018-09-21 16:32 ` [PATCH 18/34] proc: Add fs_context support to procfs " David Howells
2018-09-21 16:32 ` [PATCH 19/34] ipc: Convert mqueue fs to fs_context " David Howells
2018-09-21 16:32 ` [PATCH 20/34] cpuset: Use " David Howells
2018-09-21 16:33 ` [PATCH 21/34] kernfs, sysfs, cgroup, intel_rdt: Support " David Howells
2018-11-19  4:23   ` Andrei Vagin
2018-12-06 17:08     ` Andrei Vagin
2018-09-21 16:33 ` [PATCH 22/34] hugetlbfs: Convert to " David Howells
2018-09-21 16:33 ` [PATCH 23/34] vfs: Remove kern_mount_data() " David Howells
2018-09-21 16:33 ` [PATCH 24/34] vfs: Provide documentation for new mount API " David Howells
2018-09-21 16:33 ` [PATCH 25/34] Make anon_inodes unconditional " David Howells
2018-09-21 16:33 ` [PATCH 26/34] vfs: syscall: Add fsopen() to prepare for superblock creation " David Howells
2018-09-21 16:33 ` [PATCH 27/34] vfs: Implement logging through fs_context " David Howells
2018-09-21 16:33 ` [PATCH 28/34] vfs: Add some logging to the core users of the fs_context log " David Howells
2018-09-21 16:34 ` [PATCH 29/34] vfs: syscall: Add fsconfig() for configuring and managing a context " David Howells
2018-09-21 16:34 ` [PATCH 30/34] vfs: syscall: Add fsmount() to create a mount for a superblock " David Howells
2018-09-21 16:34 ` [PATCH 31/34] vfs: syscall: Add fspick() to select a superblock for reconfiguration " David Howells
2018-10-12 14:49   ` Alan Jenkins
2018-10-13  6:11     ` Al Viro
2018-10-13  6:11       ` Al Viro
2018-10-13  9:45       ` Alan Jenkins
2018-10-13 23:04         ` Andy Lutomirski
2018-10-17 13:15       ` David Howells
2018-10-17 13:20       ` David Howells
2018-10-17 13:20         ` David Howells
2018-10-17 14:31         ` Alan Jenkins
2018-10-17 14:35           ` Eric W. Biederman
2018-10-17 14:55             ` Alan Jenkins
2018-10-17 15:24           ` David Howells
2018-10-17 15:24             ` David Howells
2018-10-17 15:38             ` Eric W. Biederman
2018-10-17 15:45         ` David Howells
2018-10-17 17:41           ` Alan Jenkins
2018-10-17 21:20           ` David Howells
2018-10-17 22:13           ` Alan Jenkins
2018-09-21 16:34 ` [PATCH 32/34] afs: Add fs_context support " David Howells
2018-09-21 16:34 ` [PATCH 33/34] afs: Use fs_context to pass parameters over automount " David Howells
2018-09-21 16:34 ` [PATCH 34/34] vfs: Add a sample program for the new mount API " David Howells
2018-12-17 14:12   ` Anders Roxell [this message]
2018-12-20 16:36   ` David Howells
2018-10-04 18:37 ` [PATCH 00/34] VFS: Introduce filesystem context " Eric W. Biederman

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='CADYN=9KNL=6juu0WuHYPLu3bMNpVimUMWfFqmr5GbTrKPyOfVg@mail.gmail.com' \
    --to=anders.roxell@linaro.org \
    --cc=arnd@arndb.de \
    --cc=dhowells@redhat.com \
    --cc=ebiederm@xmission.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mszeredi@redhat.com \
    --cc=torvalds@linux-foundation.org \
    --cc=viro@zeniv.linux.org.uk \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.