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 29de52d21aSDag-Erling Smørgrav #include <sys/cdefs.h> 30de52d21aSDag-Erling Smørgrav __FBSDID("$FreeBSD$"); 31de52d21aSDag-Erling Smørgrav 32de52d21aSDag-Erling Smørgrav #include "opt_pseudofs.h" 33de52d21aSDag-Erling Smørgrav 349733a808SDag-Erling Smørgrav #include <sys/param.h> 359733a808SDag-Erling Smørgrav #include <sys/kernel.h> 369733a808SDag-Erling Smørgrav #include <sys/systm.h> 377106ca0dSJohn Baldwin #include <sys/lock.h> 389733a808SDag-Erling Smørgrav #include <sys/malloc.h> 399733a808SDag-Erling Smørgrav #include <sys/module.h> 409733a808SDag-Erling Smørgrav #include <sys/mount.h> 4149fa664fSDag-Erling Smørgrav #include <sys/mutex.h> 429733a808SDag-Erling Smørgrav #include <sys/proc.h> 439733a808SDag-Erling Smørgrav #include <sys/sbuf.h> 449733a808SDag-Erling Smørgrav #include <sys/sysctl.h> 459733a808SDag-Erling Smørgrav #include <sys/vnode.h> 469733a808SDag-Erling Smørgrav 479733a808SDag-Erling Smørgrav #include <fs/pseudofs/pseudofs.h> 489733a808SDag-Erling Smørgrav #include <fs/pseudofs/pseudofs_internal.h> 499733a808SDag-Erling Smørgrav 5033802b9eSDag-Erling Smørgrav static MALLOC_DEFINE(M_PFSNODES, "pfs_nodes", "pseudofs nodes"); 5133802b9eSDag-Erling Smørgrav 529733a808SDag-Erling Smørgrav SYSCTL_NODE(_vfs, OID_AUTO, pfs, CTLFLAG_RW, 0, 539733a808SDag-Erling Smørgrav "pseudofs"); 549733a808SDag-Erling Smørgrav 55388596dfSDag-Erling Smørgrav int pfs_trace; 56388596dfSDag-Erling Smørgrav SYSCTL_INT(_vfs_pfs, OID_AUTO, trace, CTLFLAG_RW, &pfs_trace, 0, 57388596dfSDag-Erling Smørgrav "enable tracing of pseudofs vnode operations"); 58388596dfSDag-Erling Smørgrav 5941aa8697SDag-Erling Smørgrav #if PFS_FSNAMELEN != MFSNAMELEN 6041aa8697SDag-Erling Smørgrav #error "PFS_FSNAMELEN is not equal to MFSNAMELEN" 6141aa8697SDag-Erling Smørgrav #endif 6241aa8697SDag-Erling Smørgrav 639733a808SDag-Erling Smørgrav /* 64388596dfSDag-Erling Smørgrav * Allocate and initialize a node 65388596dfSDag-Erling Smørgrav */ 66388596dfSDag-Erling Smørgrav static struct pfs_node * 67388596dfSDag-Erling Smørgrav pfs_alloc_node(struct pfs_info *pi, const char *name, pfs_type_t type) 68388596dfSDag-Erling Smørgrav { 69388596dfSDag-Erling Smørgrav struct pfs_node *pn; 70388596dfSDag-Erling Smørgrav 71388596dfSDag-Erling Smørgrav KASSERT(strlen(name) < PFS_NAMELEN, 72388596dfSDag-Erling Smørgrav ("%s(): node name is too long", __func__)); 73388596dfSDag-Erling Smørgrav 74388596dfSDag-Erling Smørgrav MALLOC(pn, struct pfs_node *, sizeof *pn, 75388596dfSDag-Erling Smørgrav M_PFSNODES, M_WAITOK|M_ZERO); 76388596dfSDag-Erling Smørgrav mtx_init(&pn->pn_mutex, "pfs_node", NULL, MTX_DEF | MTX_DUPOK); 77388596dfSDag-Erling Smørgrav strlcpy(pn->pn_name, name, sizeof pn->pn_name); 78388596dfSDag-Erling Smørgrav pn->pn_type = type; 79388596dfSDag-Erling Smørgrav pn->pn_info = pi; 80388596dfSDag-Erling Smørgrav return (pn); 81388596dfSDag-Erling Smørgrav } 82388596dfSDag-Erling Smørgrav 83388596dfSDag-Erling Smørgrav /* 8433802b9eSDag-Erling Smørgrav * Add a node to a directory 8533802b9eSDag-Erling Smørgrav */ 86388596dfSDag-Erling Smørgrav static void 87388596dfSDag-Erling Smørgrav pfs_add_node(struct pfs_node *parent, struct pfs_node *pn) 8833802b9eSDag-Erling Smørgrav { 89388596dfSDag-Erling Smørgrav #ifdef INVARIANTS 90388596dfSDag-Erling Smørgrav struct pfs_node *iter; 91388596dfSDag-Erling Smørgrav #endif 92388596dfSDag-Erling Smørgrav 9333802b9eSDag-Erling Smørgrav KASSERT(parent != NULL, 946e551fb6SDavid E. O'Brien ("%s(): parent is NULL", __func__)); 95388596dfSDag-Erling Smørgrav KASSERT(pn->pn_parent == NULL, 96388596dfSDag-Erling Smørgrav ("%s(): node already has a parent", __func__)); 9733802b9eSDag-Erling Smørgrav KASSERT(parent->pn_info != NULL, 986e551fb6SDavid E. O'Brien ("%s(): parent has no pn_info", __func__)); 9933802b9eSDag-Erling Smørgrav KASSERT(parent->pn_type == pfstype_dir || 10033802b9eSDag-Erling Smørgrav parent->pn_type == pfstype_procdir || 10133802b9eSDag-Erling Smørgrav parent->pn_type == pfstype_root, 1026e551fb6SDavid E. O'Brien ("%s(): parent is not a directory", __func__)); 10333802b9eSDag-Erling Smørgrav 104388596dfSDag-Erling Smørgrav #ifdef INVARIANTS 105388596dfSDag-Erling Smørgrav /* XXX no locking! */ 106388596dfSDag-Erling Smørgrav if (pn->pn_type == pfstype_procdir) 107388596dfSDag-Erling Smørgrav for (iter = parent; iter != NULL; iter = iter->pn_parent) 108388596dfSDag-Erling Smørgrav KASSERT(iter->pn_type != pfstype_procdir, 109388596dfSDag-Erling Smørgrav ("%s(): nested process directories", __func__)); 110388596dfSDag-Erling Smørgrav for (iter = parent->pn_nodes; iter != NULL; iter = iter->pn_next) { 111388596dfSDag-Erling Smørgrav KASSERT(strcmp(pn->pn_name, iter->pn_name) != 0, 112388596dfSDag-Erling Smørgrav ("%s(): homonymous siblings", __func__)); 113388596dfSDag-Erling Smørgrav if (pn->pn_type == pfstype_procdir) 114388596dfSDag-Erling Smørgrav KASSERT(iter->pn_type != pfstype_procdir, 115388596dfSDag-Erling Smørgrav ("%s(): sibling process directories", __func__)); 116388596dfSDag-Erling Smørgrav } 117388596dfSDag-Erling Smørgrav #endif 11833802b9eSDag-Erling Smørgrav 119388596dfSDag-Erling Smørgrav pn->pn_parent = parent; 120388596dfSDag-Erling Smørgrav pfs_fileno_alloc(pn); 121388596dfSDag-Erling Smørgrav 122388596dfSDag-Erling Smørgrav pfs_lock(parent); 123388596dfSDag-Erling Smørgrav pn->pn_next = parent->pn_nodes; 12406be2aaaSNate Lawson if ((parent->pn_flags & PFS_PROCDEP) != 0) 125388596dfSDag-Erling Smørgrav pn->pn_flags |= PFS_PROCDEP; 126388596dfSDag-Erling Smørgrav parent->pn_nodes = pn; 127388596dfSDag-Erling Smørgrav pfs_unlock(parent); 128388596dfSDag-Erling Smørgrav } 12933802b9eSDag-Erling Smørgrav 130388596dfSDag-Erling Smørgrav /* 131388596dfSDag-Erling Smørgrav * Detach a node from its aprent 132388596dfSDag-Erling Smørgrav */ 133388596dfSDag-Erling Smørgrav static void 134388596dfSDag-Erling Smørgrav pfs_detach_node(struct pfs_node *pn) 135388596dfSDag-Erling Smørgrav { 136388596dfSDag-Erling Smørgrav struct pfs_node *parent = pn->pn_parent; 137388596dfSDag-Erling Smørgrav struct pfs_node **iter; 138388596dfSDag-Erling Smørgrav 139388596dfSDag-Erling Smørgrav KASSERT(parent != NULL, ("%s(): node has no parent", __func__)); 140388596dfSDag-Erling Smørgrav KASSERT(parent->pn_info == pn->pn_info, 141388596dfSDag-Erling Smørgrav ("%s(): parent has different pn_info", __func__)); 142388596dfSDag-Erling Smørgrav 143388596dfSDag-Erling Smørgrav pfs_lock(parent); 144388596dfSDag-Erling Smørgrav iter = &parent->pn_nodes; 145388596dfSDag-Erling Smørgrav while (*iter != NULL) { 146388596dfSDag-Erling Smørgrav if (*iter == pn) { 147388596dfSDag-Erling Smørgrav *iter = pn->pn_next; 148388596dfSDag-Erling Smørgrav break; 149388596dfSDag-Erling Smørgrav } 150388596dfSDag-Erling Smørgrav iter = &(*iter)->pn_next; 151388596dfSDag-Erling Smørgrav } 152388596dfSDag-Erling Smørgrav pn->pn_parent = NULL; 153388596dfSDag-Erling Smørgrav pfs_unlock(parent); 15433802b9eSDag-Erling Smørgrav } 15533802b9eSDag-Erling Smørgrav 15633802b9eSDag-Erling Smørgrav /* 15733802b9eSDag-Erling Smørgrav * Add . and .. to a directory 15833802b9eSDag-Erling Smørgrav */ 159388596dfSDag-Erling Smørgrav static void 160388596dfSDag-Erling Smørgrav pfs_fixup_dir(struct pfs_node *parent) 16133802b9eSDag-Erling Smørgrav { 162388596dfSDag-Erling Smørgrav struct pfs_node *pn; 16333802b9eSDag-Erling Smørgrav 164388596dfSDag-Erling Smørgrav pn = pfs_alloc_node(parent->pn_info, ".", pfstype_this); 165388596dfSDag-Erling Smørgrav pfs_add_node(parent, pn); 166388596dfSDag-Erling Smørgrav pn = pfs_alloc_node(parent->pn_info, "..", pfstype_parent); 167388596dfSDag-Erling Smørgrav pfs_add_node(parent, pn); 16833802b9eSDag-Erling Smørgrav } 16933802b9eSDag-Erling Smørgrav 17033802b9eSDag-Erling Smørgrav /* 17133802b9eSDag-Erling Smørgrav * Create a directory 17233802b9eSDag-Erling Smørgrav */ 17333802b9eSDag-Erling Smørgrav struct pfs_node * 174b331ec01SDag-Erling Smørgrav pfs_create_dir(struct pfs_node *parent, const char *name, 175771709ebSDag-Erling Smørgrav pfs_attr_t attr, pfs_vis_t vis, pfs_destroy_t destroy, 176771709ebSDag-Erling Smørgrav int flags) 17733802b9eSDag-Erling Smørgrav { 178388596dfSDag-Erling Smørgrav struct pfs_node *pn; 17933802b9eSDag-Erling Smørgrav 180388596dfSDag-Erling Smørgrav pn = pfs_alloc_node(parent->pn_info, name, 181388596dfSDag-Erling Smørgrav (flags & PFS_PROCDEP) ? pfstype_procdir : pfstype_dir); 182388596dfSDag-Erling Smørgrav pn->pn_attr = attr; 183388596dfSDag-Erling Smørgrav pn->pn_vis = vis; 184388596dfSDag-Erling Smørgrav pn->pn_destroy = destroy; 185388596dfSDag-Erling Smørgrav pn->pn_flags = flags; 186388596dfSDag-Erling Smørgrav pfs_add_node(parent, pn); 187388596dfSDag-Erling Smørgrav pfs_fixup_dir(pn); 18833802b9eSDag-Erling Smørgrav 189388596dfSDag-Erling Smørgrav return (pn); 19033802b9eSDag-Erling Smørgrav } 19133802b9eSDag-Erling Smørgrav 19233802b9eSDag-Erling Smørgrav /* 19333802b9eSDag-Erling Smørgrav * Create a file 19433802b9eSDag-Erling Smørgrav */ 19533802b9eSDag-Erling Smørgrav struct pfs_node * 196b331ec01SDag-Erling Smørgrav pfs_create_file(struct pfs_node *parent, const char *name, pfs_fill_t fill, 197771709ebSDag-Erling Smørgrav pfs_attr_t attr, pfs_vis_t vis, pfs_destroy_t destroy, 198771709ebSDag-Erling Smørgrav int flags) 19933802b9eSDag-Erling Smørgrav { 200388596dfSDag-Erling Smørgrav struct pfs_node *pn; 20133802b9eSDag-Erling Smørgrav 202388596dfSDag-Erling Smørgrav pn = pfs_alloc_node(parent->pn_info, name, pfstype_file); 203388596dfSDag-Erling Smørgrav pn->pn_fill = fill; 204388596dfSDag-Erling Smørgrav pn->pn_attr = attr; 205388596dfSDag-Erling Smørgrav pn->pn_vis = vis; 206388596dfSDag-Erling Smørgrav pn->pn_destroy = destroy; 207388596dfSDag-Erling Smørgrav pn->pn_flags = flags; 208388596dfSDag-Erling Smørgrav pfs_add_node(parent, pn); 20933802b9eSDag-Erling Smørgrav 210388596dfSDag-Erling Smørgrav return (pn); 21133802b9eSDag-Erling Smørgrav } 21233802b9eSDag-Erling Smørgrav 21333802b9eSDag-Erling Smørgrav /* 21433802b9eSDag-Erling Smørgrav * Create a symlink 21533802b9eSDag-Erling Smørgrav */ 21633802b9eSDag-Erling Smørgrav struct pfs_node * 217b331ec01SDag-Erling Smørgrav pfs_create_link(struct pfs_node *parent, const char *name, pfs_fill_t fill, 218771709ebSDag-Erling Smørgrav pfs_attr_t attr, pfs_vis_t vis, pfs_destroy_t destroy, 219771709ebSDag-Erling Smørgrav int flags) 22033802b9eSDag-Erling Smørgrav { 221388596dfSDag-Erling Smørgrav struct pfs_node *pn; 22233802b9eSDag-Erling Smørgrav 223388596dfSDag-Erling Smørgrav pn = pfs_alloc_node(parent->pn_info, name, pfstype_symlink); 224388596dfSDag-Erling Smørgrav pn->pn_fill = fill; 225388596dfSDag-Erling Smørgrav pn->pn_attr = attr; 226388596dfSDag-Erling Smørgrav pn->pn_vis = vis; 227388596dfSDag-Erling Smørgrav pn->pn_destroy = destroy; 228388596dfSDag-Erling Smørgrav pn->pn_flags = flags; 229388596dfSDag-Erling Smørgrav pfs_add_node(parent, pn); 230388596dfSDag-Erling Smørgrav 231388596dfSDag-Erling Smørgrav return (pn); 23233802b9eSDag-Erling Smørgrav } 23333802b9eSDag-Erling Smørgrav 23433802b9eSDag-Erling Smørgrav /* 235b331ec01SDag-Erling Smørgrav * Locate a node by name 236b331ec01SDag-Erling Smørgrav */ 237b331ec01SDag-Erling Smørgrav struct pfs_node * 238b331ec01SDag-Erling Smørgrav pfs_find_node(struct pfs_node *parent, const char *name) 239b331ec01SDag-Erling Smørgrav { 240388596dfSDag-Erling Smørgrav struct pfs_node *pn; 241b331ec01SDag-Erling Smørgrav 242388596dfSDag-Erling Smørgrav pfs_lock(parent); 243388596dfSDag-Erling Smørgrav for (pn = parent->pn_nodes; pn != NULL; pn = pn->pn_next) 244388596dfSDag-Erling Smørgrav if (strcmp(pn->pn_name, name) == 0) 245f61bc4eaSDag-Erling Smørgrav break; 246388596dfSDag-Erling Smørgrav pfs_unlock(parent); 247388596dfSDag-Erling Smørgrav return (pn); 248b331ec01SDag-Erling Smørgrav } 249b331ec01SDag-Erling Smørgrav 250b331ec01SDag-Erling Smørgrav /* 251388596dfSDag-Erling Smørgrav * Destroy a node and all its descendants. If the node to be destroyed 252388596dfSDag-Erling Smørgrav * has a parent, the parent's mutex must be held. 25333802b9eSDag-Erling Smørgrav */ 25433802b9eSDag-Erling Smørgrav int 255388596dfSDag-Erling Smørgrav pfs_destroy(struct pfs_node *pn) 25633802b9eSDag-Erling Smørgrav { 257388596dfSDag-Erling Smørgrav struct pfs_node *iter; 25833802b9eSDag-Erling Smørgrav 259388596dfSDag-Erling Smørgrav KASSERT(pn != NULL, 2606e551fb6SDavid E. O'Brien ("%s(): node is NULL", __func__)); 261388596dfSDag-Erling Smørgrav KASSERT(pn->pn_info != NULL, 2626e551fb6SDavid E. O'Brien ("%s(): node has no pn_info", __func__)); 26333802b9eSDag-Erling Smørgrav 264388596dfSDag-Erling Smørgrav if (pn->pn_parent) 265388596dfSDag-Erling Smørgrav pfs_detach_node(pn); 26633802b9eSDag-Erling Smørgrav 267388596dfSDag-Erling Smørgrav /* destroy children */ 268388596dfSDag-Erling Smørgrav if (pn->pn_type == pfstype_dir || 269388596dfSDag-Erling Smørgrav pn->pn_type == pfstype_procdir || 270388596dfSDag-Erling Smørgrav pn->pn_type == pfstype_root) { 271388596dfSDag-Erling Smørgrav pfs_lock(pn); 272388596dfSDag-Erling Smørgrav while (pn->pn_nodes != NULL) { 273388596dfSDag-Erling Smørgrav iter = pn->pn_nodes; 274388596dfSDag-Erling Smørgrav pn->pn_nodes = iter->pn_next; 275388596dfSDag-Erling Smørgrav iter->pn_parent = NULL; 276388596dfSDag-Erling Smørgrav pfs_unlock(pn); 277388596dfSDag-Erling Smørgrav pfs_destroy(iter); 278388596dfSDag-Erling Smørgrav pfs_lock(pn); 27933802b9eSDag-Erling Smørgrav } 280388596dfSDag-Erling Smørgrav pfs_unlock(pn); 28133802b9eSDag-Erling Smørgrav } 282388596dfSDag-Erling Smørgrav 283388596dfSDag-Erling Smørgrav /* revoke vnodes and fileno */ 284388596dfSDag-Erling Smørgrav pfs_purge(pn); 28533802b9eSDag-Erling Smørgrav 286771709ebSDag-Erling Smørgrav /* callback to free any private resources */ 287388596dfSDag-Erling Smørgrav if (pn->pn_destroy != NULL) 288388596dfSDag-Erling Smørgrav pn_destroy(pn); 289771709ebSDag-Erling Smørgrav 290388596dfSDag-Erling Smørgrav /* destroy the node */ 291388596dfSDag-Erling Smørgrav pfs_fileno_free(pn); 292388596dfSDag-Erling Smørgrav mtx_destroy(&pn->pn_mutex); 293388596dfSDag-Erling Smørgrav FREE(pn, M_PFSNODES); 29433802b9eSDag-Erling Smørgrav 29533802b9eSDag-Erling Smørgrav return (0); 29633802b9eSDag-Erling Smørgrav } 29733802b9eSDag-Erling Smørgrav 29833802b9eSDag-Erling Smørgrav /* 2999733a808SDag-Erling Smørgrav * Mount a pseudofs instance 3009733a808SDag-Erling Smørgrav */ 3019733a808SDag-Erling Smørgrav int 3025e8c582aSPoul-Henning Kamp pfs_mount(struct pfs_info *pi, struct mount *mp, struct thread *td) 3039733a808SDag-Erling Smørgrav { 3049733a808SDag-Erling Smørgrav struct statfs *sbp; 3059733a808SDag-Erling Smørgrav 3069733a808SDag-Erling Smørgrav if (mp->mnt_flag & MNT_UPDATE) 3079733a808SDag-Erling Smørgrav return (EOPNOTSUPP); 3089733a808SDag-Erling Smørgrav 30915bad11fSDag-Erling Smørgrav MNT_ILOCK(mp); 3109733a808SDag-Erling Smørgrav mp->mnt_flag |= MNT_LOCAL; 31115bad11fSDag-Erling Smørgrav mp->mnt_kern_flag |= MNTK_MPSAFE; 31215bad11fSDag-Erling Smørgrav MNT_IUNLOCK(mp); 3139733a808SDag-Erling Smørgrav mp->mnt_data = (qaddr_t)pi; 3149733a808SDag-Erling Smørgrav vfs_getnewfsid(mp); 3159733a808SDag-Erling Smørgrav 3169733a808SDag-Erling Smørgrav sbp = &mp->mnt_stat; 317def91cf2SPoul-Henning Kamp vfs_mountedfrom(mp, pi->pi_name); 3189733a808SDag-Erling Smørgrav sbp->f_bsize = PAGE_SIZE; 3199733a808SDag-Erling Smørgrav sbp->f_iosize = PAGE_SIZE; 3209733a808SDag-Erling Smørgrav sbp->f_blocks = 1; 3219733a808SDag-Erling Smørgrav sbp->f_bfree = 0; 3229733a808SDag-Erling Smørgrav sbp->f_bavail = 0; 3239733a808SDag-Erling Smørgrav sbp->f_files = 1; 3249733a808SDag-Erling Smørgrav sbp->f_ffree = 0; 3259733a808SDag-Erling Smørgrav 3269733a808SDag-Erling Smørgrav return (0); 3279733a808SDag-Erling Smørgrav } 3289733a808SDag-Erling Smørgrav 3299733a808SDag-Erling Smørgrav /* 330388596dfSDag-Erling Smørgrav * Compatibility shim for old mount(2) system call 331c9ad8a67SKelly Yancey */ 332c9ad8a67SKelly Yancey int 333c9ad8a67SKelly Yancey pfs_cmount(struct mntarg *ma, void *data, int flags, struct thread *td) 334c9ad8a67SKelly Yancey { 335388596dfSDag-Erling Smørgrav int error; 336388596dfSDag-Erling Smørgrav 337388596dfSDag-Erling Smørgrav error = kernel_mount(ma, flags); 338388596dfSDag-Erling Smørgrav return (error); 339c9ad8a67SKelly Yancey } 340c9ad8a67SKelly Yancey 341c9ad8a67SKelly Yancey /* 3429733a808SDag-Erling Smørgrav * Unmount a pseudofs instance 3439733a808SDag-Erling Smørgrav */ 3449733a808SDag-Erling Smørgrav int 345b40ce416SJulian Elischer pfs_unmount(struct mount *mp, int mntflags, struct thread *td) 3469733a808SDag-Erling Smørgrav { 3479733a808SDag-Erling Smørgrav int error; 3489733a808SDag-Erling Smørgrav 349f257b7a5SAlfred Perlstein error = vflush(mp, 0, (mntflags & MNT_FORCE) ? FORCECLOSE : 0, td); 3509733a808SDag-Erling Smørgrav return (error); 3519733a808SDag-Erling Smørgrav } 3529733a808SDag-Erling Smørgrav 3539733a808SDag-Erling Smørgrav /* 3549733a808SDag-Erling Smørgrav * Return a root vnode 3559733a808SDag-Erling Smørgrav */ 3569733a808SDag-Erling Smørgrav int 357d9b2d9f7SJeff Roberson pfs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td) 3589733a808SDag-Erling Smørgrav { 3599733a808SDag-Erling Smørgrav struct pfs_info *pi; 3609733a808SDag-Erling Smørgrav 3619733a808SDag-Erling Smørgrav pi = (struct pfs_info *)mp->mnt_data; 362388596dfSDag-Erling Smørgrav return (pfs_vncache_alloc(mp, vpp, pi->pi_root, NO_PID)); 3639733a808SDag-Erling Smørgrav } 3649733a808SDag-Erling Smørgrav 3659733a808SDag-Erling Smørgrav /* 3669733a808SDag-Erling Smørgrav * Return filesystem stats 3679733a808SDag-Erling Smørgrav */ 3689733a808SDag-Erling Smørgrav int 369b40ce416SJulian Elischer pfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td) 3709733a808SDag-Erling Smørgrav { 371def91cf2SPoul-Henning Kamp /* no-op: always called with mp->mnt_stat */ 3729733a808SDag-Erling Smørgrav return (0); 3739733a808SDag-Erling Smørgrav } 3749733a808SDag-Erling Smørgrav 3759733a808SDag-Erling Smørgrav /* 3769733a808SDag-Erling Smørgrav * Initialize a pseudofs instance 3779733a808SDag-Erling Smørgrav */ 3789733a808SDag-Erling Smørgrav int 3799733a808SDag-Erling Smørgrav pfs_init(struct pfs_info *pi, struct vfsconf *vfc) 3809733a808SDag-Erling Smørgrav { 38133802b9eSDag-Erling Smørgrav struct pfs_node *root; 38233802b9eSDag-Erling Smørgrav int error; 38333802b9eSDag-Erling Smørgrav 384f61bc4eaSDag-Erling Smørgrav mtx_assert(&Giant, MA_OWNED); 38533802b9eSDag-Erling Smørgrav 386388596dfSDag-Erling Smørgrav pfs_fileno_init(pi); 387388596dfSDag-Erling Smørgrav 38833802b9eSDag-Erling Smørgrav /* set up the root diretory */ 389388596dfSDag-Erling Smørgrav root = pfs_alloc_node(pi, "/", pfstype_root); 39033802b9eSDag-Erling Smørgrav pi->pi_root = root; 391388596dfSDag-Erling Smørgrav pfs_fileno_alloc(root); 392388596dfSDag-Erling Smørgrav pfs_fixup_dir(root); 39333802b9eSDag-Erling Smørgrav 39433802b9eSDag-Erling Smørgrav /* construct file hierarchy */ 39533802b9eSDag-Erling Smørgrav error = (pi->pi_init)(pi, vfc); 39633802b9eSDag-Erling Smørgrav if (error) { 39733802b9eSDag-Erling Smørgrav pfs_destroy(root); 39833802b9eSDag-Erling Smørgrav pi->pi_root = NULL; 39933802b9eSDag-Erling Smørgrav return (error); 40033802b9eSDag-Erling Smørgrav } 40133802b9eSDag-Erling Smørgrav 402b7004390SDag-Erling Smørgrav if (bootverbose) 4039733a808SDag-Erling Smørgrav printf("%s registered\n", pi->pi_name); 4049733a808SDag-Erling Smørgrav return (0); 4059733a808SDag-Erling Smørgrav } 4069733a808SDag-Erling Smørgrav 4079733a808SDag-Erling Smørgrav /* 4089733a808SDag-Erling Smørgrav * Destroy a pseudofs instance 4099733a808SDag-Erling Smørgrav */ 4109733a808SDag-Erling Smørgrav int 4119733a808SDag-Erling Smørgrav pfs_uninit(struct pfs_info *pi, struct vfsconf *vfc) 4129733a808SDag-Erling Smørgrav { 41333802b9eSDag-Erling Smørgrav int error; 41433802b9eSDag-Erling Smørgrav 415f61bc4eaSDag-Erling Smørgrav mtx_assert(&Giant, MA_OWNED); 416f61bc4eaSDag-Erling Smørgrav 41733802b9eSDag-Erling Smørgrav pfs_destroy(pi->pi_root); 41833802b9eSDag-Erling Smørgrav pi->pi_root = NULL; 41915bad11fSDag-Erling Smørgrav pfs_fileno_uninit(pi); 420b7004390SDag-Erling Smørgrav if (bootverbose) 4219733a808SDag-Erling Smørgrav printf("%s unregistered\n", pi->pi_name); 42233802b9eSDag-Erling Smørgrav error = (pi->pi_uninit)(pi, vfc); 42333802b9eSDag-Erling Smørgrav return (error); 4249733a808SDag-Erling Smørgrav } 4259733a808SDag-Erling Smørgrav 4269733a808SDag-Erling Smørgrav /* 4279733a808SDag-Erling Smørgrav * Handle load / unload events 4289733a808SDag-Erling Smørgrav */ 4299733a808SDag-Erling Smørgrav static int 4309733a808SDag-Erling Smørgrav pfs_modevent(module_t mod, int evt, void *arg) 4319733a808SDag-Erling Smørgrav { 4329733a808SDag-Erling Smørgrav switch (evt) { 4339733a808SDag-Erling Smørgrav case MOD_LOAD: 4349733a808SDag-Erling Smørgrav pfs_vncache_load(); 4359733a808SDag-Erling Smørgrav break; 4369733a808SDag-Erling Smørgrav case MOD_UNLOAD: 4379733a808SDag-Erling Smørgrav case MOD_SHUTDOWN: 4389733a808SDag-Erling Smørgrav pfs_vncache_unload(); 4399733a808SDag-Erling Smørgrav break; 4409733a808SDag-Erling Smørgrav default: 4413e019deaSPoul-Henning Kamp return EOPNOTSUPP; 4429733a808SDag-Erling Smørgrav break; 4439733a808SDag-Erling Smørgrav } 4449733a808SDag-Erling Smørgrav return 0; 4459733a808SDag-Erling Smørgrav } 4469733a808SDag-Erling Smørgrav 4479733a808SDag-Erling Smørgrav /* 4489733a808SDag-Erling Smørgrav * Module declaration 4499733a808SDag-Erling Smørgrav */ 4509733a808SDag-Erling Smørgrav static moduledata_t pseudofs_data = { 4519733a808SDag-Erling Smørgrav "pseudofs", 4529733a808SDag-Erling Smørgrav pfs_modevent, 4539733a808SDag-Erling Smørgrav NULL 4549733a808SDag-Erling Smørgrav }; 4559733a808SDag-Erling Smørgrav DECLARE_MODULE(pseudofs, pseudofs_data, SI_SUB_EXEC, SI_ORDER_FIRST); 45698c7e22cSDag-Erling Smørgrav MODULE_VERSION(pseudofs, 1); 457