153846Spendry /* 263246Sbostic * Copyright (c) 1992, 1993 363246Sbostic * The Regents of the University of California. All rights reserved. 453846Spendry * All rights reserved. 553846Spendry * 653846Spendry * This code is derived from software donated to Berkeley by 753846Spendry * Jan-Simon Pendry. 853846Spendry * 953846Spendry * %sccs.include.redist.c% 1053846Spendry * 11*65380Spendry * @(#)portal_vnops.c 8.2 (Berkeley) 01/04/94 1253846Spendry * 1353846Spendry * $Id: portal_vnops.c,v 1.4 1992/05/30 10:05:24 jsp Exp jsp $ 1453846Spendry */ 1553846Spendry 1653846Spendry /* 1753846Spendry * Portal Filesystem 1853846Spendry */ 1953846Spendry 2053846Spendry #include <sys/param.h> 2153846Spendry #include <sys/systm.h> 2253846Spendry #include <sys/kernel.h> 2353846Spendry #include <sys/types.h> 2453846Spendry #include <sys/time.h> 2553846Spendry #include <sys/proc.h> 2653846Spendry #include <sys/filedesc.h> 2753846Spendry #include <sys/vnode.h> 2853846Spendry #include <sys/file.h> 2953846Spendry #include <sys/stat.h> 3053846Spendry #include <sys/mount.h> 3153846Spendry #include <sys/malloc.h> 3253846Spendry #include <sys/namei.h> 3353846Spendry #include <sys/mbuf.h> 3453846Spendry #include <sys/socket.h> 3553846Spendry #include <sys/socketvar.h> 3653846Spendry #include <sys/un.h> 3753846Spendry #include <sys/unpcb.h> 3855027Smckusick #include <miscfs/portal/portal.h> 3953846Spendry 4053846Spendry static int portal_fileid = PORTAL_ROOTFILEID+1; 4153846Spendry 4253846Spendry static void 4353846Spendry portal_closefd(p, fd) 4453846Spendry struct proc *p; 4553846Spendry int fd; 4653846Spendry { 4753846Spendry int error; 4853846Spendry struct { 4953846Spendry int fd; 5053846Spendry } ua; 5153846Spendry int rc; 5253846Spendry 5353846Spendry ua.fd = fd; 5453846Spendry error = close(p, &ua, &rc); 5553846Spendry /* 5653846Spendry * We should never get an error, and there isn't anything 5753846Spendry * we could do if we got one, so just print a message. 5853846Spendry */ 5953846Spendry if (error) 6053846Spendry printf("portal_closefd: error = %d\n", error); 6153846Spendry } 6253846Spendry 6353846Spendry /* 6453846Spendry * vp is the current namei directory 6553846Spendry * cnp is the name to locate in that directory... 6653846Spendry */ 6755027Smckusick portal_lookup(ap) 6855027Smckusick struct vop_lookup_args /* { 6955027Smckusick struct vnode * a_dvp; 7055027Smckusick struct vnode ** a_vpp; 7155027Smckusick struct componentname * a_cnp; 7255027Smckusick } */ *ap; 7353846Spendry { 7453846Spendry char *pname = ap->a_cnp->cn_nameptr; 7553846Spendry struct portalnode *pt; 7653846Spendry int error; 7753846Spendry struct vnode *fvp = 0; 7853846Spendry char *path; 7953846Spendry int size; 8053846Spendry 8153846Spendry #ifdef PORTAL_DIAGNOSTIC 8253846Spendry printf("portal_lookup(%s)\n", pname); 8353846Spendry #endif 8453846Spendry if (ap->a_cnp->cn_namelen == 1 && *pname == '.') { 8553846Spendry *ap->a_vpp = ap->a_dvp; 8653846Spendry VREF(ap->a_dvp); 8753846Spendry /*VOP_LOCK(ap->a_dvp);*/ 8853846Spendry return (0); 8953846Spendry } 9053846Spendry 9153846Spendry 9253846Spendry #ifdef PORTAL_DIAGNOSTIC 9353846Spendry printf("portal_lookup: allocate new vnode\n"); 9453846Spendry #endif 95*65380Spendry error = getnewvnode(VT_PORTAL, ap->a_dvp->v_mount, portal_vnodeop_p, &fvp); 9653846Spendry if (error) 9753846Spendry goto bad; 9853846Spendry fvp->v_type = VREG; 9953846Spendry MALLOC(fvp->v_data, void *, sizeof(struct portalnode), 10053846Spendry M_TEMP, M_WAITOK); 10153846Spendry 10253846Spendry pt = VTOPORTAL(fvp); 10353846Spendry /* 10453846Spendry * Save all of the remaining pathname and 10553846Spendry * advance the namei next pointer to the end 10653846Spendry * of the string. 10753846Spendry */ 10853846Spendry for (size = 0, path = pname; *path; path++) 10953846Spendry size++; 11054978Spendry ap->a_cnp->cn_consume = size - ap->a_cnp->cn_namelen; 11154978Spendry 11253846Spendry pt->pt_arg = malloc(size+1, M_TEMP, M_WAITOK); 11353846Spendry pt->pt_size = size+1; 11453846Spendry bcopy(pname, pt->pt_arg, pt->pt_size); 11553846Spendry pt->pt_fileid = portal_fileid++; 11653846Spendry 11753846Spendry *ap->a_vpp = fvp; 11853846Spendry /*VOP_LOCK(fvp);*/ 11953846Spendry #ifdef PORTAL_DIAGNOSTIC 12053846Spendry printf("portal_lookup: newvp = %x\n", fvp); 12153846Spendry #endif 12253846Spendry return (0); 12353846Spendry 12453846Spendry bad:; 12553846Spendry if (fvp) { 12653846Spendry #ifdef PORTAL_DIAGNOSTIC 12753846Spendry printf("portal_lookup: vrele(%x)\n", fvp); 12853846Spendry #endif 12953846Spendry vrele(fvp); 13053846Spendry } 13153846Spendry *ap->a_vpp = NULL; 13253846Spendry #ifdef PORTAL_DIAGNOSTIC 13353846Spendry printf("portal_lookup: error = %d\n", error); 13453846Spendry #endif 13553846Spendry return (error); 13653846Spendry } 13753846Spendry 13853846Spendry static int 13953846Spendry portal_connect(so, so2) 14053846Spendry struct socket *so; 14153846Spendry struct socket *so2; 14253846Spendry { 14353846Spendry /* from unp_connect, bypassing the namei stuff... */ 14453846Spendry 14553846Spendry struct socket *so3; 14653846Spendry struct unpcb *unp2; 14753846Spendry struct unpcb *unp3; 14853846Spendry 14953846Spendry #ifdef PORTAL_DIAGNOSTIC 15053846Spendry printf("portal_connect\n"); 15153846Spendry #endif 15253846Spendry 15353846Spendry if (so2 == 0) 15453846Spendry return (ECONNREFUSED); 15553846Spendry 15653846Spendry if (so->so_type != so2->so_type) 15753846Spendry return (EPROTOTYPE); 15853846Spendry 15953846Spendry if ((so2->so_options & SO_ACCEPTCONN) == 0) 16053846Spendry return (ECONNREFUSED); 16153846Spendry 16253846Spendry #ifdef PORTAL_DIAGNOSTIC 16353846Spendry printf("portal_connect: calling sonewconn\n"); 16453846Spendry #endif 16553846Spendry 16653846Spendry if ((so3 = sonewconn(so2, 0)) == 0) 16753846Spendry return (ECONNREFUSED); 16853846Spendry 16953846Spendry unp2 = sotounpcb(so2); 17053846Spendry unp3 = sotounpcb(so3); 17153846Spendry if (unp2->unp_addr) 17253846Spendry unp3->unp_addr = m_copy(unp2->unp_addr, 0, (int)M_COPYALL); 17353846Spendry 17453846Spendry so2 = so3; 17553846Spendry 17653846Spendry #ifdef PORTAL_DIAGNOSTIC 17753846Spendry printf("portal_connect: calling unp_connect2\n"); 17853846Spendry #endif 17953846Spendry 18053846Spendry return (unp_connect2(so, so2)); 18153846Spendry } 18253846Spendry 18355027Smckusick portal_open(ap) 18455027Smckusick struct vop_open_args /* { 18555027Smckusick struct vnode *a_vp; 18655027Smckusick int a_mode; 18755027Smckusick struct ucred *a_cred; 18855027Smckusick struct proc *a_p; 18955027Smckusick } */ *ap; 19053846Spendry { 19153846Spendry struct socket *so = 0; 19253846Spendry struct portalnode *pt; 19355910Spendry struct proc *p = ap->a_p; 19455910Spendry struct vnode *vp = ap->a_vp; 19553846Spendry int s; 19653846Spendry struct uio auio; 19753846Spendry struct iovec aiov[2]; 19853846Spendry int res; 19953846Spendry struct mbuf *cm = 0; 20053846Spendry struct cmsghdr *cmsg; 20153846Spendry int newfds; 20253846Spendry int *ip; 20353846Spendry int fd; 20453846Spendry int error; 20553846Spendry int len; 20653846Spendry struct portalmount *fmp; 20753846Spendry struct file *fp; 20853846Spendry struct portal_cred pcred; 20953846Spendry 21053846Spendry /* 21153846Spendry * Nothing to do when opening the root node. 21253846Spendry */ 21355910Spendry if (vp->v_flag & VROOT) 21453846Spendry return (0); 21553846Spendry 21653846Spendry #ifdef PORTAL_DIAGNOSTIC 21755910Spendry printf("portal_open(%x)\n", vp); 21853846Spendry #endif 21953846Spendry 22053846Spendry /* 22153846Spendry * Can't be opened unless the caller is set up 22253846Spendry * to deal with the side effects. Check for this 22353846Spendry * by testing whether the p_dupfd has been set. 22453846Spendry */ 22555910Spendry if (p->p_dupfd >= 0) 22653846Spendry return (ENODEV); 22753846Spendry 22855910Spendry pt = VTOPORTAL(vp); 22955910Spendry fmp = VFSTOPORTAL(vp->v_mount); 23053846Spendry 23153846Spendry /* 23253846Spendry * Create a new socket. 23353846Spendry */ 23453846Spendry error = socreate(AF_UNIX, &so, SOCK_STREAM, 0); 23553846Spendry if (error) 23653846Spendry goto bad; 23753846Spendry 23853846Spendry /* 23953846Spendry * Reserve some buffer space 24053846Spendry */ 24153846Spendry #ifdef PORTAL_DIAGNOSTIC 24253846Spendry printf("portal_open: calling soreserve\n"); 24353846Spendry #endif 24454978Spendry res = pt->pt_size + sizeof(pcred) + 512; /* XXX */ 24553846Spendry error = soreserve(so, res, res); 24653846Spendry if (error) 24753846Spendry goto bad; 24853846Spendry 24953846Spendry /* 25053846Spendry * Kick off connection 25153846Spendry */ 25253846Spendry #ifdef PORTAL_DIAGNOSTIC 25353846Spendry printf("portal_open: calling portal_connect\n"); 25453846Spendry #endif 25553846Spendry error = portal_connect(so, (struct socket *)fmp->pm_server->f_data); 25653846Spendry if (error) 25753846Spendry goto bad; 25853846Spendry 25953846Spendry /* 26053846Spendry * Wait for connection to complete 26153846Spendry */ 26253846Spendry #ifdef PORTAL_DIAGNOSTIC 26353846Spendry printf("portal_open: waiting for connect\n"); 26453846Spendry #endif 26553846Spendry /* 26653846Spendry * XXX: Since the mount point is holding a reference on the 26753846Spendry * underlying server socket, it is not easy to find out whether 26853846Spendry * the server process is still running. To handle this problem 26953846Spendry * we loop waiting for the new socket to be connected (something 27053846Spendry * which will only happen if the server is still running) or for 27153846Spendry * the reference count on the server socket to drop to 1, which 27253846Spendry * will happen if the server dies. Sleep for 5 second intervals 27353846Spendry * and keep polling the reference count. XXX. 27453846Spendry */ 27553846Spendry s = splnet(); 27653846Spendry while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) { 27753846Spendry if (fmp->pm_server->f_count == 1) { 27853846Spendry error = ECONNREFUSED; 27953846Spendry splx(s); 28053846Spendry #ifdef PORTAL_DIAGNOSTIC 28153846Spendry printf("portal_open: server process has gone away\n"); 28253846Spendry #endif 28353846Spendry goto bad; 28453846Spendry } 28553846Spendry (void) tsleep((caddr_t) &so->so_timeo, PSOCK, "portalcon", 5 * hz); 28653846Spendry } 28753846Spendry splx(s); 28853846Spendry 28953846Spendry if (so->so_error) { 29053846Spendry error = so->so_error; 29153846Spendry goto bad; 29253846Spendry } 29353846Spendry 29453846Spendry /* 29553846Spendry * Set miscellaneous flags 29653846Spendry */ 29753846Spendry so->so_rcv.sb_timeo = 0; 29853846Spendry so->so_snd.sb_timeo = 0; 29953846Spendry so->so_rcv.sb_flags |= SB_NOINTR; 30053846Spendry so->so_snd.sb_flags |= SB_NOINTR; 30153846Spendry 30253846Spendry #ifdef PORTAL_DIAGNOSTIC 30353846Spendry printf("portal_open: constructing data uio\n"); 30453846Spendry #endif 30553846Spendry 30654978Spendry pcred.pcr_flag = ap->a_mode; 30753846Spendry pcred.pcr_uid = ap->a_cred->cr_uid; 30854978Spendry pcred.pcr_ngroups = ap->a_cred->cr_ngroups; 30954978Spendry bcopy(ap->a_cred->cr_groups, pcred.pcr_groups, NGROUPS * sizeof(gid_t)); 31053846Spendry aiov[0].iov_base = (caddr_t) &pcred; 31153846Spendry aiov[0].iov_len = sizeof(pcred); 31253846Spendry aiov[1].iov_base = pt->pt_arg; 31353846Spendry aiov[1].iov_len = pt->pt_size; 31453846Spendry auio.uio_iov = aiov; 31553846Spendry auio.uio_iovcnt = 2; 31653846Spendry auio.uio_rw = UIO_WRITE; 31753846Spendry auio.uio_segflg = UIO_SYSSPACE; 31855910Spendry auio.uio_procp = p; 31953846Spendry auio.uio_offset = 0; 32053846Spendry auio.uio_resid = aiov[0].iov_len + aiov[1].iov_len; 32153846Spendry 32253846Spendry #ifdef PORTAL_DIAGNOSTIC 32353846Spendry printf("portal_open: sending data to server\n"); 32453846Spendry #endif 32553846Spendry error = sosend(so, (struct sockaddr *) 0, &auio, 32653846Spendry (struct mbuf *) 0, (struct mbuf *) 0, 0); 32753846Spendry if (error) 32853846Spendry goto bad; 32953846Spendry 33053846Spendry len = auio.uio_resid = sizeof(int); 33153846Spendry do { 33253846Spendry struct mbuf *m = 0; 33353846Spendry int flags = MSG_WAITALL; 33453846Spendry #ifdef PORTAL_DIAGNOSTIC 33553846Spendry printf("portal_open: receiving data from server\n"); 33653846Spendry printf("portal_open: so = %x, cm = %x, resid = %d\n", 33753846Spendry so, cm, auio.uio_resid); 33853846Spendry printf("portal_open, uio=%x, mp0=%x, controlp=%x\n", &auio, &cm); 33953846Spendry #endif 34053846Spendry error = soreceive(so, (struct mbuf **) 0, &auio, 34153846Spendry &m, &cm, &flags); 34253846Spendry #ifdef PORTAL_DIAGNOSTIC 34353846Spendry printf("portal_open: after receiving data\n"); 34453846Spendry printf("portal_open: so = %x, cm = %x, resid = %d\n", 34553846Spendry so, cm, auio.uio_resid); 34653846Spendry #endif 34753846Spendry if (error) 34853846Spendry goto bad; 34953846Spendry 35053846Spendry /* 35153846Spendry * Grab an error code from the mbuf. 35253846Spendry */ 35353846Spendry if (m) { 35453846Spendry m = m_pullup(m, sizeof(int)); /* Needed? */ 35553846Spendry if (m) { 35653846Spendry error = *(mtod(m, int *)); 35753846Spendry m_freem(m); 35853846Spendry } else { 35953846Spendry error = EINVAL; 36053846Spendry } 36153846Spendry #ifdef PORTAL_DIAGNOSTIC 36253846Spendry printf("portal_open: error returned is %d\n", error); 36353846Spendry #endif 36453846Spendry } else { 36553846Spendry if (cm == 0) { 36653846Spendry #ifdef PORTAL_DIAGNOSTIC 36753846Spendry printf("portal_open: no rights received\n"); 36853846Spendry #endif 36953846Spendry error = ECONNRESET; /* XXX */ 37053846Spendry #ifdef notdef 37153846Spendry break; 37253846Spendry #endif 37353846Spendry } 37453846Spendry } 37553846Spendry } while (cm == 0 && auio.uio_resid == len && !error); 37653846Spendry 37753846Spendry if (cm == 0) 37853846Spendry goto bad; 37953846Spendry 38053846Spendry if (auio.uio_resid) { 38153846Spendry #ifdef PORTAL_DIAGNOSTIC 38253846Spendry printf("portal_open: still need another %d bytes\n", auio.uio_resid); 38353846Spendry #endif 38453846Spendry error = 0; 38553846Spendry #ifdef notdef 38653846Spendry error = EMSGSIZE; 38753846Spendry goto bad; 38853846Spendry #endif 38953846Spendry } 39053846Spendry 39153846Spendry /* 39253846Spendry * XXX: Break apart the control message, and retrieve the 39353846Spendry * received file descriptor. Note that more than one descriptor 39453846Spendry * may have been received, or that the rights chain may have more 39553846Spendry * than a single mbuf in it. What to do? 39653846Spendry */ 39753846Spendry #ifdef PORTAL_DIAGNOSTIC 39853846Spendry printf("portal_open: about to break apart control message\n"); 39953846Spendry #endif 40053846Spendry cmsg = mtod(cm, struct cmsghdr *); 40153846Spendry newfds = (cmsg->cmsg_len - sizeof(*cmsg)) / sizeof (int); 40253846Spendry if (newfds == 0) { 40353846Spendry #ifdef PORTAL_DIAGNOSTIC 40453846Spendry printf("portal_open: received no fds\n"); 40553846Spendry #endif 40653846Spendry error = ECONNREFUSED; 40753846Spendry goto bad; 40853846Spendry } 40953846Spendry /* 41053846Spendry * At this point the rights message consists of a control message 41153846Spendry * header, followed by a data region containing a vector of 41253846Spendry * integer file descriptors. The fds were allocated by the action 41353846Spendry * of receiving the control message. 41453846Spendry */ 41553846Spendry ip = (int *) (cmsg + 1); 41653846Spendry fd = *ip++; 41753846Spendry if (newfds > 1) { 41853846Spendry /* 41953846Spendry * Close extra fds. 42053846Spendry */ 42153846Spendry int i; 42253846Spendry printf("portal_open: %d extra fds\n", newfds - 1); 42353846Spendry for (i = 1; i < newfds; i++) { 42455910Spendry portal_closefd(p, *ip); 42553846Spendry ip++; 42653846Spendry } 42753846Spendry } 42853846Spendry 42953846Spendry /* 43055910Spendry * Check that the mode the file is being opened for is a subset 43155910Spendry * of the mode of the existing descriptor. 43253846Spendry */ 43353846Spendry #ifdef PORTAL_DIAGNOSTIC 43453846Spendry printf("portal_open: checking file flags, fd = %d\n", fd); 43553846Spendry #endif 43655910Spendry fp = p->p_fd->fd_ofiles[fd]; 43753846Spendry if (((ap->a_mode & (FREAD|FWRITE)) | fp->f_flag) != fp->f_flag) { 43855910Spendry portal_closefd(p, fd); 43953846Spendry error = EACCES; 44053846Spendry goto bad; 44153846Spendry } 44253846Spendry 44353846Spendry #ifdef PORTAL_DIAGNOSTIC 44453846Spendry printf("portal_open: got fd = %d\n", fd); 44553846Spendry #endif 44653846Spendry /* 44753846Spendry * Save the dup fd in the proc structure then return the 44853846Spendry * special error code (ENXIO) which causes magic things to 44953846Spendry * happen in vn_open. The whole concept is, well, hmmm. 45053846Spendry */ 45155910Spendry p->p_dupfd = fd; 45253846Spendry error = ENXIO; 45353846Spendry 45453846Spendry bad:; 45553846Spendry /* 45653846Spendry * And discard the control message. 45753846Spendry */ 45853846Spendry if (cm) { 45953846Spendry #ifdef PORTAL_DIAGNOSTIC 46053846Spendry printf("portal_open: free'ing control message\n"); 46153846Spendry #endif 46253846Spendry m_freem(cm); 46353846Spendry } 46453846Spendry 46553846Spendry if (so) { 46653846Spendry #ifdef PORTAL_DIAGNOSTIC 46753846Spendry printf("portal_open: calling soshutdown\n"); 46853846Spendry #endif 46953846Spendry soshutdown(so, 2); 47053846Spendry #ifdef PORTAL_DIAGNOSTIC 47153846Spendry printf("portal_open: calling soclose\n"); 47253846Spendry #endif 47353846Spendry soclose(so); 47453846Spendry } 47553846Spendry #ifdef PORTAL_DIAGNOSTIC 47653846Spendry if (error != ENODEV) 47753846Spendry printf("portal_open: error = %d\n", error); 47853846Spendry #endif 47953846Spendry return (error); 48053846Spendry } 48153846Spendry 48255027Smckusick portal_getattr(ap) 48355027Smckusick struct vop_getattr_args /* { 48455027Smckusick struct vnode *a_vp; 48555027Smckusick struct vattr *a_vap; 48655027Smckusick struct ucred *a_cred; 48755027Smckusick struct proc *a_p; 48855027Smckusick } */ *ap; 48953846Spendry { 49055910Spendry struct vnode *vp = ap->a_vp; 49155910Spendry struct vattr *vap = ap->a_vap; 49253846Spendry unsigned fd; 49353846Spendry int error; 49453846Spendry 49555910Spendry bzero((caddr_t) vap, sizeof(*vap)); 49655910Spendry vattr_null(vap); 49755910Spendry vap->va_uid = 0; 49855910Spendry vap->va_gid = 0; 49955910Spendry vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0]; 50055910Spendry vap->va_size = DEV_BSIZE; 50155910Spendry vap->va_blocksize = DEV_BSIZE; 50255910Spendry microtime(&vap->va_atime); 50355910Spendry vap->va_mtime = vap->va_atime; 50455910Spendry vap->va_ctime = vap->va_ctime; 50555910Spendry vap->va_gen = 0; 50655910Spendry vap->va_flags = 0; 50755910Spendry vap->va_rdev = 0; 50855910Spendry /* vap->va_qbytes = 0; */ 50955910Spendry vap->va_bytes = 0; 51055910Spendry /* vap->va_qsize = 0; */ 51155910Spendry if (vp->v_flag & VROOT) { 51253846Spendry #ifdef PORTAL_DIAGNOSTIC 51353846Spendry printf("portal_getattr: stat rootdir\n"); 51453846Spendry #endif 51555910Spendry vap->va_type = VDIR; 51655910Spendry vap->va_mode = S_IRUSR|S_IWUSR|S_IXUSR| 51753846Spendry S_IRGRP|S_IWGRP|S_IXGRP| 51853846Spendry S_IROTH|S_IWOTH|S_IXOTH; 51955910Spendry vap->va_nlink = 2; 52055910Spendry vap->va_fileid = 2; 52153846Spendry } else { 52253846Spendry #ifdef PORTAL_DIAGNOSTIC 52353846Spendry printf("portal_getattr: stat portal\n"); 52453846Spendry #endif 52555910Spendry vap->va_type = VREG; 52655910Spendry vap->va_mode = S_IRUSR|S_IWUSR| 52753846Spendry S_IRGRP|S_IWGRP| 52853846Spendry S_IROTH|S_IWOTH; 52955910Spendry vap->va_nlink = 1; 53055910Spendry vap->va_fileid = VTOPORTAL(vp)->pt_fileid; 53153846Spendry } 53253846Spendry return (0); 53353846Spendry } 53453846Spendry 53555027Smckusick portal_setattr(ap) 53655027Smckusick struct vop_setattr_args /* { 53755027Smckusick struct vnode *a_vp; 53855027Smckusick struct vattr *a_vap; 53955027Smckusick struct ucred *a_cred; 54055027Smckusick struct proc *a_p; 54155027Smckusick } */ *ap; 54253846Spendry { 54353846Spendry /* 54453846Spendry * Can't mess with the root vnode 54553846Spendry */ 54653846Spendry if (ap->a_vp->v_flag & VROOT) 54753846Spendry return (EACCES); 54853846Spendry 54953846Spendry return (0); 55053846Spendry } 55153846Spendry 55253846Spendry /* 55353846Spendry * Fake readdir, just return empty directory. 55453846Spendry * It is hard to deal with '.' and '..' so don't bother. 55553846Spendry */ 55655027Smckusick portal_readdir(ap) 55755027Smckusick struct vop_readdir_args /* { 55855027Smckusick struct vnode *a_vp; 55955027Smckusick struct uio *a_uio; 56055027Smckusick struct ucred *a_cred; 56155027Smckusick } */ *ap; 56253846Spendry { 56354978Spendry /* *ap->a_eofflagp = 1; */ 56453846Spendry return (0); 56553846Spendry } 56653846Spendry 56755027Smckusick portal_inactive(ap) 56855027Smckusick struct vop_inactive_args /* { 56955027Smckusick struct vnode *a_vp; 57055027Smckusick } */ *ap; 57153846Spendry { 57253846Spendry #ifdef PORTAL_DIAGNOSTIC 57353846Spendry if (VTOPORTAL(ap->a_vp)->pt_arg) 57453846Spendry printf("portal_inactive(%x, %s)\n", ap->a_vp, VTOPORTAL(ap->a_vp)->pt_arg); 57553846Spendry else 57653846Spendry printf("portal_inactive(%x)\n", ap->a_vp); 57753846Spendry #endif 57853846Spendry /*vgone(ap->a_vp);*/ 57953846Spendry return (0); 58053846Spendry } 58153846Spendry 58255027Smckusick portal_reclaim(ap) 58355027Smckusick struct vop_reclaim_args /* { 58455027Smckusick struct vnode *a_vp; 58555027Smckusick } */ *ap; 58653846Spendry { 58753846Spendry struct portalnode *pt = VTOPORTAL(ap->a_vp); 58853846Spendry #ifdef PORTAL_DIAGOISTIC 58953846Spendry printf("portal_reclaim(%x)\n", ap->a_vp); 59053846Spendry #endif 59153846Spendry if (pt->pt_arg) { 59253846Spendry free((caddr_t) pt->pt_arg, M_TEMP); 59353846Spendry pt->pt_arg = 0; 59453846Spendry } 59553846Spendry FREE(pt, M_TEMP); 59653846Spendry return (0); 59753846Spendry } 59853846Spendry 59953846Spendry /* 60053846Spendry * Print out the contents of a Portal vnode. 60153846Spendry */ 60253846Spendry /* ARGSUSED */ 60355027Smckusick portal_print(ap) 60455027Smckusick struct vop_print_args /* { 60555027Smckusick struct vnode *a_vp; 60655027Smckusick } */ *ap; 60753846Spendry { 60855027Smckusick 60953846Spendry printf("tag VT_PORTAL, portal vnode\n"); 61055027Smckusick return (0); 61153846Spendry } 61253846Spendry 61353846Spendry /*void*/ 61455027Smckusick portal_vfree(ap) 61555027Smckusick struct vop_vfree_args /* { 61655027Smckusick struct vnode *a_pvp; 61755027Smckusick ino_t a_ino; 61855027Smckusick int a_mode; 61955027Smckusick } */ *ap; 62053846Spendry { 62155027Smckusick 62255027Smckusick return (0); 62353846Spendry } 62453846Spendry 62553846Spendry 62653846Spendry /* 62753846Spendry * Portal vnode unsupported operation 62853846Spendry */ 62953846Spendry portal_enotsupp() 63053846Spendry { 63155027Smckusick 63253846Spendry return (EOPNOTSUPP); 63353846Spendry } 63453846Spendry 63553846Spendry /* 63653846Spendry * Portal "should never get here" operation 63753846Spendry */ 63853846Spendry portal_badop() 63953846Spendry { 64055027Smckusick 64153846Spendry panic("portal: bad op"); 64253846Spendry /* NOTREACHED */ 64353846Spendry } 64453846Spendry 64553846Spendry /* 64653846Spendry * Portal vnode null operation 64753846Spendry */ 64853846Spendry portal_nullop() 64953846Spendry { 65055027Smckusick 65153846Spendry return (0); 65253846Spendry } 65353846Spendry 65455027Smckusick #define portal_create ((int (*) __P((struct vop_create_args *)))portal_enotsupp) 65553846Spendry #define portal_mknod ((int (*) __P((struct vop_mknod_args *)))portal_enotsupp) 65653846Spendry #define portal_close ((int (*) __P((struct vop_close_args *)))nullop) 65753846Spendry #define portal_access ((int (*) __P((struct vop_access_args *)))nullop) 65853846Spendry #define portal_read ((int (*) __P((struct vop_read_args *)))portal_enotsupp) 65953846Spendry #define portal_write ((int (*) __P((struct vop_write_args *)))portal_enotsupp) 66053846Spendry #define portal_ioctl ((int (*) __P((struct vop_ioctl_args *)))portal_enotsupp) 66155027Smckusick #define portal_select ((int (*) __P((struct vop_select_args *)))portal_enotsupp) 66253846Spendry #define portal_mmap ((int (*) __P((struct vop_mmap_args *)))portal_enotsupp) 66353846Spendry #define portal_fsync ((int (*) __P((struct vop_fsync_args *)))nullop) 66453846Spendry #define portal_seek ((int (*) __P((struct vop_seek_args *)))nullop) 66555027Smckusick #define portal_remove ((int (*) __P((struct vop_remove_args *)))portal_enotsupp) 66653846Spendry #define portal_link ((int (*) __P((struct vop_link_args *)))portal_enotsupp) 66755027Smckusick #define portal_rename ((int (*) __P((struct vop_rename_args *)))portal_enotsupp) 66853846Spendry #define portal_mkdir ((int (*) __P((struct vop_mkdir_args *)))portal_enotsupp) 66953846Spendry #define portal_rmdir ((int (*) __P((struct vop_rmdir_args *)))portal_enotsupp) 67055171Spendry #define portal_symlink \ 67155027Smckusick ((int (*) __P((struct vop_symlink_args *)))portal_enotsupp) 67255171Spendry #define portal_readlink \ 67355027Smckusick ((int (*) __P((struct vop_readlink_args *)))portal_enotsupp) 67453846Spendry #define portal_abortop ((int (*) __P((struct vop_abortop_args *)))nullop) 67553846Spendry #define portal_lock ((int (*) __P((struct vop_lock_args *)))nullop) 67653846Spendry #define portal_unlock ((int (*) __P((struct vop_unlock_args *)))nullop) 67753846Spendry #define portal_bmap ((int (*) __P((struct vop_bmap_args *)))portal_badop) 67855171Spendry #define portal_strategy \ 67955027Smckusick ((int (*) __P((struct vop_strategy_args *)))portal_badop) 68053846Spendry #define portal_islocked ((int (*) __P((struct vop_islocked_args *)))nullop) 68155171Spendry #define portal_advlock \ 68255027Smckusick ((int (*) __P((struct vop_advlock_args *)))portal_enotsupp) 68355171Spendry #define portal_blkatoff \ 68455027Smckusick ((int (*) __P((struct vop_blkatoff_args *)))portal_enotsupp) 68553846Spendry #define portal_valloc ((int(*) __P(( \ 68653846Spendry struct vnode *pvp, \ 68753846Spendry int mode, \ 68853846Spendry struct ucred *cred, \ 68953846Spendry struct vnode **vpp))) portal_enotsupp) 69055171Spendry #define portal_truncate \ 69155027Smckusick ((int (*) __P((struct vop_truncate_args *)))portal_enotsupp) 69255027Smckusick #define portal_update ((int (*) __P((struct vop_update_args *)))portal_enotsupp) 69355027Smckusick #define portal_bwrite ((int (*) __P((struct vop_bwrite_args *)))portal_enotsupp) 69453846Spendry 69553846Spendry int (**portal_vnodeop_p)(); 69653846Spendry struct vnodeopv_entry_desc portal_vnodeop_entries[] = { 69753846Spendry { &vop_default_desc, vn_default_error }, 69853846Spendry { &vop_lookup_desc, portal_lookup }, /* lookup */ 69953846Spendry { &vop_create_desc, portal_create }, /* create */ 70053846Spendry { &vop_mknod_desc, portal_mknod }, /* mknod */ 70153846Spendry { &vop_open_desc, portal_open }, /* open */ 70253846Spendry { &vop_close_desc, portal_close }, /* close */ 70353846Spendry { &vop_access_desc, portal_access }, /* access */ 70453846Spendry { &vop_getattr_desc, portal_getattr }, /* getattr */ 70553846Spendry { &vop_setattr_desc, portal_setattr }, /* setattr */ 70653846Spendry { &vop_read_desc, portal_read }, /* read */ 70753846Spendry { &vop_write_desc, portal_write }, /* write */ 70853846Spendry { &vop_ioctl_desc, portal_ioctl }, /* ioctl */ 70953846Spendry { &vop_select_desc, portal_select }, /* select */ 71053846Spendry { &vop_mmap_desc, portal_mmap }, /* mmap */ 71153846Spendry { &vop_fsync_desc, portal_fsync }, /* fsync */ 71253846Spendry { &vop_seek_desc, portal_seek }, /* seek */ 71353846Spendry { &vop_remove_desc, portal_remove }, /* remove */ 71453846Spendry { &vop_link_desc, portal_link }, /* link */ 71553846Spendry { &vop_rename_desc, portal_rename }, /* rename */ 71653846Spendry { &vop_mkdir_desc, portal_mkdir }, /* mkdir */ 71753846Spendry { &vop_rmdir_desc, portal_rmdir }, /* rmdir */ 71853846Spendry { &vop_symlink_desc, portal_symlink }, /* symlink */ 71953846Spendry { &vop_readdir_desc, portal_readdir }, /* readdir */ 72053846Spendry { &vop_readlink_desc, portal_readlink }, /* readlink */ 72153846Spendry { &vop_abortop_desc, portal_abortop }, /* abortop */ 72253846Spendry { &vop_inactive_desc, portal_inactive }, /* inactive */ 72353846Spendry { &vop_reclaim_desc, portal_reclaim }, /* reclaim */ 72453846Spendry { &vop_lock_desc, portal_lock }, /* lock */ 72553846Spendry { &vop_unlock_desc, portal_unlock }, /* unlock */ 72653846Spendry { &vop_bmap_desc, portal_bmap }, /* bmap */ 72753846Spendry { &vop_strategy_desc, portal_strategy }, /* strategy */ 72853846Spendry { &vop_print_desc, portal_print }, /* print */ 72953846Spendry { &vop_islocked_desc, portal_islocked }, /* islocked */ 73053846Spendry { &vop_advlock_desc, portal_advlock }, /* advlock */ 73153846Spendry { &vop_blkatoff_desc, portal_blkatoff }, /* blkatoff */ 73253846Spendry { &vop_valloc_desc, portal_valloc }, /* valloc */ 73353846Spendry { &vop_vfree_desc, portal_vfree }, /* vfree */ 73453846Spendry { &vop_truncate_desc, portal_truncate }, /* truncate */ 73553846Spendry { &vop_update_desc, portal_update }, /* update */ 73653846Spendry { &vop_bwrite_desc, portal_bwrite }, /* bwrite */ 73753846Spendry { (struct vnodeop_desc*)NULL, (int(*)())NULL } 73853846Spendry }; 73953846Spendry struct vnodeopv_desc portal_vnodeop_opv_desc = 74053846Spendry { &portal_vnodeop_p, portal_vnodeop_entries }; 741