portal_vfsops.c revision 116271
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 116271 2003-06-12 20:48:38Z phk $ 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 65116271Sphkstatic vfs_mount_t portal_mount; 66116271Sphkstatic vfs_unmount_t portal_unmount; 67116271Sphkstatic vfs_root_t portal_root; 68116271Sphkstatic vfs_statfs_t portal_statfs; 6912335Sbde 701541Srgrimes/* 711541Srgrimes * Mount the per-process file descriptors (/dev/fd) 721541Srgrimes */ 7312769Sphkstatic int 7483366Sjulianportal_mount(mp, path, data, ndp, td) 751541Srgrimes struct mount *mp; 761541Srgrimes char *path; 771541Srgrimes caddr_t data; 781541Srgrimes struct nameidata *ndp; 7983366Sjulian struct thread *td; 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; 87104565Smux size_t 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 10086872Sdillon if ((error = fget(td, args.pa_socket, &fp)) != 0) 1011541Srgrimes return (error); 10286872Sdillon if (fp->f_type != DTYPE_SOCKET) { 10386872Sdillon fdrop(fp, td); 10486872Sdillon return(ENOTSOCK); 10586872Sdillon } 106109153Sdillon so = fp->f_data; /* XXX race against userland */ 10769149Sjlemon if (so->so_proto->pr_domain->dom_family != AF_UNIX) { 10883366Sjulian fdrop(fp, td); 1091541Srgrimes return (ESOCKTNOSUPPORT); 11069149Sjlemon } 1111541Srgrimes 11216312Sdg MALLOC(pn, struct portalnode *, sizeof(struct portalnode), 113111119Simp M_TEMP, M_WAITOK); 11416312Sdg 11516312Sdg MALLOC(fmp, struct portalmount *, sizeof(struct portalmount), 116111119Simp M_PORTALFSMNT, M_WAITOK); /* XXX */ 11716312Sdg 118103314Snjl error = getnewvnode("portal", mp, portal_vnodeop_p, &rvp); /* XXX */ 11916312Sdg if (error) { 12030354Sphk FREE(fmp, M_PORTALFSMNT); 12116312Sdg FREE(pn, M_TEMP); 12283366Sjulian fdrop(fp, td); 1231541Srgrimes return (error); 12416312Sdg } 1251541Srgrimes 12616312Sdg rvp->v_data = pn; 1271541Srgrimes rvp->v_type = VDIR; 128101308Sjeff rvp->v_vflag |= VV_ROOT; 1291541Srgrimes VTOPORTAL(rvp)->pt_arg = 0; 1301541Srgrimes VTOPORTAL(rvp)->pt_size = 0; 1311541Srgrimes VTOPORTAL(rvp)->pt_fileid = PORTAL_ROOTFILEID; 1321541Srgrimes fmp->pm_root = rvp; 13389306Salfred fhold(fp); 13489306Salfred fmp->pm_server = fp; 1351541Srgrimes 1361541Srgrimes mp->mnt_flag |= MNT_LOCAL; 1371541Srgrimes mp->mnt_data = (qaddr_t) fmp; 13822521Sdyson vfs_getnewfsid(mp); 1391541Srgrimes 1401541Srgrimes (void)copyinstr(args.pa_config, 1411541Srgrimes mp->mnt_stat.f_mntfromname, MNAMELEN - 1, &size); 1421541Srgrimes bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 1431541Srgrimes 1441541Srgrimes#ifdef notdef 1451541Srgrimes bzero(mp->mnt_stat.f_mntfromname, MNAMELEN); 1461541Srgrimes bcopy("portal", mp->mnt_stat.f_mntfromname, sizeof("portal")); 1471541Srgrimes#endif 1481541Srgrimes 14983366Sjulian (void)portal_statfs(mp, &mp->mnt_stat, td); 15083366Sjulian fdrop(fp, td); 1511541Srgrimes return (0); 1521541Srgrimes} 1531541Srgrimes 15412769Sphkstatic int 15583366Sjulianportal_unmount(mp, mntflags, td) 1561541Srgrimes struct mount *mp; 1571541Srgrimes int mntflags; 15883366Sjulian struct thread *td; 1591541Srgrimes{ 1601541Srgrimes int error, flags = 0; 1611541Srgrimes 1621541Srgrimes 16322521Sdyson if (mntflags & MNT_FORCE) 1641541Srgrimes flags |= FORCECLOSE; 1651541Srgrimes 1661541Srgrimes /* 1671541Srgrimes * Clear out buffer cache. I don't think we 1681541Srgrimes * ever get anything cached at this level at the 1691541Srgrimes * moment, but who knows... 1701541Srgrimes */ 1711541Srgrimes#ifdef notyet 1728876Srgrimes mntflushbuf(mp, 0); 1731541Srgrimes if (mntinvalbuf(mp, 1)) 1741541Srgrimes return (EBUSY); 1751541Srgrimes#endif 17676688Siedowse /* There is 1 extra root vnode reference (pm_root). */ 17776688Siedowse error = vflush(mp, 1, flags); 1783496Sphk if (error) 1791541Srgrimes return (error); 1801541Srgrimes 1811541Srgrimes /* 1821541Srgrimes * Shutdown the socket. This will cause the select in the 1831541Srgrimes * daemon to wake up, and then the accept will get ECONNABORTED 1841541Srgrimes * which it interprets as a request to go and bury itself. 1851541Srgrimes */ 186109153Sdillon soshutdown(VFSTOPORTAL(mp)->pm_server->f_data, 2); 1871541Srgrimes /* 1881541Srgrimes * Discard reference to underlying file. Must call closef because 1891541Srgrimes * this may be the last reference. 1901541Srgrimes */ 19183366Sjulian closef(VFSTOPORTAL(mp)->pm_server, (struct thread *) 0); 1921541Srgrimes /* 1931541Srgrimes * Finally, throw away the portalmount structure 1941541Srgrimes */ 19530354Sphk free(mp->mnt_data, M_PORTALFSMNT); /* XXX */ 1961541Srgrimes mp->mnt_data = 0; 1971541Srgrimes return (0); 1981541Srgrimes} 1991541Srgrimes 20012769Sphkstatic int 2011541Srgrimesportal_root(mp, vpp) 2021541Srgrimes struct mount *mp; 2031541Srgrimes struct vnode **vpp; 2041541Srgrimes{ 20583366Sjulian struct thread *td = curthread; /* XXX */ 2061541Srgrimes struct vnode *vp; 2071541Srgrimes 2081541Srgrimes /* 2091541Srgrimes * Return locked reference to root. 2101541Srgrimes */ 2111541Srgrimes vp = VFSTOPORTAL(mp)->pm_root; 2121541Srgrimes VREF(vp); 21383366Sjulian vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2141541Srgrimes *vpp = vp; 2151541Srgrimes return (0); 2161541Srgrimes} 2171541Srgrimes 21812769Sphkstatic int 21983366Sjulianportal_statfs(mp, sbp, td) 2201541Srgrimes struct mount *mp; 2211541Srgrimes struct statfs *sbp; 22283366Sjulian struct thread *td; 2231541Srgrimes{ 2241541Srgrimes 2251541Srgrimes sbp->f_flags = 0; 2261541Srgrimes sbp->f_bsize = DEV_BSIZE; 2271541Srgrimes sbp->f_iosize = DEV_BSIZE; 2281541Srgrimes sbp->f_blocks = 2; /* 1K to keep df happy */ 2291541Srgrimes sbp->f_bfree = 0; 2301541Srgrimes sbp->f_bavail = 0; 2311541Srgrimes sbp->f_files = 1; /* Allow for "." */ 2321541Srgrimes sbp->f_ffree = 0; /* See comments above */ 2331541Srgrimes if (sbp != &mp->mnt_stat) { 23422521Sdyson sbp->f_type = mp->mnt_vfc->vfc_typenum; 2351541Srgrimes bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 2361541Srgrimes bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 2371541Srgrimes bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 2381541Srgrimes } 2391541Srgrimes return (0); 2401541Srgrimes} 2411541Srgrimes 24212769Sphkstatic struct vfsops portal_vfsops = { 243116271Sphk .vfs_mount = portal_mount, 244116271Sphk .vfs_root = portal_root, 245116271Sphk .vfs_statfs = portal_statfs, 246116271Sphk .vfs_unmount = portal_unmount, 2471541Srgrimes}; 2482946Swollman 24977133SruVFS_SET(portal_vfsops, portalfs, VFCF_SYNTHETIC); 250