aboutsummaryrefslogtreecommitdiffstats
path: root/samples
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2018-11-01 19:36:32 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2019-03-20 18:49:06 -0400
commitf1b5618e013af28b3c78daf424436a79674423c0 (patch)
tree7fea6c6bb8ef683b92fcabaa9e3f48ed2ec8eeb0 /samples
parentcf3cba4a429be43e5527a3f78859b1bfd9ebc5fb (diff)
vfs: Add a sample program for the new mount API
Add a sample program to demonstrate fsopen/fsmount/move_mount to mount something. To make it compile on all arches, irrespective of whether or not syscall numbers are assigned, define the syscall number to -1 if it isn't to cause the kernel to return -ENOSYS. Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'samples')
-rw-r--r--samples/Kconfig9
-rw-r--r--samples/Makefile2
-rw-r--r--samples/vfs/Makefile (renamed from samples/statx/Makefile)5
-rw-r--r--samples/vfs/test-fsmount.c133
-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
157config SAMPLE_STATX 157config 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
163endif # SAMPLES 164endif # SAMPLES
diff --git a/samples/Makefile b/samples/Makefile
index b1142a958811..95d71ffd62d5 100644
--- a/samples/Makefile
+++ b/samples/Makefile
@@ -3,4 +3,4 @@
3obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ trace_events/ livepatch/ \ 3obj-$(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
2hostprogs-$(CONFIG_SAMPLE_STATX) := test-statx 2hostprogs-$(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
5always := $(hostprogs-y) 7always := $(hostprogs-y)
6 8
9HOSTCFLAGS_test-fsmount.o += -I$(objtree)/usr/include
7HOSTCFLAGS_test-statx.o += -I$(objtree)/usr/include 10HOSTCFLAGS_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
24static 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
53static __attribute__((noreturn))
54void 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
76static inline int fsopen(const char *fs_name, unsigned int flags)
77{
78 return syscall(__NR_fsopen, fs_name, flags);
79}
80
81static inline int fsmount(int fsfd, unsigned int flags, unsigned int ms_flags)
82{
83 return syscall(__NR_fsmount, fsfd, flags, ms_flags);
84}
85
86static 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
92static 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
107int 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
35static __attribute__((unused)) 43static __attribute__((unused))
36ssize_t statx(int dfd, const char *filename, unsigned flags, 44ssize_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;