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 #define PFS_DISABLED 0x8000 /* node is disabled */ 77 78 /* 79 * Data structures 80 */ 81 struct pfs_info; 82 struct pfs_node; 83 struct pfs_bitmap; 84 85 /* 86 * Init / uninit callback 87 */ 88 #define PFS_INIT_ARGS \ 89 struct pfs_info *pi, struct vfsconf *vfc 90 #define PFS_INIT_PROTO(name) \ 91 int name(PFS_INIT_ARGS); 92 typedef int (*pfs_init_t)(PFS_INIT_ARGS); 93 94 /* 95 * Filler callback 96 */ 97 #define PFS_FILL_ARGS \ 98 struct thread *td, struct proc *p, struct pfs_node *pn, \ 99 struct sbuf *sb, struct uio *uio 100 #define PFS_FILL_PROTO(name) \ 101 int name(PFS_FILL_ARGS); 102 typedef int (*pfs_fill_t)(PFS_FILL_ARGS); 103 104 /* 105 * Attribute callback 106 */ 107 struct vattr; 108 #define PFS_ATTR_ARGS \ 109 struct thread *td, struct proc *p, struct pfs_node *pn, \ 110 struct vattr *vap 111 #define PFS_ATTR_PROTO(name) \ 112 int name(PFS_ATTR_ARGS); 113 typedef int (*pfs_attr_t)(PFS_ATTR_ARGS); 114 115 struct pfs_bitmap; /* opaque */ 116 117 /* 118 * Visibility callback 119 */ 120 #define PFS_VIS_ARGS \ 121 struct thread *td, struct proc *p, struct pfs_node *pn 122 #define PFS_VIS_PROTO(name) \ 123 int name(PFS_VIS_ARGS); 124 typedef int (*pfs_vis_t)(PFS_VIS_ARGS); 125 126 /* 127 * Ioctl callback 128 */ 129 #define PFS_IOCTL_ARGS \ 130 struct thread *td, struct proc *p, struct pfs_node *pn, \ 131 unsigned long cmd, void *data 132 #define PFS_IOCTL_PROTO(name) \ 133 int name(PFS_IOCTL_ARGS); 134 typedef int (*pfs_ioctl_t)(PFS_IOCTL_ARGS); 135 136 /* 137 * Getextattr callback 138 */ 139 #define PFS_GETEXTATTR_ARGS \ 140 struct thread *td, struct proc *p, struct pfs_node *pn, \ 141 int attrnamespace, const char *name, struct uio *uio, \ 142 size_t *size, struct ucred *cred 143 #define PFS_GETEXTATTR_PROTO(name) \ 144 int name(PFS_GETEXTATTR_ARGS); 145 struct ucred; 146 typedef int (*pfs_getextattr_t)(PFS_GETEXTATTR_ARGS); 147 148 /* 149 * Last-close callback 150 */ 151 #define PFS_CLOSE_ARGS \ 152 struct thread *td, struct proc *p, struct pfs_node *pn 153 #define PFS_CLOSE_PROTO(name) \ 154 int name(PFS_CLOSE_ARGS); 155 typedef int (*pfs_close_t)(PFS_CLOSE_ARGS); 156 157 /* 158 * Destroy callback 159 */ 160 #define PFS_DESTROY_ARGS \ 161 struct pfs_node *pn 162 #define PFS_DESTROY_PROTO(name) \ 163 int name(PFS_DESTROY_ARGS); 164 typedef int (*pfs_destroy_t)(PFS_DESTROY_ARGS); 165 166 /* 167 * pfs_info: describes a pseudofs instance 168 */ 169 struct pfs_info { 170 char pi_name[PFS_FSNAMELEN]; 171 pfs_init_t pi_init; 172 pfs_init_t pi_uninit; 173 /* members below this line aren't initialized */ 174 struct pfs_node *pi_root; 175 /* currently, the mutex is only used to protect the bitmap */ 176 struct mtx pi_mutex; 177 struct unrhdr *pi_unrhdr; 178 }; 179 180 /* 181 * pfs_node: describes a node (file or directory) within a pseudofs 182 */ 183 struct pfs_node { 184 char pn_name[PFS_NAMELEN]; 185 pfs_type_t pn_type; 186 union { 187 void *_pn_dummy; 188 pfs_fill_t _pn_func; 189 struct pfs_node *_pn_nodes; 190 } u1; 191 #define pn_func u1._pn_func 192 #define pn_nodes u1._pn_nodes 193 pfs_ioctl_t pn_ioctl; 194 pfs_close_t pn_close; 195 pfs_attr_t pn_attr; 196 pfs_vis_t pn_vis; 197 pfs_getextattr_t pn_getextattr; 198 pfs_destroy_t pn_destroy; 199 void *pn_data; 200 int pn_flags; 201 202 struct pfs_info *pn_info; 203 struct pfs_node *pn_parent; 204 struct pfs_node *pn_next; 205 u_int32_t pn_fileno; 206 }; 207 208 /* 209 * VFS interface 210 */ 211 int pfs_mount (struct pfs_info *pi, struct mount *mp, 212 struct thread *td); 213 int pfs_cmount (struct mntarg *ma, void *data, int flags, 214 struct thread *td); 215 int pfs_unmount (struct mount *mp, int mntflags, 216 struct thread *td); 217 int pfs_root (struct mount *mp, int flags, 218 struct vnode **vpp, struct thread *td); 219 int pfs_statfs (struct mount *mp, struct statfs *sbp, 220 struct thread *td); 221 int pfs_init (struct pfs_info *pi, struct vfsconf *vfc); 222 int pfs_uninit (struct pfs_info *pi, struct vfsconf *vfc); 223 224 /* 225 * Directory structure construction and manipulation 226 */ 227 struct pfs_node *pfs_create_dir (struct pfs_node *parent, const char *name, 228 pfs_attr_t attr, pfs_vis_t vis, 229 pfs_destroy_t destroy, int flags); 230 struct pfs_node *pfs_create_file(struct pfs_node *parent, const char *name, 231 pfs_fill_t fill, pfs_attr_t attr, 232 pfs_vis_t vis, pfs_destroy_t destroy, 233 int flags); 234 struct pfs_node *pfs_create_link(struct pfs_node *parent, const char *name, 235 pfs_fill_t fill, pfs_attr_t attr, 236 pfs_vis_t vis, pfs_destroy_t destroy, 237 int flags); 238 struct pfs_node *pfs_find_node (struct pfs_node *parent, const char *name); 239 int pfs_disable (struct pfs_node *pn); 240 int pfs_enable (struct pfs_node *pn); 241 int pfs_destroy (struct pfs_node *pn); 242 243 /* 244 * Now for some initialization magic... 245 */ 246 #define PSEUDOFS(name, version) \ 247 \ 248 static struct pfs_info name##_info = { \ 249 #name, \ 250 name##_init, \ 251 name##_uninit, \ 252 }; \ 253 \ 254 static int \ 255 _##name##_mount(struct mount *mp, struct thread *td) { \ 256 return pfs_mount(&name##_info, mp, td); \ 257 } \ 258 \ 259 static int \ 260 _##name##_init(struct vfsconf *vfc) { \ 261 return pfs_init(&name##_info, vfc); \ 262 } \ 263 \ 264 static int \ 265 _##name##_uninit(struct vfsconf *vfc) { \ 266 return pfs_uninit(&name##_info, vfc); \ 267 } \ 268 \ 269 static struct vfsops name##_vfsops = { \ 270 .vfs_cmount = pfs_cmount, \ 271 .vfs_init = _##name##_init, \ 272 .vfs_mount = _##name##_mount, \ 273 .vfs_root = pfs_root, \ 274 .vfs_statfs = pfs_statfs, \ 275 .vfs_uninit = _##name##_uninit, \ 276 .vfs_unmount = pfs_unmount, \ 277 }; \ 278 VFS_SET(name##_vfsops, name, VFCF_SYNTHETIC); \ 279 MODULE_VERSION(name, version); \ 280 MODULE_DEPEND(name, pseudofs, 1, 1, 1); 281 282 #endif 283