1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 2001 Dag-Erling Coïdan 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 * $FreeBSD$ 31 */ 32 33 #ifndef _PSEUDOFS_H_INCLUDED 34 #define _PSEUDOFS_H_INCLUDED 35 36 #include <sys/jail.h> 37 38 /* 39 * Opaque structures 40 */ 41 struct mntarg; 42 struct mount; 43 struct nameidata; 44 struct proc; 45 struct sbuf; 46 struct statfs; 47 struct thread; 48 struct uio; 49 struct vfsconf; 50 struct vnode; 51 52 /* 53 * Limits and constants 54 */ 55 #define PFS_NAMELEN 48 56 #define PFS_FSNAMELEN 16 /* equal to MFSNAMELEN */ 57 #define PFS_DELEN (offsetof(struct dirent, d_name) + PFS_NAMELEN) 58 59 typedef enum { 60 pfstype_none = 0, 61 pfstype_root, 62 pfstype_dir, 63 pfstype_this, 64 pfstype_parent, 65 pfstype_file, 66 pfstype_symlink, 67 pfstype_procdir 68 } pfs_type_t; 69 70 /* 71 * Flags 72 */ 73 #define PFS_RD 0x0001 /* readable */ 74 #define PFS_WR 0x0002 /* writeable */ 75 #define PFS_RDWR (PFS_RD|PFS_WR) 76 #define PFS_RAWRD 0x0004 /* raw reader */ 77 #define PFS_RAWWR 0x0008 /* raw writer */ 78 #define PFS_RAW (PFS_RAWRD|PFS_RAWWR) 79 #define PFS_PROCDEP 0x0010 /* process-dependent */ 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 char pn_name[PFS_NAMELEN]; 221 pfs_type_t pn_type; 222 int pn_flags; 223 struct mtx pn_mutex; 224 void *pn_data; /* (o) */ 225 226 pfs_fill_t pn_fill; 227 pfs_ioctl_t pn_ioctl; 228 pfs_close_t pn_close; 229 pfs_attr_t pn_attr; 230 pfs_vis_t pn_vis; 231 pfs_getextattr_t pn_getextattr; 232 pfs_destroy_t pn_destroy; 233 234 struct pfs_info *pn_info; 235 u_int32_t pn_fileno; /* (o) */ 236 237 struct pfs_node *pn_parent; /* (o) */ 238 struct pfs_node *pn_nodes; /* (o) */ 239 struct pfs_node *pn_next; /* (p) */ 240 }; 241 242 /* 243 * VFS interface 244 */ 245 int pfs_mount (struct pfs_info *pi, struct mount *mp); 246 int pfs_cmount (struct mntarg *ma, void *data, uint64_t flags); 247 int pfs_unmount (struct mount *mp, int mntflags); 248 int pfs_root (struct mount *mp, int flags, 249 struct vnode **vpp); 250 int pfs_statfs (struct mount *mp, struct statfs *sbp); 251 int pfs_init (struct pfs_info *pi, struct vfsconf *vfc); 252 int pfs_uninit (struct pfs_info *pi, struct vfsconf *vfc); 253 254 /* 255 * Directory structure construction and manipulation 256 */ 257 struct pfs_node *pfs_create_dir (struct pfs_node *parent, const char *name, 258 pfs_attr_t attr, pfs_vis_t vis, 259 pfs_destroy_t destroy, int flags); 260 struct pfs_node *pfs_create_file(struct pfs_node *parent, const char *name, 261 pfs_fill_t fill, pfs_attr_t attr, 262 pfs_vis_t vis, pfs_destroy_t destroy, 263 int flags); 264 struct pfs_node *pfs_create_link(struct pfs_node *parent, const char *name, 265 pfs_fill_t fill, pfs_attr_t attr, 266 pfs_vis_t vis, pfs_destroy_t destroy, 267 int flags); 268 struct pfs_node *pfs_find_node (struct pfs_node *parent, const char *name); 269 void pfs_purge (struct pfs_node *pn); 270 int pfs_destroy (struct pfs_node *pn); 271 272 /* 273 * Now for some initialization magic... 274 */ 275 #define PSEUDOFS(name, version, jflag) \ 276 \ 277 static struct pfs_info name##_info = { \ 278 #name, \ 279 name##_init, \ 280 name##_uninit, \ 281 }; \ 282 \ 283 static int \ 284 _##name##_mount(struct mount *mp) { \ 285 if (jflag && !prison_allow(curthread->td_ucred, jflag)) \ 286 return (EPERM); \ 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 | (jflag ? VFCF_JAIL : 0)); \ 310 MODULE_VERSION(name, version); \ 311 MODULE_DEPEND(name, pseudofs, 1, 1, 1); 312 313 #endif 314