portal_vfsops.c revision 101308
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 101308 2002-08-04 10:29:36Z jeff $ 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> 5189316Salfred#include <sys/mutex.h> 5276166Smarkm#include <sys/malloc.h> 5376166Smarkm#include <sys/file.h> /* Must come after sys/malloc.h */ 5476166Smarkm#include <sys/mount.h> 551541Srgrimes#include <sys/proc.h> 5676166Smarkm#include <sys/protosw.h> 571541Srgrimes#include <sys/socket.h> 581541Srgrimes#include <sys/socketvar.h> 5976166Smarkm#include <sys/vnode.h> 6076166Smarkm 6177031Sru#include <fs/portalfs/portal.h> 621541Srgrimes 6330354Sphkstatic MALLOC_DEFINE(M_PORTALFSMNT, "PORTAL mount", "PORTAL mount structure"); 6430354Sphk 6592727Salfredstatic int portal_mount(struct mount *mp, char *path, caddr_t data, 6692727Salfred struct nameidata *ndp, struct thread *td); 6792727Salfredstatic int portal_unmount(struct mount *mp, int mntflags, 6892727Salfred struct thread *td); 6992727Salfredstatic int portal_root(struct mount *mp, struct vnode **vpp); 7092727Salfredstatic int portal_statfs(struct mount *mp, struct statfs *sbp, 7192727Salfred struct thread *td); 7212335Sbde 731541Srgrimes/* 741541Srgrimes * Mount the per-process file descriptors (/dev/fd) 751541Srgrimes */ 7612769Sphkstatic int 7783366Sjulianportal_mount(mp, path, data, ndp, td) 781541Srgrimes struct mount *mp; 791541Srgrimes char *path; 801541Srgrimes caddr_t data; 811541Srgrimes struct nameidata *ndp; 8283366Sjulian struct thread *td; 831541Srgrimes{ 841541Srgrimes struct file *fp; 851541Srgrimes struct portal_args args; 861541Srgrimes struct portalmount *fmp; 871541Srgrimes struct socket *so; 881541Srgrimes struct vnode *rvp; 8916312Sdg struct portalnode *pn; 901541Srgrimes u_int size; 911541Srgrimes int error; 921541Srgrimes 931541Srgrimes /* 941541Srgrimes * Update is a no-op 951541Srgrimes */ 961541Srgrimes if (mp->mnt_flag & MNT_UPDATE) 971541Srgrimes return (EOPNOTSUPP); 981541Srgrimes 993496Sphk error = copyin(data, (caddr_t) &args, sizeof(struct portal_args)); 1003496Sphk if (error) 1011541Srgrimes return (error); 1021541Srgrimes 10386872Sdillon if ((error = fget(td, args.pa_socket, &fp)) != 0) 1041541Srgrimes return (error); 10586872Sdillon if (fp->f_type != DTYPE_SOCKET) { 10686872Sdillon fdrop(fp, td); 10786872Sdillon return(ENOTSOCK); 10886872Sdillon } 10986872Sdillon so = (struct socket *) fp->f_data; /* XXX race against userland */ 11069149Sjlemon if (so->so_proto->pr_domain->dom_family != AF_UNIX) { 11183366Sjulian fdrop(fp, td); 1121541Srgrimes return (ESOCKTNOSUPPORT); 11369149Sjlemon } 1141541Srgrimes 11516312Sdg MALLOC(pn, struct portalnode *, sizeof(struct portalnode), 11616312Sdg M_TEMP, M_WAITOK); 11716312Sdg 11816312Sdg MALLOC(fmp, struct portalmount *, sizeof(struct portalmount), 11930354Sphk M_PORTALFSMNT, M_WAITOK); /* XXX */ 12016312Sdg 1211541Srgrimes error = getnewvnode(VT_PORTAL, mp, portal_vnodeop_p, &rvp); /* XXX */ 12216312Sdg if (error) { 12330354Sphk FREE(fmp, M_PORTALFSMNT); 12416312Sdg FREE(pn, M_TEMP); 12583366Sjulian fdrop(fp, td); 1261541Srgrimes return (error); 12716312Sdg } 1281541Srgrimes 12916312Sdg rvp->v_data = pn; 1301541Srgrimes rvp->v_type = VDIR; 131101308Sjeff rvp->v_vflag |= VV_ROOT; 1321541Srgrimes VTOPORTAL(rvp)->pt_arg = 0; 1331541Srgrimes VTOPORTAL(rvp)->pt_size = 0; 1341541Srgrimes VTOPORTAL(rvp)->pt_fileid = PORTAL_ROOTFILEID; 1351541Srgrimes fmp->pm_root = rvp; 13689306Salfred fhold(fp); 13789306Salfred fmp->pm_server = fp; 1381541Srgrimes 1391541Srgrimes mp->mnt_flag |= MNT_LOCAL; 1401541Srgrimes mp->mnt_data = (qaddr_t) fmp; 14122521Sdyson vfs_getnewfsid(mp); 1421541Srgrimes 1431541Srgrimes (void)copyinstr(args.pa_config, 1441541Srgrimes mp->mnt_stat.f_mntfromname, MNAMELEN - 1, &size); 1451541Srgrimes bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 1461541Srgrimes 1471541Srgrimes#ifdef notdef 1481541Srgrimes bzero(mp->mnt_stat.f_mntfromname, MNAMELEN); 1491541Srgrimes bcopy("portal", mp->mnt_stat.f_mntfromname, sizeof("portal")); 1501541Srgrimes#endif 1511541Srgrimes 15283366Sjulian (void)portal_statfs(mp, &mp->mnt_stat, td); 15383366Sjulian fdrop(fp, td); 1541541Srgrimes return (0); 1551541Srgrimes} 1561541Srgrimes 15712769Sphkstatic int 15883366Sjulianportal_unmount(mp, mntflags, td) 1591541Srgrimes struct mount *mp; 1601541Srgrimes int mntflags; 16183366Sjulian struct thread *td; 1621541Srgrimes{ 1631541Srgrimes int error, flags = 0; 1641541Srgrimes 1651541Srgrimes 16622521Sdyson if (mntflags & MNT_FORCE) 1671541Srgrimes flags |= FORCECLOSE; 1681541Srgrimes 1691541Srgrimes /* 1701541Srgrimes * Clear out buffer cache. I don't think we 1711541Srgrimes * ever get anything cached at this level at the 1721541Srgrimes * moment, but who knows... 1731541Srgrimes */ 1741541Srgrimes#ifdef notyet 1758876Srgrimes mntflushbuf(mp, 0); 1761541Srgrimes if (mntinvalbuf(mp, 1)) 1771541Srgrimes return (EBUSY); 1781541Srgrimes#endif 17976688Siedowse /* There is 1 extra root vnode reference (pm_root). */ 18076688Siedowse error = vflush(mp, 1, flags); 1813496Sphk if (error) 1821541Srgrimes return (error); 1831541Srgrimes 1841541Srgrimes /* 1851541Srgrimes * Shutdown the socket. This will cause the select in the 1861541Srgrimes * daemon to wake up, and then the accept will get ECONNABORTED 1871541Srgrimes * which it interprets as a request to go and bury itself. 1881541Srgrimes */ 1891541Srgrimes soshutdown((struct socket *) VFSTOPORTAL(mp)->pm_server->f_data, 2); 1901541Srgrimes /* 1911541Srgrimes * Discard reference to underlying file. Must call closef because 1921541Srgrimes * this may be the last reference. 1931541Srgrimes */ 19483366Sjulian closef(VFSTOPORTAL(mp)->pm_server, (struct thread *) 0); 1951541Srgrimes /* 1961541Srgrimes * Finally, throw away the portalmount structure 1971541Srgrimes */ 19830354Sphk free(mp->mnt_data, M_PORTALFSMNT); /* XXX */ 1991541Srgrimes mp->mnt_data = 0; 2001541Srgrimes return (0); 2011541Srgrimes} 2021541Srgrimes 20312769Sphkstatic int 2041541Srgrimesportal_root(mp, vpp) 2051541Srgrimes struct mount *mp; 2061541Srgrimes struct vnode **vpp; 2071541Srgrimes{ 20883366Sjulian struct thread *td = curthread; /* XXX */ 2091541Srgrimes struct vnode *vp; 2101541Srgrimes 2111541Srgrimes /* 2121541Srgrimes * Return locked reference to root. 2131541Srgrimes */ 2141541Srgrimes vp = VFSTOPORTAL(mp)->pm_root; 2151541Srgrimes VREF(vp); 21683366Sjulian vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2171541Srgrimes *vpp = vp; 2181541Srgrimes return (0); 2191541Srgrimes} 2201541Srgrimes 22112769Sphkstatic int 22283366Sjulianportal_statfs(mp, sbp, td) 2231541Srgrimes struct mount *mp; 2241541Srgrimes struct statfs *sbp; 22583366Sjulian struct thread *td; 2261541Srgrimes{ 2271541Srgrimes 2281541Srgrimes sbp->f_flags = 0; 2291541Srgrimes sbp->f_bsize = DEV_BSIZE; 2301541Srgrimes sbp->f_iosize = DEV_BSIZE; 2311541Srgrimes sbp->f_blocks = 2; /* 1K to keep df happy */ 2321541Srgrimes sbp->f_bfree = 0; 2331541Srgrimes sbp->f_bavail = 0; 2341541Srgrimes sbp->f_files = 1; /* Allow for "." */ 2351541Srgrimes sbp->f_ffree = 0; /* See comments above */ 2361541Srgrimes if (sbp != &mp->mnt_stat) { 23722521Sdyson sbp->f_type = mp->mnt_vfc->vfc_typenum; 2381541Srgrimes bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 2391541Srgrimes bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 2401541Srgrimes bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 2411541Srgrimes } 2421541Srgrimes return (0); 2431541Srgrimes} 2441541Srgrimes 24512769Sphkstatic struct vfsops portal_vfsops = { 2461541Srgrimes portal_mount, 24751068Salfred vfs_stdstart, 2481541Srgrimes portal_unmount, 2491541Srgrimes portal_root, 25051068Salfred vfs_stdquotactl, 2511541Srgrimes portal_statfs, 25251068Salfred vfs_stdsync, 25351068Salfred vfs_stdvget, 25451068Salfred vfs_stdfhtovp, 25551138Salfred vfs_stdcheckexp, 25651068Salfred vfs_stdvptofh, 25751068Salfred vfs_stdinit, 25854803Srwatson vfs_stduninit, 25954803Srwatson vfs_stdextattrctl, 2601541Srgrimes}; 2612946Swollman 26277133SruVFS_SET(portal_vfsops, portalfs, VFCF_SYNTHETIC); 263