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 #include <sys/param.h> 329733a808SDag-Erling Smørgrav #include <sys/kernel.h> 339733a808SDag-Erling Smørgrav #include <sys/systm.h> 347106ca0dSJohn Baldwin #include <sys/lock.h> 359733a808SDag-Erling Smørgrav #include <sys/malloc.h> 369733a808SDag-Erling Smørgrav #include <sys/module.h> 379733a808SDag-Erling Smørgrav #include <sys/mount.h> 3849fa664fSDag-Erling Smørgrav #include <sys/mutex.h> 399733a808SDag-Erling Smørgrav #include <sys/proc.h> 409733a808SDag-Erling Smørgrav #include <sys/sbuf.h> 419733a808SDag-Erling Smørgrav #include <sys/sysctl.h> 429733a808SDag-Erling Smørgrav #include <sys/vnode.h> 439733a808SDag-Erling Smørgrav 449733a808SDag-Erling Smørgrav #include <fs/pseudofs/pseudofs.h> 459733a808SDag-Erling Smørgrav #include <fs/pseudofs/pseudofs_internal.h> 469733a808SDag-Erling Smørgrav 4733802b9eSDag-Erling Smørgrav static MALLOC_DEFINE(M_PFSNODES, "pfs_nodes", "pseudofs nodes"); 4833802b9eSDag-Erling Smørgrav 499733a808SDag-Erling Smørgrav SYSCTL_NODE(_vfs, OID_AUTO, pfs, CTLFLAG_RW, 0, 509733a808SDag-Erling Smørgrav "pseudofs"); 519733a808SDag-Erling Smørgrav 5241aa8697SDag-Erling Smørgrav #if PFS_FSNAMELEN != MFSNAMELEN 5341aa8697SDag-Erling Smørgrav #error "PFS_FSNAMELEN is not equal to MFSNAMELEN" 5441aa8697SDag-Erling Smørgrav #endif 5541aa8697SDag-Erling Smørgrav 569733a808SDag-Erling Smørgrav /* 5733802b9eSDag-Erling Smørgrav * Add a node to a directory 5833802b9eSDag-Erling Smørgrav */ 5933802b9eSDag-Erling Smørgrav static int 6033802b9eSDag-Erling Smørgrav _pfs_add_node(struct pfs_node *parent, struct pfs_node *node) 6133802b9eSDag-Erling Smørgrav { 6233802b9eSDag-Erling Smørgrav KASSERT(parent != NULL, 636e551fb6SDavid E. O'Brien ("%s(): parent is NULL", __func__)); 6433802b9eSDag-Erling Smørgrav KASSERT(parent->pn_info != NULL, 656e551fb6SDavid E. O'Brien ("%s(): parent has no pn_info", __func__)); 6633802b9eSDag-Erling Smørgrav KASSERT(parent->pn_type == pfstype_dir || 6733802b9eSDag-Erling Smørgrav parent->pn_type == pfstype_procdir || 6833802b9eSDag-Erling Smørgrav parent->pn_type == pfstype_root, 696e551fb6SDavid E. O'Brien ("%s(): parent is not a directory", __func__)); 7033802b9eSDag-Erling Smørgrav 7133802b9eSDag-Erling Smørgrav /* XXX should check for duplicate names etc. */ 7233802b9eSDag-Erling Smørgrav 7333802b9eSDag-Erling Smørgrav mtx_lock(&parent->pn_info->pi_mutex); 7433802b9eSDag-Erling Smørgrav node->pn_info = parent->pn_info; 7533802b9eSDag-Erling Smørgrav node->pn_parent = parent; 7633802b9eSDag-Erling Smørgrav node->pn_next = parent->pn_nodes; 7733802b9eSDag-Erling Smørgrav parent->pn_nodes = node; 7806be2aaaSNate Lawson /* Propagate flag to all child nodes (and thus their vnodes) */ 7906be2aaaSNate Lawson if ((parent->pn_flags & PFS_PROCDEP) != 0) 8006be2aaaSNate Lawson node->pn_flags |= PFS_PROCDEP; 8133802b9eSDag-Erling Smørgrav mtx_unlock(&parent->pn_info->pi_mutex); 8233802b9eSDag-Erling Smørgrav 8333802b9eSDag-Erling Smørgrav return (0); 8433802b9eSDag-Erling Smørgrav } 8533802b9eSDag-Erling Smørgrav 8633802b9eSDag-Erling Smørgrav /* 8733802b9eSDag-Erling Smørgrav * Add . and .. to a directory 8833802b9eSDag-Erling Smørgrav */ 8933802b9eSDag-Erling Smørgrav static int 9033802b9eSDag-Erling Smørgrav _pfs_fixup_dir(struct pfs_node *parent) 9133802b9eSDag-Erling Smørgrav { 9233802b9eSDag-Erling Smørgrav struct pfs_node *dir; 9333802b9eSDag-Erling Smørgrav 9433802b9eSDag-Erling Smørgrav MALLOC(dir, struct pfs_node *, sizeof *dir, 95a163d034SWarner Losh M_PFSNODES, M_WAITOK|M_ZERO); 9633802b9eSDag-Erling Smørgrav dir->pn_name[0] = '.'; 9733802b9eSDag-Erling Smørgrav dir->pn_type = pfstype_this; 9833802b9eSDag-Erling Smørgrav 9933802b9eSDag-Erling Smørgrav if (_pfs_add_node(parent, dir) != 0) { 10033802b9eSDag-Erling Smørgrav FREE(dir, M_PFSNODES); 10133802b9eSDag-Erling Smørgrav return (-1); 10233802b9eSDag-Erling Smørgrav } 10333802b9eSDag-Erling Smørgrav 10433802b9eSDag-Erling Smørgrav MALLOC(dir, struct pfs_node *, sizeof *dir, 105a163d034SWarner Losh M_PFSNODES, M_WAITOK|M_ZERO); 10633802b9eSDag-Erling Smørgrav dir->pn_name[0] = dir->pn_name[1] = '.'; 10733802b9eSDag-Erling Smørgrav dir->pn_type = pfstype_parent; 10833802b9eSDag-Erling Smørgrav 10933802b9eSDag-Erling Smørgrav if (_pfs_add_node(parent, dir) != 0) { 11033802b9eSDag-Erling Smørgrav FREE(dir, M_PFSNODES); 11133802b9eSDag-Erling Smørgrav return (-1); 11233802b9eSDag-Erling Smørgrav } 11333802b9eSDag-Erling Smørgrav 11433802b9eSDag-Erling Smørgrav return (0); 11533802b9eSDag-Erling Smørgrav } 11633802b9eSDag-Erling Smørgrav 11733802b9eSDag-Erling Smørgrav /* 11833802b9eSDag-Erling Smørgrav * Create a directory 11933802b9eSDag-Erling Smørgrav */ 12033802b9eSDag-Erling Smørgrav struct pfs_node * 121b331ec01SDag-Erling Smørgrav pfs_create_dir(struct pfs_node *parent, const char *name, 12233802b9eSDag-Erling Smørgrav pfs_attr_t attr, pfs_vis_t vis, int flags) 12333802b9eSDag-Erling Smørgrav { 12433802b9eSDag-Erling Smørgrav struct pfs_node *dir; 12533802b9eSDag-Erling Smørgrav 12633802b9eSDag-Erling Smørgrav KASSERT(strlen(name) < PFS_NAMELEN, 1276e551fb6SDavid E. O'Brien ("%s(): node name is too long", __func__)); 12833802b9eSDag-Erling Smørgrav 12933802b9eSDag-Erling Smørgrav MALLOC(dir, struct pfs_node *, sizeof *dir, 130a163d034SWarner Losh M_PFSNODES, M_WAITOK|M_ZERO); 13133802b9eSDag-Erling Smørgrav strcpy(dir->pn_name, name); 13233802b9eSDag-Erling Smørgrav dir->pn_type = (flags & PFS_PROCDEP) ? pfstype_procdir : pfstype_dir; 13333802b9eSDag-Erling Smørgrav dir->pn_attr = attr; 13433802b9eSDag-Erling Smørgrav dir->pn_vis = vis; 13506be2aaaSNate Lawson dir->pn_flags = flags; 13633802b9eSDag-Erling Smørgrav 13733802b9eSDag-Erling Smørgrav if (_pfs_add_node(parent, dir) != 0) { 13833802b9eSDag-Erling Smørgrav FREE(dir, M_PFSNODES); 13933802b9eSDag-Erling Smørgrav return (NULL); 14033802b9eSDag-Erling Smørgrav } 14133802b9eSDag-Erling Smørgrav 14233802b9eSDag-Erling Smørgrav if (_pfs_fixup_dir(dir) != 0) { 14333802b9eSDag-Erling Smørgrav pfs_destroy(dir); 14433802b9eSDag-Erling Smørgrav return (NULL); 14533802b9eSDag-Erling Smørgrav } 14633802b9eSDag-Erling Smørgrav 14733802b9eSDag-Erling Smørgrav return (dir); 14833802b9eSDag-Erling Smørgrav } 14933802b9eSDag-Erling Smørgrav 15033802b9eSDag-Erling Smørgrav /* 15133802b9eSDag-Erling Smørgrav * Create a file 15233802b9eSDag-Erling Smørgrav */ 15333802b9eSDag-Erling Smørgrav struct pfs_node * 154b331ec01SDag-Erling Smørgrav pfs_create_file(struct pfs_node *parent, const char *name, pfs_fill_t fill, 15533802b9eSDag-Erling Smørgrav pfs_attr_t attr, pfs_vis_t vis, int flags) 15633802b9eSDag-Erling Smørgrav { 15733802b9eSDag-Erling Smørgrav struct pfs_node *node; 15833802b9eSDag-Erling Smørgrav 15933802b9eSDag-Erling Smørgrav KASSERT(strlen(name) < PFS_NAMELEN, 1606e551fb6SDavid E. O'Brien ("%s(): node name is too long", __func__)); 16133802b9eSDag-Erling Smørgrav 16233802b9eSDag-Erling Smørgrav MALLOC(node, struct pfs_node *, sizeof *node, 163a163d034SWarner Losh M_PFSNODES, M_WAITOK|M_ZERO); 16433802b9eSDag-Erling Smørgrav strcpy(node->pn_name, name); 16533802b9eSDag-Erling Smørgrav node->pn_type = pfstype_file; 16633802b9eSDag-Erling Smørgrav node->pn_func = fill; 16733802b9eSDag-Erling Smørgrav node->pn_attr = attr; 16833802b9eSDag-Erling Smørgrav node->pn_vis = vis; 16933802b9eSDag-Erling Smørgrav node->pn_flags = flags; 17033802b9eSDag-Erling Smørgrav 17133802b9eSDag-Erling Smørgrav if (_pfs_add_node(parent, node) != 0) { 17233802b9eSDag-Erling Smørgrav FREE(node, M_PFSNODES); 17333802b9eSDag-Erling Smørgrav return (NULL); 17433802b9eSDag-Erling Smørgrav } 17533802b9eSDag-Erling Smørgrav 17633802b9eSDag-Erling Smørgrav return (node); 17733802b9eSDag-Erling Smørgrav } 17833802b9eSDag-Erling Smørgrav 17933802b9eSDag-Erling Smørgrav /* 18033802b9eSDag-Erling Smørgrav * Create a symlink 18133802b9eSDag-Erling Smørgrav */ 18233802b9eSDag-Erling Smørgrav struct pfs_node * 183b331ec01SDag-Erling Smørgrav pfs_create_link(struct pfs_node *parent, const char *name, pfs_fill_t fill, 18433802b9eSDag-Erling Smørgrav pfs_attr_t attr, pfs_vis_t vis, int flags) 18533802b9eSDag-Erling Smørgrav { 18633802b9eSDag-Erling Smørgrav struct pfs_node *node; 18733802b9eSDag-Erling Smørgrav 18833802b9eSDag-Erling Smørgrav node = pfs_create_file(parent, name, fill, attr, vis, flags); 18933802b9eSDag-Erling Smørgrav if (node == NULL) 19033802b9eSDag-Erling Smørgrav return (NULL); 19133802b9eSDag-Erling Smørgrav node->pn_type = pfstype_symlink; 19233802b9eSDag-Erling Smørgrav return (node); 19333802b9eSDag-Erling Smørgrav } 19433802b9eSDag-Erling Smørgrav 19533802b9eSDag-Erling Smørgrav /* 196b331ec01SDag-Erling Smørgrav * Locate a node by name 197b331ec01SDag-Erling Smørgrav */ 198b331ec01SDag-Erling Smørgrav struct pfs_node * 199b331ec01SDag-Erling Smørgrav pfs_find_node(struct pfs_node *parent, const char *name) 200b331ec01SDag-Erling Smørgrav { 201b331ec01SDag-Erling Smørgrav struct pfs_node *node; 202b331ec01SDag-Erling Smørgrav 203b331ec01SDag-Erling Smørgrav for (node = parent->pn_nodes; node != NULL; node = node->pn_next) 204b331ec01SDag-Erling Smørgrav if (strcmp(node->pn_name, name) == 0) 205b331ec01SDag-Erling Smørgrav return (node); 206b331ec01SDag-Erling Smørgrav return (NULL); 207b331ec01SDag-Erling Smørgrav } 208b331ec01SDag-Erling Smørgrav 209b331ec01SDag-Erling Smørgrav /* 21033802b9eSDag-Erling Smørgrav * Destroy a node or a tree of nodes 21133802b9eSDag-Erling Smørgrav */ 21233802b9eSDag-Erling Smørgrav int 21333802b9eSDag-Erling Smørgrav pfs_destroy(struct pfs_node *node) 21433802b9eSDag-Erling Smørgrav { 21533802b9eSDag-Erling Smørgrav struct pfs_node *parent, *rover; 21633802b9eSDag-Erling Smørgrav 21733802b9eSDag-Erling Smørgrav KASSERT(node != NULL, 2186e551fb6SDavid E. O'Brien ("%s(): node is NULL", __func__)); 21933802b9eSDag-Erling Smørgrav KASSERT(node->pn_info != NULL, 2206e551fb6SDavid E. O'Brien ("%s(): node has no pn_info", __func__)); 22133802b9eSDag-Erling Smørgrav 22233802b9eSDag-Erling Smørgrav /* destroy children */ 22333802b9eSDag-Erling Smørgrav if (node->pn_type == pfstype_dir || 22433802b9eSDag-Erling Smørgrav node->pn_type == pfstype_procdir || 22533802b9eSDag-Erling Smørgrav node->pn_type == pfstype_root) 22633802b9eSDag-Erling Smørgrav while (node->pn_nodes != NULL) 22733802b9eSDag-Erling Smørgrav pfs_destroy(node->pn_nodes); 22833802b9eSDag-Erling Smørgrav 22933802b9eSDag-Erling Smørgrav /* unlink from parent */ 23033802b9eSDag-Erling Smørgrav if ((parent = node->pn_parent) != NULL) { 23133802b9eSDag-Erling Smørgrav KASSERT(parent->pn_info == node->pn_info, 2326e551fb6SDavid E. O'Brien ("%s(): parent has different pn_info", __func__)); 23333802b9eSDag-Erling Smørgrav mtx_lock(&node->pn_info->pi_mutex); 23433802b9eSDag-Erling Smørgrav if (parent->pn_nodes == node) { 23533802b9eSDag-Erling Smørgrav parent->pn_nodes = node->pn_next; 23633802b9eSDag-Erling Smørgrav } else { 23733802b9eSDag-Erling Smørgrav rover = parent->pn_nodes; 23833802b9eSDag-Erling Smørgrav while (rover->pn_next != NULL) { 23933802b9eSDag-Erling Smørgrav if (rover->pn_next == node) { 24033802b9eSDag-Erling Smørgrav rover->pn_next = node->pn_next; 24133802b9eSDag-Erling Smørgrav break; 24233802b9eSDag-Erling Smørgrav } 24333802b9eSDag-Erling Smørgrav rover = rover->pn_next; 24433802b9eSDag-Erling Smørgrav } 24533802b9eSDag-Erling Smørgrav } 24633802b9eSDag-Erling Smørgrav mtx_unlock(&node->pn_info->pi_mutex); 24733802b9eSDag-Erling Smørgrav } 24833802b9eSDag-Erling Smørgrav 24933802b9eSDag-Erling Smørgrav /* revoke vnodes and release memory */ 25033802b9eSDag-Erling Smørgrav pfs_disable(node); 25133802b9eSDag-Erling Smørgrav FREE(node, M_PFSNODES); 25233802b9eSDag-Erling Smørgrav 25333802b9eSDag-Erling Smørgrav return (0); 25433802b9eSDag-Erling Smørgrav } 25533802b9eSDag-Erling Smørgrav 25633802b9eSDag-Erling Smørgrav /* 2579733a808SDag-Erling Smørgrav * Mount a pseudofs instance 2589733a808SDag-Erling Smørgrav */ 2599733a808SDag-Erling Smørgrav int 2605e8c582aSPoul-Henning Kamp pfs_mount(struct pfs_info *pi, struct mount *mp, struct thread *td) 2619733a808SDag-Erling Smørgrav { 2629733a808SDag-Erling Smørgrav struct statfs *sbp; 2639733a808SDag-Erling Smørgrav 2649733a808SDag-Erling Smørgrav if (mp->mnt_flag & MNT_UPDATE) 2659733a808SDag-Erling Smørgrav return (EOPNOTSUPP); 2669733a808SDag-Erling Smørgrav 2679733a808SDag-Erling Smørgrav mp->mnt_flag |= MNT_LOCAL; 2689733a808SDag-Erling Smørgrav mp->mnt_data = (qaddr_t)pi; 2699733a808SDag-Erling Smørgrav vfs_getnewfsid(mp); 2709733a808SDag-Erling Smørgrav 2719733a808SDag-Erling Smørgrav sbp = &mp->mnt_stat; 272def91cf2SPoul-Henning Kamp vfs_mountedfrom(mp, pi->pi_name); 2739733a808SDag-Erling Smørgrav sbp->f_bsize = PAGE_SIZE; 2749733a808SDag-Erling Smørgrav sbp->f_iosize = PAGE_SIZE; 2759733a808SDag-Erling Smørgrav sbp->f_blocks = 1; 2769733a808SDag-Erling Smørgrav sbp->f_bfree = 0; 2779733a808SDag-Erling Smørgrav sbp->f_bavail = 0; 2789733a808SDag-Erling Smørgrav sbp->f_files = 1; 2799733a808SDag-Erling Smørgrav sbp->f_ffree = 0; 2809733a808SDag-Erling Smørgrav 2819733a808SDag-Erling Smørgrav return (0); 2829733a808SDag-Erling Smørgrav } 2839733a808SDag-Erling Smørgrav 2849733a808SDag-Erling Smørgrav /* 2859733a808SDag-Erling Smørgrav * Unmount a pseudofs instance 2869733a808SDag-Erling Smørgrav */ 2879733a808SDag-Erling Smørgrav int 288b40ce416SJulian Elischer pfs_unmount(struct mount *mp, int mntflags, struct thread *td) 2899733a808SDag-Erling Smørgrav { 2909733a808SDag-Erling Smørgrav struct pfs_info *pi; 2919733a808SDag-Erling Smørgrav int error; 2929733a808SDag-Erling Smørgrav 2939733a808SDag-Erling Smørgrav pi = (struct pfs_info *)mp->mnt_data; 2949733a808SDag-Erling Smørgrav 2959733a808SDag-Erling Smørgrav /* XXX do stuff with pi... */ 2969733a808SDag-Erling Smørgrav 297f257b7a5SAlfred Perlstein error = vflush(mp, 0, (mntflags & MNT_FORCE) ? FORCECLOSE : 0, td); 2989733a808SDag-Erling Smørgrav return (error); 2999733a808SDag-Erling Smørgrav } 3009733a808SDag-Erling Smørgrav 3019733a808SDag-Erling Smørgrav /* 3029733a808SDag-Erling Smørgrav * Return a root vnode 3039733a808SDag-Erling Smørgrav */ 3049733a808SDag-Erling Smørgrav int 305f257b7a5SAlfred Perlstein pfs_root(struct mount *mp, struct vnode **vpp, struct thread *td) 3069733a808SDag-Erling Smørgrav { 3079733a808SDag-Erling Smørgrav struct pfs_info *pi; 3089733a808SDag-Erling Smørgrav 3099733a808SDag-Erling Smørgrav pi = (struct pfs_info *)mp->mnt_data; 310649ad985SDag-Erling Smørgrav return pfs_vncache_alloc(mp, vpp, pi->pi_root, NO_PID); 3119733a808SDag-Erling Smørgrav } 3129733a808SDag-Erling Smørgrav 3139733a808SDag-Erling Smørgrav /* 3149733a808SDag-Erling Smørgrav * Return filesystem stats 3159733a808SDag-Erling Smørgrav */ 3169733a808SDag-Erling Smørgrav int 317b40ce416SJulian Elischer pfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td) 3189733a808SDag-Erling Smørgrav { 319def91cf2SPoul-Henning Kamp /* no-op: always called with mp->mnt_stat */ 3209733a808SDag-Erling Smørgrav return (0); 3219733a808SDag-Erling Smørgrav } 3229733a808SDag-Erling Smørgrav 3239733a808SDag-Erling Smørgrav /* 3249733a808SDag-Erling Smørgrav * Initialize a pseudofs instance 3259733a808SDag-Erling Smørgrav */ 3269733a808SDag-Erling Smørgrav int 3279733a808SDag-Erling Smørgrav pfs_init(struct pfs_info *pi, struct vfsconf *vfc) 3289733a808SDag-Erling Smørgrav { 32933802b9eSDag-Erling Smørgrav struct pfs_node *root; 33033802b9eSDag-Erling Smørgrav int error; 33133802b9eSDag-Erling Smørgrav 3326008862bSJohn Baldwin mtx_init(&pi->pi_mutex, "pseudofs", NULL, MTX_DEF); 33333802b9eSDag-Erling Smørgrav 33433802b9eSDag-Erling Smørgrav /* set up the root diretory */ 33533802b9eSDag-Erling Smørgrav MALLOC(root, struct pfs_node *, sizeof *root, 336a163d034SWarner Losh M_PFSNODES, M_WAITOK|M_ZERO); 33733802b9eSDag-Erling Smørgrav root->pn_type = pfstype_root; 33833802b9eSDag-Erling Smørgrav root->pn_name[0] = '/'; 33933802b9eSDag-Erling Smørgrav root->pn_info = pi; 34033802b9eSDag-Erling Smørgrav if (_pfs_fixup_dir(root) != 0) { 34133802b9eSDag-Erling Smørgrav FREE(root, M_PFSNODES); 34233802b9eSDag-Erling Smørgrav return (ENODEV); /* XXX not really the right errno */ 34333802b9eSDag-Erling Smørgrav } 34433802b9eSDag-Erling Smørgrav pi->pi_root = root; 34533802b9eSDag-Erling Smørgrav 34633802b9eSDag-Erling Smørgrav /* construct file hierarchy */ 34733802b9eSDag-Erling Smørgrav error = (pi->pi_init)(pi, vfc); 34833802b9eSDag-Erling Smørgrav if (error) { 34933802b9eSDag-Erling Smørgrav pfs_destroy(root); 35033802b9eSDag-Erling Smørgrav pi->pi_root = NULL; 35133802b9eSDag-Erling Smørgrav mtx_destroy(&pi->pi_mutex); 35233802b9eSDag-Erling Smørgrav return (error); 35333802b9eSDag-Erling Smørgrav } 35433802b9eSDag-Erling Smørgrav 3559733a808SDag-Erling Smørgrav pfs_fileno_init(pi); 356b7004390SDag-Erling Smørgrav if (bootverbose) 3579733a808SDag-Erling Smørgrav printf("%s registered\n", pi->pi_name); 3589733a808SDag-Erling Smørgrav return (0); 3599733a808SDag-Erling Smørgrav } 3609733a808SDag-Erling Smørgrav 3619733a808SDag-Erling Smørgrav /* 3629733a808SDag-Erling Smørgrav * Destroy a pseudofs instance 3639733a808SDag-Erling Smørgrav */ 3649733a808SDag-Erling Smørgrav int 3659733a808SDag-Erling Smørgrav pfs_uninit(struct pfs_info *pi, struct vfsconf *vfc) 3669733a808SDag-Erling Smørgrav { 36733802b9eSDag-Erling Smørgrav int error; 36833802b9eSDag-Erling Smørgrav 3699733a808SDag-Erling Smørgrav pfs_fileno_uninit(pi); 37033802b9eSDag-Erling Smørgrav pfs_destroy(pi->pi_root); 37133802b9eSDag-Erling Smørgrav pi->pi_root = NULL; 3729733a808SDag-Erling Smørgrav mtx_destroy(&pi->pi_mutex); 373b7004390SDag-Erling Smørgrav if (bootverbose) 3749733a808SDag-Erling Smørgrav printf("%s unregistered\n", pi->pi_name); 37533802b9eSDag-Erling Smørgrav error = (pi->pi_uninit)(pi, vfc); 37633802b9eSDag-Erling Smørgrav return (error); 3779733a808SDag-Erling Smørgrav } 3789733a808SDag-Erling Smørgrav 3799733a808SDag-Erling Smørgrav /* 3809733a808SDag-Erling Smørgrav * Handle load / unload events 3819733a808SDag-Erling Smørgrav */ 3829733a808SDag-Erling Smørgrav static int 3839733a808SDag-Erling Smørgrav pfs_modevent(module_t mod, int evt, void *arg) 3849733a808SDag-Erling Smørgrav { 3859733a808SDag-Erling Smørgrav switch (evt) { 3869733a808SDag-Erling Smørgrav case MOD_LOAD: 3879733a808SDag-Erling Smørgrav pfs_fileno_load(); 3889733a808SDag-Erling Smørgrav pfs_vncache_load(); 3899733a808SDag-Erling Smørgrav break; 3909733a808SDag-Erling Smørgrav case MOD_UNLOAD: 3919733a808SDag-Erling Smørgrav case MOD_SHUTDOWN: 3929733a808SDag-Erling Smørgrav pfs_vncache_unload(); 3939733a808SDag-Erling Smørgrav pfs_fileno_unload(); 3949733a808SDag-Erling Smørgrav break; 3959733a808SDag-Erling Smørgrav default: 3963e019deaSPoul-Henning Kamp return EOPNOTSUPP; 3979733a808SDag-Erling Smørgrav break; 3989733a808SDag-Erling Smørgrav } 3999733a808SDag-Erling Smørgrav return 0; 4009733a808SDag-Erling Smørgrav } 4019733a808SDag-Erling Smørgrav 4029733a808SDag-Erling Smørgrav /* 4039733a808SDag-Erling Smørgrav * Module declaration 4049733a808SDag-Erling Smørgrav */ 4059733a808SDag-Erling Smørgrav static moduledata_t pseudofs_data = { 4069733a808SDag-Erling Smørgrav "pseudofs", 4079733a808SDag-Erling Smørgrav pfs_modevent, 4089733a808SDag-Erling Smørgrav NULL 4099733a808SDag-Erling Smørgrav }; 4109733a808SDag-Erling Smørgrav DECLARE_MODULE(pseudofs, pseudofs_data, SI_SUB_EXEC, SI_ORDER_FIRST); 41198c7e22cSDag-Erling Smørgrav MODULE_VERSION(pseudofs, 1); 412