diff options
| -rw-r--r-- | samples/Kconfig | 9 | ||||
| -rw-r--r-- | samples/Makefile | 2 | ||||
| -rw-r--r-- | samples/vfs/Makefile (renamed from samples/statx/Makefile) | 5 | ||||
| -rw-r--r-- | samples/vfs/test-fsmount.c | 133 | ||||
| -rw-r--r-- | samples/vfs/test-statx.c (renamed from samples/statx/test-statx.c) | 11 |
5 files changed, 153 insertions, 7 deletions
diff --git a/samples/Kconfig b/samples/Kconfig index d19754ccad08..30a89425009c 100644 --- a/samples/Kconfig +++ b/samples/Kconfig | |||
| @@ -154,10 +154,11 @@ config SAMPLE_ANDROID_BINDERFS | |||
| 154 | Builds a sample program to illustrate the use of the Android binderfs | 154 | Builds a sample program to illustrate the use of the Android binderfs |
| 155 | filesystem. | 155 | filesystem. |
| 156 | 156 | ||
| 157 | config SAMPLE_STATX | 157 | config SAMPLE_VFS |
| 158 | bool "Build example extended-stat using code" | 158 | bool "Build example programs that use new VFS system calls" |
| 159 | depends on BROKEN | ||
| 160 | help | 159 | help |
| 161 | Build example userspace program to use the new extended-stat syscall. | 160 | Build example userspace programs that use new VFS system calls such |
| 161 | as mount API and statx(). Note that this is restricted to the x86 | ||
| 162 | arch whilst it accesses system calls that aren't yet in all arches. | ||
| 162 | 163 | ||
| 163 | endif # SAMPLES | 164 | endif # SAMPLES |
diff --git a/samples/Makefile b/samples/Makefile index b1142a958811..95d71ffd62d5 100644 --- a/samples/Makefile +++ b/samples/Makefile | |||
| @@ -3,4 +3,4 @@ | |||
| 3 | obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ trace_events/ livepatch/ \ | 3 | obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ trace_events/ livepatch/ \ |
| 4 | hw_breakpoint/ kfifo/ kdb/ hidraw/ rpmsg/ seccomp/ \ | 4 | hw_breakpoint/ kfifo/ kdb/ hidraw/ rpmsg/ seccomp/ \ |
| 5 | configfs/ connector/ v4l/ trace_printk/ \ | 5 | configfs/ connector/ v4l/ trace_printk/ \ |
| 6 | vfio-mdev/ statx/ qmi/ binderfs/ | 6 | vfio-mdev/ vfs/ qmi/ binderfs/ |
diff --git a/samples/statx/Makefile b/samples/vfs/Makefile index 59df7c25a9d1..4ac9690fb3c4 100644 --- a/samples/statx/Makefile +++ b/samples/vfs/Makefile | |||
| @@ -1,7 +1,10 @@ | |||
| 1 | # List of programs to build | 1 | # List of programs to build |
| 2 | hostprogs-$(CONFIG_SAMPLE_STATX) := test-statx | 2 | hostprogs-$(CONFIG_SAMPLE_VFS) := \ |
| 3 | test-fsmount \ | ||
| 4 | test-statx | ||
| 3 | 5 | ||
| 4 | # Tell kbuild to always build the programs | 6 | # Tell kbuild to always build the programs |
| 5 | always := $(hostprogs-y) | 7 | always := $(hostprogs-y) |
| 6 | 8 | ||
| 9 | HOSTCFLAGS_test-fsmount.o += -I$(objtree)/usr/include | ||
| 7 | HOSTCFLAGS_test-statx.o += -I$(objtree)/usr/include | 10 | 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..266d72b3dce4 --- /dev/null +++ b/samples/vfs/test-fsmount.c | |||
| @@ -0,0 +1,133 @@ | |||
| 1 | /* fd-based mount test. | ||
| 2 | * | ||
| 3 | * Copyright (C) 2017 Red Hat, Inc. All Rights Reserved. | ||
| 4 | * Written by David Howells (dhowells@redhat.com) | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public Licence | ||
| 8 | * as published by the Free Software Foundation; either version | ||
| 9 | * 2 of the Licence, or (at your option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <stdio.h> | ||
| 13 | #include <stdlib.h> | ||
| 14 | #include <unistd.h> | ||
| 15 | #include <errno.h> | ||
| 16 | #include <fcntl.h> | ||
| 17 | #include <sys/prctl.h> | ||
| 18 | #include <sys/wait.h> | ||
| 19 | #include <linux/mount.h> | ||
| 20 | #include <linux/unistd.h> | ||
| 21 | |||
| 22 | #define E(x) do { if ((x) == -1) { perror(#x); exit(1); } } while(0) | ||
| 23 | |||
| 24 | static void check_messages(int fd) | ||
| 25 | { | ||
| 26 | char buf[4096]; | ||
| 27 | int err, n; | ||
| 28 | |||
| 29 | err = errno; | ||
| 30 | |||
| 31 | for (;;) { | ||
| 32 | n = read(fd, buf, sizeof(buf)); | ||
| 33 | if (n < 0) | ||
| 34 | break; | ||
| 35 | n -= 2; | ||
| 36 | |||
| 37 | switch (buf[0]) { | ||
| 38 | case 'e': | ||
| 39 | fprintf(stderr, "Error: %*.*s\n", n, n, buf + 2); | ||
| 40 | break; | ||
| 41 | case 'w': | ||
| 42 | fprintf(stderr, "Warning: %*.*s\n", n, n, buf + 2); | ||
| 43 | break; | ||
| 44 | case 'i': | ||
| 45 | fprintf(stderr, "Info: %*.*s\n", n, n, buf + 2); | ||
| 46 | break; | ||
| 47 | } | ||
| 48 | } | ||
| 49 | |||
| 50 | errno = err; | ||
| 51 | } | ||
| 52 | |||
| 53 | static __attribute__((noreturn)) | ||
| 54 | void mount_error(int fd, const char *s) | ||
| 55 | { | ||
| 56 | check_messages(fd); | ||
| 57 | fprintf(stderr, "%s: %m\n", s); | ||
| 58 | exit(1); | ||
| 59 | } | ||
| 60 | |||
| 61 | /* Hope -1 isn't a syscall */ | ||
| 62 | #ifndef __NR_fsopen | ||
| 63 | #define __NR_fsopen -1 | ||
| 64 | #endif | ||
| 65 | #ifndef __NR_fsmount | ||
| 66 | #define __NR_fsmount -1 | ||
| 67 | #endif | ||
| 68 | #ifndef __NR_fsconfig | ||
| 69 | #define __NR_fsconfig -1 | ||
| 70 | #endif | ||
| 71 | #ifndef __NR_move_mount | ||
| 72 | #define __NR_move_mount -1 | ||
| 73 | #endif | ||
| 74 | |||
| 75 | |||
| 76 | static inline int fsopen(const char *fs_name, unsigned int flags) | ||
| 77 | { | ||
| 78 | return syscall(__NR_fsopen, fs_name, flags); | ||
| 79 | } | ||
| 80 | |||
| 81 | static inline int fsmount(int fsfd, unsigned int flags, unsigned int ms_flags) | ||
| 82 | { | ||
| 83 | return syscall(__NR_fsmount, fsfd, flags, ms_flags); | ||
| 84 | } | ||
| 85 | |||
| 86 | static inline int fsconfig(int fsfd, unsigned int cmd, | ||
| 87 | const char *key, const void *val, int aux) | ||
| 88 | { | ||
| 89 | return syscall(__NR_fsconfig, fsfd, cmd, key, val, aux); | ||
| 90 | } | ||
| 91 | |||
| 92 | static inline int move_mount(int from_dfd, const char *from_pathname, | ||
| 93 | int to_dfd, const char *to_pathname, | ||
| 94 | unsigned int flags) | ||
| 95 | { | ||
| 96 | return syscall(__NR_move_mount, | ||
| 97 | from_dfd, from_pathname, | ||
| 98 | to_dfd, to_pathname, flags); | ||
| 99 | } | ||
| 100 | |||
| 101 | #define E_fsconfig(fd, cmd, key, val, aux) \ | ||
| 102 | do { \ | ||
| 103 | if (fsconfig(fd, cmd, key, val, aux) == -1) \ | ||
| 104 | mount_error(fd, key ?: "create"); \ | ||
| 105 | } while (0) | ||
| 106 | |||
| 107 | int main(int argc, char *argv[]) | ||
| 108 | { | ||
| 109 | int fsfd, mfd; | ||
| 110 | |||
| 111 | /* Mount a publically available AFS filesystem */ | ||
| 112 | fsfd = fsopen("afs", 0); | ||
| 113 | if (fsfd == -1) { | ||
| 114 | perror("fsopen"); | ||
| 115 | exit(1); | ||
| 116 | } | ||
| 117 | |||
| 118 | E_fsconfig(fsfd, FSCONFIG_SET_STRING, "source", "#grand.central.org:root.cell.", 0); | ||
| 119 | E_fsconfig(fsfd, FSCONFIG_CMD_CREATE, NULL, NULL, 0); | ||
| 120 | |||
| 121 | mfd = fsmount(fsfd, 0, MOUNT_ATTR_RDONLY); | ||
| 122 | if (mfd < 0) | ||
| 123 | mount_error(fsfd, "fsmount"); | ||
| 124 | E(close(fsfd)); | ||
| 125 | |||
| 126 | if (move_mount(mfd, "", AT_FDCWD, "/mnt", MOVE_MOUNT_F_EMPTY_PATH) < 0) { | ||
| 127 | perror("move_mount"); | ||
| 128 | exit(1); | ||
| 129 | } | ||
| 130 | |||
| 131 | E(close(mfd)); | ||
| 132 | exit(0); | ||
| 133 | } | ||
diff --git a/samples/statx/test-statx.c b/samples/vfs/test-statx.c index d4d77b09412c..e91f918e84c4 100644 --- a/samples/statx/test-statx.c +++ b/samples/vfs/test-statx.c | |||
| @@ -25,13 +25,21 @@ | |||
| 25 | #include <sys/types.h> | 25 | #include <sys/types.h> |
| 26 | #include <linux/stat.h> | 26 | #include <linux/stat.h> |
| 27 | #include <linux/fcntl.h> | 27 | #include <linux/fcntl.h> |
| 28 | #define statx foo | ||
| 29 | #define statx_timestamp foo_timestamp | ||
| 28 | #include <sys/stat.h> | 30 | #include <sys/stat.h> |
| 31 | #undef statx | ||
| 32 | #undef statx_timestamp | ||
| 29 | 33 | ||
| 30 | #define AT_STATX_SYNC_TYPE 0x6000 | 34 | #define AT_STATX_SYNC_TYPE 0x6000 |
| 31 | #define AT_STATX_SYNC_AS_STAT 0x0000 | 35 | #define AT_STATX_SYNC_AS_STAT 0x0000 |
| 32 | #define AT_STATX_FORCE_SYNC 0x2000 | 36 | #define AT_STATX_FORCE_SYNC 0x2000 |
| 33 | #define AT_STATX_DONT_SYNC 0x4000 | 37 | #define AT_STATX_DONT_SYNC 0x4000 |
| 34 | 38 | ||
| 39 | #ifndef __NR_statx | ||
| 40 | #define __NR_statx -1 | ||
| 41 | #endif | ||
| 42 | |||
| 35 | static __attribute__((unused)) | 43 | static __attribute__((unused)) |
| 36 | ssize_t statx(int dfd, const char *filename, unsigned flags, | 44 | ssize_t statx(int dfd, const char *filename, unsigned flags, |
| 37 | unsigned int mask, struct statx *buffer) | 45 | unsigned int mask, struct statx *buffer) |
| @@ -157,7 +165,8 @@ static void dump_statx(struct statx *stx) | |||
| 157 | "?dai?c??" /* 7- 0 0x00000000-000000ff */ | 165 | "?dai?c??" /* 7- 0 0x00000000-000000ff */ |
| 158 | ; | 166 | ; |
| 159 | 167 | ||
| 160 | printf("Attributes: %016llx (", stx->stx_attributes); | 168 | printf("Attributes: %016llx (", |
| 169 | (unsigned long long)stx->stx_attributes); | ||
| 161 | for (byte = 64 - 8; byte >= 0; byte -= 8) { | 170 | for (byte = 64 - 8; byte >= 0; byte -= 8) { |
| 162 | bits = stx->stx_attributes >> byte; | 171 | bits = stx->stx_attributes >> byte; |
| 163 | mbits = stx->stx_attributes_mask >> byte; | 172 | mbits = stx->stx_attributes_mask >> byte; |
