portal_vfsops.c revision 50477
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 50477 1999-08-28 01:08:13Z peter $ 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 6222579Smppstatic int portal_init __P((struct vfsconf *)); 6312769Sphkstatic int portal_mount __P((struct mount *mp, char *path, caddr_t data, 6412335Sbde struct nameidata *ndp, struct proc *p)); 6512769Sphkstatic int portal_start __P((struct mount *mp, int flags, 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 7212769Sphkstatic int 7322521Sdysonportal_init(vfsp) 7422521Sdyson struct vfsconf *vfsp; 751541Srgrimes{ 761541Srgrimes 771541Srgrimes return (0); 781541Srgrimes} 791541Srgrimes 801541Srgrimes/* 811541Srgrimes * Mount the per-process file descriptors (/dev/fd) 821541Srgrimes */ 8312769Sphkstatic int 841541Srgrimesportal_mount(mp, path, data, ndp, p) 851541Srgrimes struct mount *mp; 861541Srgrimes char *path; 871541Srgrimes caddr_t data; 881541Srgrimes struct nameidata *ndp; 891541Srgrimes struct proc *p; 901541Srgrimes{ 911541Srgrimes struct file *fp; 921541Srgrimes struct portal_args args; 931541Srgrimes struct portalmount *fmp; 941541Srgrimes struct socket *so; 951541Srgrimes struct vnode *rvp; 9616312Sdg struct portalnode *pn; 971541Srgrimes u_int size; 981541Srgrimes int error; 991541Srgrimes 1001541Srgrimes /* 1011541Srgrimes * Update is a no-op 1021541Srgrimes */ 1031541Srgrimes if (mp->mnt_flag & MNT_UPDATE) 1041541Srgrimes return (EOPNOTSUPP); 1051541Srgrimes 1063496Sphk error = copyin(data, (caddr_t) &args, sizeof(struct portal_args)); 1073496Sphk if (error) 1081541Srgrimes return (error); 1091541Srgrimes 1103496Sphk error = getsock(p->p_fd, args.pa_socket, &fp); 1113496Sphk if (error) 1121541Srgrimes return (error); 1131541Srgrimes so = (struct socket *) fp->f_data; 1141541Srgrimes if (so->so_proto->pr_domain->dom_family != AF_UNIX) 1151541Srgrimes return (ESOCKTNOSUPPORT); 1161541Srgrimes 11716312Sdg MALLOC(pn, struct portalnode *, sizeof(struct portalnode), 11816312Sdg M_TEMP, M_WAITOK); 11916312Sdg 12016312Sdg MALLOC(fmp, struct portalmount *, sizeof(struct portalmount), 12130354Sphk M_PORTALFSMNT, M_WAITOK); /* XXX */ 12216312Sdg 1231541Srgrimes error = getnewvnode(VT_PORTAL, mp, portal_vnodeop_p, &rvp); /* XXX */ 12416312Sdg if (error) { 12530354Sphk FREE(fmp, M_PORTALFSMNT); 12616312Sdg FREE(pn, M_TEMP); 1271541Srgrimes return (error); 12816312Sdg } 1291541Srgrimes 13016312Sdg rvp->v_data = pn; 1311541Srgrimes rvp->v_type = VDIR; 1321541Srgrimes rvp->v_flag |= VROOT; 1331541Srgrimes VTOPORTAL(rvp)->pt_arg = 0; 1341541Srgrimes VTOPORTAL(rvp)->pt_size = 0; 1351541Srgrimes VTOPORTAL(rvp)->pt_fileid = PORTAL_ROOTFILEID; 1361541Srgrimes fmp->pm_root = rvp; 1371541Srgrimes fmp->pm_server = fp; fp->f_count++; 1381541Srgrimes 1391541Srgrimes mp->mnt_flag |= MNT_LOCAL; 1401541Srgrimes mp->mnt_data = (qaddr_t) fmp; 14122521Sdyson vfs_getnewfsid(mp); 1421541Srgrimes 1431541Srgrimes (void)copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); 1441541Srgrimes bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); 1451541Srgrimes (void)copyinstr(args.pa_config, 1461541Srgrimes mp->mnt_stat.f_mntfromname, MNAMELEN - 1, &size); 1471541Srgrimes bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 1481541Srgrimes 1491541Srgrimes#ifdef notdef 1501541Srgrimes bzero(mp->mnt_stat.f_mntfromname, MNAMELEN); 1511541Srgrimes bcopy("portal", mp->mnt_stat.f_mntfromname, sizeof("portal")); 1521541Srgrimes#endif 1531541Srgrimes 15432150Sbde (void)portal_statfs(mp, &mp->mnt_stat, p); 1551541Srgrimes return (0); 1561541Srgrimes} 1571541Srgrimes 15812769Sphkstatic int 1591541Srgrimesportal_start(mp, flags, p) 1601541Srgrimes struct mount *mp; 1611541Srgrimes int flags; 1621541Srgrimes struct proc *p; 1631541Srgrimes{ 1641541Srgrimes 1651541Srgrimes return (0); 1661541Srgrimes} 1671541Srgrimes 16812769Sphkstatic int 1691541Srgrimesportal_unmount(mp, mntflags, p) 1701541Srgrimes struct mount *mp; 1711541Srgrimes int mntflags; 1721541Srgrimes struct proc *p; 1731541Srgrimes{ 1741541Srgrimes struct vnode *rootvp = VFSTOPORTAL(mp)->pm_root; 1751541Srgrimes int error, flags = 0; 1761541Srgrimes 1771541Srgrimes 17822521Sdyson if (mntflags & MNT_FORCE) 1791541Srgrimes flags |= FORCECLOSE; 1801541Srgrimes 1811541Srgrimes /* 1821541Srgrimes * Clear out buffer cache. I don't think we 1831541Srgrimes * ever get anything cached at this level at the 1841541Srgrimes * moment, but who knows... 1851541Srgrimes */ 1861541Srgrimes#ifdef notyet 1878876Srgrimes mntflushbuf(mp, 0); 1881541Srgrimes if (mntinvalbuf(mp, 1)) 1891541Srgrimes return (EBUSY); 1901541Srgrimes#endif 1911541Srgrimes if (rootvp->v_usecount > 1) 1921541Srgrimes return (EBUSY); 1933496Sphk error = vflush(mp, rootvp, flags); 1943496Sphk if (error) 1951541Srgrimes return (error); 1961541Srgrimes 1971541Srgrimes /* 1981541Srgrimes * Release reference on underlying root vnode 1991541Srgrimes */ 2001541Srgrimes vrele(rootvp); 2011541Srgrimes /* 2021541Srgrimes * And blow it away for future re-use 2031541Srgrimes */ 2041541Srgrimes vgone(rootvp); 2051541Srgrimes /* 2061541Srgrimes * Shutdown the socket. This will cause the select in the 2071541Srgrimes * daemon to wake up, and then the accept will get ECONNABORTED 2081541Srgrimes * which it interprets as a request to go and bury itself. 2091541Srgrimes */ 2101541Srgrimes soshutdown((struct socket *) VFSTOPORTAL(mp)->pm_server->f_data, 2); 2111541Srgrimes /* 2121541Srgrimes * Discard reference to underlying file. Must call closef because 2131541Srgrimes * this may be the last reference. 2141541Srgrimes */ 2151541Srgrimes closef(VFSTOPORTAL(mp)->pm_server, (struct proc *) 0); 2161541Srgrimes /* 2171541Srgrimes * Finally, throw away the portalmount structure 2181541Srgrimes */ 21930354Sphk free(mp->mnt_data, M_PORTALFSMNT); /* XXX */ 2201541Srgrimes mp->mnt_data = 0; 2211541Srgrimes return (0); 2221541Srgrimes} 2231541Srgrimes 22412769Sphkstatic int 2251541Srgrimesportal_root(mp, vpp) 2261541Srgrimes struct mount *mp; 2271541Srgrimes struct vnode **vpp; 2281541Srgrimes{ 22922521Sdyson struct proc *p = curproc; /* XXX */ 2301541Srgrimes struct vnode *vp; 2311541Srgrimes 2321541Srgrimes /* 2331541Srgrimes * Return locked reference to root. 2341541Srgrimes */ 2351541Srgrimes vp = VFSTOPORTAL(mp)->pm_root; 2361541Srgrimes VREF(vp); 23722521Sdyson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 2381541Srgrimes *vpp = vp; 2391541Srgrimes return (0); 2401541Srgrimes} 2411541Srgrimes 24212769Sphkstatic int 2431541Srgrimesportal_statfs(mp, sbp, p) 2441541Srgrimes struct mount *mp; 2451541Srgrimes struct statfs *sbp; 2461541Srgrimes struct proc *p; 2471541Srgrimes{ 2481541Srgrimes 2491541Srgrimes sbp->f_flags = 0; 2501541Srgrimes sbp->f_bsize = DEV_BSIZE; 2511541Srgrimes sbp->f_iosize = DEV_BSIZE; 2521541Srgrimes sbp->f_blocks = 2; /* 1K to keep df happy */ 2531541Srgrimes sbp->f_bfree = 0; 2541541Srgrimes sbp->f_bavail = 0; 2551541Srgrimes sbp->f_files = 1; /* Allow for "." */ 2561541Srgrimes sbp->f_ffree = 0; /* See comments above */ 2571541Srgrimes if (sbp != &mp->mnt_stat) { 25822521Sdyson sbp->f_type = mp->mnt_vfc->vfc_typenum; 2591541Srgrimes bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 2601541Srgrimes bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 2611541Srgrimes bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 2621541Srgrimes } 2631541Srgrimes return (0); 2641541Srgrimes} 2651541Srgrimes 26622521Sdyson#define portal_fhtovp ((int (*) __P((struct mount *, struct fid *, \ 26728270Swollman struct sockaddr *, struct vnode **, int *, struct ucred **)))eopnotsupp) 26822521Sdyson#define portal_quotactl ((int (*) __P((struct mount *, int, uid_t, caddr_t, \ 26922521Sdyson struct proc *)))eopnotsupp) 27022521Sdyson#define portal_sync ((int (*) __P((struct mount *, int, struct ucred *, \ 27122521Sdyson struct proc *)))nullop) 27222521Sdyson#define portal_sysctl ((int (*) __P((int *, u_int, void *, size_t *, void *, \ 27322521Sdyson size_t, struct proc *)))eopnotsupp) 27422521Sdyson#define portal_vget ((int (*) __P((struct mount *, ino_t, struct vnode **))) \ 27522521Sdyson eopnotsupp) 27622521Sdyson#define portal_vptofh ((int (*) __P((struct vnode *, struct fid *)))eopnotsupp) 2771541Srgrimes 27812769Sphkstatic struct vfsops portal_vfsops = { 2791541Srgrimes portal_mount, 2801541Srgrimes portal_start, 2811541Srgrimes portal_unmount, 2821541Srgrimes portal_root, 2831541Srgrimes portal_quotactl, 2841541Srgrimes portal_statfs, 2851541Srgrimes portal_sync, 2861541Srgrimes portal_vget, 2871541Srgrimes portal_fhtovp, 2881541Srgrimes portal_vptofh, 2891541Srgrimes portal_init, 2901541Srgrimes}; 2912946Swollman 29238909SbdeVFS_SET(portal_vfsops, portal, VFCF_SYNTHETIC); 293