1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __STATMOUNT_H
#define __STATMOUNT_H
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <linux/mount.h>
#include <asm/unistd.h>
#define STATMOUNT_BUFSIZE (1 << 15)
#ifndef __NR_statmount
#if defined __alpha__
#define __NR_statmount 567
#elif defined _MIPS_SIM
#if _MIPS_SIM == _MIPS_SIM_ABI32 /* o32 */
#define __NR_statmount 4457
#endif
#if _MIPS_SIM == _MIPS_SIM_NABI32 /* n32 */
#define __NR_statmount 6457
#endif
#if _MIPS_SIM == _MIPS_SIM_ABI64 /* n64 */
#define __NR_statmount 5457
#endif
#else
#define __NR_statmount 457
#endif
#endif
#ifndef __NR_listmount
#if defined __alpha__
#define __NR_listmount 568
#elif defined _MIPS_SIM
#if _MIPS_SIM == _MIPS_SIM_ABI32 /* o32 */
#define __NR_listmount 4458
#endif
#if _MIPS_SIM == _MIPS_SIM_NABI32 /* n32 */
#define __NR_listmount 6458
#endif
#if _MIPS_SIM == _MIPS_SIM_ABI64 /* n64 */
#define __NR_listmount 5458
#endif
#else
#define __NR_listmount 458
#endif
#endif
static inline int statmount(uint64_t mnt_id, uint64_t mnt_ns_id, uint32_t fd,
uint64_t mask, struct statmount *buf, size_t bufsize,
unsigned int flags)
{
struct mnt_id_req req = {
.size = MNT_ID_REQ_SIZE_VER0,
.param = mask,
};
if (flags & STATMOUNT_BY_FD) {
req.size = MNT_ID_REQ_SIZE_VER1;
req.mnt_fd = fd;
} else {
req.mnt_id = mnt_id;
if (mnt_ns_id) {
req.size = MNT_ID_REQ_SIZE_VER1;
req.mnt_ns_id = mnt_ns_id;
}
}
return syscall(__NR_statmount, &req, buf, bufsize, flags);
}
static inline ssize_t listmount(uint64_t mnt_id, uint64_t mnt_ns_id,
uint64_t last_mnt_id, uint64_t list[], size_t num,
unsigned int flags)
{
struct mnt_id_req req = {
.size = MNT_ID_REQ_SIZE_VER0,
.mnt_id = mnt_id,
.param = last_mnt_id,
};
if (mnt_ns_id) {
req.size = MNT_ID_REQ_SIZE_VER1;
req.mnt_ns_id = mnt_ns_id;
}
return syscall(__NR_listmount, &req, list, num, flags);
}
static inline struct statmount *statmount_alloc(uint64_t mnt_id, uint64_t mnt_ns_id,
uint64_t mask, unsigned int flags)
{
struct statmount *buf;
size_t bufsize = STATMOUNT_BUFSIZE;
int ret;
for (;;) {
buf = malloc(bufsize);
if (!buf)
return NULL;
ret = statmount(mnt_id, mnt_ns_id, 0, mask, buf, bufsize, flags);
if (ret == 0)
return buf;
free(buf);
if (errno != EOVERFLOW)
return NULL;
bufsize <<= 1;
}
}
static inline struct statmount *statmount_alloc_by_fd(int fd, uint64_t mask)
{
struct statmount *buf;
size_t bufsize = STATMOUNT_BUFSIZE;
int ret;
for (;;) {
buf = malloc(bufsize);
if (!buf)
return NULL;
ret = statmount(0, 0, fd, mask, buf, bufsize, STATMOUNT_BY_FD);
if (ret == 0)
return buf;
free(buf);
if (errno != EOVERFLOW)
return NULL;
bufsize <<= 1;
}
}
#endif /* __STATMOUNT_H */
|