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