portal_vfsops.c revision 76166
11541Srgrimes/* 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 * 3. All advertising materials mentioning features or use of this software 171541Srgrimes * must display the following acknowledgement: 181541Srgrimes * This product includes software developed by the University of 191541Srgrimes * California, Berkeley and its contributors. 201541Srgrimes * 4. Neither the name of the University nor the names of its contributors 211541Srgrimes * may be used to endorse or promote products derived from this software 221541Srgrimes * without specific prior written permission. 231541Srgrimes * 241541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 251541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 261541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 271541Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 281541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 291541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 301541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 311541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 321541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 331541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 341541Srgrimes * SUCH DAMAGE. 351541Srgrimes * 3622521Sdyson * @(#)portal_vfsops.c 8.11 (Berkeley) 5/14/95 371541Srgrimes * 3850477Speter * $FreeBSD: head/sys/fs/portalfs/portal_vfsops.c 76166 2001-05-01 08:13:21Z markm $ 391541Srgrimes */ 401541Srgrimes 411541Srgrimes/* 421541Srgrimes * Portal Filesystem 431541Srgrimes */ 441541Srgrimes 451541Srgrimes#include <sys/param.h> 461541Srgrimes#include <sys/systm.h> 4776166Smarkm#include <sys/domain.h> 4876166Smarkm#include <sys/filedesc.h> 493034Sdg#include <sys/kernel.h> 5076166Smarkm#include <sys/lock.h> 5176166Smarkm#include <sys/malloc.h> 5276166Smarkm#include <sys/file.h> /* Must come after sys/malloc.h */ 5376166Smarkm#include <sys/mount.h> 541541Srgrimes#include <sys/proc.h> 5576166Smarkm#include <sys/protosw.h> 561541Srgrimes#include <sys/socket.h> 571541Srgrimes#include <sys/socketvar.h> 5876166Smarkm#include <sys/vnode.h> 5976166Smarkm 601541Srgrimes#include <miscfs/portal/portal.h> 611541Srgrimes 6230354Sphkstatic MALLOC_DEFINE(M_PORTALFSMNT, "PORTAL mount", "PORTAL mount structure"); 6330354Sphk 6412769Sphkstatic int portal_mount __P((struct mount *mp, char *path, caddr_t data, 6512335Sbde struct nameidata *ndp, struct proc *p)); 6612769Sphkstatic int portal_unmount __P((struct mount *mp, int mntflags, 6712335Sbde struct proc *p)); 6812769Sphkstatic int portal_root __P((struct mount *mp, struct vnode **vpp)); 6912769Sphkstatic int portal_statfs __P((struct mount *mp, struct statfs *sbp, 7012335Sbde struct proc *p)); 7112335Sbde 721541Srgrimes/* 731541Srgrimes * Mount the per-process file descriptors (/dev/fd) 741541Srgrimes */ 7512769Sphkstatic int 761541Srgrimesportal_mount(mp, path, data, ndp, p) 771541Srgrimes struct mount *mp; 781541Srgrimes char *path; 791541Srgrimes caddr_t data; 801541Srgrimes struct nameidata *ndp; 811541Srgrimes struct proc *p; 821541Srgrimes{ 831541Srgrimes struct file *fp; 841541Srgrimes struct portal_args args; 851541Srgrimes struct portalmount *fmp; 861541Srgrimes struct socket *so; 871541Srgrimes struct vnode *rvp; 8816312Sdg struct portalnode *pn; 891541Srgrimes u_int size; 901541Srgrimes int error; 911541Srgrimes 921541Srgrimes /* 931541Srgrimes * Update is a no-op 941541Srgrimes */ 951541Srgrimes if (mp->mnt_flag & MNT_UPDATE) 961541Srgrimes return (EOPNOTSUPP); 971541Srgrimes 983496Sphk error = copyin(data, (caddr_t) &args, sizeof(struct portal_args)); 993496Sphk if (error) 1001541Srgrimes return (error); 1011541Srgrimes 10269149Sjlemon error = holdsock(p->p_fd, args.pa_socket, &fp); 1033496Sphk if (error) 1041541Srgrimes return (error); 1051541Srgrimes so = (struct socket *) fp->f_data; 10669149Sjlemon if (so->so_proto->pr_domain->dom_family != AF_UNIX) { 10769149Sjlemon fdrop(fp, p); 1081541Srgrimes return (ESOCKTNOSUPPORT); 10969149Sjlemon } 1101541Srgrimes 11116312Sdg MALLOC(pn, struct portalnode *, sizeof(struct portalnode), 11216312Sdg M_TEMP, M_WAITOK); 11316312Sdg 11416312Sdg MALLOC(fmp, struct portalmount *, sizeof(struct portalmount), 11530354Sphk M_PORTALFSMNT, M_WAITOK); /* XXX */ 11616312Sdg 1171541Srgrimes error = getnewvnode(VT_PORTAL, mp, portal_vnodeop_p, &rvp); /* XXX */ 11816312Sdg if (error) { 11930354Sphk FREE(fmp, M_PORTALFSMNT); 12016312Sdg FREE(pn, M_TEMP); 12169149Sjlemon fdrop(fp, p); 1221541Srgrimes return (error); 12316312Sdg } 1241541Srgrimes 12516312Sdg rvp->v_data = pn; 1261541Srgrimes rvp->v_type = VDIR; 1271541Srgrimes rvp->v_flag |= VROOT; 1281541Srgrimes VTOPORTAL(rvp)->pt_arg = 0; 1291541Srgrimes VTOPORTAL(rvp)->pt_size = 0; 1301541Srgrimes VTOPORTAL(rvp)->pt_fileid = PORTAL_ROOTFILEID; 1311541Srgrimes fmp->pm_root = rvp; 1321541Srgrimes fmp->pm_server = fp; fp->f_count++; 1331541Srgrimes 1341541Srgrimes mp->mnt_flag |= MNT_LOCAL; 1351541Srgrimes mp->mnt_data = (qaddr_t) fmp; 13622521Sdyson vfs_getnewfsid(mp); 1371541Srgrimes 1381541Srgrimes (void)copyinstr(args.pa_config, 1391541Srgrimes mp->mnt_stat.f_mntfromname, MNAMELEN - 1, &size); 1401541Srgrimes bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 1411541Srgrimes 1421541Srgrimes#ifdef notdef 1431541Srgrimes bzero(mp->mnt_stat.f_mntfromname, MNAMELEN); 1441541Srgrimes bcopy("portal", mp->mnt_stat.f_mntfromname, sizeof("portal")); 1451541Srgrimes#endif 1461541Srgrimes 14732150Sbde (void)portal_statfs(mp, &mp->mnt_stat, p); 14869149Sjlemon fdrop(fp, p); 1491541Srgrimes return (0); 1501541Srgrimes} 1511541Srgrimes 15212769Sphkstatic int 1531541Srgrimesportal_unmount(mp, mntflags, p) 1541541Srgrimes struct mount *mp; 1551541Srgrimes int mntflags; 1561541Srgrimes struct proc *p; 1571541Srgrimes{ 1581541Srgrimes struct vnode *rootvp = VFSTOPORTAL(mp)->pm_root; 1591541Srgrimes int error, flags = 0; 1601541Srgrimes 1611541Srgrimes 16222521Sdyson if (mntflags & MNT_FORCE) 1631541Srgrimes flags |= FORCECLOSE; 1641541Srgrimes 1651541Srgrimes /* 1661541Srgrimes * Clear out buffer cache. I don't think we 1671541Srgrimes * ever get anything cached at this level at the 1681541Srgrimes * moment, but who knows... 1691541Srgrimes */ 1701541Srgrimes#ifdef notyet 1718876Srgrimes mntflushbuf(mp, 0); 1721541Srgrimes if (mntinvalbuf(mp, 1)) 1731541Srgrimes return (EBUSY); 1741541Srgrimes#endif 1751541Srgrimes if (rootvp->v_usecount > 1) 1761541Srgrimes return (EBUSY); 1773496Sphk error = vflush(mp, rootvp, flags); 1783496Sphk if (error) 1791541Srgrimes return (error); 1801541Srgrimes 1811541Srgrimes /* 1821541Srgrimes * Release reference on underlying root vnode 1831541Srgrimes */ 1841541Srgrimes vrele(rootvp); 1851541Srgrimes /* 1861541Srgrimes * And blow it away for future re-use 1871541Srgrimes */ 1881541Srgrimes vgone(rootvp); 1891541Srgrimes /* 1901541Srgrimes * Shutdown the socket. This will cause the select in the 1911541Srgrimes * daemon to wake up, and then the accept will get ECONNABORTED 1921541Srgrimes * which it interprets as a request to go and bury itself. 1931541Srgrimes */ 1941541Srgrimes soshutdown((struct socket *) VFSTOPORTAL(mp)->pm_server->f_data, 2); 1951541Srgrimes /* 1961541Srgrimes * Discard reference to underlying file. Must call closef because 1971541Srgrimes * this may be the last reference. 1981541Srgrimes */ 1991541Srgrimes closef(VFSTOPORTAL(mp)->pm_server, (struct proc *) 0); 2001541Srgrimes /* 2011541Srgrimes * Finally, throw away the portalmount structure 2021541Srgrimes */ 20330354Sphk free(mp->mnt_data, M_PORTALFSMNT); /* XXX */ 2041541Srgrimes mp->mnt_data = 0; 2051541Srgrimes return (0); 2061541Srgrimes} 2071541Srgrimes 20812769Sphkstatic int 2091541Srgrimesportal_root(mp, vpp) 2101541Srgrimes struct mount *mp; 2111541Srgrimes struct vnode **vpp; 2121541Srgrimes{ 21322521Sdyson struct proc *p = curproc; /* XXX */ 2141541Srgrimes struct vnode *vp; 2151541Srgrimes 2161541Srgrimes /* 2171541Srgrimes * Return locked reference to root. 2181541Srgrimes */ 2191541Srgrimes vp = VFSTOPORTAL(mp)->pm_root; 2201541Srgrimes VREF(vp); 22122521Sdyson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 2221541Srgrimes *vpp = vp; 2231541Srgrimes return (0); 2241541Srgrimes} 2251541Srgrimes 22612769Sphkstatic int 2271541Srgrimesportal_statfs(mp, sbp, p) 2281541Srgrimes struct mount *mp; 2291541Srgrimes struct statfs *sbp; 2301541Srgrimes struct proc *p; 2311541Srgrimes{ 2321541Srgrimes 2331541Srgrimes sbp->f_flags = 0; 2341541Srgrimes sbp->f_bsize = DEV_BSIZE; 2351541Srgrimes sbp->f_iosize = DEV_BSIZE; 2361541Srgrimes sbp->f_blocks = 2; /* 1K to keep df happy */ 2371541Srgrimes sbp->f_bfree = 0; 2381541Srgrimes sbp->f_bavail = 0; 2391541Srgrimes sbp->f_files = 1; /* Allow for "." */ 2401541Srgrimes sbp->f_ffree = 0; /* See comments above */ 2411541Srgrimes if (sbp != &mp->mnt_stat) { 24222521Sdyson sbp->f_type = mp->mnt_vfc->vfc_typenum; 2431541Srgrimes bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 2441541Srgrimes bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 2451541Srgrimes bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 2461541Srgrimes } 2471541Srgrimes return (0); 2481541Srgrimes} 2491541Srgrimes 25012769Sphkstatic struct vfsops portal_vfsops = { 2511541Srgrimes portal_mount, 25251068Salfred vfs_stdstart, 2531541Srgrimes portal_unmount, 2541541Srgrimes portal_root, 25551068Salfred vfs_stdquotactl, 2561541Srgrimes portal_statfs, 25751068Salfred vfs_stdsync, 25851068Salfred vfs_stdvget, 25951068Salfred vfs_stdfhtovp, 26051138Salfred vfs_stdcheckexp, 26151068Salfred vfs_stdvptofh, 26251068Salfred vfs_stdinit, 26354803Srwatson vfs_stduninit, 26454803Srwatson vfs_stdextattrctl, 2651541Srgrimes}; 2662946Swollman 26738909SbdeVFS_SET(portal_vfsops, portal, VFCF_SYNTHETIC); 268