1139776Simp/*- 222521Sdyson * Copyright (c) 1992, 1993, 1995 31541Srgrimes * The Regents of the University of California. All rights reserved. 41541Srgrimes * 51541Srgrimes * This code is derived from software donated to Berkeley by 61541Srgrimes * Jan-Simon Pendry. 71541Srgrimes * 81541Srgrimes * Redistribution and use in source and binary forms, with or without 91541Srgrimes * modification, are permitted provided that the following conditions 101541Srgrimes * are met: 111541Srgrimes * 1. Redistributions of source code must retain the above copyright 121541Srgrimes * notice, this list of conditions and the following disclaimer. 131541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 141541Srgrimes * notice, this list of conditions and the following disclaimer in the 151541Srgrimes * documentation and/or other materials provided with the distribution. 161541Srgrimes * 4. Neither the name of the University nor the names of its contributors 171541Srgrimes * may be used to endorse or promote products derived from this software 181541Srgrimes * without specific prior written permission. 191541Srgrimes * 201541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 211541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 221541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 231541Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 241541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 251541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 261541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 271541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 281541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 291541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 301541Srgrimes * SUCH DAMAGE. 311541Srgrimes * 3222521Sdyson * @(#)portal_vfsops.c 8.11 (Berkeley) 5/14/95 331541Srgrimes * 3450477Speter * $FreeBSD$ 351541Srgrimes */ 361541Srgrimes 371541Srgrimes/* 381541Srgrimes * Portal Filesystem 391541Srgrimes */ 401541Srgrimes 411541Srgrimes#include <sys/param.h> 421541Srgrimes#include <sys/systm.h> 43224778Srwatson#include <sys/capability.h> 4476166Smarkm#include <sys/domain.h> 4576166Smarkm#include <sys/filedesc.h> 463034Sdg#include <sys/kernel.h> 4776166Smarkm#include <sys/lock.h> 4889316Salfred#include <sys/mutex.h> 4976166Smarkm#include <sys/malloc.h> 5076166Smarkm#include <sys/file.h> /* Must come after sys/malloc.h */ 5176166Smarkm#include <sys/mount.h> 521541Srgrimes#include <sys/proc.h> 5376166Smarkm#include <sys/protosw.h> 541541Srgrimes#include <sys/socket.h> 551541Srgrimes#include <sys/socketvar.h> 5676166Smarkm#include <sys/vnode.h> 5776166Smarkm 5877031Sru#include <fs/portalfs/portal.h> 591541Srgrimes 60151897Srwatsonstatic MALLOC_DEFINE(M_PORTALFSMNT, "portal_mount", "PORTAL mount structure"); 6130354Sphk 62116271Sphkstatic vfs_unmount_t portal_unmount; 63116271Sphkstatic vfs_root_t portal_root; 64116271Sphkstatic vfs_statfs_t portal_statfs; 6512335Sbde 66138489Sphkstatic const char *portal_opts[] = { 67138489Sphk "socket", "config", 68138489Sphk NULL 69138489Sphk}; 70138489Sphk 71138489Sphkstatic int 72230725Smckusickportal_cmount(struct mntarg *ma, void *data, uint64_t flags) 73138489Sphk{ 74138489Sphk struct portal_args args; 75138489Sphk int error; 76138489Sphk 77138489Sphk if (data == NULL) 78138489Sphk return (EINVAL); 79138489Sphk error = copyin(data, &args, sizeof args); 80138489Sphk if (error) 81138489Sphk return (error); 82138489Sphk 83138489Sphk ma = mount_argf(ma, "socket", "%d", args.pa_socket); 84138489Sphk ma = mount_argsu(ma, "config", args.pa_config, MAXPATHLEN); 85138489Sphk error = kernel_mount(ma, flags); 86138489Sphk 87138489Sphk return (error); 88138489Sphk} 89138489Sphk 901541Srgrimes/* 911541Srgrimes * Mount the per-process file descriptors (/dev/fd) 921541Srgrimes */ 9312769Sphkstatic int 94191990Sattilioportal_mount(struct mount *mp) 951541Srgrimes{ 961541Srgrimes struct file *fp; 971541Srgrimes struct portalmount *fmp; 981541Srgrimes struct socket *so; 991541Srgrimes struct vnode *rvp; 100191990Sattilio struct thread *td; 10116312Sdg struct portalnode *pn; 102138489Sphk int error, v; 103138489Sphk char *p; 1041541Srgrimes 105191990Sattilio td = curthread; 106138489Sphk if (vfs_filteropt(mp->mnt_optnew, portal_opts)) 107138489Sphk return (EINVAL); 1081541Srgrimes 109138489Sphk error = vfs_scanopt(mp->mnt_optnew, "socket", "%d", &v); 110138489Sphk if (error != 1) 111138489Sphk return (EINVAL); 112138489Sphk error = vfs_getopt(mp->mnt_optnew, "config", (void **)&p, NULL); 1133496Sphk if (error) 1141541Srgrimes return (error); 1151541Srgrimes 116224778Srwatson /* 117224778Srwatson * Capsicum is not incompatible with portalfs, but we don't really 118224778Srwatson * know what rights are required. In the spirit of "better safe than 119224778Srwatson * sorry", pretend that all rights are required for now. 120224778Srwatson */ 121224778Srwatson if ((error = fget(td, v, CAP_MASK_VALID, &fp)) != 0) 1221541Srgrimes return (error); 12386872Sdillon if (fp->f_type != DTYPE_SOCKET) { 12486872Sdillon fdrop(fp, td); 12586872Sdillon return(ENOTSOCK); 12686872Sdillon } 127109153Sdillon so = fp->f_data; /* XXX race against userland */ 12869149Sjlemon if (so->so_proto->pr_domain->dom_family != AF_UNIX) { 12983366Sjulian fdrop(fp, td); 1301541Srgrimes return (ESOCKTNOSUPPORT); 13169149Sjlemon } 1321541Srgrimes 133184205Sdes pn = malloc(sizeof(struct portalnode), 134111119Simp M_TEMP, M_WAITOK); 13516312Sdg 136184205Sdes fmp = malloc(sizeof(struct portalmount), 137111119Simp M_PORTALFSMNT, M_WAITOK); /* XXX */ 13816312Sdg 139138290Sphk error = getnewvnode("portal", mp, &portal_vnodeops, &rvp); /* XXX */ 14016312Sdg if (error) { 141184205Sdes free(fmp, M_PORTALFSMNT); 142184205Sdes free(pn, M_TEMP); 14383366Sjulian fdrop(fp, td); 1441541Srgrimes return (error); 14516312Sdg } 1461541Srgrimes 147167497Stegge error = insmntque(rvp, mp); /* XXX: Too early for mpsafe fs */ 148167497Stegge if (error != 0) { 149184205Sdes free(fmp, M_PORTALFSMNT); 150184205Sdes free(pn, M_TEMP); 151167497Stegge fdrop(fp, td); 152167497Stegge return (error); 153167497Stegge } 15416312Sdg rvp->v_data = pn; 1551541Srgrimes rvp->v_type = VDIR; 156101308Sjeff rvp->v_vflag |= VV_ROOT; 1571541Srgrimes VTOPORTAL(rvp)->pt_arg = 0; 1581541Srgrimes VTOPORTAL(rvp)->pt_size = 0; 1591541Srgrimes VTOPORTAL(rvp)->pt_fileid = PORTAL_ROOTFILEID; 1601541Srgrimes fmp->pm_root = rvp; 16189306Salfred fhold(fp); 16289306Salfred fmp->pm_server = fp; 1631541Srgrimes 164162647Stegge MNT_ILOCK(mp); 1651541Srgrimes mp->mnt_flag |= MNT_LOCAL; 166162647Stegge MNT_IUNLOCK(mp); 167172697Salfred mp->mnt_data = fmp; 16822521Sdyson vfs_getnewfsid(mp); 1691541Srgrimes 170138489Sphk vfs_mountedfrom(mp, p); 17183366Sjulian fdrop(fp, td); 1721541Srgrimes return (0); 1731541Srgrimes} 1741541Srgrimes 17512769Sphkstatic int 176191990Sattilioportal_unmount(mp, mntflags) 1771541Srgrimes struct mount *mp; 1781541Srgrimes int mntflags; 1791541Srgrimes{ 1801541Srgrimes int error, flags = 0; 1811541Srgrimes 1821541Srgrimes 18322521Sdyson if (mntflags & MNT_FORCE) 1841541Srgrimes flags |= FORCECLOSE; 1851541Srgrimes 1861541Srgrimes /* 1871541Srgrimes * Clear out buffer cache. I don't think we 1881541Srgrimes * ever get anything cached at this level at the 1891541Srgrimes * moment, but who knows... 1901541Srgrimes */ 1911541Srgrimes#ifdef notyet 1928876Srgrimes mntflushbuf(mp, 0); 1931541Srgrimes if (mntinvalbuf(mp, 1)) 1941541Srgrimes return (EBUSY); 1951541Srgrimes#endif 19676688Siedowse /* There is 1 extra root vnode reference (pm_root). */ 197191990Sattilio error = vflush(mp, 1, flags, curthread); 1983496Sphk if (error) 1991541Srgrimes return (error); 2001541Srgrimes 2011541Srgrimes /* 2021541Srgrimes * Shutdown the socket. This will cause the select in the 2031541Srgrimes * daemon to wake up, and then the accept will get ECONNABORTED 2041541Srgrimes * which it interprets as a request to go and bury itself. 2051541Srgrimes */ 206109153Sdillon soshutdown(VFSTOPORTAL(mp)->pm_server->f_data, 2); 2071541Srgrimes /* 2081541Srgrimes * Discard reference to underlying file. Must call closef because 2091541Srgrimes * this may be the last reference. 2101541Srgrimes */ 21183366Sjulian closef(VFSTOPORTAL(mp)->pm_server, (struct thread *) 0); 2121541Srgrimes /* 2131541Srgrimes * Finally, throw away the portalmount structure 2141541Srgrimes */ 21530354Sphk free(mp->mnt_data, M_PORTALFSMNT); /* XXX */ 2161541Srgrimes mp->mnt_data = 0; 2171541Srgrimes return (0); 2181541Srgrimes} 2191541Srgrimes 22012769Sphkstatic int 221191990Sattilioportal_root(mp, flags, vpp) 2221541Srgrimes struct mount *mp; 223144058Sjeff int flags; 2241541Srgrimes struct vnode **vpp; 2251541Srgrimes{ 2261541Srgrimes struct vnode *vp; 2271541Srgrimes 2281541Srgrimes /* 2291541Srgrimes * Return locked reference to root. 2301541Srgrimes */ 2311541Srgrimes vp = VFSTOPORTAL(mp)->pm_root; 2321541Srgrimes VREF(vp); 233175202Sattilio vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 2341541Srgrimes *vpp = vp; 2351541Srgrimes return (0); 2361541Srgrimes} 2371541Srgrimes 23812769Sphkstatic int 239191990Sattilioportal_statfs(mp, sbp) 2401541Srgrimes struct mount *mp; 2411541Srgrimes struct statfs *sbp; 2421541Srgrimes{ 2431541Srgrimes 2441541Srgrimes sbp->f_flags = 0; 2451541Srgrimes sbp->f_bsize = DEV_BSIZE; 2461541Srgrimes sbp->f_iosize = DEV_BSIZE; 2471541Srgrimes sbp->f_blocks = 2; /* 1K to keep df happy */ 2481541Srgrimes sbp->f_bfree = 0; 2491541Srgrimes sbp->f_bavail = 0; 2501541Srgrimes sbp->f_files = 1; /* Allow for "." */ 2511541Srgrimes sbp->f_ffree = 0; /* See comments above */ 2521541Srgrimes return (0); 2531541Srgrimes} 2541541Srgrimes 25512769Sphkstatic struct vfsops portal_vfsops = { 256138489Sphk .vfs_cmount = portal_cmount, 257138489Sphk .vfs_mount = portal_mount, 258116271Sphk .vfs_root = portal_root, 259116271Sphk .vfs_statfs = portal_statfs, 260116271Sphk .vfs_unmount = portal_unmount, 2611541Srgrimes}; 2622946Swollman 26377133SruVFS_SET(portal_vfsops, portalfs, VFCF_SYNTHETIC); 264