Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/fs/pseudofs/pseudofs.h
39483 views
1
/*-
2
* SPDX-License-Identifier: BSD-3-Clause
3
*
4
* Copyright (c) 2001 Dag-Erling Smørgrav
5
* All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer
12
* in this position and unchanged.
13
* 2. Redistributions in binary form must reproduce the above copyright
14
* notice, this list of conditions and the following disclaimer in the
15
* documentation and/or other materials provided with the distribution.
16
* 3. The name of the author may not be used to endorse or promote products
17
* derived from this software without specific prior written permission.
18
*
19
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
*/
30
31
#ifndef _PSEUDOFS_H_INCLUDED
32
#define _PSEUDOFS_H_INCLUDED
33
34
#include <sys/jail.h>
35
36
/*
37
* Opaque structures
38
*/
39
struct mntarg;
40
struct mount;
41
struct nameidata;
42
struct proc;
43
struct sbuf;
44
struct statfs;
45
struct thread;
46
struct uio;
47
struct vfsconf;
48
struct vnode;
49
50
/*
51
* Limits and constants
52
*/
53
#define PFS_NAMELEN 128
54
#define PFS_FSNAMELEN 16 /* equal to MFSNAMELEN */
55
#define PFS_DELEN (offsetof(struct dirent, d_name) + PFS_NAMELEN)
56
57
typedef enum {
58
pfstype_none = 0,
59
pfstype_root,
60
pfstype_dir,
61
pfstype_this,
62
pfstype_parent,
63
pfstype_file,
64
pfstype_symlink,
65
pfstype_procdir
66
} pfs_type_t;
67
68
/*
69
* Flags
70
*/
71
#define PFS_RD 0x0001 /* readable */
72
#define PFS_WR 0x0002 /* writeable */
73
#define PFS_RDWR (PFS_RD|PFS_WR)
74
#define PFS_RAWRD 0x0004 /* raw reader */
75
#define PFS_RAWWR 0x0008 /* raw writer */
76
#define PFS_RAW (PFS_RAWRD|PFS_RAWWR)
77
#define PFS_PROCDEP 0x0010 /* process-dependent */
78
#define PFS_NOWAIT 0x0020 /* allow malloc to fail */
79
#define PFS_AUTODRAIN 0x0040 /* sbuf_print can sleep to drain */
80
81
/*
82
* Data structures
83
*/
84
struct pfs_info;
85
struct pfs_node;
86
87
/*
88
* Init / uninit callback
89
*/
90
#define PFS_INIT_ARGS \
91
struct pfs_info *pi, struct vfsconf *vfc
92
#define PFS_INIT_ARGNAMES \
93
pi, vfc
94
#define PFS_INIT_PROTO(name) \
95
int name(PFS_INIT_ARGS);
96
typedef int (*pfs_init_t)(PFS_INIT_ARGS);
97
98
/*
99
* Filler callback
100
* Called with proc held but unlocked
101
*/
102
#define PFS_FILL_ARGS \
103
struct thread *td, struct proc *p, struct pfs_node *pn, \
104
struct sbuf *sb, struct uio *uio
105
#define PFS_FILL_ARGNAMES \
106
td, p, pn, sb, uio
107
#define PFS_FILL_PROTO(name) \
108
int name(PFS_FILL_ARGS);
109
typedef int (*pfs_fill_t)(PFS_FILL_ARGS);
110
111
/*
112
* Attribute callback
113
* Called with proc locked
114
*/
115
struct vattr;
116
#define PFS_ATTR_ARGS \
117
struct thread *td, struct proc *p, struct pfs_node *pn, \
118
struct vattr *vap
119
#define PFS_ATTR_ARGNAMES \
120
td, p, pn, vap
121
#define PFS_ATTR_PROTO(name) \
122
int name(PFS_ATTR_ARGS);
123
typedef int (*pfs_attr_t)(PFS_ATTR_ARGS);
124
125
/*
126
* Visibility callback
127
* Called with proc locked
128
*/
129
#define PFS_VIS_ARGS \
130
struct thread *td, struct proc *p, struct pfs_node *pn
131
#define PFS_VIS_ARGNAMES \
132
td, p, pn
133
#define PFS_VIS_PROTO(name) \
134
int name(PFS_VIS_ARGS);
135
typedef int (*pfs_vis_t)(PFS_VIS_ARGS);
136
137
/*
138
* Ioctl callback
139
* Called with proc locked
140
*/
141
#define PFS_IOCTL_ARGS \
142
struct thread *td, struct proc *p, struct pfs_node *pn, \
143
unsigned long cmd, void *data
144
#define PFS_IOCTL_ARGNAMES \
145
td, p, pn, cmd, data
146
#define PFS_IOCTL_PROTO(name) \
147
int name(PFS_IOCTL_ARGS);
148
typedef int (*pfs_ioctl_t)(PFS_IOCTL_ARGS);
149
150
/*
151
* Getextattr callback
152
* Called with proc locked
153
*/
154
#define PFS_GETEXTATTR_ARGS \
155
struct thread *td, struct proc *p, struct pfs_node *pn, \
156
int attrnamespace, const char *name, struct uio *uio, \
157
size_t *size, struct ucred *cred
158
#define PFS_GETEXTATTR_ARGNAMES \
159
td, p, pn, attrnamespace, name, uio, size, cred
160
#define PFS_GETEXTATTR_PROTO(name) \
161
int name(PFS_GETEXTATTR_ARGS);
162
struct ucred;
163
typedef int (*pfs_getextattr_t)(PFS_GETEXTATTR_ARGS);
164
165
/*
166
* Last-close callback
167
* Called with proc locked
168
*/
169
#define PFS_CLOSE_ARGS \
170
struct thread *td, struct proc *p, struct pfs_node *pn
171
#define PFS_CLOSE_ARGNAMES \
172
td, p, pn
173
#define PFS_CLOSE_PROTO(name) \
174
int name(PFS_CLOSE_ARGS);
175
typedef int (*pfs_close_t)(PFS_CLOSE_ARGS);
176
177
/*
178
* Destroy callback
179
*/
180
#define PFS_DESTROY_ARGS \
181
struct pfs_node *pn
182
#define PFS_DESTROY_ARGNAMES \
183
pn
184
#define PFS_DESTROY_PROTO(name) \
185
int name(PFS_DESTROY_ARGS);
186
typedef int (*pfs_destroy_t)(PFS_DESTROY_ARGS);
187
188
/*
189
* pfs_info: describes a pseudofs instance
190
*
191
* The pi_mutex is only used to avoid using the global subr_unit lock
192
* for unrhdr. The rest of struct pfs_info is only modified during
193
* vfs_init() and vfs_uninit() of the consumer filesystem.
194
*/
195
struct pfs_info {
196
char pi_name[PFS_FSNAMELEN];
197
pfs_init_t pi_init;
198
pfs_init_t pi_uninit;
199
200
/* members below this line are initialized at run time */
201
struct pfs_node *pi_root;
202
struct mtx pi_mutex;
203
struct unrhdr *pi_unrhdr;
204
};
205
206
/*
207
* pfs_node: describes a node (file or directory) within a pseudofs
208
*
209
* - Fields marked (o) are protected by the node's own mutex.
210
* - Fields marked (p) are protected by the node's parent's mutex.
211
* - Remaining fields are not protected by any lock and are assumed to be
212
* immutable once the node has been created.
213
*
214
* To prevent deadlocks, if a node's mutex is to be held at the same time
215
* as its parent's (e.g. when adding or removing nodes to a directory),
216
* the parent's mutex must always be acquired first. Unfortunately, this
217
* is not enforcable by WITNESS.
218
*/
219
struct pfs_node {
220
pfs_type_t pn_type;
221
int pn_flags;
222
struct mtx pn_mutex;
223
void *pn_data; /* (o) */
224
225
pfs_fill_t pn_fill;
226
pfs_ioctl_t pn_ioctl;
227
pfs_close_t pn_close;
228
pfs_attr_t pn_attr;
229
pfs_vis_t pn_vis;
230
pfs_getextattr_t pn_getextattr;
231
pfs_destroy_t pn_destroy;
232
233
struct pfs_info *pn_info;
234
u_int32_t pn_fileno; /* (o) */
235
236
struct pfs_node *pn_parent; /* (o) */
237
struct pfs_node *pn_nodes; /* (o) */
238
struct pfs_node *pn_last_node; /* (o) */
239
struct pfs_node *pn_next; /* (p) */
240
char pn_name[]; /* Keep it last */
241
};
242
243
/*
244
* VFS interface
245
*/
246
int pfs_mount (struct pfs_info *pi, struct mount *mp);
247
int pfs_cmount (struct mntarg *ma, void *data, uint64_t flags);
248
int pfs_unmount (struct mount *mp, int mntflags);
249
int pfs_root (struct mount *mp, int flags,
250
struct vnode **vpp);
251
int pfs_statfs (struct mount *mp, struct statfs *sbp);
252
int pfs_init (struct pfs_info *pi, struct vfsconf *vfc);
253
int pfs_uninit (struct pfs_info *pi, struct vfsconf *vfc);
254
255
/*
256
* Directory structure construction and manipulation
257
*/
258
int pfs_create_dir (struct pfs_node *parent, struct pfs_node **opn,
259
const char *name, pfs_attr_t attr,
260
pfs_vis_t vis, pfs_destroy_t destroy,
261
int flags);
262
int pfs_create_file (struct pfs_node *parent, struct pfs_node **opn,
263
const char *name, pfs_fill_t fill,
264
pfs_attr_t attr, pfs_vis_t vis,
265
pfs_destroy_t destroy, int flags);
266
int pfs_create_link (struct pfs_node *parent, struct pfs_node **opn,
267
const char *name, pfs_fill_t fill,
268
pfs_attr_t attr, pfs_vis_t vis,
269
pfs_destroy_t destroy, int flags);
270
struct pfs_node *pfs_find_node (struct pfs_node *parent, const char *name);
271
void pfs_purge (struct pfs_node *pn);
272
int pfs_destroy (struct pfs_node *pn);
273
274
/*
275
* Now for some initialization magic...
276
*/
277
#define PSEUDOFS(name, version, flags) \
278
\
279
static struct pfs_info name##_info = { \
280
#name, \
281
name##_init, \
282
name##_uninit, \
283
}; \
284
\
285
static int \
286
_##name##_mount(struct mount *mp) { \
287
return (pfs_mount(&name##_info, mp)); \
288
} \
289
\
290
static int \
291
_##name##_init(struct vfsconf *vfc) { \
292
return (pfs_init(&name##_info, vfc)); \
293
} \
294
\
295
static int \
296
_##name##_uninit(struct vfsconf *vfc) { \
297
return (pfs_uninit(&name##_info, vfc)); \
298
} \
299
\
300
static struct vfsops name##_vfsops = { \
301
.vfs_cmount = pfs_cmount, \
302
.vfs_init = _##name##_init, \
303
.vfs_mount = _##name##_mount, \
304
.vfs_root = pfs_root, \
305
.vfs_statfs = pfs_statfs, \
306
.vfs_uninit = _##name##_uninit, \
307
.vfs_unmount = pfs_unmount, \
308
}; \
309
VFS_SET(name##_vfsops, name, VFCF_SYNTHETIC | flags); \
310
MODULE_VERSION(name, version); \
311
MODULE_DEPEND(name, pseudofs, 1, 1, 1);
312
313
#endif
314
315