Skip to content

Commit f1b5618

Browse files
dhowellsAl Viro
authored andcommitted
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 <[email protected]> Signed-off-by: Al Viro <[email protected]>
1 parent cf3cba4 commit f1b5618

File tree

5 files changed

+153
-7
lines changed

5 files changed

+153
-7
lines changed

samples/Kconfig

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,11 @@ config SAMPLE_ANDROID_BINDERFS
154154
Builds a sample program to illustrate the use of the Android binderfs
155155
filesystem.
156156

157-
config SAMPLE_STATX
158-
bool "Build example extended-stat using code"
159-
depends on BROKEN
157+
config SAMPLE_VFS
158+
bool "Build example programs that use new VFS system calls"
160159
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.
162163

163164
endif # SAMPLES

samples/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ trace_events/ livepatch/ \
44
hw_breakpoint/ kfifo/ kdb/ hidraw/ rpmsg/ seccomp/ \
55
configfs/ connector/ v4l/ trace_printk/ \
6-
vfio-mdev/ statx/ qmi/ binderfs/
6+
vfio-mdev/ vfs/ qmi/ binderfs/
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
# List of programs to build
2-
hostprogs-$(CONFIG_SAMPLE_STATX) := test-statx
2+
hostprogs-$(CONFIG_SAMPLE_VFS) := \
3+
test-fsmount \
4+
test-statx
35

46
# Tell kbuild to always build the programs
57
always := $(hostprogs-y)
68

9+
HOSTCFLAGS_test-fsmount.o += -I$(objtree)/usr/include
710
HOSTCFLAGS_test-statx.o += -I$(objtree)/usr/include

samples/vfs/test-fsmount.c

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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 ([email protected])
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+
}

samples/statx/test-statx.c renamed to samples/vfs/test-statx.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,21 @@
2525
#include <sys/types.h>
2626
#include <linux/stat.h>
2727
#include <linux/fcntl.h>
28+
#define statx foo
29+
#define statx_timestamp foo_timestamp
2830
#include <sys/stat.h>
31+
#undef statx
32+
#undef statx_timestamp
2933

3034
#define AT_STATX_SYNC_TYPE 0x6000
3135
#define AT_STATX_SYNC_AS_STAT 0x0000
3236
#define AT_STATX_FORCE_SYNC 0x2000
3337
#define AT_STATX_DONT_SYNC 0x4000
3438

39+
#ifndef __NR_statx
40+
#define __NR_statx -1
41+
#endif
42+
3543
static __attribute__((unused))
3644
ssize_t statx(int dfd, const char *filename, unsigned flags,
3745
unsigned int mask, struct statx *buffer)
@@ -157,7 +165,8 @@ static void dump_statx(struct statx *stx)
157165
"?dai?c??" /* 7- 0 0x00000000-000000ff */
158166
;
159167

160-
printf("Attributes: %016llx (", stx->stx_attributes);
168+
printf("Attributes: %016llx (",
169+
(unsigned long long)stx->stx_attributes);
161170
for (byte = 64 - 8; byte >= 0; byte -= 8) {
162171
bits = stx->stx_attributes >> byte;
163172
mbits = stx->stx_attributes_mask >> byte;

0 commit comments

Comments
 (0)