153845Spendry /* 263246Sbostic * Copyright (c) 1992, 1993 363246Sbostic * The Regents of the University of California. All rights reserved. 453845Spendry * All rights reserved. 553845Spendry * 653845Spendry * This code is derived from software donated to Berkeley by 753845Spendry * Jan-Simon Pendry. 853845Spendry * 953845Spendry * %sccs.include.redist.c% 1053845Spendry * 11*65380Spendry * @(#)portal_vfsops.c 8.2 (Berkeley) 01/04/94 1253845Spendry * 1353845Spendry * $Id: portal_vfsops.c,v 1.5 1992/05/30 10:25:27 jsp Exp jsp $ 1453845Spendry */ 1553845Spendry 1653845Spendry /* 1753845Spendry * Portal Filesystem 1853845Spendry */ 1953845Spendry 2053845Spendry #include <sys/param.h> 2153845Spendry #include <sys/systm.h> 2253845Spendry #include <sys/time.h> 2353845Spendry #include <sys/types.h> 2453845Spendry #include <sys/proc.h> 2553845Spendry #include <sys/filedesc.h> 2653845Spendry #include <sys/file.h> 2753845Spendry #include <sys/vnode.h> 2853845Spendry #include <sys/mount.h> 2953845Spendry #include <sys/namei.h> 3053845Spendry #include <sys/malloc.h> 3153845Spendry #include <sys/mbuf.h> 3253845Spendry #include <sys/socket.h> 3353845Spendry #include <sys/socketvar.h> 3453845Spendry #include <sys/protosw.h> 3553845Spendry #include <sys/domain.h> 3653845Spendry #include <sys/un.h> 3755027Smckusick #include <miscfs/portal/portal.h> 3853845Spendry 3953845Spendry static u_short portal_mntid; 4053845Spendry 4153845Spendry int portal_init() 4253845Spendry { 4355027Smckusick 4453845Spendry #ifdef PORTAL_DIAGNOSTIC 4553845Spendry printf("portal_init\n"); /* printed during system boot */ 4653845Spendry #endif 4753845Spendry } 4853845Spendry 4953845Spendry /* 5053845Spendry * Mount the per-process file descriptors (/dev/fd) 5153845Spendry */ 5253845Spendry portal_mount(mp, path, data, ndp, p) 5353845Spendry struct mount *mp; 5453845Spendry char *path; 5553845Spendry caddr_t data; 5653845Spendry struct nameidata *ndp; 5753845Spendry struct proc *p; 5853845Spendry { 5953845Spendry int error = 0; 6053845Spendry struct portal_args args; 6153845Spendry u_int size; 6253845Spendry struct portalmount *fmp; 6353845Spendry struct vnode *rvp; 6453845Spendry struct sockaddr_un *unp; 6553845Spendry struct file *fp; 6653845Spendry struct socket *so; 6753845Spendry char cfile[MAXPATHLEN]; 6853845Spendry 6953845Spendry #ifdef PORTAL_DIAGNOSTIC 7053845Spendry printf("portal_mount(mp = %x)\n", mp); 7153845Spendry #endif 7253845Spendry 7353845Spendry /* 7453845Spendry * Update is a no-op 7553845Spendry */ 7653845Spendry if (mp->mnt_flag & MNT_UPDATE) 7753845Spendry return (EOPNOTSUPP); 7853845Spendry 7953845Spendry if (error = copyin(data, (caddr_t) &args, sizeof(struct portal_args))) 8053845Spendry return (error); 8153845Spendry 8253845Spendry if (error = getsock(p->p_fd, args.pa_socket, &fp)) 8353845Spendry return (error); 8453845Spendry so = (struct socket *) fp->f_data; 8553845Spendry if (so->so_proto->pr_domain->dom_family != AF_UNIX) 8653845Spendry return (ESOCKTNOSUPPORT); 8753845Spendry 88*65380Spendry error = getnewvnode(VT_PORTAL, mp, portal_vnodeop_p, &rvp); /* XXX */ 8953845Spendry if (error) 9053845Spendry return (error); 9153845Spendry MALLOC(rvp->v_data, void *, sizeof(struct portalnode), 9253845Spendry M_TEMP, M_WAITOK); 9353845Spendry 9453845Spendry fmp = (struct portalmount *) malloc(sizeof(struct portalmount), 9553845Spendry M_UFSMNT, M_WAITOK); /* XXX */ 9653845Spendry rvp->v_type = VDIR; 9753845Spendry rvp->v_flag |= VROOT; 9853845Spendry VTOPORTAL(rvp)->pt_arg = 0; 9953845Spendry VTOPORTAL(rvp)->pt_size = 0; 10053845Spendry VTOPORTAL(rvp)->pt_fileid = PORTAL_ROOTFILEID; 10153845Spendry #ifdef PORTAL_DIAGNOSTIC 10253845Spendry printf("portal_mount: root vp = %x\n", rvp); 10353845Spendry #endif 10453845Spendry fmp->pm_root = rvp; 10553845Spendry fmp->pm_server = fp; fp->f_count++; 10653845Spendry 10753845Spendry mp->mnt_flag |= MNT_LOCAL; 10853845Spendry mp->mnt_data = (qaddr_t) fmp; 10953845Spendry getnewfsid(mp, MOUNT_PORTAL); 11053845Spendry 11153845Spendry (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); 11253845Spendry bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); 11353845Spendry (void) copyinstr(args.pa_config, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, 11453845Spendry &size); 11553845Spendry bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 11653845Spendry 11753845Spendry #ifdef notdef 11853845Spendry bzero(mp->mnt_stat.f_mntfromname, MNAMELEN); 11953845Spendry bcopy("portal", mp->mnt_stat.f_mntfromname, sizeof("portal")); 12053845Spendry #endif 12153845Spendry 12253845Spendry #ifdef PORTAL_DIAGNOSTIC 12353845Spendry printf("portal_mount: config %s at %s\n", 12453845Spendry mp->mnt_stat.f_mntfromname, mp->mnt_stat.f_mntonname); 12553845Spendry #endif 12653845Spendry return (0); 12753845Spendry } 12853845Spendry 12953845Spendry portal_start(mp, flags, p) 13053845Spendry struct mount *mp; 13153845Spendry int flags; 13253845Spendry struct proc *p; 13353845Spendry { 13455027Smckusick 13553845Spendry return (0); 13653845Spendry } 13753845Spendry 13853845Spendry portal_unmount(mp, mntflags, p) 13953845Spendry struct mount *mp; 14053845Spendry int mntflags; 14153845Spendry struct proc *p; 14253845Spendry { 14353845Spendry int error; 14453845Spendry int flags = 0; 14553845Spendry extern int doforce; 14653845Spendry struct vnode *rootvp = VFSTOPORTAL(mp)->pm_root; 14753845Spendry 14853845Spendry #ifdef PORTAL_DIAGNOSTIC 14953845Spendry printf("portal_unmount(mp = %x)\n", mp); 15053845Spendry #endif 15153845Spendry 15253845Spendry if (mntflags & MNT_FORCE) { 15353845Spendry /* portal can never be rootfs so don't check for it */ 15453845Spendry if (!doforce) 15553845Spendry return (EINVAL); 15653845Spendry flags |= FORCECLOSE; 15753845Spendry } 15853845Spendry 15953845Spendry /* 16053845Spendry * Clear out buffer cache. I don't think we 16153845Spendry * ever get anything cached at this level at the 16253845Spendry * moment, but who knows... 16353845Spendry */ 16455027Smckusick #ifdef notyet 16553845Spendry #ifdef PORTAL_DIAGNOSTIC 16653845Spendry printf("portal_unmount: calling mntflushbuf\n"); 16753845Spendry #endif 16853845Spendry mntflushbuf(mp, 0); 16953845Spendry #ifdef PORTAL_DIAGNOSTIC 17053845Spendry printf("portal_unmount: calling mntinvalbuf\n"); 17153845Spendry #endif 17253845Spendry if (mntinvalbuf(mp, 1)) 17353845Spendry return (EBUSY); 17454977Spendry #endif 17553845Spendry if (rootvp->v_usecount > 1) 17653845Spendry return (EBUSY); 17753845Spendry #ifdef PORTAL_DIAGNOSTIC 17853845Spendry printf("portal_unmount: calling vflush\n"); 17953845Spendry #endif 18053845Spendry if (error = vflush(mp, rootvp, flags)) 18153845Spendry return (error); 18253845Spendry 18353845Spendry #ifdef PORTAL_DIAGNOSTIC 18453845Spendry vprint("portal root", rootvp); 18553845Spendry #endif 18653845Spendry /* 18753845Spendry * Release reference on underlying root vnode 18853845Spendry */ 18953845Spendry vrele(rootvp); 19053845Spendry /* 19153845Spendry * And blow it away for future re-use 19253845Spendry */ 19353845Spendry vgone(rootvp); 19453845Spendry /* 19553845Spendry * Shutdown the socket. This will cause the select in the 19653845Spendry * daemon to wake up, and then the accept will get ECONNABORTED 19753845Spendry * which it interprets as a request to go and bury itself. 19853845Spendry */ 19953845Spendry #ifdef PORTAL_DIAGNOSTIC 20053845Spendry printf("portal_unmount: shutdown socket\n"); 20153845Spendry #endif 20253845Spendry soshutdown((struct socket *) VFSTOPORTAL(mp)->pm_server->f_data, 2); 20353845Spendry /* 20453845Spendry * Discard reference to underlying file. Must call closef because 20553845Spendry * this may be the last reference. 20653845Spendry */ 20753845Spendry #ifdef PORTAL_DIAGNOSTIC 20853845Spendry printf("portal_unmount: closef(%x)\n", VFSTOPORTAL(mp)->pm_server); 20953845Spendry #endif 21053845Spendry closef(VFSTOPORTAL(mp)->pm_server, (struct proc *) 0); 21153845Spendry /* 21253845Spendry * Finally, throw away the portalmount structure 21353845Spendry */ 21453845Spendry free(mp->mnt_data, M_UFSMNT); /* XXX */ 21553845Spendry mp->mnt_data = 0; 21655027Smckusick return (0); 21753845Spendry } 21853845Spendry 21953845Spendry portal_root(mp, vpp) 22053845Spendry struct mount *mp; 22153845Spendry struct vnode **vpp; 22253845Spendry { 22353845Spendry struct vnode *vp; 22453845Spendry int error; 22553845Spendry 22653845Spendry #ifdef PORTAL_DIAGNOSTIC 22753845Spendry printf("portal_root(mp = %x)\n", mp); 22853845Spendry #endif 22953845Spendry 23053845Spendry /* 23153845Spendry * Return locked reference to root. 23253845Spendry */ 23353845Spendry vp = VFSTOPORTAL(mp)->pm_root; 23453845Spendry VREF(vp); 23553845Spendry VOP_LOCK(vp); 23653845Spendry *vpp = vp; 23753845Spendry return (0); 23853845Spendry } 23953845Spendry 24053845Spendry portal_quotactl(mp, cmd, uid, arg, p) 24153845Spendry struct mount *mp; 24253845Spendry int cmd; 24353845Spendry uid_t uid; 24453845Spendry caddr_t arg; 24553845Spendry struct proc *p; 24653845Spendry { 24755027Smckusick 24853845Spendry return (EOPNOTSUPP); 24953845Spendry } 25053845Spendry 25153845Spendry portal_statfs(mp, sbp, p) 25253845Spendry struct mount *mp; 25353845Spendry struct statfs *sbp; 25453845Spendry struct proc *p; 25553845Spendry { 25653845Spendry struct filedesc *fdp; 25753845Spendry int lim; 25853845Spendry int i; 25953845Spendry int last; 26053845Spendry int freefd; 26153845Spendry 26253845Spendry #ifdef PORTAL_DIAGNOSTIC 26353845Spendry printf("portal_statfs(mp = %x)\n", mp); 26453845Spendry #endif 26553845Spendry 26653845Spendry sbp->f_type = MOUNT_PORTAL; 26753845Spendry sbp->f_flags = 0; 26853845Spendry sbp->f_bsize = DEV_BSIZE; 26953845Spendry sbp->f_iosize = DEV_BSIZE; 27053845Spendry sbp->f_blocks = 2; /* 1K to keep df happy */ 27153845Spendry sbp->f_bfree = 0; 27253845Spendry sbp->f_bavail = 0; 27353845Spendry sbp->f_files = 1; /* Allow for "." */ 27453845Spendry sbp->f_ffree = 0; /* See comments above */ 27553845Spendry if (sbp != &mp->mnt_stat) { 27653845Spendry bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 27753845Spendry bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 27853845Spendry bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 27953845Spendry } 28053845Spendry return (0); 28153845Spendry } 28253845Spendry 28353845Spendry portal_sync(mp, waitfor) 28453845Spendry struct mount *mp; 28553845Spendry int waitfor; 28653845Spendry { 28755027Smckusick 28853845Spendry return (0); 28953845Spendry } 29053845Spendry 29154977Spendry portal_vget(mp, ino, vpp) 29254977Spendry struct mount *mp; 29354977Spendry ino_t ino; 29454977Spendry struct vnode **vpp; 29554977Spendry { 29654977Spendry 29754977Spendry return (EOPNOTSUPP); 29854977Spendry } 29954977Spendry 30053845Spendry portal_fhtovp(mp, fhp, vpp) 30153845Spendry struct mount *mp; 30253845Spendry struct fid *fhp; 30353845Spendry struct vnode **vpp; 30453845Spendry { 30555027Smckusick 30653845Spendry return (EOPNOTSUPP); 30753845Spendry } 30853845Spendry 30953845Spendry portal_vptofh(vp, fhp) 31053845Spendry struct vnode *vp; 31153845Spendry struct fid *fhp; 31253845Spendry { 31355027Smckusick 31453845Spendry return (EOPNOTSUPP); 31553845Spendry } 31653845Spendry 31753845Spendry struct vfsops portal_vfsops = { 31853845Spendry portal_mount, 31953845Spendry portal_start, 32053845Spendry portal_unmount, 32153845Spendry portal_root, 32253845Spendry portal_quotactl, 32353845Spendry portal_statfs, 32453845Spendry portal_sync, 32554977Spendry portal_vget, 32653845Spendry portal_fhtovp, 32753845Spendry portal_vptofh, 32853845Spendry portal_init, 32953845Spendry }; 330