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 mount; 38 struct nameidata; 39 struct proc; 40 struct sbuf; 41 struct statfs; 42 struct thread; 43 struct uio; 44 struct vfsconf; 45 struct vnode; 46 47 /* 48 * Limits and constants 49 */ 50 #define PFS_NAMELEN 24 51 #define PFS_FSNAMELEN 16 /* equal to MFSNAMELEN */ 52 #define PFS_DELEN (8 + PFS_NAMELEN) 53 54 typedef enum { 55 pfstype_none = 0, 56 pfstype_root, 57 pfstype_dir, 58 pfstype_this, 59 pfstype_parent, 60 pfstype_file, 61 pfstype_symlink, 62 pfstype_procdir 63 } pfs_type_t; 64 65 /* 66 * Flags 67 */ 68 #define PFS_RD 0x0001 /* readable */ 69 #define PFS_WR 0x0002 /* writeable */ 70 #define PFS_RDWR (PFS_RD|PFS_WR) 71 #define PFS_RAWRD 0x0004 /* raw reader */ 72 #define PFS_RAWWR 0x0008 /* raw writer */ 73 #define PFS_RAW (PFS_RAWRD|PFS_RAWWR) 74 #define PFS_PROCDEP 0x0010 /* process-dependent */ 75 #define PFS_DISABLED 0x8000 /* node is disabled */ 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_PROTO(name) \ 90 int name(PFS_INIT_ARGS); 91 typedef int (*pfs_init_t)(PFS_INIT_ARGS); 92 93 /* 94 * Filler callback 95 */ 96 #define PFS_FILL_ARGS \ 97 struct thread *td, struct proc *p, struct pfs_node *pn, \ 98 struct sbuf *sb, struct uio *uio 99 #define PFS_FILL_PROTO(name) \ 100 int name(PFS_FILL_ARGS); 101 typedef int (*pfs_fill_t)(PFS_FILL_ARGS); 102 103 /* 104 * Attribute callback 105 */ 106 struct vattr; 107 #define PFS_ATTR_ARGS \ 108 struct thread *td, struct proc *p, struct pfs_node *pn, \ 109 struct vattr *vap 110 #define PFS_ATTR_PROTO(name) \ 111 int name(PFS_ATTR_ARGS); 112 typedef int (*pfs_attr_t)(PFS_ATTR_ARGS); 113 114 struct pfs_bitmap; /* opaque */ 115 116 /* 117 * Visibility callback 118 */ 119 #define PFS_VIS_ARGS \ 120 struct thread *td, struct proc *p, struct pfs_node *pn 121 #define PFS_VIS_PROTO(name) \ 122 int name(PFS_VIS_ARGS); 123 typedef int (*pfs_vis_t)(PFS_VIS_ARGS); 124 125 /* 126 * Ioctl callback 127 */ 128 #define PFS_IOCTL_ARGS \ 129 struct thread *td, struct proc *p, struct pfs_node *pn, \ 130 unsigned long cmd, caddr_t data 131 #define PFS_IOCTL_PROTO(name) \ 132 int name(PFS_IOCTL_ARGS); 133 typedef int (*pfs_ioctl_t)(PFS_IOCTL_ARGS); 134 135 /* 136 * Last-close callback 137 */ 138 #define PFS_CLOSE_ARGS \ 139 struct thread *td, struct proc *p, struct pfs_node *pn 140 #define PFS_CLOSE_PROTO(name) \ 141 int name(PFS_CLOSE_ARGS); 142 typedef int (*pfs_close_t)(PFS_CLOSE_ARGS); 143 144 /* 145 * pfs_info: describes a pseudofs instance 146 */ 147 struct pfs_info { 148 char pi_name[PFS_FSNAMELEN]; 149 pfs_init_t pi_init; 150 pfs_init_t pi_uninit; 151 /* members below this line aren't initialized */ 152 struct pfs_node *pi_root; 153 /* currently, the mutex is only used to protect the bitmap */ 154 struct mtx pi_mutex; 155 struct pfs_bitmap *pi_bitmap; 156 }; 157 158 /* 159 * pfs_node: describes a node (file or directory) within a pseudofs 160 */ 161 struct pfs_node { 162 char pn_name[PFS_NAMELEN]; 163 pfs_type_t pn_type; 164 union { 165 void *_pn_dummy; 166 pfs_fill_t _pn_func; 167 struct pfs_node *_pn_nodes; 168 } u1; 169 #define pn_func u1._pn_func 170 #define pn_nodes u1._pn_nodes 171 pfs_ioctl_t pn_ioctl; 172 pfs_close_t pn_close; 173 pfs_attr_t pn_attr; 174 pfs_vis_t pn_vis; 175 void *pn_data; 176 int pn_flags; 177 178 struct pfs_info *pn_info; 179 struct pfs_node *pn_parent; 180 struct pfs_node *pn_next; 181 u_int32_t pn_fileno; 182 }; 183 184 /* 185 * VFS interface 186 */ 187 int pfs_mount (struct pfs_info *pi, 188 struct mount *mp, char *path, caddr_t data, 189 struct nameidata *ndp, struct thread *td); 190 int pfs_unmount (struct mount *mp, int mntflags, 191 struct thread *td); 192 int pfs_root (struct mount *mp, struct vnode **vpp); 193 int pfs_statfs (struct mount *mp, struct statfs *sbp, 194 struct thread *td); 195 int pfs_init (struct pfs_info *pi, struct vfsconf *vfc); 196 int pfs_uninit (struct pfs_info *pi, struct vfsconf *vfc); 197 198 /* 199 * Directory structure construction and manipulation 200 */ 201 struct pfs_node *pfs_create_dir (struct pfs_node *parent, char *name, 202 pfs_attr_t attr, pfs_vis_t vis, int flags); 203 struct pfs_node *pfs_create_file(struct pfs_node *parent, char *name, 204 pfs_fill_t fill, pfs_attr_t attr, 205 pfs_vis_t vis, int flags); 206 struct pfs_node *pfs_create_link(struct pfs_node *parent, char *name, 207 pfs_fill_t fill, pfs_attr_t attr, 208 pfs_vis_t vis, int flags); 209 int pfs_disable (struct pfs_node *pn); 210 int pfs_enable (struct pfs_node *pn); 211 int pfs_destroy (struct pfs_node *pn); 212 213 /* 214 * Now for some initialization magic... 215 */ 216 #define PSEUDOFS(name, version) \ 217 \ 218 static struct pfs_info name##_info = { \ 219 #name, \ 220 &name##_init, \ 221 &name##_uninit, \ 222 }; \ 223 \ 224 static int \ 225 _##name##_mount(struct mount *mp, char *path, caddr_t data, \ 226 struct nameidata *ndp, struct thread *td) { \ 227 return pfs_mount(&name##_info, mp, path, data, ndp, td); \ 228 } \ 229 \ 230 static int \ 231 _##name##_init(struct vfsconf *vfc) { \ 232 return pfs_init(&name##_info, vfc); \ 233 } \ 234 \ 235 static int \ 236 _##name##_uninit(struct vfsconf *vfc) { \ 237 return pfs_uninit(&name##_info, vfc); \ 238 } \ 239 \ 240 static struct vfsops name##_vfsops = { \ 241 _##name##_mount, \ 242 vfs_stdstart, \ 243 pfs_unmount, \ 244 pfs_root, \ 245 vfs_stdquotactl, \ 246 pfs_statfs, \ 247 vfs_stdsync, \ 248 vfs_stdvget, \ 249 vfs_stdfhtovp, \ 250 vfs_stdcheckexp, \ 251 vfs_stdvptofh, \ 252 _##name##_init, \ 253 _##name##_uninit, \ 254 vfs_stdextattrctl, \ 255 }; \ 256 VFS_SET(name##_vfsops, name, VFCF_SYNTHETIC); \ 257 MODULE_VERSION(name, version); \ 258 MODULE_DEPEND(name, pseudofs, 1, 1, 1); 259 260 #endif 261