portal_vfsops.c revision 22521
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 * 3821673Sjkh * $FreeBSD: head/sys/fs/portalfs/portal_vfsops.c 22521 1997-02-10 02:22:35Z dyson $ 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/time.h> 491541Srgrimes#include <sys/types.h> 501541Srgrimes#include <sys/proc.h> 511541Srgrimes#include <sys/filedesc.h> 521541Srgrimes#include <sys/file.h> 531541Srgrimes#include <sys/vnode.h> 541541Srgrimes#include <sys/mount.h> 551541Srgrimes#include <sys/namei.h> 561541Srgrimes#include <sys/malloc.h> 571541Srgrimes#include <sys/mbuf.h> 581541Srgrimes#include <sys/socket.h> 591541Srgrimes#include <sys/socketvar.h> 601541Srgrimes#include <sys/protosw.h> 611541Srgrimes#include <sys/domain.h> 621541Srgrimes#include <sys/un.h> 631541Srgrimes#include <miscfs/portal/portal.h> 641541Srgrimes 6512769Sphkstatic int portal_mount __P((struct mount *mp, char *path, caddr_t data, 6612335Sbde struct nameidata *ndp, struct proc *p)); 6712769Sphkstatic int portal_start __P((struct mount *mp, int flags, struct proc *p)); 6812769Sphkstatic int portal_unmount __P((struct mount *mp, int mntflags, 6912335Sbde struct proc *p)); 7012769Sphkstatic int portal_root __P((struct mount *mp, struct vnode **vpp)); 7112769Sphkstatic int portal_statfs __P((struct mount *mp, struct statfs *sbp, 7212335Sbde struct proc *p)); 7312335Sbde 7412769Sphkstatic int 7522521Sdysonportal_init(vfsp) 7622521Sdyson struct vfsconf *vfsp; 771541Srgrimes{ 781541Srgrimes 791541Srgrimes return (0); 801541Srgrimes} 811541Srgrimes 821541Srgrimes/* 831541Srgrimes * Mount the per-process file descriptors (/dev/fd) 841541Srgrimes */ 8512769Sphkstatic int 861541Srgrimesportal_mount(mp, path, data, ndp, p) 871541Srgrimes struct mount *mp; 881541Srgrimes char *path; 891541Srgrimes caddr_t data; 901541Srgrimes struct nameidata *ndp; 911541Srgrimes struct proc *p; 921541Srgrimes{ 931541Srgrimes struct file *fp; 941541Srgrimes struct portal_args args; 951541Srgrimes struct portalmount *fmp; 961541Srgrimes struct socket *so; 971541Srgrimes struct vnode *rvp; 9816312Sdg struct portalnode *pn; 991541Srgrimes u_int size; 1001541Srgrimes int error; 1011541Srgrimes 1021541Srgrimes /* 1031541Srgrimes * Update is a no-op 1041541Srgrimes */ 1051541Srgrimes if (mp->mnt_flag & MNT_UPDATE) 1061541Srgrimes return (EOPNOTSUPP); 1071541Srgrimes 1083496Sphk error = copyin(data, (caddr_t) &args, sizeof(struct portal_args)); 1093496Sphk if (error) 1101541Srgrimes return (error); 1111541Srgrimes 1123496Sphk error = getsock(p->p_fd, args.pa_socket, &fp); 1133496Sphk if (error) 1141541Srgrimes return (error); 1151541Srgrimes so = (struct socket *) fp->f_data; 1161541Srgrimes if (so->so_proto->pr_domain->dom_family != AF_UNIX) 1171541Srgrimes return (ESOCKTNOSUPPORT); 1181541Srgrimes 11916312Sdg MALLOC(pn, struct portalnode *, sizeof(struct portalnode), 12016312Sdg M_TEMP, M_WAITOK); 12116312Sdg 12216312Sdg MALLOC(fmp, struct portalmount *, sizeof(struct portalmount), 12316312Sdg M_UFSMNT, M_WAITOK); /* XXX */ 12416312Sdg 1251541Srgrimes error = getnewvnode(VT_PORTAL, mp, portal_vnodeop_p, &rvp); /* XXX */ 12616312Sdg if (error) { 12716312Sdg FREE(fmp, M_UFSMNT); 12816312Sdg FREE(pn, M_TEMP); 1291541Srgrimes return (error); 13016312Sdg } 1311541Srgrimes 13216312Sdg rvp->v_data = pn; 1331541Srgrimes rvp->v_type = VDIR; 1341541Srgrimes rvp->v_flag |= VROOT; 1351541Srgrimes VTOPORTAL(rvp)->pt_arg = 0; 1361541Srgrimes VTOPORTAL(rvp)->pt_size = 0; 1371541Srgrimes VTOPORTAL(rvp)->pt_fileid = PORTAL_ROOTFILEID; 1381541Srgrimes fmp->pm_root = rvp; 1391541Srgrimes fmp->pm_server = fp; fp->f_count++; 1401541Srgrimes 1411541Srgrimes mp->mnt_flag |= MNT_LOCAL; 1421541Srgrimes mp->mnt_data = (qaddr_t) fmp; 14322521Sdyson vfs_getnewfsid(mp); 1441541Srgrimes 1451541Srgrimes (void)copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); 1461541Srgrimes bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); 1471541Srgrimes (void)copyinstr(args.pa_config, 1481541Srgrimes mp->mnt_stat.f_mntfromname, MNAMELEN - 1, &size); 1491541Srgrimes bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 1501541Srgrimes 1511541Srgrimes#ifdef notdef 1521541Srgrimes bzero(mp->mnt_stat.f_mntfromname, MNAMELEN); 1531541Srgrimes bcopy("portal", mp->mnt_stat.f_mntfromname, sizeof("portal")); 1541541Srgrimes#endif 1551541Srgrimes 1561541Srgrimes return (0); 1571541Srgrimes} 1581541Srgrimes 15912769Sphkstatic int 1601541Srgrimesportal_start(mp, flags, p) 1611541Srgrimes struct mount *mp; 1621541Srgrimes int flags; 1631541Srgrimes struct proc *p; 1641541Srgrimes{ 1651541Srgrimes 1661541Srgrimes return (0); 1671541Srgrimes} 1681541Srgrimes 16912769Sphkstatic int 1701541Srgrimesportal_unmount(mp, mntflags, p) 1711541Srgrimes struct mount *mp; 1721541Srgrimes int mntflags; 1731541Srgrimes struct proc *p; 1741541Srgrimes{ 1751541Srgrimes struct vnode *rootvp = VFSTOPORTAL(mp)->pm_root; 1761541Srgrimes int error, flags = 0; 1771541Srgrimes 1781541Srgrimes 17922521Sdyson if (mntflags & MNT_FORCE) 1801541Srgrimes flags |= FORCECLOSE; 1811541Srgrimes 1821541Srgrimes /* 1831541Srgrimes * Clear out buffer cache. I don't think we 1841541Srgrimes * ever get anything cached at this level at the 1851541Srgrimes * moment, but who knows... 1861541Srgrimes */ 1871541Srgrimes#ifdef notyet 1888876Srgrimes mntflushbuf(mp, 0); 1891541Srgrimes if (mntinvalbuf(mp, 1)) 1901541Srgrimes return (EBUSY); 1911541Srgrimes#endif 1921541Srgrimes if (rootvp->v_usecount > 1) 1931541Srgrimes return (EBUSY); 1943496Sphk error = vflush(mp, rootvp, flags); 1953496Sphk if (error) 1961541Srgrimes return (error); 1971541Srgrimes 1981541Srgrimes /* 1991541Srgrimes * Release reference on underlying root vnode 2001541Srgrimes */ 2011541Srgrimes vrele(rootvp); 2021541Srgrimes /* 2031541Srgrimes * And blow it away for future re-use 2041541Srgrimes */ 2051541Srgrimes vgone(rootvp); 2061541Srgrimes /* 2071541Srgrimes * Shutdown the socket. This will cause the select in the 2081541Srgrimes * daemon to wake up, and then the accept will get ECONNABORTED 2091541Srgrimes * which it interprets as a request to go and bury itself. 2101541Srgrimes */ 2111541Srgrimes soshutdown((struct socket *) VFSTOPORTAL(mp)->pm_server->f_data, 2); 2121541Srgrimes /* 2131541Srgrimes * Discard reference to underlying file. Must call closef because 2141541Srgrimes * this may be the last reference. 2151541Srgrimes */ 2161541Srgrimes closef(VFSTOPORTAL(mp)->pm_server, (struct proc *) 0); 2171541Srgrimes /* 2181541Srgrimes * Finally, throw away the portalmount structure 2191541Srgrimes */ 2201541Srgrimes free(mp->mnt_data, M_UFSMNT); /* XXX */ 2211541Srgrimes mp->mnt_data = 0; 2221541Srgrimes return (0); 2231541Srgrimes} 2241541Srgrimes 22512769Sphkstatic int 2261541Srgrimesportal_root(mp, vpp) 2271541Srgrimes struct mount *mp; 2281541Srgrimes struct vnode **vpp; 2291541Srgrimes{ 23022521Sdyson struct proc *p = curproc; /* XXX */ 2311541Srgrimes struct vnode *vp; 2321541Srgrimes 2331541Srgrimes /* 2341541Srgrimes * Return locked reference to root. 2351541Srgrimes */ 2361541Srgrimes vp = VFSTOPORTAL(mp)->pm_root; 2371541Srgrimes VREF(vp); 23822521Sdyson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 2391541Srgrimes *vpp = vp; 2401541Srgrimes return (0); 2411541Srgrimes} 2421541Srgrimes 24312769Sphkstatic int 2441541Srgrimesportal_statfs(mp, sbp, p) 2451541Srgrimes struct mount *mp; 2461541Srgrimes struct statfs *sbp; 2471541Srgrimes struct proc *p; 2481541Srgrimes{ 2491541Srgrimes 2501541Srgrimes sbp->f_flags = 0; 2511541Srgrimes sbp->f_bsize = DEV_BSIZE; 2521541Srgrimes sbp->f_iosize = DEV_BSIZE; 2531541Srgrimes sbp->f_blocks = 2; /* 1K to keep df happy */ 2541541Srgrimes sbp->f_bfree = 0; 2551541Srgrimes sbp->f_bavail = 0; 2561541Srgrimes sbp->f_files = 1; /* Allow for "." */ 2571541Srgrimes sbp->f_ffree = 0; /* See comments above */ 2581541Srgrimes if (sbp != &mp->mnt_stat) { 25922521Sdyson sbp->f_type = mp->mnt_vfc->vfc_typenum; 2601541Srgrimes bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 2611541Srgrimes bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 2621541Srgrimes bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 2631541Srgrimes } 2641541Srgrimes return (0); 2651541Srgrimes} 2661541Srgrimes 26722521Sdyson#define portal_fhtovp ((int (*) __P((struct mount *, struct fid *, \ 26822521Sdyson struct mbuf *, struct vnode **, int *, struct ucred **)))eopnotsupp) 26922521Sdyson#define portal_quotactl ((int (*) __P((struct mount *, int, uid_t, caddr_t, \ 27022521Sdyson struct proc *)))eopnotsupp) 27122521Sdyson#define portal_sync ((int (*) __P((struct mount *, int, struct ucred *, \ 27222521Sdyson struct proc *)))nullop) 27322521Sdyson#define portal_sysctl ((int (*) __P((int *, u_int, void *, size_t *, void *, \ 27422521Sdyson size_t, struct proc *)))eopnotsupp) 27522521Sdyson#define portal_vget ((int (*) __P((struct mount *, ino_t, struct vnode **))) \ 27622521Sdyson eopnotsupp) 27722521Sdyson#define portal_vptofh ((int (*) __P((struct vnode *, struct fid *)))eopnotsupp) 2781541Srgrimes 27912769Sphkstatic struct vfsops portal_vfsops = { 2801541Srgrimes portal_mount, 2811541Srgrimes portal_start, 2821541Srgrimes portal_unmount, 2831541Srgrimes portal_root, 2841541Srgrimes portal_quotactl, 2851541Srgrimes portal_statfs, 2861541Srgrimes portal_sync, 2871541Srgrimes portal_vget, 2881541Srgrimes portal_fhtovp, 2891541Srgrimes portal_vptofh, 2901541Srgrimes portal_init, 2911541Srgrimes}; 2922946Swollman 2937095SwollmanVFS_SET(portal_vfsops, portal, MOUNT_PORTAL, VFCF_SYNTHETIC); 294