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