153846Spendry /* 263246Sbostic * Copyright (c) 1992, 1993 363246Sbostic * The Regents of the University of California. All rights reserved. 453846Spendry * 553846Spendry * This code is derived from software donated to Berkeley by 653846Spendry * Jan-Simon Pendry. 753846Spendry * 853846Spendry * %sccs.include.redist.c% 953846Spendry * 10*69350Smckusick * @(#)portal_vnops.c 8.12 (Berkeley) 05/10/95 1153846Spendry * 1253846Spendry * $Id: portal_vnops.c,v 1.4 1992/05/30 10:05:24 jsp Exp jsp $ 1353846Spendry */ 1453846Spendry 1553846Spendry /* 1653846Spendry * Portal Filesystem 1753846Spendry */ 1853846Spendry 1953846Spendry #include <sys/param.h> 2053846Spendry #include <sys/systm.h> 2153846Spendry #include <sys/kernel.h> 2253846Spendry #include <sys/types.h> 2353846Spendry #include <sys/time.h> 2453846Spendry #include <sys/proc.h> 2553846Spendry #include <sys/filedesc.h> 2653846Spendry #include <sys/vnode.h> 2753846Spendry #include <sys/file.h> 2853846Spendry #include <sys/stat.h> 2953846Spendry #include <sys/mount.h> 3053846Spendry #include <sys/malloc.h> 3153846Spendry #include <sys/namei.h> 3253846Spendry #include <sys/mbuf.h> 3353846Spendry #include <sys/socket.h> 3453846Spendry #include <sys/socketvar.h> 3553846Spendry #include <sys/un.h> 3653846Spendry #include <sys/unpcb.h> 3755027Smckusick #include <miscfs/portal/portal.h> 3853846Spendry 3953846Spendry static int portal_fileid = PORTAL_ROOTFILEID+1; 4053846Spendry 4153846Spendry static void 4253846Spendry portal_closefd(p, fd) 4353846Spendry struct proc *p; 4453846Spendry int fd; 4553846Spendry { 4653846Spendry int error; 4753846Spendry struct { 4853846Spendry int fd; 4953846Spendry } ua; 5053846Spendry int rc; 5153846Spendry 5253846Spendry ua.fd = fd; 5353846Spendry error = close(p, &ua, &rc); 5453846Spendry /* 5553846Spendry * We should never get an error, and there isn't anything 5653846Spendry * we could do if we got one, so just print a message. 5753846Spendry */ 5853846Spendry if (error) 5953846Spendry printf("portal_closefd: error = %d\n", error); 6053846Spendry } 6153846Spendry 6253846Spendry /* 6353846Spendry * vp is the current namei directory 6453846Spendry * cnp is the name to locate in that directory... 6553846Spendry */ 6665516Spendry int 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 { 74*69350Smckusick struct componentname *cnp = ap->a_cnp; 75*69350Smckusick struct vnode **vpp = ap->a_vpp; 76*69350Smckusick struct vnode *dvp = ap->a_dvp; 77*69350Smckusick char *pname = cnp->cn_nameptr; 7853846Spendry struct portalnode *pt; 7953846Spendry int error; 8053846Spendry struct vnode *fvp = 0; 8153846Spendry char *path; 8253846Spendry int size; 8353846Spendry 84*69350Smckusick *vpp = NULLVP; 85*69350Smckusick 86*69350Smckusick if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME) 87*69350Smckusick return (EROFS); 88*69350Smckusick 89*69350Smckusick if (cnp->cn_namelen == 1 && *pname == '.') { 90*69350Smckusick *vpp = dvp; 91*69350Smckusick VREF(dvp); 92*69350Smckusick /*VOP_LOCK(dvp);*/ 9353846Spendry return (0); 9453846Spendry } 9553846Spendry 96*69350Smckusick error = getnewvnode(VT_PORTAL, dvp->v_mount, portal_vnodeop_p, &fvp); 9753846Spendry if (error) 9853846Spendry goto bad; 9953846Spendry fvp->v_type = VREG; 100*69350Smckusick MALLOC(fvp->v_data, void *, sizeof(struct portalnode), M_TEMP, 101*69350Smckusick M_WAITOK); 10253846Spendry 10353846Spendry pt = VTOPORTAL(fvp); 10453846Spendry /* 10553846Spendry * Save all of the remaining pathname and 10653846Spendry * advance the namei next pointer to the end 10753846Spendry * of the string. 10853846Spendry */ 10953846Spendry for (size = 0, path = pname; *path; path++) 11053846Spendry size++; 111*69350Smckusick cnp->cn_consume = size - cnp->cn_namelen; 11254978Spendry 11353846Spendry pt->pt_arg = malloc(size+1, M_TEMP, M_WAITOK); 11453846Spendry pt->pt_size = size+1; 11553846Spendry bcopy(pname, pt->pt_arg, pt->pt_size); 11653846Spendry pt->pt_fileid = portal_fileid++; 11753846Spendry 118*69350Smckusick *vpp = fvp; 11953846Spendry /*VOP_LOCK(fvp);*/ 12053846Spendry return (0); 12153846Spendry 12253846Spendry bad:; 123*69350Smckusick if (fvp) 12453846Spendry vrele(fvp); 12553846Spendry return (error); 12653846Spendry } 12753846Spendry 12853846Spendry static int 12953846Spendry portal_connect(so, so2) 13053846Spendry struct socket *so; 13153846Spendry struct socket *so2; 13253846Spendry { 13353846Spendry /* from unp_connect, bypassing the namei stuff... */ 13453846Spendry struct socket *so3; 13553846Spendry struct unpcb *unp2; 13653846Spendry struct unpcb *unp3; 13753846Spendry 13853846Spendry if (so2 == 0) 13953846Spendry return (ECONNREFUSED); 14053846Spendry 14153846Spendry if (so->so_type != so2->so_type) 14253846Spendry return (EPROTOTYPE); 14353846Spendry 14453846Spendry if ((so2->so_options & SO_ACCEPTCONN) == 0) 14553846Spendry return (ECONNREFUSED); 14653846Spendry 14753846Spendry if ((so3 = sonewconn(so2, 0)) == 0) 14853846Spendry return (ECONNREFUSED); 14953846Spendry 15053846Spendry unp2 = sotounpcb(so2); 15153846Spendry unp3 = sotounpcb(so3); 15253846Spendry if (unp2->unp_addr) 15353846Spendry unp3->unp_addr = m_copy(unp2->unp_addr, 0, (int)M_COPYALL); 15453846Spendry 15553846Spendry so2 = so3; 15653846Spendry 15753846Spendry 15853846Spendry return (unp_connect2(so, so2)); 15953846Spendry } 16053846Spendry 16165516Spendry int 16255027Smckusick portal_open(ap) 16355027Smckusick struct vop_open_args /* { 16455027Smckusick struct vnode *a_vp; 16555027Smckusick int a_mode; 16655027Smckusick struct ucred *a_cred; 16755027Smckusick struct proc *a_p; 16855027Smckusick } */ *ap; 16953846Spendry { 17053846Spendry struct socket *so = 0; 17153846Spendry struct portalnode *pt; 17255910Spendry struct proc *p = ap->a_p; 17355910Spendry struct vnode *vp = ap->a_vp; 17453846Spendry int s; 17553846Spendry struct uio auio; 17653846Spendry struct iovec aiov[2]; 17753846Spendry int res; 17853846Spendry struct mbuf *cm = 0; 17953846Spendry struct cmsghdr *cmsg; 18053846Spendry int newfds; 18153846Spendry int *ip; 18253846Spendry int fd; 18353846Spendry int error; 18453846Spendry int len; 18553846Spendry struct portalmount *fmp; 18653846Spendry struct file *fp; 18753846Spendry struct portal_cred pcred; 18853846Spendry 18953846Spendry /* 19053846Spendry * Nothing to do when opening the root node. 19153846Spendry */ 19255910Spendry if (vp->v_flag & VROOT) 19353846Spendry return (0); 19453846Spendry 19553846Spendry /* 19653846Spendry * Can't be opened unless the caller is set up 19753846Spendry * to deal with the side effects. Check for this 19853846Spendry * by testing whether the p_dupfd has been set. 19953846Spendry */ 20055910Spendry if (p->p_dupfd >= 0) 20153846Spendry return (ENODEV); 20253846Spendry 20355910Spendry pt = VTOPORTAL(vp); 20455910Spendry fmp = VFSTOPORTAL(vp->v_mount); 20553846Spendry 20653846Spendry /* 20753846Spendry * Create a new socket. 20853846Spendry */ 20953846Spendry error = socreate(AF_UNIX, &so, SOCK_STREAM, 0); 21053846Spendry if (error) 21153846Spendry goto bad; 21253846Spendry 21353846Spendry /* 21453846Spendry * Reserve some buffer space 21553846Spendry */ 21654978Spendry res = pt->pt_size + sizeof(pcred) + 512; /* XXX */ 21753846Spendry error = soreserve(so, res, res); 21853846Spendry if (error) 21953846Spendry goto bad; 22053846Spendry 22153846Spendry /* 22253846Spendry * Kick off connection 22353846Spendry */ 22453846Spendry error = portal_connect(so, (struct socket *)fmp->pm_server->f_data); 22553846Spendry if (error) 22653846Spendry goto bad; 22753846Spendry 22853846Spendry /* 22953846Spendry * Wait for connection to complete 23053846Spendry */ 23153846Spendry /* 23253846Spendry * XXX: Since the mount point is holding a reference on the 23353846Spendry * underlying server socket, it is not easy to find out whether 23453846Spendry * the server process is still running. To handle this problem 23553846Spendry * we loop waiting for the new socket to be connected (something 23653846Spendry * which will only happen if the server is still running) or for 23753846Spendry * the reference count on the server socket to drop to 1, which 23853846Spendry * will happen if the server dies. Sleep for 5 second intervals 23953846Spendry * and keep polling the reference count. XXX. 24053846Spendry */ 24153846Spendry s = splnet(); 24253846Spendry while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) { 24353846Spendry if (fmp->pm_server->f_count == 1) { 24453846Spendry error = ECONNREFUSED; 24553846Spendry splx(s); 24653846Spendry goto bad; 24753846Spendry } 24853846Spendry (void) tsleep((caddr_t) &so->so_timeo, PSOCK, "portalcon", 5 * hz); 24953846Spendry } 25053846Spendry splx(s); 25153846Spendry 25253846Spendry if (so->so_error) { 25353846Spendry error = so->so_error; 25453846Spendry goto bad; 25553846Spendry } 25653846Spendry 25753846Spendry /* 25853846Spendry * Set miscellaneous flags 25953846Spendry */ 26053846Spendry so->so_rcv.sb_timeo = 0; 26153846Spendry so->so_snd.sb_timeo = 0; 26253846Spendry so->so_rcv.sb_flags |= SB_NOINTR; 26353846Spendry so->so_snd.sb_flags |= SB_NOINTR; 26453846Spendry 26553846Spendry 26654978Spendry pcred.pcr_flag = ap->a_mode; 26753846Spendry pcred.pcr_uid = ap->a_cred->cr_uid; 26854978Spendry pcred.pcr_ngroups = ap->a_cred->cr_ngroups; 26954978Spendry bcopy(ap->a_cred->cr_groups, pcred.pcr_groups, NGROUPS * sizeof(gid_t)); 27053846Spendry aiov[0].iov_base = (caddr_t) &pcred; 27153846Spendry aiov[0].iov_len = sizeof(pcred); 27253846Spendry aiov[1].iov_base = pt->pt_arg; 27353846Spendry aiov[1].iov_len = pt->pt_size; 27453846Spendry auio.uio_iov = aiov; 27553846Spendry auio.uio_iovcnt = 2; 27653846Spendry auio.uio_rw = UIO_WRITE; 27753846Spendry auio.uio_segflg = UIO_SYSSPACE; 27855910Spendry auio.uio_procp = p; 27953846Spendry auio.uio_offset = 0; 28053846Spendry auio.uio_resid = aiov[0].iov_len + aiov[1].iov_len; 28153846Spendry 28265492Spendry error = sosend(so, (struct mbuf *) 0, &auio, 28353846Spendry (struct mbuf *) 0, (struct mbuf *) 0, 0); 28453846Spendry if (error) 28553846Spendry goto bad; 28653846Spendry 28753846Spendry len = auio.uio_resid = sizeof(int); 28853846Spendry do { 28953846Spendry struct mbuf *m = 0; 29053846Spendry int flags = MSG_WAITALL; 29153846Spendry error = soreceive(so, (struct mbuf **) 0, &auio, 29253846Spendry &m, &cm, &flags); 29353846Spendry if (error) 29453846Spendry goto bad; 29553846Spendry 29653846Spendry /* 29753846Spendry * Grab an error code from the mbuf. 29853846Spendry */ 29953846Spendry if (m) { 30053846Spendry m = m_pullup(m, sizeof(int)); /* Needed? */ 30153846Spendry if (m) { 30253846Spendry error = *(mtod(m, int *)); 30353846Spendry m_freem(m); 30453846Spendry } else { 30553846Spendry error = EINVAL; 30653846Spendry } 30753846Spendry } else { 30853846Spendry if (cm == 0) { 30953846Spendry error = ECONNRESET; /* XXX */ 31053846Spendry #ifdef notdef 31153846Spendry break; 31253846Spendry #endif 31353846Spendry } 31453846Spendry } 31553846Spendry } while (cm == 0 && auio.uio_resid == len && !error); 31653846Spendry 31753846Spendry if (cm == 0) 31853846Spendry goto bad; 31953846Spendry 32053846Spendry if (auio.uio_resid) { 32153846Spendry error = 0; 32253846Spendry #ifdef notdef 32353846Spendry error = EMSGSIZE; 32453846Spendry goto bad; 32553846Spendry #endif 32653846Spendry } 32753846Spendry 32853846Spendry /* 32953846Spendry * XXX: Break apart the control message, and retrieve the 33053846Spendry * received file descriptor. Note that more than one descriptor 33153846Spendry * may have been received, or that the rights chain may have more 33253846Spendry * than a single mbuf in it. What to do? 33353846Spendry */ 33453846Spendry cmsg = mtod(cm, struct cmsghdr *); 33553846Spendry newfds = (cmsg->cmsg_len - sizeof(*cmsg)) / sizeof (int); 33653846Spendry if (newfds == 0) { 33753846Spendry error = ECONNREFUSED; 33853846Spendry goto bad; 33953846Spendry } 34053846Spendry /* 34153846Spendry * At this point the rights message consists of a control message 34253846Spendry * header, followed by a data region containing a vector of 34353846Spendry * integer file descriptors. The fds were allocated by the action 34453846Spendry * of receiving the control message. 34553846Spendry */ 34653846Spendry ip = (int *) (cmsg + 1); 34753846Spendry fd = *ip++; 34853846Spendry if (newfds > 1) { 34953846Spendry /* 35053846Spendry * Close extra fds. 35153846Spendry */ 35253846Spendry int i; 35353846Spendry printf("portal_open: %d extra fds\n", newfds - 1); 35453846Spendry for (i = 1; i < newfds; i++) { 35555910Spendry portal_closefd(p, *ip); 35653846Spendry ip++; 35753846Spendry } 35853846Spendry } 35953846Spendry 36053846Spendry /* 36155910Spendry * Check that the mode the file is being opened for is a subset 36255910Spendry * of the mode of the existing descriptor. 36353846Spendry */ 36455910Spendry fp = p->p_fd->fd_ofiles[fd]; 36553846Spendry if (((ap->a_mode & (FREAD|FWRITE)) | fp->f_flag) != fp->f_flag) { 36655910Spendry portal_closefd(p, fd); 36753846Spendry error = EACCES; 36853846Spendry goto bad; 36953846Spendry } 37053846Spendry 37153846Spendry /* 37253846Spendry * Save the dup fd in the proc structure then return the 37353846Spendry * special error code (ENXIO) which causes magic things to 37453846Spendry * happen in vn_open. The whole concept is, well, hmmm. 37553846Spendry */ 37655910Spendry p->p_dupfd = fd; 37753846Spendry error = ENXIO; 37853846Spendry 37953846Spendry bad:; 38053846Spendry /* 38153846Spendry * And discard the control message. 38253846Spendry */ 38353846Spendry if (cm) { 38453846Spendry m_freem(cm); 38553846Spendry } 38653846Spendry 38753846Spendry if (so) { 38853846Spendry soshutdown(so, 2); 38953846Spendry soclose(so); 39053846Spendry } 39153846Spendry return (error); 39253846Spendry } 39353846Spendry 39465516Spendry int 39555027Smckusick portal_getattr(ap) 39655027Smckusick struct vop_getattr_args /* { 39755027Smckusick struct vnode *a_vp; 39855027Smckusick struct vattr *a_vap; 39955027Smckusick struct ucred *a_cred; 40055027Smckusick struct proc *a_p; 40155027Smckusick } */ *ap; 40253846Spendry { 40355910Spendry struct vnode *vp = ap->a_vp; 40455910Spendry struct vattr *vap = ap->a_vap; 40568172Scgd struct timeval tv; 40653846Spendry 40765450Sbostic bzero(vap, sizeof(*vap)); 40855910Spendry vattr_null(vap); 40955910Spendry vap->va_uid = 0; 41055910Spendry vap->va_gid = 0; 41155910Spendry vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0]; 41255910Spendry vap->va_size = DEV_BSIZE; 41355910Spendry vap->va_blocksize = DEV_BSIZE; 41468172Scgd microtime(&tv); 41568172Scgd TIMEVAL_TO_TIMESPEC(&tv, &vap->va_atime); 41655910Spendry vap->va_mtime = vap->va_atime; 41755910Spendry vap->va_ctime = vap->va_ctime; 41855910Spendry vap->va_gen = 0; 41955910Spendry vap->va_flags = 0; 42055910Spendry vap->va_rdev = 0; 42155910Spendry /* vap->va_qbytes = 0; */ 42255910Spendry vap->va_bytes = 0; 42355910Spendry /* vap->va_qsize = 0; */ 42455910Spendry if (vp->v_flag & VROOT) { 42555910Spendry vap->va_type = VDIR; 42655910Spendry vap->va_mode = S_IRUSR|S_IWUSR|S_IXUSR| 42753846Spendry S_IRGRP|S_IWGRP|S_IXGRP| 42853846Spendry S_IROTH|S_IWOTH|S_IXOTH; 42955910Spendry vap->va_nlink = 2; 43055910Spendry vap->va_fileid = 2; 43153846Spendry } else { 43255910Spendry vap->va_type = VREG; 43355910Spendry vap->va_mode = S_IRUSR|S_IWUSR| 43453846Spendry S_IRGRP|S_IWGRP| 43553846Spendry S_IROTH|S_IWOTH; 43655910Spendry vap->va_nlink = 1; 43755910Spendry vap->va_fileid = VTOPORTAL(vp)->pt_fileid; 43853846Spendry } 43953846Spendry return (0); 44053846Spendry } 44153846Spendry 44265516Spendry int 44355027Smckusick portal_setattr(ap) 44455027Smckusick struct vop_setattr_args /* { 44555027Smckusick struct vnode *a_vp; 44655027Smckusick struct vattr *a_vap; 44755027Smckusick struct ucred *a_cred; 44855027Smckusick struct proc *a_p; 44955027Smckusick } */ *ap; 45053846Spendry { 45165516Spendry 45253846Spendry /* 45353846Spendry * Can't mess with the root vnode 45453846Spendry */ 45553846Spendry if (ap->a_vp->v_flag & VROOT) 45653846Spendry return (EACCES); 45753846Spendry 45853846Spendry return (0); 45953846Spendry } 46053846Spendry 46153846Spendry /* 46253846Spendry * Fake readdir, just return empty directory. 46353846Spendry * It is hard to deal with '.' and '..' so don't bother. 46453846Spendry */ 46565516Spendry int 46655027Smckusick portal_readdir(ap) 46755027Smckusick struct vop_readdir_args /* { 46855027Smckusick struct vnode *a_vp; 46955027Smckusick struct uio *a_uio; 47055027Smckusick struct ucred *a_cred; 47167366Smckusick int *a_eofflag; 47267366Smckusick u_long *a_cookies; 47367366Smckusick int a_ncookies; 47455027Smckusick } */ *ap; 47553846Spendry { 47665516Spendry 47767366Smckusick /* 47867366Smckusick * We don't allow exporting portal mounts, and currently local 47967366Smckusick * requests do not need cookies. 48067366Smckusick */ 48167366Smckusick if (ap->a_ncookies) 48267366Smckusick panic("portal_readdir: not hungry"); 48367366Smckusick 48453846Spendry return (0); 48553846Spendry } 48653846Spendry 48765516Spendry int 48855027Smckusick portal_inactive(ap) 48955027Smckusick struct vop_inactive_args /* { 49055027Smckusick struct vnode *a_vp; 49155027Smckusick } */ *ap; 49253846Spendry { 49365516Spendry 49453846Spendry return (0); 49553846Spendry } 49653846Spendry 49765516Spendry int 49855027Smckusick portal_reclaim(ap) 49955027Smckusick struct vop_reclaim_args /* { 50055027Smckusick struct vnode *a_vp; 50155027Smckusick } */ *ap; 50253846Spendry { 50353846Spendry struct portalnode *pt = VTOPORTAL(ap->a_vp); 50465516Spendry 50553846Spendry if (pt->pt_arg) { 50653846Spendry free((caddr_t) pt->pt_arg, M_TEMP); 50753846Spendry pt->pt_arg = 0; 50853846Spendry } 50965384Spendry FREE(ap->a_vp->v_data, M_TEMP); 51065384Spendry ap->a_vp->v_data = 0; 51165516Spendry 51253846Spendry return (0); 51353846Spendry } 51453846Spendry 51553846Spendry /* 51665741Spendry * Return POSIX pathconf information applicable to special devices. 51765741Spendry */ 51865741Spendry portal_pathconf(ap) 51965741Spendry struct vop_pathconf_args /* { 52065741Spendry struct vnode *a_vp; 52165741Spendry int a_name; 52265741Spendry int *a_retval; 52365741Spendry } */ *ap; 52465741Spendry { 52565741Spendry 52665741Spendry switch (ap->a_name) { 52765741Spendry case _PC_LINK_MAX: 52865741Spendry *ap->a_retval = LINK_MAX; 52965741Spendry return (0); 53065741Spendry case _PC_MAX_CANON: 53165741Spendry *ap->a_retval = MAX_CANON; 53265741Spendry return (0); 53365741Spendry case _PC_MAX_INPUT: 53465741Spendry *ap->a_retval = MAX_INPUT; 53565741Spendry return (0); 53665741Spendry case _PC_PIPE_BUF: 53765741Spendry *ap->a_retval = PIPE_BUF; 53865741Spendry return (0); 53965741Spendry case _PC_CHOWN_RESTRICTED: 54065741Spendry *ap->a_retval = 1; 54165741Spendry return (0); 54265741Spendry case _PC_VDISABLE: 54365741Spendry *ap->a_retval = _POSIX_VDISABLE; 54465741Spendry return (0); 54565741Spendry default: 54665741Spendry return (EINVAL); 54765741Spendry } 54865741Spendry /* NOTREACHED */ 54965741Spendry } 55065741Spendry 55165741Spendry /* 55253846Spendry * Print out the contents of a Portal vnode. 55353846Spendry */ 55453846Spendry /* ARGSUSED */ 55565516Spendry int 55655027Smckusick portal_print(ap) 55755027Smckusick struct vop_print_args /* { 55855027Smckusick struct vnode *a_vp; 55955027Smckusick } */ *ap; 56053846Spendry { 56155027Smckusick 56253846Spendry printf("tag VT_PORTAL, portal vnode\n"); 56355027Smckusick return (0); 56453846Spendry } 56553846Spendry 56653846Spendry /*void*/ 56765516Spendry int 56855027Smckusick portal_vfree(ap) 56955027Smckusick struct vop_vfree_args /* { 57055027Smckusick struct vnode *a_pvp; 57155027Smckusick ino_t a_ino; 57255027Smckusick int a_mode; 57355027Smckusick } */ *ap; 57453846Spendry { 57555027Smckusick 57655027Smckusick return (0); 57753846Spendry } 57853846Spendry 57953846Spendry 58053846Spendry /* 58153846Spendry * Portal vnode unsupported operation 58253846Spendry */ 58365516Spendry int 58453846Spendry portal_enotsupp() 58553846Spendry { 58655027Smckusick 58753846Spendry return (EOPNOTSUPP); 58853846Spendry } 58953846Spendry 59053846Spendry /* 59153846Spendry * Portal "should never get here" operation 59253846Spendry */ 59365516Spendry int 59453846Spendry portal_badop() 59553846Spendry { 59655027Smckusick 59753846Spendry panic("portal: bad op"); 59853846Spendry /* NOTREACHED */ 59953846Spendry } 60053846Spendry 60153846Spendry /* 60253846Spendry * Portal vnode null operation 60353846Spendry */ 60465516Spendry int 60553846Spendry portal_nullop() 60653846Spendry { 60755027Smckusick 60853846Spendry return (0); 60953846Spendry } 61053846Spendry 61155027Smckusick #define portal_create ((int (*) __P((struct vop_create_args *)))portal_enotsupp) 61253846Spendry #define portal_mknod ((int (*) __P((struct vop_mknod_args *)))portal_enotsupp) 61353846Spendry #define portal_close ((int (*) __P((struct vop_close_args *)))nullop) 61453846Spendry #define portal_access ((int (*) __P((struct vop_access_args *)))nullop) 61553846Spendry #define portal_read ((int (*) __P((struct vop_read_args *)))portal_enotsupp) 61653846Spendry #define portal_write ((int (*) __P((struct vop_write_args *)))portal_enotsupp) 61753846Spendry #define portal_ioctl ((int (*) __P((struct vop_ioctl_args *)))portal_enotsupp) 61855027Smckusick #define portal_select ((int (*) __P((struct vop_select_args *)))portal_enotsupp) 61953846Spendry #define portal_mmap ((int (*) __P((struct vop_mmap_args *)))portal_enotsupp) 62068731Smckusick #define portal_revoke vop_revoke 62153846Spendry #define portal_fsync ((int (*) __P((struct vop_fsync_args *)))nullop) 62253846Spendry #define portal_seek ((int (*) __P((struct vop_seek_args *)))nullop) 62355027Smckusick #define portal_remove ((int (*) __P((struct vop_remove_args *)))portal_enotsupp) 62453846Spendry #define portal_link ((int (*) __P((struct vop_link_args *)))portal_enotsupp) 62555027Smckusick #define portal_rename ((int (*) __P((struct vop_rename_args *)))portal_enotsupp) 62653846Spendry #define portal_mkdir ((int (*) __P((struct vop_mkdir_args *)))portal_enotsupp) 62753846Spendry #define portal_rmdir ((int (*) __P((struct vop_rmdir_args *)))portal_enotsupp) 62855171Spendry #define portal_symlink \ 62955027Smckusick ((int (*) __P((struct vop_symlink_args *)))portal_enotsupp) 63055171Spendry #define portal_readlink \ 63155027Smckusick ((int (*) __P((struct vop_readlink_args *)))portal_enotsupp) 63253846Spendry #define portal_abortop ((int (*) __P((struct vop_abortop_args *)))nullop) 63353846Spendry #define portal_lock ((int (*) __P((struct vop_lock_args *)))nullop) 63453846Spendry #define portal_unlock ((int (*) __P((struct vop_unlock_args *)))nullop) 63553846Spendry #define portal_bmap ((int (*) __P((struct vop_bmap_args *)))portal_badop) 63655171Spendry #define portal_strategy \ 63755027Smckusick ((int (*) __P((struct vop_strategy_args *)))portal_badop) 63853846Spendry #define portal_islocked ((int (*) __P((struct vop_islocked_args *)))nullop) 63955171Spendry #define portal_advlock \ 64055027Smckusick ((int (*) __P((struct vop_advlock_args *)))portal_enotsupp) 64155171Spendry #define portal_blkatoff \ 64255027Smckusick ((int (*) __P((struct vop_blkatoff_args *)))portal_enotsupp) 64353846Spendry #define portal_valloc ((int(*) __P(( \ 64453846Spendry struct vnode *pvp, \ 64553846Spendry int mode, \ 64653846Spendry struct ucred *cred, \ 64753846Spendry struct vnode **vpp))) portal_enotsupp) 64855171Spendry #define portal_truncate \ 64955027Smckusick ((int (*) __P((struct vop_truncate_args *)))portal_enotsupp) 65055027Smckusick #define portal_update ((int (*) __P((struct vop_update_args *)))portal_enotsupp) 65155027Smckusick #define portal_bwrite ((int (*) __P((struct vop_bwrite_args *)))portal_enotsupp) 65253846Spendry 65353846Spendry int (**portal_vnodeop_p)(); 65453846Spendry struct vnodeopv_entry_desc portal_vnodeop_entries[] = { 65553846Spendry { &vop_default_desc, vn_default_error }, 65653846Spendry { &vop_lookup_desc, portal_lookup }, /* lookup */ 65753846Spendry { &vop_create_desc, portal_create }, /* create */ 65853846Spendry { &vop_mknod_desc, portal_mknod }, /* mknod */ 65953846Spendry { &vop_open_desc, portal_open }, /* open */ 66053846Spendry { &vop_close_desc, portal_close }, /* close */ 66153846Spendry { &vop_access_desc, portal_access }, /* access */ 66253846Spendry { &vop_getattr_desc, portal_getattr }, /* getattr */ 66353846Spendry { &vop_setattr_desc, portal_setattr }, /* setattr */ 66453846Spendry { &vop_read_desc, portal_read }, /* read */ 66553846Spendry { &vop_write_desc, portal_write }, /* write */ 66653846Spendry { &vop_ioctl_desc, portal_ioctl }, /* ioctl */ 66753846Spendry { &vop_select_desc, portal_select }, /* select */ 66853846Spendry { &vop_mmap_desc, portal_mmap }, /* mmap */ 66968731Smckusick { &vop_revoke_desc, portal_revoke }, /* revoke */ 67053846Spendry { &vop_fsync_desc, portal_fsync }, /* fsync */ 67153846Spendry { &vop_seek_desc, portal_seek }, /* seek */ 67253846Spendry { &vop_remove_desc, portal_remove }, /* remove */ 67353846Spendry { &vop_link_desc, portal_link }, /* link */ 67453846Spendry { &vop_rename_desc, portal_rename }, /* rename */ 67553846Spendry { &vop_mkdir_desc, portal_mkdir }, /* mkdir */ 67653846Spendry { &vop_rmdir_desc, portal_rmdir }, /* rmdir */ 67753846Spendry { &vop_symlink_desc, portal_symlink }, /* symlink */ 67853846Spendry { &vop_readdir_desc, portal_readdir }, /* readdir */ 67953846Spendry { &vop_readlink_desc, portal_readlink }, /* readlink */ 68053846Spendry { &vop_abortop_desc, portal_abortop }, /* abortop */ 68153846Spendry { &vop_inactive_desc, portal_inactive }, /* inactive */ 68253846Spendry { &vop_reclaim_desc, portal_reclaim }, /* reclaim */ 68353846Spendry { &vop_lock_desc, portal_lock }, /* lock */ 68453846Spendry { &vop_unlock_desc, portal_unlock }, /* unlock */ 68553846Spendry { &vop_bmap_desc, portal_bmap }, /* bmap */ 68653846Spendry { &vop_strategy_desc, portal_strategy }, /* strategy */ 68753846Spendry { &vop_print_desc, portal_print }, /* print */ 68853846Spendry { &vop_islocked_desc, portal_islocked }, /* islocked */ 68965741Spendry { &vop_pathconf_desc, portal_pathconf }, /* pathconf */ 69053846Spendry { &vop_advlock_desc, portal_advlock }, /* advlock */ 69153846Spendry { &vop_blkatoff_desc, portal_blkatoff }, /* blkatoff */ 69253846Spendry { &vop_valloc_desc, portal_valloc }, /* valloc */ 69353846Spendry { &vop_vfree_desc, portal_vfree }, /* vfree */ 69453846Spendry { &vop_truncate_desc, portal_truncate }, /* truncate */ 69553846Spendry { &vop_update_desc, portal_update }, /* update */ 69653846Spendry { &vop_bwrite_desc, portal_bwrite }, /* bwrite */ 69753846Spendry { (struct vnodeop_desc*)NULL, (int(*)())NULL } 69853846Spendry }; 69953846Spendry struct vnodeopv_desc portal_vnodeop_opv_desc = 70053846Spendry { &portal_vnodeop_p, portal_vnodeop_entries }; 701