19733a808SDag-Erling Smørgrav /*- 29733a808SDag-Erling Smørgrav * Copyright (c) 2001 Dag-Erling Co�dan Sm�rgrav 39733a808SDag-Erling Smørgrav * All rights reserved. 49733a808SDag-Erling Smørgrav * 59733a808SDag-Erling Smørgrav * Redistribution and use in source and binary forms, with or without 69733a808SDag-Erling Smørgrav * modification, are permitted provided that the following conditions 79733a808SDag-Erling Smørgrav * are met: 89733a808SDag-Erling Smørgrav * 1. Redistributions of source code must retain the above copyright 99733a808SDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer 109733a808SDag-Erling Smørgrav * in this position and unchanged. 119733a808SDag-Erling Smørgrav * 2. Redistributions in binary form must reproduce the above copyright 129733a808SDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer in the 139733a808SDag-Erling Smørgrav * documentation and/or other materials provided with the distribution. 149733a808SDag-Erling Smørgrav * 3. The name of the author may not be used to endorse or promote products 159733a808SDag-Erling Smørgrav * derived from this software without specific prior written permission. 169733a808SDag-Erling Smørgrav * 179733a808SDag-Erling Smørgrav * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 189733a808SDag-Erling Smørgrav * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 199733a808SDag-Erling Smørgrav * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 209733a808SDag-Erling Smørgrav * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 219733a808SDag-Erling Smørgrav * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 229733a808SDag-Erling Smørgrav * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 239733a808SDag-Erling Smørgrav * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 249733a808SDag-Erling Smørgrav * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 259733a808SDag-Erling Smørgrav * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 269733a808SDag-Erling Smørgrav * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 279733a808SDag-Erling Smørgrav * 289733a808SDag-Erling Smørgrav * $FreeBSD$ 299733a808SDag-Erling Smørgrav */ 309733a808SDag-Erling Smørgrav 319733a808SDag-Erling Smørgrav #ifndef _PSEUDOFS_H_INCLUDED 329733a808SDag-Erling Smørgrav #define _PSEUDOFS_H_INCLUDED 339733a808SDag-Erling Smørgrav 349733a808SDag-Erling Smørgrav /* 3541aa8697SDag-Erling Smørgrav * Opaque structures 3641aa8697SDag-Erling Smørgrav */ 37c9ad8a67SKelly Yancey struct mntarg; 3841aa8697SDag-Erling Smørgrav struct mount; 3941aa8697SDag-Erling Smørgrav struct nameidata; 4041aa8697SDag-Erling Smørgrav struct proc; 4141aa8697SDag-Erling Smørgrav struct sbuf; 4241aa8697SDag-Erling Smørgrav struct statfs; 4341aa8697SDag-Erling Smørgrav struct thread; 4441aa8697SDag-Erling Smørgrav struct uio; 4541aa8697SDag-Erling Smørgrav struct vfsconf; 4641aa8697SDag-Erling Smørgrav struct vnode; 4741aa8697SDag-Erling Smørgrav 4841aa8697SDag-Erling Smørgrav /* 499733a808SDag-Erling Smørgrav * Limits and constants 509733a808SDag-Erling Smørgrav */ 519733a808SDag-Erling Smørgrav #define PFS_NAMELEN 24 5241aa8697SDag-Erling Smørgrav #define PFS_FSNAMELEN 16 /* equal to MFSNAMELEN */ 539733a808SDag-Erling Smørgrav #define PFS_DELEN (8 + PFS_NAMELEN) 549733a808SDag-Erling Smørgrav 559733a808SDag-Erling Smørgrav typedef enum { 569733a808SDag-Erling Smørgrav pfstype_none = 0, 579733a808SDag-Erling Smørgrav pfstype_root, 589733a808SDag-Erling Smørgrav pfstype_dir, 599733a808SDag-Erling Smørgrav pfstype_this, 609733a808SDag-Erling Smørgrav pfstype_parent, 619733a808SDag-Erling Smørgrav pfstype_file, 629733a808SDag-Erling Smørgrav pfstype_symlink, 63649ad985SDag-Erling Smørgrav pfstype_procdir 649733a808SDag-Erling Smørgrav } pfs_type_t; 659733a808SDag-Erling Smørgrav 669733a808SDag-Erling Smørgrav /* 678712e867SDag-Erling Smørgrav * Flags 688712e867SDag-Erling Smørgrav */ 697d8f809fSDag-Erling Smørgrav #define PFS_RD 0x0001 /* readable */ 707d8f809fSDag-Erling Smørgrav #define PFS_WR 0x0002 /* writeable */ 717d8f809fSDag-Erling Smørgrav #define PFS_RDWR (PFS_RD|PFS_WR) 728712e867SDag-Erling Smørgrav #define PFS_RAWRD 0x0004 /* raw reader */ 738712e867SDag-Erling Smørgrav #define PFS_RAWWR 0x0008 /* raw writer */ 747d8f809fSDag-Erling Smørgrav #define PFS_RAW (PFS_RAWRD|PFS_RAWWR) 7533802b9eSDag-Erling Smørgrav #define PFS_PROCDEP 0x0010 /* process-dependent */ 768712e867SDag-Erling Smørgrav 778712e867SDag-Erling Smørgrav /* 789733a808SDag-Erling Smørgrav * Data structures 799733a808SDag-Erling Smørgrav */ 809733a808SDag-Erling Smørgrav struct pfs_info; 819733a808SDag-Erling Smørgrav struct pfs_node; 829733a808SDag-Erling Smørgrav struct pfs_bitmap; 839733a808SDag-Erling Smørgrav 8480a3cef8SDag-Erling Smørgrav /* 8533802b9eSDag-Erling Smørgrav * Init / uninit callback 8633802b9eSDag-Erling Smørgrav */ 8733802b9eSDag-Erling Smørgrav #define PFS_INIT_ARGS \ 8833802b9eSDag-Erling Smørgrav struct pfs_info *pi, struct vfsconf *vfc 89388596dfSDag-Erling Smørgrav #define PFS_INIT_ARGNAMES \ 90388596dfSDag-Erling Smørgrav pi, vfc 9133802b9eSDag-Erling Smørgrav #define PFS_INIT_PROTO(name) \ 9233802b9eSDag-Erling Smørgrav int name(PFS_INIT_ARGS); 9333802b9eSDag-Erling Smørgrav typedef int (*pfs_init_t)(PFS_INIT_ARGS); 9433802b9eSDag-Erling Smørgrav 9533802b9eSDag-Erling Smørgrav /* 9680a3cef8SDag-Erling Smørgrav * Filler callback 97388596dfSDag-Erling Smørgrav * Called with proc held but unlocked 9880a3cef8SDag-Erling Smørgrav */ 99649ad985SDag-Erling Smørgrav #define PFS_FILL_ARGS \ 1008712e867SDag-Erling Smørgrav struct thread *td, struct proc *p, struct pfs_node *pn, \ 1018712e867SDag-Erling Smørgrav struct sbuf *sb, struct uio *uio 102388596dfSDag-Erling Smørgrav #define PFS_FILL_ARGNAMES \ 103388596dfSDag-Erling Smørgrav td, p, pn, sb, uio 104649ad985SDag-Erling Smørgrav #define PFS_FILL_PROTO(name) \ 105649ad985SDag-Erling Smørgrav int name(PFS_FILL_ARGS); 106649ad985SDag-Erling Smørgrav typedef int (*pfs_fill_t)(PFS_FILL_ARGS); 1079733a808SDag-Erling Smørgrav 10880a3cef8SDag-Erling Smørgrav /* 10980a3cef8SDag-Erling Smørgrav * Attribute callback 110388596dfSDag-Erling Smørgrav * Called with proc locked 11180a3cef8SDag-Erling Smørgrav */ 11280a3cef8SDag-Erling Smørgrav struct vattr; 11380a3cef8SDag-Erling Smørgrav #define PFS_ATTR_ARGS \ 11480a3cef8SDag-Erling Smørgrav struct thread *td, struct proc *p, struct pfs_node *pn, \ 11580a3cef8SDag-Erling Smørgrav struct vattr *vap 116388596dfSDag-Erling Smørgrav #define PFS_ATTR_ARGNAMES \ 117388596dfSDag-Erling Smørgrav td, p, pn, vap 11880a3cef8SDag-Erling Smørgrav #define PFS_ATTR_PROTO(name) \ 11980a3cef8SDag-Erling Smørgrav int name(PFS_ATTR_ARGS); 12080a3cef8SDag-Erling Smørgrav typedef int (*pfs_attr_t)(PFS_ATTR_ARGS); 12180a3cef8SDag-Erling Smørgrav 1229733a808SDag-Erling Smørgrav struct pfs_bitmap; /* opaque */ 1239733a808SDag-Erling Smørgrav 1249733a808SDag-Erling Smørgrav /* 125198bc14bSDag-Erling Smørgrav * Visibility callback 126388596dfSDag-Erling Smørgrav * Called with proc locked 127198bc14bSDag-Erling Smørgrav */ 128198bc14bSDag-Erling Smørgrav #define PFS_VIS_ARGS \ 129198bc14bSDag-Erling Smørgrav struct thread *td, struct proc *p, struct pfs_node *pn 130388596dfSDag-Erling Smørgrav #define PFS_VIS_ARGNAMES \ 131388596dfSDag-Erling Smørgrav td, p, pn 132198bc14bSDag-Erling Smørgrav #define PFS_VIS_PROTO(name) \ 133198bc14bSDag-Erling Smørgrav int name(PFS_VIS_ARGS); 134198bc14bSDag-Erling Smørgrav typedef int (*pfs_vis_t)(PFS_VIS_ARGS); 135198bc14bSDag-Erling Smørgrav 136198bc14bSDag-Erling Smørgrav /* 13718319000SDag-Erling Smørgrav * Ioctl callback 138388596dfSDag-Erling Smørgrav * Called with proc locked 13918319000SDag-Erling Smørgrav */ 14018319000SDag-Erling Smørgrav #define PFS_IOCTL_ARGS \ 14118319000SDag-Erling Smørgrav struct thread *td, struct proc *p, struct pfs_node *pn, \ 1427b726be3SDag-Erling Smørgrav unsigned long cmd, void *data 143388596dfSDag-Erling Smørgrav #define PFS_IOCTL_ARGNAMES \ 144388596dfSDag-Erling Smørgrav td, p, pn, cmd, data 14518319000SDag-Erling Smørgrav #define PFS_IOCTL_PROTO(name) \ 14618319000SDag-Erling Smørgrav int name(PFS_IOCTL_ARGS); 14718319000SDag-Erling Smørgrav typedef int (*pfs_ioctl_t)(PFS_IOCTL_ARGS); 14818319000SDag-Erling Smørgrav 14918319000SDag-Erling Smørgrav /* 15041a35633SBrian Feldman * Getextattr callback 151388596dfSDag-Erling Smørgrav * Called with proc locked 15241a35633SBrian Feldman */ 15341a35633SBrian Feldman #define PFS_GETEXTATTR_ARGS \ 15441a35633SBrian Feldman struct thread *td, struct proc *p, struct pfs_node *pn, \ 15541a35633SBrian Feldman int attrnamespace, const char *name, struct uio *uio, \ 15674237f55SRobert Watson size_t *size, struct ucred *cred 157388596dfSDag-Erling Smørgrav #define PFS_GETEXTATTR_ARGNAMES \ 158388596dfSDag-Erling Smørgrav td, p, pn, attrnamespace, name, uio, size, cred 15941a35633SBrian Feldman #define PFS_GETEXTATTR_PROTO(name) \ 16041a35633SBrian Feldman int name(PFS_GETEXTATTR_ARGS); 16141a35633SBrian Feldman struct ucred; 16241a35633SBrian Feldman typedef int (*pfs_getextattr_t)(PFS_GETEXTATTR_ARGS); 16341a35633SBrian Feldman 16441a35633SBrian Feldman /* 16598c7e22cSDag-Erling Smørgrav * Last-close callback 166388596dfSDag-Erling Smørgrav * Called with proc locked 16798c7e22cSDag-Erling Smørgrav */ 16898c7e22cSDag-Erling Smørgrav #define PFS_CLOSE_ARGS \ 16998c7e22cSDag-Erling Smørgrav struct thread *td, struct proc *p, struct pfs_node *pn 170388596dfSDag-Erling Smørgrav #define PFS_CLOSE_ARGNAMES \ 171388596dfSDag-Erling Smørgrav td, p, pn 17298c7e22cSDag-Erling Smørgrav #define PFS_CLOSE_PROTO(name) \ 17398c7e22cSDag-Erling Smørgrav int name(PFS_CLOSE_ARGS); 17498c7e22cSDag-Erling Smørgrav typedef int (*pfs_close_t)(PFS_CLOSE_ARGS); 17598c7e22cSDag-Erling Smørgrav 17698c7e22cSDag-Erling Smørgrav /* 177771709ebSDag-Erling Smørgrav * Destroy callback 178771709ebSDag-Erling Smørgrav */ 179771709ebSDag-Erling Smørgrav #define PFS_DESTROY_ARGS \ 180771709ebSDag-Erling Smørgrav struct pfs_node *pn 181388596dfSDag-Erling Smørgrav #define PFS_DESTROY_ARGNAMES \ 182388596dfSDag-Erling Smørgrav pn 183771709ebSDag-Erling Smørgrav #define PFS_DESTROY_PROTO(name) \ 184771709ebSDag-Erling Smørgrav int name(PFS_DESTROY_ARGS); 185771709ebSDag-Erling Smørgrav typedef int (*pfs_destroy_t)(PFS_DESTROY_ARGS); 186771709ebSDag-Erling Smørgrav 187771709ebSDag-Erling Smørgrav /* 1889733a808SDag-Erling Smørgrav * pfs_info: describes a pseudofs instance 189f61bc4eaSDag-Erling Smørgrav * 190f61bc4eaSDag-Erling Smørgrav * The pi_mutex is only used to avoid using the global subr_unit lock for 191f61bc4eaSDag-Erling Smørgrav * unrhdr. The rest of struct pfs_info is only modified while Giant is 192f61bc4eaSDag-Erling Smørgrav * held (during vfs_init() and vfs_uninit()). 1939733a808SDag-Erling Smørgrav */ 1949733a808SDag-Erling Smørgrav struct pfs_info { 19541aa8697SDag-Erling Smørgrav char pi_name[PFS_FSNAMELEN]; 19633802b9eSDag-Erling Smørgrav pfs_init_t pi_init; 19733802b9eSDag-Erling Smørgrav pfs_init_t pi_uninit; 198f61bc4eaSDag-Erling Smørgrav 199f61bc4eaSDag-Erling Smørgrav /* members below this line are initialized at run time*/ 20033802b9eSDag-Erling Smørgrav struct pfs_node *pi_root; 2019733a808SDag-Erling Smørgrav struct mtx pi_mutex; 2027f661c6bSPoul-Henning Kamp struct unrhdr *pi_unrhdr; 2039733a808SDag-Erling Smørgrav }; 2049733a808SDag-Erling Smørgrav 2059733a808SDag-Erling Smørgrav /* 2069733a808SDag-Erling Smørgrav * pfs_node: describes a node (file or directory) within a pseudofs 207388596dfSDag-Erling Smørgrav * 208388596dfSDag-Erling Smørgrav * - Fields marked (o) are protected by the node's own mutex. 209388596dfSDag-Erling Smørgrav * - Fields marked (p) are protected by the node's parent's mutex. 210388596dfSDag-Erling Smørgrav * - Remaining fields are not protected by any lock and are assumed to be 211388596dfSDag-Erling Smørgrav * immutable once the node has been created. 212388596dfSDag-Erling Smørgrav * 213388596dfSDag-Erling Smørgrav * To prevent deadlocks, if a node's mutex is to be held at the same time 214388596dfSDag-Erling Smørgrav * as its parent's (e.g. when adding or removing nodes to a directory), 215388596dfSDag-Erling Smørgrav * the parent's mutex must always be acquired first. Unfortunately, this 216388596dfSDag-Erling Smørgrav * is not enforcable by WITNESS. 2179733a808SDag-Erling Smørgrav */ 2189733a808SDag-Erling Smørgrav struct pfs_node { 2199733a808SDag-Erling Smørgrav char pn_name[PFS_NAMELEN]; 2209733a808SDag-Erling Smørgrav pfs_type_t pn_type; 221388596dfSDag-Erling Smørgrav int pn_flags; 222388596dfSDag-Erling Smørgrav struct mtx pn_mutex; 223388596dfSDag-Erling Smørgrav void *pn_data; /* (o) */ 224388596dfSDag-Erling Smørgrav 225388596dfSDag-Erling Smørgrav pfs_fill_t pn_fill; 22618319000SDag-Erling Smørgrav pfs_ioctl_t pn_ioctl; 22798c7e22cSDag-Erling Smørgrav pfs_close_t pn_close; 22880a3cef8SDag-Erling Smørgrav pfs_attr_t pn_attr; 229198bc14bSDag-Erling Smørgrav pfs_vis_t pn_vis; 23041a35633SBrian Feldman pfs_getextattr_t pn_getextattr; 231771709ebSDag-Erling Smørgrav pfs_destroy_t pn_destroy; 23233802b9eSDag-Erling Smørgrav 23333802b9eSDag-Erling Smørgrav struct pfs_info *pn_info; 234388596dfSDag-Erling Smørgrav u_int32_t pn_fileno; /* (o) */ 235388596dfSDag-Erling Smørgrav 236388596dfSDag-Erling Smørgrav struct pfs_node *pn_parent; /* (o) */ 237388596dfSDag-Erling Smørgrav struct pfs_node *pn_nodes; /* (o) */ 238388596dfSDag-Erling Smørgrav struct pfs_node *pn_next; /* (p) */ 2399733a808SDag-Erling Smørgrav }; 2409733a808SDag-Erling Smørgrav 2419733a808SDag-Erling Smørgrav /* 2429733a808SDag-Erling Smørgrav * VFS interface 2439733a808SDag-Erling Smørgrav */ 244dfd233edSAttilio Rao int pfs_mount (struct pfs_info *pi, struct mount *mp); 245dfd233edSAttilio Rao int pfs_cmount (struct mntarg *ma, void *data, int flags); 246dfd233edSAttilio Rao int pfs_unmount (struct mount *mp, int mntflags); 247d9b2d9f7SJeff Roberson int pfs_root (struct mount *mp, int flags, 248dfd233edSAttilio Rao struct vnode **vpp); 249dfd233edSAttilio Rao int pfs_statfs (struct mount *mp, struct statfs *sbp); 2509733a808SDag-Erling Smørgrav int pfs_init (struct pfs_info *pi, struct vfsconf *vfc); 2519733a808SDag-Erling Smørgrav int pfs_uninit (struct pfs_info *pi, struct vfsconf *vfc); 2529733a808SDag-Erling Smørgrav 2539733a808SDag-Erling Smørgrav /* 25433802b9eSDag-Erling Smørgrav * Directory structure construction and manipulation 255b84ce334SDag-Erling Smørgrav */ 256b331ec01SDag-Erling Smørgrav struct pfs_node *pfs_create_dir (struct pfs_node *parent, const char *name, 257771709ebSDag-Erling Smørgrav pfs_attr_t attr, pfs_vis_t vis, 258771709ebSDag-Erling Smørgrav pfs_destroy_t destroy, int flags); 259b331ec01SDag-Erling Smørgrav struct pfs_node *pfs_create_file(struct pfs_node *parent, const char *name, 26033802b9eSDag-Erling Smørgrav pfs_fill_t fill, pfs_attr_t attr, 261771709ebSDag-Erling Smørgrav pfs_vis_t vis, pfs_destroy_t destroy, 262771709ebSDag-Erling Smørgrav int flags); 263b331ec01SDag-Erling Smørgrav struct pfs_node *pfs_create_link(struct pfs_node *parent, const char *name, 26433802b9eSDag-Erling Smørgrav pfs_fill_t fill, pfs_attr_t attr, 265771709ebSDag-Erling Smørgrav pfs_vis_t vis, pfs_destroy_t destroy, 266771709ebSDag-Erling Smørgrav int flags); 267b331ec01SDag-Erling Smørgrav struct pfs_node *pfs_find_node (struct pfs_node *parent, const char *name); 26815bad11fSDag-Erling Smørgrav void pfs_purge (struct pfs_node *pn); 26933802b9eSDag-Erling Smørgrav int pfs_destroy (struct pfs_node *pn); 270b84ce334SDag-Erling Smørgrav 271b84ce334SDag-Erling Smørgrav /* 2729733a808SDag-Erling Smørgrav * Now for some initialization magic... 2739733a808SDag-Erling Smørgrav */ 27433802b9eSDag-Erling Smørgrav #define PSEUDOFS(name, version) \ 2759733a808SDag-Erling Smørgrav \ 2769733a808SDag-Erling Smørgrav static struct pfs_info name##_info = { \ 2779733a808SDag-Erling Smørgrav #name, \ 278ce2fb577SPoul-Henning Kamp name##_init, \ 279ce2fb577SPoul-Henning Kamp name##_uninit, \ 2809733a808SDag-Erling Smørgrav }; \ 2819733a808SDag-Erling Smørgrav \ 2829733a808SDag-Erling Smørgrav static int \ 283dfd233edSAttilio Rao _##name##_mount(struct mount *mp) { \ 284dfd233edSAttilio Rao return pfs_mount(&name##_info, mp); \ 2859733a808SDag-Erling Smørgrav } \ 2869733a808SDag-Erling Smørgrav \ 2879733a808SDag-Erling Smørgrav static int \ 2889733a808SDag-Erling Smørgrav _##name##_init(struct vfsconf *vfc) { \ 2899733a808SDag-Erling Smørgrav return pfs_init(&name##_info, vfc); \ 2909733a808SDag-Erling Smørgrav } \ 2919733a808SDag-Erling Smørgrav \ 2929733a808SDag-Erling Smørgrav static int \ 2939733a808SDag-Erling Smørgrav _##name##_uninit(struct vfsconf *vfc) { \ 2949733a808SDag-Erling Smørgrav return pfs_uninit(&name##_info, vfc); \ 2959733a808SDag-Erling Smørgrav } \ 2969733a808SDag-Erling Smørgrav \ 2977005ce8aSDag-Erling Smørgrav static struct vfsops name##_vfsops = { \ 298c9ad8a67SKelly Yancey .vfs_cmount = pfs_cmount, \ 2997652131bSPoul-Henning Kamp .vfs_init = _##name##_init, \ 3005e8c582aSPoul-Henning Kamp .vfs_mount = _##name##_mount, \ 3017652131bSPoul-Henning Kamp .vfs_root = pfs_root, \ 3027652131bSPoul-Henning Kamp .vfs_statfs = pfs_statfs, \ 3037652131bSPoul-Henning Kamp .vfs_uninit = _##name##_uninit, \ 3047652131bSPoul-Henning Kamp .vfs_unmount = pfs_unmount, \ 3059733a808SDag-Erling Smørgrav }; \ 3069733a808SDag-Erling Smørgrav VFS_SET(name##_vfsops, name, VFCF_SYNTHETIC); \ 3078712e867SDag-Erling Smørgrav MODULE_VERSION(name, version); \ 30898c7e22cSDag-Erling Smørgrav MODULE_DEPEND(name, pseudofs, 1, 1, 1); 3099733a808SDag-Erling Smørgrav 3109733a808SDag-Erling Smørgrav #endif 311