portal_vfsops.c revision 69149
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 69149 2000-11-25 07:16:06Z jlemon $ 391541Srgrimes */ 401541Srgrimes 411541Srgrimes/* 421541Srgrimes * Portal Filesystem 431541Srgrimes */ 441541Srgrimes 451541Srgrimes#include <sys/param.h> 461541Srgrimes#include <sys/systm.h> 473034Sdg#include <sys/kernel.h> 481541Srgrimes#include <sys/proc.h> 491541Srgrimes#include <sys/filedesc.h> 501541Srgrimes#include <sys/file.h> 511541Srgrimes#include <sys/vnode.h> 521541Srgrimes#include <sys/mount.h> 531541Srgrimes#include <sys/malloc.h> 541541Srgrimes#include <sys/socket.h> 551541Srgrimes#include <sys/socketvar.h> 561541Srgrimes#include <sys/protosw.h> 571541Srgrimes#include <sys/domain.h> 581541Srgrimes#include <miscfs/portal/portal.h> 591541Srgrimes 6030354Sphkstatic MALLOC_DEFINE(M_PORTALFSMNT, "PORTAL mount", "PORTAL mount structure"); 6130354Sphk 6212769Sphkstatic int portal_mount __P((struct mount *mp, char *path, caddr_t data, 6312335Sbde struct nameidata *ndp, struct proc *p)); 6412769Sphkstatic int portal_unmount __P((struct mount *mp, int mntflags, 6512335Sbde struct proc *p)); 6612769Sphkstatic int portal_root __P((struct mount *mp, struct vnode **vpp)); 6712769Sphkstatic int portal_statfs __P((struct mount *mp, struct statfs *sbp, 6812335Sbde struct proc *p)); 6912335Sbde 701541Srgrimes/* 711541Srgrimes * Mount the per-process file descriptors (/dev/fd) 721541Srgrimes */ 7312769Sphkstatic int 741541Srgrimesportal_mount(mp, path, data, ndp, p) 751541Srgrimes struct mount *mp; 761541Srgrimes char *path; 771541Srgrimes caddr_t data; 781541Srgrimes struct nameidata *ndp; 791541Srgrimes struct proc *p; 801541Srgrimes{ 811541Srgrimes struct file *fp; 821541Srgrimes struct portal_args args; 831541Srgrimes struct portalmount *fmp; 841541Srgrimes struct socket *so; 851541Srgrimes struct vnode *rvp; 8616312Sdg struct portalnode *pn; 871541Srgrimes u_int size; 881541Srgrimes int error; 891541Srgrimes 901541Srgrimes /* 911541Srgrimes * Update is a no-op 921541Srgrimes */ 931541Srgrimes if (mp->mnt_flag & MNT_UPDATE) 941541Srgrimes return (EOPNOTSUPP); 951541Srgrimes 963496Sphk error = copyin(data, (caddr_t) &args, sizeof(struct portal_args)); 973496Sphk if (error) 981541Srgrimes return (error); 991541Srgrimes 10069149Sjlemon error = holdsock(p->p_fd, args.pa_socket, &fp); 1013496Sphk if (error) 1021541Srgrimes return (error); 1031541Srgrimes so = (struct socket *) fp->f_data; 10469149Sjlemon if (so->so_proto->pr_domain->dom_family != AF_UNIX) { 10569149Sjlemon fdrop(fp, p); 1061541Srgrimes return (ESOCKTNOSUPPORT); 10769149Sjlemon } 1081541Srgrimes 10916312Sdg MALLOC(pn, struct portalnode *, sizeof(struct portalnode), 11016312Sdg M_TEMP, M_WAITOK); 11116312Sdg 11216312Sdg MALLOC(fmp, struct portalmount *, sizeof(struct portalmount), 11330354Sphk M_PORTALFSMNT, M_WAITOK); /* XXX */ 11416312Sdg 1151541Srgrimes error = getnewvnode(VT_PORTAL, mp, portal_vnodeop_p, &rvp); /* XXX */ 11616312Sdg if (error) { 11730354Sphk FREE(fmp, M_PORTALFSMNT); 11816312Sdg FREE(pn, M_TEMP); 11969149Sjlemon fdrop(fp, p); 1201541Srgrimes return (error); 12116312Sdg } 1221541Srgrimes 12316312Sdg rvp->v_data = pn; 1241541Srgrimes rvp->v_type = VDIR; 1251541Srgrimes rvp->v_flag |= VROOT; 1261541Srgrimes VTOPORTAL(rvp)->pt_arg = 0; 1271541Srgrimes VTOPORTAL(rvp)->pt_size = 0; 1281541Srgrimes VTOPORTAL(rvp)->pt_fileid = PORTAL_ROOTFILEID; 1291541Srgrimes fmp->pm_root = rvp; 1301541Srgrimes fmp->pm_server = fp; fp->f_count++; 1311541Srgrimes 1321541Srgrimes mp->mnt_flag |= MNT_LOCAL; 1331541Srgrimes mp->mnt_data = (qaddr_t) fmp; 13422521Sdyson vfs_getnewfsid(mp); 1351541Srgrimes 1361541Srgrimes (void)copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); 1371541Srgrimes bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); 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