1*53845Spendry /* 2*53845Spendry * Copyright (c) 1992 The Regents of the University of California 3*53845Spendry * Copyright (c) 1990, 1992 Jan-Simon Pendry 4*53845Spendry * All rights reserved. 5*53845Spendry * 6*53845Spendry * This code is derived from software donated to Berkeley by 7*53845Spendry * Jan-Simon Pendry. 8*53845Spendry * 9*53845Spendry * %sccs.include.redist.c% 10*53845Spendry * 11*53845Spendry * @(#)portal_vfsops.c 1.1 (Berkeley) 06/03/92 12*53845Spendry * 13*53845Spendry * $Id: portal_vfsops.c,v 1.5 1992/05/30 10:25:27 jsp Exp jsp $ 14*53845Spendry */ 15*53845Spendry 16*53845Spendry /* 17*53845Spendry * Portal Filesystem 18*53845Spendry */ 19*53845Spendry 20*53845Spendry #include <sys/param.h> 21*53845Spendry #include <sys/systm.h> 22*53845Spendry #include <sys/time.h> 23*53845Spendry #include <sys/types.h> 24*53845Spendry #include <sys/proc.h> 25*53845Spendry /*#include <sys/resourcevar.h>*/ 26*53845Spendry #include <sys/filedesc.h> 27*53845Spendry #include <sys/file.h> 28*53845Spendry #include <sys/vnode.h> 29*53845Spendry #include <sys/mount.h> 30*53845Spendry #include <sys/namei.h> 31*53845Spendry #include <sys/malloc.h> 32*53845Spendry #include <sys/mbuf.h> 33*53845Spendry #include <sys/socket.h> 34*53845Spendry #include <sys/socketvar.h> 35*53845Spendry #include <sys/protosw.h> 36*53845Spendry #include <sys/domain.h> 37*53845Spendry #include <sys/un.h> 38*53845Spendry #include <portal/portal.h> 39*53845Spendry 40*53845Spendry static u_short portal_mntid; 41*53845Spendry 42*53845Spendry int portal_init() 43*53845Spendry { 44*53845Spendry #ifdef PORTAL_DIAGNOSTIC 45*53845Spendry printf("portal_init\n"); /* printed during system boot */ 46*53845Spendry #endif 47*53845Spendry } 48*53845Spendry 49*53845Spendry /* 50*53845Spendry * Mount the per-process file descriptors (/dev/fd) 51*53845Spendry */ 52*53845Spendry portal_mount(mp, path, data, ndp, p) 53*53845Spendry struct mount *mp; 54*53845Spendry char *path; 55*53845Spendry caddr_t data; 56*53845Spendry struct nameidata *ndp; 57*53845Spendry struct proc *p; 58*53845Spendry { 59*53845Spendry int error = 0; 60*53845Spendry struct portal_args args; 61*53845Spendry u_int size; 62*53845Spendry struct portalmount *fmp; 63*53845Spendry struct vnode *rvp; 64*53845Spendry struct sockaddr_un *unp; 65*53845Spendry struct file *fp; 66*53845Spendry struct socket *so; 67*53845Spendry char cfile[MAXPATHLEN]; 68*53845Spendry 69*53845Spendry #ifdef PORTAL_DIAGNOSTIC 70*53845Spendry printf("portal_mount(mp = %x)\n", mp); 71*53845Spendry #endif 72*53845Spendry 73*53845Spendry /* 74*53845Spendry * Update is a no-op 75*53845Spendry */ 76*53845Spendry if (mp->mnt_flag & MNT_UPDATE) 77*53845Spendry return (EOPNOTSUPP); 78*53845Spendry 79*53845Spendry if (error = copyin(data, (caddr_t) &args, sizeof(struct portal_args))) 80*53845Spendry return (error); 81*53845Spendry 82*53845Spendry if (error = getsock(p->p_fd, args.pa_socket, &fp)) 83*53845Spendry return (error); 84*53845Spendry so = (struct socket *) fp->f_data; 85*53845Spendry if (so->so_proto->pr_domain->dom_family != AF_UNIX) 86*53845Spendry return (ESOCKTNOSUPPORT); 87*53845Spendry 88*53845Spendry error = getnewvnode(VT_UFS, mp, portal_vnodeop_p, &rvp); /* XXX */ 89*53845Spendry if (error) 90*53845Spendry return (error); 91*53845Spendry MALLOC(rvp->v_data, void *, sizeof(struct portalnode), 92*53845Spendry M_TEMP, M_WAITOK); 93*53845Spendry 94*53845Spendry fmp = (struct portalmount *) malloc(sizeof(struct portalmount), 95*53845Spendry M_UFSMNT, M_WAITOK); /* XXX */ 96*53845Spendry rvp->v_type = VDIR; 97*53845Spendry rvp->v_flag |= VROOT; 98*53845Spendry VTOPORTAL(rvp)->pt_arg = 0; 99*53845Spendry VTOPORTAL(rvp)->pt_size = 0; 100*53845Spendry VTOPORTAL(rvp)->pt_fileid = PORTAL_ROOTFILEID; 101*53845Spendry #ifdef PORTAL_DIAGNOSTIC 102*53845Spendry printf("portal_mount: root vp = %x\n", rvp); 103*53845Spendry #endif 104*53845Spendry fmp->pm_root = rvp; 105*53845Spendry fmp->pm_server = fp; fp->f_count++; 106*53845Spendry 107*53845Spendry mp->mnt_flag |= MNT_LOCAL; 108*53845Spendry mp->mnt_data = (qaddr_t) fmp; 109*53845Spendry getnewfsid(mp, MOUNT_PORTAL); 110*53845Spendry 111*53845Spendry (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); 112*53845Spendry bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); 113*53845Spendry (void) copyinstr(args.pa_config, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, 114*53845Spendry &size); 115*53845Spendry bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 116*53845Spendry 117*53845Spendry #ifdef notdef 118*53845Spendry bzero(mp->mnt_stat.f_mntfromname, MNAMELEN); 119*53845Spendry bcopy("portal", mp->mnt_stat.f_mntfromname, sizeof("portal")); 120*53845Spendry #endif 121*53845Spendry 122*53845Spendry #ifdef PORTAL_DIAGNOSTIC 123*53845Spendry printf("portal_mount: config %s at %s\n", 124*53845Spendry mp->mnt_stat.f_mntfromname, mp->mnt_stat.f_mntonname); 125*53845Spendry #endif 126*53845Spendry return (0); 127*53845Spendry } 128*53845Spendry 129*53845Spendry portal_start(mp, flags, p) 130*53845Spendry struct mount *mp; 131*53845Spendry int flags; 132*53845Spendry struct proc *p; 133*53845Spendry { 134*53845Spendry return (0); 135*53845Spendry } 136*53845Spendry 137*53845Spendry portal_unmount(mp, mntflags, p) 138*53845Spendry struct mount *mp; 139*53845Spendry int mntflags; 140*53845Spendry struct proc *p; 141*53845Spendry { 142*53845Spendry int error; 143*53845Spendry int flags = 0; 144*53845Spendry extern int doforce; 145*53845Spendry struct vnode *rootvp = VFSTOPORTAL(mp)->pm_root; 146*53845Spendry 147*53845Spendry #ifdef PORTAL_DIAGNOSTIC 148*53845Spendry printf("portal_unmount(mp = %x)\n", mp); 149*53845Spendry #endif 150*53845Spendry 151*53845Spendry if (mntflags & MNT_FORCE) { 152*53845Spendry /* portal can never be rootfs so don't check for it */ 153*53845Spendry if (!doforce) 154*53845Spendry return (EINVAL); 155*53845Spendry flags |= FORCECLOSE; 156*53845Spendry } 157*53845Spendry 158*53845Spendry /* 159*53845Spendry * Clear out buffer cache. I don't think we 160*53845Spendry * ever get anything cached at this level at the 161*53845Spendry * moment, but who knows... 162*53845Spendry */ 163*53845Spendry #ifdef PORTAL_DIAGNOSTIC 164*53845Spendry printf("portal_unmount: calling mntflushbuf\n"); 165*53845Spendry #endif 166*53845Spendry mntflushbuf(mp, 0); 167*53845Spendry #ifdef PORTAL_DIAGNOSTIC 168*53845Spendry printf("portal_unmount: calling mntinvalbuf\n"); 169*53845Spendry #endif 170*53845Spendry if (mntinvalbuf(mp, 1)) 171*53845Spendry return (EBUSY); 172*53845Spendry if (rootvp->v_usecount > 1) 173*53845Spendry return (EBUSY); 174*53845Spendry #ifdef PORTAL_DIAGNOSTIC 175*53845Spendry printf("portal_unmount: calling vflush\n"); 176*53845Spendry #endif 177*53845Spendry if (error = vflush(mp, rootvp, flags)) 178*53845Spendry return (error); 179*53845Spendry 180*53845Spendry #ifdef PORTAL_DIAGNOSTIC 181*53845Spendry vprint("portal root", rootvp); 182*53845Spendry #endif 183*53845Spendry /* 184*53845Spendry * Release reference on underlying root vnode 185*53845Spendry */ 186*53845Spendry vrele(rootvp); 187*53845Spendry /* 188*53845Spendry * And blow it away for future re-use 189*53845Spendry */ 190*53845Spendry vgone(rootvp); 191*53845Spendry /* 192*53845Spendry * Shutdown the socket. This will cause the select in the 193*53845Spendry * daemon to wake up, and then the accept will get ECONNABORTED 194*53845Spendry * which it interprets as a request to go and bury itself. 195*53845Spendry */ 196*53845Spendry #ifdef PORTAL_DIAGNOSTIC 197*53845Spendry printf("portal_unmount: shutdown socket\n"); 198*53845Spendry #endif 199*53845Spendry soshutdown((struct socket *) VFSTOPORTAL(mp)->pm_server->f_data, 2); 200*53845Spendry /* 201*53845Spendry * Discard reference to underlying file. Must call closef because 202*53845Spendry * this may be the last reference. 203*53845Spendry */ 204*53845Spendry #ifdef PORTAL_DIAGNOSTIC 205*53845Spendry printf("portal_unmount: closef(%x)\n", VFSTOPORTAL(mp)->pm_server); 206*53845Spendry #endif 207*53845Spendry closef(VFSTOPORTAL(mp)->pm_server, (struct proc *) 0); 208*53845Spendry /* 209*53845Spendry * Finally, throw away the portalmount structure 210*53845Spendry */ 211*53845Spendry free(mp->mnt_data, M_UFSMNT); /* XXX */ 212*53845Spendry mp->mnt_data = 0; 213*53845Spendry return 0; 214*53845Spendry } 215*53845Spendry 216*53845Spendry portal_root(mp, vpp) 217*53845Spendry struct mount *mp; 218*53845Spendry struct vnode **vpp; 219*53845Spendry { 220*53845Spendry USES_VOP_LOCK; 221*53845Spendry struct vnode *vp; 222*53845Spendry int error; 223*53845Spendry 224*53845Spendry #ifdef PORTAL_DIAGNOSTIC 225*53845Spendry printf("portal_root(mp = %x)\n", mp); 226*53845Spendry #endif 227*53845Spendry 228*53845Spendry /* 229*53845Spendry * Return locked reference to root. 230*53845Spendry */ 231*53845Spendry vp = VFSTOPORTAL(mp)->pm_root; 232*53845Spendry VREF(vp); 233*53845Spendry VOP_LOCK(vp); 234*53845Spendry *vpp = vp; 235*53845Spendry return (0); 236*53845Spendry } 237*53845Spendry 238*53845Spendry portal_quotactl(mp, cmd, uid, arg, p) 239*53845Spendry struct mount *mp; 240*53845Spendry int cmd; 241*53845Spendry uid_t uid; 242*53845Spendry caddr_t arg; 243*53845Spendry struct proc *p; 244*53845Spendry { 245*53845Spendry return (EOPNOTSUPP); 246*53845Spendry } 247*53845Spendry 248*53845Spendry portal_statfs(mp, sbp, p) 249*53845Spendry struct mount *mp; 250*53845Spendry struct statfs *sbp; 251*53845Spendry struct proc *p; 252*53845Spendry { 253*53845Spendry struct filedesc *fdp; 254*53845Spendry int lim; 255*53845Spendry int i; 256*53845Spendry int last; 257*53845Spendry int freefd; 258*53845Spendry 259*53845Spendry #ifdef PORTAL_DIAGNOSTIC 260*53845Spendry printf("portal_statfs(mp = %x)\n", mp); 261*53845Spendry #endif 262*53845Spendry 263*53845Spendry sbp->f_type = MOUNT_PORTAL; 264*53845Spendry sbp->f_flags = 0; 265*53845Spendry sbp->f_bsize = DEV_BSIZE; 266*53845Spendry sbp->f_iosize = DEV_BSIZE; 267*53845Spendry sbp->f_blocks = 2; /* 1K to keep df happy */ 268*53845Spendry sbp->f_bfree = 0; 269*53845Spendry sbp->f_bavail = 0; 270*53845Spendry sbp->f_files = 1; /* Allow for "." */ 271*53845Spendry sbp->f_ffree = 0; /* See comments above */ 272*53845Spendry if (sbp != &mp->mnt_stat) { 273*53845Spendry bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); 274*53845Spendry bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 275*53845Spendry bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 276*53845Spendry } 277*53845Spendry return (0); 278*53845Spendry } 279*53845Spendry 280*53845Spendry portal_sync(mp, waitfor) 281*53845Spendry struct mount *mp; 282*53845Spendry int waitfor; 283*53845Spendry { 284*53845Spendry return (0); 285*53845Spendry } 286*53845Spendry 287*53845Spendry portal_fhtovp(mp, fhp, vpp) 288*53845Spendry struct mount *mp; 289*53845Spendry struct fid *fhp; 290*53845Spendry struct vnode **vpp; 291*53845Spendry { 292*53845Spendry return (EOPNOTSUPP); 293*53845Spendry } 294*53845Spendry 295*53845Spendry portal_vptofh(vp, fhp) 296*53845Spendry struct vnode *vp; 297*53845Spendry struct fid *fhp; 298*53845Spendry { 299*53845Spendry return (EOPNOTSUPP); 300*53845Spendry } 301*53845Spendry 302*53845Spendry struct vfsops portal_vfsops = { 303*53845Spendry portal_mount, 304*53845Spendry portal_start, 305*53845Spendry portal_unmount, 306*53845Spendry portal_root, 307*53845Spendry portal_quotactl, 308*53845Spendry portal_statfs, 309*53845Spendry portal_sync, 310*53845Spendry portal_fhtovp, 311*53845Spendry portal_vptofh, 312*53845Spendry portal_init, 313*53845Spendry }; 314