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: stable/11/sys/fs/pseudofs/pseudofs.h 325104 2017-10-29 14:57:58Z markj $ 29 */ 30 31#ifndef _PSEUDOFS_H_INCLUDED 32#define _PSEUDOFS_H_INCLUDED 33 34#include <sys/jail.h> 35 36/* 37 * Opaque structures 38 */ 39struct mntarg; 40struct mount; 41struct nameidata; 42struct proc; 43struct sbuf; 44struct statfs; 45struct thread; 46struct uio; 47struct vfsconf; 48struct vnode; 49 50/* 51 * Limits and constants 52 */ 53#define PFS_NAMELEN 24 54#define PFS_FSNAMELEN 16 /* equal to MFSNAMELEN */ 55#define PFS_DELEN (8 + PFS_NAMELEN) 56 57typedef 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 79/* 80 * Data structures 81 */ 82struct pfs_info; 83struct pfs_node; 84 85/* 86 * Init / uninit callback 87 */ 88#define PFS_INIT_ARGS \ 89 struct pfs_info *pi, struct vfsconf *vfc 90#define PFS_INIT_ARGNAMES \ 91 pi, vfc 92#define PFS_INIT_PROTO(name) \ 93 int name(PFS_INIT_ARGS); 94typedef int (*pfs_init_t)(PFS_INIT_ARGS); 95 96/* 97 * Filler callback 98 * Called with proc held but unlocked 99 */ 100#define PFS_FILL_ARGS \ 101 struct thread *td, struct proc *p, struct pfs_node *pn, \ 102 struct sbuf *sb, struct uio *uio 103#define PFS_FILL_ARGNAMES \ 104 td, p, pn, sb, uio 105#define PFS_FILL_PROTO(name) \ 106 int name(PFS_FILL_ARGS); 107typedef int (*pfs_fill_t)(PFS_FILL_ARGS); 108 109/* 110 * Attribute callback 111 * Called with proc locked 112 */ 113struct vattr; 114#define PFS_ATTR_ARGS \ 115 struct thread *td, struct proc *p, struct pfs_node *pn, \ 116 struct vattr *vap 117#define PFS_ATTR_ARGNAMES \ 118 td, p, pn, vap 119#define PFS_ATTR_PROTO(name) \ 120 int name(PFS_ATTR_ARGS); 121typedef int (*pfs_attr_t)(PFS_ATTR_ARGS); 122 123/* 124 * Visibility callback 125 * Called with proc locked 126 */ 127#define PFS_VIS_ARGS \ 128 struct thread *td, struct proc *p, struct pfs_node *pn 129#define PFS_VIS_ARGNAMES \ 130 td, p, pn 131#define PFS_VIS_PROTO(name) \ 132 int name(PFS_VIS_ARGS); 133typedef int (*pfs_vis_t)(PFS_VIS_ARGS); 134 135/* 136 * Ioctl callback 137 * Called with proc locked 138 */ 139#define PFS_IOCTL_ARGS \ 140 struct thread *td, struct proc *p, struct pfs_node *pn, \ 141 unsigned long cmd, void *data 142#define PFS_IOCTL_ARGNAMES \ 143 td, p, pn, cmd, data 144#define PFS_IOCTL_PROTO(name) \ 145 int name(PFS_IOCTL_ARGS); 146typedef int (*pfs_ioctl_t)(PFS_IOCTL_ARGS); 147 148/* 149 * Getextattr callback 150 * Called with proc locked 151 */ 152#define PFS_GETEXTATTR_ARGS \ 153 struct thread *td, struct proc *p, struct pfs_node *pn, \ 154 int attrnamespace, const char *name, struct uio *uio, \ 155 size_t *size, struct ucred *cred 156#define PFS_GETEXTATTR_ARGNAMES \ 157 td, p, pn, attrnamespace, name, uio, size, cred 158#define PFS_GETEXTATTR_PROTO(name) \ 159 int name(PFS_GETEXTATTR_ARGS); 160struct ucred; 161typedef int (*pfs_getextattr_t)(PFS_GETEXTATTR_ARGS); 162 163/* 164 * Last-close callback 165 * Called with proc locked 166 */ 167#define PFS_CLOSE_ARGS \ 168 struct thread *td, struct proc *p, struct pfs_node *pn 169#define PFS_CLOSE_ARGNAMES \ 170 td, p, pn 171#define PFS_CLOSE_PROTO(name) \ 172 int name(PFS_CLOSE_ARGS); 173typedef int (*pfs_close_t)(PFS_CLOSE_ARGS); 174 175/* 176 * Destroy callback 177 */ 178#define PFS_DESTROY_ARGS \ 179 struct pfs_node *pn 180#define PFS_DESTROY_ARGNAMES \ 181 pn 182#define PFS_DESTROY_PROTO(name) \ 183 int name(PFS_DESTROY_ARGS); 184typedef int (*pfs_destroy_t)(PFS_DESTROY_ARGS); 185 186/* 187 * pfs_info: describes a pseudofs instance 188 * 189 * The pi_mutex is only used to avoid using the global subr_unit lock 190 * for unrhdr. The rest of struct pfs_info is only modified during 191 * vfs_init() and vfs_uninit() of the consumer filesystem. 192 */ 193struct pfs_info { 194 char pi_name[PFS_FSNAMELEN]; 195 pfs_init_t pi_init; 196 pfs_init_t pi_uninit; 197 198 /* members below this line are initialized at run time */ 199 struct pfs_node *pi_root; 200 struct mtx pi_mutex; 201 struct unrhdr *pi_unrhdr; 202}; 203 204/* 205 * pfs_node: describes a node (file or directory) within a pseudofs 206 * 207 * - Fields marked (o) are protected by the node's own mutex. 208 * - Fields marked (p) are protected by the node's parent's mutex. 209 * - Remaining fields are not protected by any lock and are assumed to be 210 * immutable once the node has been created. 211 * 212 * To prevent deadlocks, if a node's mutex is to be held at the same time 213 * as its parent's (e.g. when adding or removing nodes to a directory), 214 * the parent's mutex must always be acquired first. Unfortunately, this 215 * is not enforcable by WITNESS. 216 */ 217struct pfs_node { 218 char pn_name[PFS_NAMELEN]; 219 pfs_type_t pn_type; 220 int pn_flags; 221 struct mtx pn_mutex; 222 void *pn_data; /* (o) */ 223 224 pfs_fill_t pn_fill; 225 pfs_ioctl_t pn_ioctl; 226 pfs_close_t pn_close; 227 pfs_attr_t pn_attr; 228 pfs_vis_t pn_vis; 229 pfs_getextattr_t pn_getextattr; 230 pfs_destroy_t pn_destroy; 231 232 struct pfs_info *pn_info; 233 u_int32_t pn_fileno; /* (o) */ 234 235 struct pfs_node *pn_parent; /* (o) */ 236 struct pfs_node *pn_nodes; /* (o) */ 237 struct pfs_node *pn_next; /* (p) */ 238}; 239 240/* 241 * VFS interface 242 */ 243int pfs_mount (struct pfs_info *pi, struct mount *mp); 244int pfs_cmount (struct mntarg *ma, void *data, uint64_t flags); 245int pfs_unmount (struct mount *mp, int mntflags); 246int pfs_root (struct mount *mp, int flags, 247 struct vnode **vpp); 248int pfs_statfs (struct mount *mp, struct statfs *sbp); 249int pfs_init (struct pfs_info *pi, struct vfsconf *vfc); 250int pfs_uninit (struct pfs_info *pi, struct vfsconf *vfc); 251 252/* 253 * Directory structure construction and manipulation 254 */ 255struct pfs_node *pfs_create_dir (struct pfs_node *parent, const char *name, 256 pfs_attr_t attr, pfs_vis_t vis, 257 pfs_destroy_t destroy, int flags); 258struct pfs_node *pfs_create_file(struct pfs_node *parent, const char *name, 259 pfs_fill_t fill, pfs_attr_t attr, 260 pfs_vis_t vis, pfs_destroy_t destroy, 261 int flags); 262struct pfs_node *pfs_create_link(struct pfs_node *parent, const char *name, 263 pfs_fill_t fill, pfs_attr_t attr, 264 pfs_vis_t vis, pfs_destroy_t destroy, 265 int flags); 266struct pfs_node *pfs_find_node (struct pfs_node *parent, const char *name); 267void pfs_purge (struct pfs_node *pn); 268int pfs_destroy (struct pfs_node *pn); 269 270/* 271 * Now for some initialization magic... 272 */ 273#define PSEUDOFS(name, version, jflag) \ 274 \ 275static struct pfs_info name##_info = { \ 276 #name, \ 277 name##_init, \ 278 name##_uninit, \ 279}; \ 280 \ 281static int \ 282_##name##_mount(struct mount *mp) { \ 283 if (jflag && !prison_allow(curthread->td_ucred, jflag)) \ 284 return (EPERM); \ 285 return (pfs_mount(&name##_info, mp)); \ 286} \ 287 \ 288static int \ 289_##name##_init(struct vfsconf *vfc) { \ 290 return (pfs_init(&name##_info, vfc)); \ 291} \ 292 \ 293static int \ 294_##name##_uninit(struct vfsconf *vfc) { \ 295 return (pfs_uninit(&name##_info, vfc)); \ 296} \ 297 \ 298static struct vfsops name##_vfsops = { \ 299 .vfs_cmount = pfs_cmount, \ 300 .vfs_init = _##name##_init, \ 301 .vfs_mount = _##name##_mount, \ 302 .vfs_root = pfs_root, \ 303 .vfs_statfs = pfs_statfs, \ 304 .vfs_uninit = _##name##_uninit, \ 305 .vfs_unmount = pfs_unmount, \ 306}; \ 307VFS_SET(name##_vfsops, name, VFCF_SYNTHETIC | (jflag ? VFCF_JAIL : 0)); \ 308MODULE_VERSION(name, version); \ 309MODULE_DEPEND(name, pseudofs, 1, 1, 1); 310 311#endif 312