153845Spendry /* 263246Sbostic * Copyright (c) 1992, 1993 363246Sbostic * The Regents of the University of California. All rights reserved. 453845Spendry * 553845Spendry * This code is derived from software donated to Berkeley by 653845Spendry * Jan-Simon Pendry. 753845Spendry * 853845Spendry * %sccs.include.redist.c% 953845Spendry * 10*68428Smckusick * @(#)portal_vfsops.c 8.7 (Berkeley) 02/23/95 1153845Spendry * 1253845Spendry * $Id: portal_vfsops.c,v 1.5 1992/05/30 10:25:27 jsp Exp jsp $ 1353845Spendry */ 1453845Spendry 1553845Spendry /* 1653845Spendry * Portal Filesystem 1753845Spendry */ 1853845Spendry 1953845Spendry #include <sys/param.h> 2053845Spendry #include <sys/systm.h> 2153845Spendry #include <sys/time.h> 2253845Spendry #include <sys/types.h> 2353845Spendry #include <sys/proc.h> 2453845Spendry #include <sys/filedesc.h> 2553845Spendry #include <sys/file.h> 2653845Spendry #include <sys/vnode.h> 2753845Spendry #include <sys/mount.h> 2853845Spendry #include <sys/namei.h> 2953845Spendry #include <sys/malloc.h> 3053845Spendry #include <sys/mbuf.h> 3153845Spendry #include <sys/socket.h> 3253845Spendry #include <sys/socketvar.h> 3353845Spendry #include <sys/protosw.h> 3453845Spendry #include <sys/domain.h> 3553845Spendry #include <sys/un.h> 3655027Smckusick #include <miscfs/portal/portal.h> 3753845Spendry 3865449Sbostic int 3965449Sbostic portal_init() 4053845Spendry { 4155027Smckusick 4265516Spendry return (0); 4353845Spendry } 4453845Spendry 4553845Spendry /* 4653845Spendry * Mount the per-process file descriptors (/dev/fd) 4753845Spendry */ 4865516Spendry int 4953845Spendry portal_mount(mp, path, data, ndp, p) 5053845Spendry struct mount *mp; 5153845Spendry char *path; 5253845Spendry caddr_t data; 5353845Spendry struct nameidata *ndp; 5453845Spendry struct proc *p; 5553845Spendry { 5665449Sbostic struct file *fp; 5753845Spendry struct portal_args args; 5853845Spendry struct portalmount *fmp; 5965449Sbostic struct socket *so; 6053845Spendry struct vnode *rvp; 6165449Sbostic u_int size; 6265449Sbostic int error; 6353845Spendry 6453845Spendry /* 6553845Spendry * Update is a no-op 6653845Spendry */ 6753845Spendry if (mp->mnt_flag & MNT_UPDATE) 6853845Spendry return (EOPNOTSUPP); 6953845Spendry 7053845Spendry if (error = copyin(data, (caddr_t) &args, sizeof(struct portal_args))) 7153845Spendry return (error); 7253845Spendry 7353845Spendry if (error = getsock(p->p_fd, args.pa_socket, &fp)) 7453845Spendry return (error); 7553845Spendry so = (struct socket *) fp->f_data; 7653845Spendry if (so->so_proto->pr_domain->dom_family != AF_UNIX) 7753845Spendry return (ESOCKTNOSUPPORT); 7853845Spendry 7965380Spendry error = getnewvnode(VT_PORTAL, mp, portal_vnodeop_p, &rvp); /* XXX */ 8053845Spendry if (error) 8153845Spendry return (error); 8253845Spendry MALLOC(rvp->v_data, void *, sizeof(struct portalnode), 8353845Spendry M_TEMP, M_WAITOK); 8453845Spendry 8553845Spendry fmp = (struct portalmount *) malloc(sizeof(struct portalmount), 8653845Spendry M_UFSMNT, M_WAITOK); /* XXX */ 8753845Spendry rvp->v_type = VDIR; 8853845Spendry rvp->v_flag |= VROOT; 8953845Spendry VTOPORTAL(rvp)->pt_arg = 0; 9053845Spendry VTOPORTAL(rvp)->pt_size = 0; 9153845Spendry VTOPORTAL(rvp)->pt_fileid = PORTAL_ROOTFILEID; 9253845Spendry fmp->pm_root = rvp; 9353845Spendry fmp->pm_server = fp; fp->f_count++; 9453845Spendry 9553845Spendry mp->mnt_flag |= MNT_LOCAL; 9653845Spendry mp->mnt_data = (qaddr_t) fmp; 9753845Spendry getnewfsid(mp, MOUNT_PORTAL); 9853845Spendry 9965449Sbostic (void)copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); 10053845Spendry bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); 10165449Sbostic (void)copyinstr(args.pa_config, 10265449Sbostic mp->mnt_stat.f_mntfromname, MNAMELEN - 1, &size); 10353845Spendry bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 10453845Spendry 10553845Spendry #ifdef notdef 10653845Spendry bzero(mp->mnt_stat.f_mntfromname, MNAMELEN); 10753845Spendry bcopy("portal", mp->mnt_stat.f_mntfromname, sizeof("portal")); 10853845Spendry #endif 10953845Spendry 11053845Spendry return (0); 11153845Spendry } 11253845Spendry 11365516Spendry int 11453845Spendry portal_start(mp, flags, p) 11553845Spendry struct mount *mp; 11653845Spendry int flags; 11753845Spendry struct proc *p; 11853845Spendry { 11955027Smckusick 12053845Spendry return (0); 12153845Spendry } 12253845Spendry 12365516Spendry int 12453845Spendry portal_unmount(mp, mntflags, p) 12553845Spendry struct mount *mp; 12653845Spendry int mntflags; 12753845Spendry struct proc *p; 12853845Spendry { 12953845Spendry extern int doforce; 13053845Spendry struct vnode *rootvp = VFSTOPORTAL(mp)->pm_root; 13165448Sbostic int error, flags = 0; 13253845Spendry 13353845Spendry 13453845Spendry if (mntflags & MNT_FORCE) { 13553845Spendry /* portal can never be rootfs so don't check for it */ 13653845Spendry if (!doforce) 13753845Spendry return (EINVAL); 13853845Spendry flags |= FORCECLOSE; 13953845Spendry } 14053845Spendry 14153845Spendry /* 14253845Spendry * Clear out buffer cache. I don't think we 14353845Spendry * ever get anything cached at this level at the 14453845Spendry * moment, but who knows... 14553845Spendry */ 14655027Smckusick #ifdef notyet 14753845Spendry mntflushbuf(mp, 0); 14853845Spendry if (mntinvalbuf(mp, 1)) 14953845Spendry return (EBUSY); 15054977Spendry #endif 15153845Spendry if (rootvp->v_usecount > 1) 15253845Spendry return (EBUSY); 15353845Spendry if (error = vflush(mp, rootvp, flags)) 15453845Spendry return (error); 15553845Spendry 15653845Spendry /* 15753845Spendry * Release reference on underlying root vnode 15853845Spendry */ 15953845Spendry vrele(rootvp); 16053845Spendry /* 16153845Spendry * And blow it away for future re-use 16253845Spendry */ 163*68428Smckusick VOP_REVOKE(rootvp, 0); 16453845Spendry /* 16553845Spendry * Shutdown the socket. This will cause the select in the 16653845Spendry * daemon to wake up, and then the accept will get ECONNABORTED 16753845Spendry * which it interprets as a request to go and bury itself. 16853845Spendry */ 16953845Spendry soshutdown((struct socket *) VFSTOPORTAL(mp)->pm_server->f_data, 2); 17053845Spendry /* 17153845Spendry * Discard reference to underlying file. Must call closef because 17253845Spendry * this may be the last reference. 17353845Spendry */ 17453845Spendry closef(VFSTOPORTAL(mp)->pm_server, (struct proc *) 0); 17553845Spendry /* 17653845Spendry * Finally, throw away the portalmount structure 17753845Spendry */ 17853845Spendry free(mp->mnt_data, M_UFSMNT); /* XXX */ 17953845Spendry mp->mnt_data = 0; 18055027Smckusick return (0); 18153845Spendry } 18253845Spendry 18365516Spendry int 18453845Spendry portal_root(mp, vpp) 18553845Spendry struct mount *mp; 18653845Spendry struct vnode **vpp; 18753845Spendry { 18853845Spendry struct vnode *vp; 18953845Spendry 19053845Spendry 19153845Spendry /* 19253845Spendry * Return locked reference to root. 19353845Spendry */ 19453845Spendry vp = VFSTOPORTAL(mp)->pm_root; 19553845Spendry VREF(vp); 19653845Spendry VOP_LOCK(vp); 19753845Spendry *vpp = vp; 19853845Spendry return (0); 19953845Spendry } 20053845Spendry 20165516Spendry int 20253845Spendry portal_quotactl(mp, cmd, uid, arg, p) 20353845Spendry struct mount *mp; 20453845Spendry int cmd; 20553845Spendry uid_t uid; 20653845Spendry caddr_t arg; 20753845Spendry struct proc *p; 20853845Spendry { 20955027Smckusick 21053845Spendry return (EOPNOTSUPP); 21153845Spendry } 21253845Spendry 21365516Spendry int 21453845Spendry portal_statfs(mp, sbp, p) 21553845Spendry struct mount *mp; 21653845Spendry struct statfs *sbp; 21753845Spendry struct proc *p; 21853845Spendry { 21953845Spendry 22053845Spendry sbp->f_type = MOUNT_PORTAL; 22153845Spendry sbp->f_flags = 0; 22253845Spendry sbp->f_bsize = DEV_BSIZE; 22353845Spendry sbp->f_iosize = DEV_BSIZE; 22453845Spendry sbp->f_blocks = 2; /* 1K to keep df happy */ 22553845Spendry sbp->f_bfree = 0; 22653845Spendry sbp->f_bavail = 0; 22753845Spendry sbp->f_files = 1; /* Allow for "." */ 22853845Spendry sbp->f_ffree = 0; /* See comments above */ 22953845Spendry if (sbp != &mp->mnt_stat) { 23053845Spendry bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 23153845Spendry bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 23253845Spendry bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 23353845Spendry } 23453845Spendry return (0); 23553845Spendry } 23653845Spendry 23765516Spendry int 23853845Spendry portal_sync(mp, waitfor) 23953845Spendry struct mount *mp; 24053845Spendry int waitfor; 24153845Spendry { 24255027Smckusick 24353845Spendry return (0); 24453845Spendry } 24553845Spendry 24665516Spendry int 24754977Spendry portal_vget(mp, ino, vpp) 24854977Spendry struct mount *mp; 24954977Spendry ino_t ino; 25054977Spendry struct vnode **vpp; 25154977Spendry { 25254977Spendry 25354977Spendry return (EOPNOTSUPP); 25454977Spendry } 25554977Spendry 25665516Spendry int 25753845Spendry portal_fhtovp(mp, fhp, vpp) 25853845Spendry struct mount *mp; 25953845Spendry struct fid *fhp; 26053845Spendry struct vnode **vpp; 26153845Spendry { 26255027Smckusick 26353845Spendry return (EOPNOTSUPP); 26453845Spendry } 26553845Spendry 26665516Spendry int 26753845Spendry portal_vptofh(vp, fhp) 26853845Spendry struct vnode *vp; 26953845Spendry struct fid *fhp; 27053845Spendry { 27155027Smckusick 27253845Spendry return (EOPNOTSUPP); 27353845Spendry } 27453845Spendry 27553845Spendry struct vfsops portal_vfsops = { 27653845Spendry portal_mount, 27753845Spendry portal_start, 27853845Spendry portal_unmount, 27953845Spendry portal_root, 28053845Spendry portal_quotactl, 28153845Spendry portal_statfs, 28253845Spendry portal_sync, 28354977Spendry portal_vget, 28453845Spendry portal_fhtovp, 28553845Spendry portal_vptofh, 28653845Spendry portal_init, 28753845Spendry }; 288