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*65516Spendry * @(#)portal_vnops.c 8.6 (Berkeley) 01/05/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 */ 67*65516Spendry int 6855027Smckusick portal_lookup(ap) 6955027Smckusick struct vop_lookup_args /* { 7055027Smckusick struct vnode * a_dvp; 7155027Smckusick struct vnode ** a_vpp; 7255027Smckusick struct componentname * a_cnp; 7355027Smckusick } */ *ap; 7453846Spendry { 7553846Spendry char *pname = ap->a_cnp->cn_nameptr; 7653846Spendry struct portalnode *pt; 7753846Spendry int error; 7853846Spendry struct vnode *fvp = 0; 7953846Spendry char *path; 8053846Spendry int size; 8153846Spendry 8253846Spendry if (ap->a_cnp->cn_namelen == 1 && *pname == '.') { 8353846Spendry *ap->a_vpp = ap->a_dvp; 8453846Spendry VREF(ap->a_dvp); 8553846Spendry /*VOP_LOCK(ap->a_dvp);*/ 8653846Spendry return (0); 8753846Spendry } 8853846Spendry 8953846Spendry 9065380Spendry error = getnewvnode(VT_PORTAL, ap->a_dvp->v_mount, portal_vnodeop_p, &fvp); 9153846Spendry if (error) 9253846Spendry goto bad; 9353846Spendry fvp->v_type = VREG; 9453846Spendry MALLOC(fvp->v_data, void *, sizeof(struct portalnode), 9553846Spendry M_TEMP, M_WAITOK); 9653846Spendry 9753846Spendry pt = VTOPORTAL(fvp); 9853846Spendry /* 9953846Spendry * Save all of the remaining pathname and 10053846Spendry * advance the namei next pointer to the end 10153846Spendry * of the string. 10253846Spendry */ 10353846Spendry for (size = 0, path = pname; *path; path++) 10453846Spendry size++; 10554978Spendry ap->a_cnp->cn_consume = size - ap->a_cnp->cn_namelen; 10654978Spendry 10753846Spendry pt->pt_arg = malloc(size+1, M_TEMP, M_WAITOK); 10853846Spendry pt->pt_size = size+1; 10953846Spendry bcopy(pname, pt->pt_arg, pt->pt_size); 11053846Spendry pt->pt_fileid = portal_fileid++; 11153846Spendry 11253846Spendry *ap->a_vpp = fvp; 11353846Spendry /*VOP_LOCK(fvp);*/ 11453846Spendry return (0); 11553846Spendry 11653846Spendry bad:; 11753846Spendry if (fvp) { 11853846Spendry vrele(fvp); 11953846Spendry } 12053846Spendry *ap->a_vpp = NULL; 12153846Spendry return (error); 12253846Spendry } 12353846Spendry 12453846Spendry static int 12553846Spendry portal_connect(so, so2) 12653846Spendry struct socket *so; 12753846Spendry struct socket *so2; 12853846Spendry { 12953846Spendry /* from unp_connect, bypassing the namei stuff... */ 13053846Spendry struct socket *so3; 13153846Spendry struct unpcb *unp2; 13253846Spendry struct unpcb *unp3; 13353846Spendry 13453846Spendry if (so2 == 0) 13553846Spendry return (ECONNREFUSED); 13653846Spendry 13753846Spendry if (so->so_type != so2->so_type) 13853846Spendry return (EPROTOTYPE); 13953846Spendry 14053846Spendry if ((so2->so_options & SO_ACCEPTCONN) == 0) 14153846Spendry return (ECONNREFUSED); 14253846Spendry 14353846Spendry if ((so3 = sonewconn(so2, 0)) == 0) 14453846Spendry return (ECONNREFUSED); 14553846Spendry 14653846Spendry unp2 = sotounpcb(so2); 14753846Spendry unp3 = sotounpcb(so3); 14853846Spendry if (unp2->unp_addr) 14953846Spendry unp3->unp_addr = m_copy(unp2->unp_addr, 0, (int)M_COPYALL); 15053846Spendry 15153846Spendry so2 = so3; 15253846Spendry 15353846Spendry 15453846Spendry return (unp_connect2(so, so2)); 15553846Spendry } 15653846Spendry 157*65516Spendry int 15855027Smckusick portal_open(ap) 15955027Smckusick struct vop_open_args /* { 16055027Smckusick struct vnode *a_vp; 16155027Smckusick int a_mode; 16255027Smckusick struct ucred *a_cred; 16355027Smckusick struct proc *a_p; 16455027Smckusick } */ *ap; 16553846Spendry { 16653846Spendry struct socket *so = 0; 16753846Spendry struct portalnode *pt; 16855910Spendry struct proc *p = ap->a_p; 16955910Spendry struct vnode *vp = ap->a_vp; 17053846Spendry int s; 17153846Spendry struct uio auio; 17253846Spendry struct iovec aiov[2]; 17353846Spendry int res; 17453846Spendry struct mbuf *cm = 0; 17553846Spendry struct cmsghdr *cmsg; 17653846Spendry int newfds; 17753846Spendry int *ip; 17853846Spendry int fd; 17953846Spendry int error; 18053846Spendry int len; 18153846Spendry struct portalmount *fmp; 18253846Spendry struct file *fp; 18353846Spendry struct portal_cred pcred; 18453846Spendry 18553846Spendry /* 18653846Spendry * Nothing to do when opening the root node. 18753846Spendry */ 18855910Spendry if (vp->v_flag & VROOT) 18953846Spendry return (0); 19053846Spendry 19153846Spendry /* 19253846Spendry * Can't be opened unless the caller is set up 19353846Spendry * to deal with the side effects. Check for this 19453846Spendry * by testing whether the p_dupfd has been set. 19553846Spendry */ 19655910Spendry if (p->p_dupfd >= 0) 19753846Spendry return (ENODEV); 19853846Spendry 19955910Spendry pt = VTOPORTAL(vp); 20055910Spendry fmp = VFSTOPORTAL(vp->v_mount); 20153846Spendry 20253846Spendry /* 20353846Spendry * Create a new socket. 20453846Spendry */ 20553846Spendry error = socreate(AF_UNIX, &so, SOCK_STREAM, 0); 20653846Spendry if (error) 20753846Spendry goto bad; 20853846Spendry 20953846Spendry /* 21053846Spendry * Reserve some buffer space 21153846Spendry */ 21254978Spendry res = pt->pt_size + sizeof(pcred) + 512; /* XXX */ 21353846Spendry error = soreserve(so, res, res); 21453846Spendry if (error) 21553846Spendry goto bad; 21653846Spendry 21753846Spendry /* 21853846Spendry * Kick off connection 21953846Spendry */ 22053846Spendry error = portal_connect(so, (struct socket *)fmp->pm_server->f_data); 22153846Spendry if (error) 22253846Spendry goto bad; 22353846Spendry 22453846Spendry /* 22553846Spendry * Wait for connection to complete 22653846Spendry */ 22753846Spendry /* 22853846Spendry * XXX: Since the mount point is holding a reference on the 22953846Spendry * underlying server socket, it is not easy to find out whether 23053846Spendry * the server process is still running. To handle this problem 23153846Spendry * we loop waiting for the new socket to be connected (something 23253846Spendry * which will only happen if the server is still running) or for 23353846Spendry * the reference count on the server socket to drop to 1, which 23453846Spendry * will happen if the server dies. Sleep for 5 second intervals 23553846Spendry * and keep polling the reference count. XXX. 23653846Spendry */ 23753846Spendry s = splnet(); 23853846Spendry while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) { 23953846Spendry if (fmp->pm_server->f_count == 1) { 24053846Spendry error = ECONNREFUSED; 24153846Spendry splx(s); 24253846Spendry goto bad; 24353846Spendry } 24453846Spendry (void) tsleep((caddr_t) &so->so_timeo, PSOCK, "portalcon", 5 * hz); 24553846Spendry } 24653846Spendry splx(s); 24753846Spendry 24853846Spendry if (so->so_error) { 24953846Spendry error = so->so_error; 25053846Spendry goto bad; 25153846Spendry } 25253846Spendry 25353846Spendry /* 25453846Spendry * Set miscellaneous flags 25553846Spendry */ 25653846Spendry so->so_rcv.sb_timeo = 0; 25753846Spendry so->so_snd.sb_timeo = 0; 25853846Spendry so->so_rcv.sb_flags |= SB_NOINTR; 25953846Spendry so->so_snd.sb_flags |= SB_NOINTR; 26053846Spendry 26153846Spendry 26254978Spendry pcred.pcr_flag = ap->a_mode; 26353846Spendry pcred.pcr_uid = ap->a_cred->cr_uid; 26454978Spendry pcred.pcr_ngroups = ap->a_cred->cr_ngroups; 26554978Spendry bcopy(ap->a_cred->cr_groups, pcred.pcr_groups, NGROUPS * sizeof(gid_t)); 26653846Spendry aiov[0].iov_base = (caddr_t) &pcred; 26753846Spendry aiov[0].iov_len = sizeof(pcred); 26853846Spendry aiov[1].iov_base = pt->pt_arg; 26953846Spendry aiov[1].iov_len = pt->pt_size; 27053846Spendry auio.uio_iov = aiov; 27153846Spendry auio.uio_iovcnt = 2; 27253846Spendry auio.uio_rw = UIO_WRITE; 27353846Spendry auio.uio_segflg = UIO_SYSSPACE; 27455910Spendry auio.uio_procp = p; 27553846Spendry auio.uio_offset = 0; 27653846Spendry auio.uio_resid = aiov[0].iov_len + aiov[1].iov_len; 27753846Spendry 27865492Spendry error = sosend(so, (struct mbuf *) 0, &auio, 27953846Spendry (struct mbuf *) 0, (struct mbuf *) 0, 0); 28053846Spendry if (error) 28153846Spendry goto bad; 28253846Spendry 28353846Spendry len = auio.uio_resid = sizeof(int); 28453846Spendry do { 28553846Spendry struct mbuf *m = 0; 28653846Spendry int flags = MSG_WAITALL; 28753846Spendry error = soreceive(so, (struct mbuf **) 0, &auio, 28853846Spendry &m, &cm, &flags); 28953846Spendry if (error) 29053846Spendry goto bad; 29153846Spendry 29253846Spendry /* 29353846Spendry * Grab an error code from the mbuf. 29453846Spendry */ 29553846Spendry if (m) { 29653846Spendry m = m_pullup(m, sizeof(int)); /* Needed? */ 29753846Spendry if (m) { 29853846Spendry error = *(mtod(m, int *)); 29953846Spendry m_freem(m); 30053846Spendry } else { 30153846Spendry error = EINVAL; 30253846Spendry } 30353846Spendry } else { 30453846Spendry if (cm == 0) { 30553846Spendry error = ECONNRESET; /* XXX */ 30653846Spendry #ifdef notdef 30753846Spendry break; 30853846Spendry #endif 30953846Spendry } 31053846Spendry } 31153846Spendry } while (cm == 0 && auio.uio_resid == len && !error); 31253846Spendry 31353846Spendry if (cm == 0) 31453846Spendry goto bad; 31553846Spendry 31653846Spendry if (auio.uio_resid) { 31753846Spendry error = 0; 31853846Spendry #ifdef notdef 31953846Spendry error = EMSGSIZE; 32053846Spendry goto bad; 32153846Spendry #endif 32253846Spendry } 32353846Spendry 32453846Spendry /* 32553846Spendry * XXX: Break apart the control message, and retrieve the 32653846Spendry * received file descriptor. Note that more than one descriptor 32753846Spendry * may have been received, or that the rights chain may have more 32853846Spendry * than a single mbuf in it. What to do? 32953846Spendry */ 33053846Spendry cmsg = mtod(cm, struct cmsghdr *); 33153846Spendry newfds = (cmsg->cmsg_len - sizeof(*cmsg)) / sizeof (int); 33253846Spendry if (newfds == 0) { 33353846Spendry error = ECONNREFUSED; 33453846Spendry goto bad; 33553846Spendry } 33653846Spendry /* 33753846Spendry * At this point the rights message consists of a control message 33853846Spendry * header, followed by a data region containing a vector of 33953846Spendry * integer file descriptors. The fds were allocated by the action 34053846Spendry * of receiving the control message. 34153846Spendry */ 34253846Spendry ip = (int *) (cmsg + 1); 34353846Spendry fd = *ip++; 34453846Spendry if (newfds > 1) { 34553846Spendry /* 34653846Spendry * Close extra fds. 34753846Spendry */ 34853846Spendry int i; 34953846Spendry printf("portal_open: %d extra fds\n", newfds - 1); 35053846Spendry for (i = 1; i < newfds; i++) { 35155910Spendry portal_closefd(p, *ip); 35253846Spendry ip++; 35353846Spendry } 35453846Spendry } 35553846Spendry 35653846Spendry /* 35755910Spendry * Check that the mode the file is being opened for is a subset 35855910Spendry * of the mode of the existing descriptor. 35953846Spendry */ 36055910Spendry fp = p->p_fd->fd_ofiles[fd]; 36153846Spendry if (((ap->a_mode & (FREAD|FWRITE)) | fp->f_flag) != fp->f_flag) { 36255910Spendry portal_closefd(p, fd); 36353846Spendry error = EACCES; 36453846Spendry goto bad; 36553846Spendry } 36653846Spendry 36753846Spendry /* 36853846Spendry * Save the dup fd in the proc structure then return the 36953846Spendry * special error code (ENXIO) which causes magic things to 37053846Spendry * happen in vn_open. The whole concept is, well, hmmm. 37153846Spendry */ 37255910Spendry p->p_dupfd = fd; 37353846Spendry error = ENXIO; 37453846Spendry 37553846Spendry bad:; 37653846Spendry /* 37753846Spendry * And discard the control message. 37853846Spendry */ 37953846Spendry if (cm) { 38053846Spendry m_freem(cm); 38153846Spendry } 38253846Spendry 38353846Spendry if (so) { 38453846Spendry soshutdown(so, 2); 38553846Spendry soclose(so); 38653846Spendry } 38753846Spendry return (error); 38853846Spendry } 38953846Spendry 390*65516Spendry int 39155027Smckusick portal_getattr(ap) 39255027Smckusick struct vop_getattr_args /* { 39355027Smckusick struct vnode *a_vp; 39455027Smckusick struct vattr *a_vap; 39555027Smckusick struct ucred *a_cred; 39655027Smckusick struct proc *a_p; 39755027Smckusick } */ *ap; 39853846Spendry { 39955910Spendry struct vnode *vp = ap->a_vp; 40055910Spendry struct vattr *vap = ap->a_vap; 40153846Spendry 40265450Sbostic bzero(vap, sizeof(*vap)); 40355910Spendry vattr_null(vap); 40455910Spendry vap->va_uid = 0; 40555910Spendry vap->va_gid = 0; 40655910Spendry vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0]; 40755910Spendry vap->va_size = DEV_BSIZE; 40855910Spendry vap->va_blocksize = DEV_BSIZE; 40955910Spendry microtime(&vap->va_atime); 41055910Spendry vap->va_mtime = vap->va_atime; 41155910Spendry vap->va_ctime = vap->va_ctime; 41255910Spendry vap->va_gen = 0; 41355910Spendry vap->va_flags = 0; 41455910Spendry vap->va_rdev = 0; 41555910Spendry /* vap->va_qbytes = 0; */ 41655910Spendry vap->va_bytes = 0; 41755910Spendry /* vap->va_qsize = 0; */ 41855910Spendry if (vp->v_flag & VROOT) { 41955910Spendry vap->va_type = VDIR; 42055910Spendry vap->va_mode = S_IRUSR|S_IWUSR|S_IXUSR| 42153846Spendry S_IRGRP|S_IWGRP|S_IXGRP| 42253846Spendry S_IROTH|S_IWOTH|S_IXOTH; 42355910Spendry vap->va_nlink = 2; 42455910Spendry vap->va_fileid = 2; 42553846Spendry } else { 42655910Spendry vap->va_type = VREG; 42755910Spendry vap->va_mode = S_IRUSR|S_IWUSR| 42853846Spendry S_IRGRP|S_IWGRP| 42953846Spendry S_IROTH|S_IWOTH; 43055910Spendry vap->va_nlink = 1; 43155910Spendry vap->va_fileid = VTOPORTAL(vp)->pt_fileid; 43253846Spendry } 43353846Spendry return (0); 43453846Spendry } 43553846Spendry 436*65516Spendry int 43755027Smckusick portal_setattr(ap) 43855027Smckusick struct vop_setattr_args /* { 43955027Smckusick struct vnode *a_vp; 44055027Smckusick struct vattr *a_vap; 44155027Smckusick struct ucred *a_cred; 44255027Smckusick struct proc *a_p; 44355027Smckusick } */ *ap; 44453846Spendry { 445*65516Spendry 44653846Spendry /* 44753846Spendry * Can't mess with the root vnode 44853846Spendry */ 44953846Spendry if (ap->a_vp->v_flag & VROOT) 45053846Spendry return (EACCES); 45153846Spendry 45253846Spendry return (0); 45353846Spendry } 45453846Spendry 45553846Spendry /* 45653846Spendry * Fake readdir, just return empty directory. 45753846Spendry * It is hard to deal with '.' and '..' so don't bother. 45853846Spendry */ 459*65516Spendry int 46055027Smckusick portal_readdir(ap) 46155027Smckusick struct vop_readdir_args /* { 46255027Smckusick struct vnode *a_vp; 46355027Smckusick struct uio *a_uio; 46455027Smckusick struct ucred *a_cred; 46555027Smckusick } */ *ap; 46653846Spendry { 467*65516Spendry 46853846Spendry return (0); 46953846Spendry } 47053846Spendry 471*65516Spendry int 47255027Smckusick portal_inactive(ap) 47355027Smckusick struct vop_inactive_args /* { 47455027Smckusick struct vnode *a_vp; 47555027Smckusick } */ *ap; 47653846Spendry { 477*65516Spendry 47853846Spendry return (0); 47953846Spendry } 48053846Spendry 481*65516Spendry int 48255027Smckusick portal_reclaim(ap) 48355027Smckusick struct vop_reclaim_args /* { 48455027Smckusick struct vnode *a_vp; 48555027Smckusick } */ *ap; 48653846Spendry { 48753846Spendry struct portalnode *pt = VTOPORTAL(ap->a_vp); 488*65516Spendry 48953846Spendry if (pt->pt_arg) { 49053846Spendry free((caddr_t) pt->pt_arg, M_TEMP); 49153846Spendry pt->pt_arg = 0; 49253846Spendry } 49365384Spendry FREE(ap->a_vp->v_data, M_TEMP); 49465384Spendry ap->a_vp->v_data = 0; 495*65516Spendry 49653846Spendry return (0); 49753846Spendry } 49853846Spendry 49953846Spendry /* 50053846Spendry * Print out the contents of a Portal vnode. 50153846Spendry */ 50253846Spendry /* ARGSUSED */ 503*65516Spendry int 50455027Smckusick portal_print(ap) 50555027Smckusick struct vop_print_args /* { 50655027Smckusick struct vnode *a_vp; 50755027Smckusick } */ *ap; 50853846Spendry { 50955027Smckusick 51053846Spendry printf("tag VT_PORTAL, portal vnode\n"); 51155027Smckusick return (0); 51253846Spendry } 51353846Spendry 51453846Spendry /*void*/ 515*65516Spendry int 51655027Smckusick portal_vfree(ap) 51755027Smckusick struct vop_vfree_args /* { 51855027Smckusick struct vnode *a_pvp; 51955027Smckusick ino_t a_ino; 52055027Smckusick int a_mode; 52155027Smckusick } */ *ap; 52253846Spendry { 52355027Smckusick 52455027Smckusick return (0); 52553846Spendry } 52653846Spendry 52753846Spendry 52853846Spendry /* 52953846Spendry * Portal vnode unsupported operation 53053846Spendry */ 531*65516Spendry int 53253846Spendry portal_enotsupp() 53353846Spendry { 53455027Smckusick 53553846Spendry return (EOPNOTSUPP); 53653846Spendry } 53753846Spendry 53853846Spendry /* 53953846Spendry * Portal "should never get here" operation 54053846Spendry */ 541*65516Spendry int 54253846Spendry portal_badop() 54353846Spendry { 54455027Smckusick 54553846Spendry panic("portal: bad op"); 54653846Spendry /* NOTREACHED */ 54753846Spendry } 54853846Spendry 54953846Spendry /* 55053846Spendry * Portal vnode null operation 55153846Spendry */ 552*65516Spendry int 55353846Spendry portal_nullop() 55453846Spendry { 55555027Smckusick 55653846Spendry return (0); 55753846Spendry } 55853846Spendry 55955027Smckusick #define portal_create ((int (*) __P((struct vop_create_args *)))portal_enotsupp) 56053846Spendry #define portal_mknod ((int (*) __P((struct vop_mknod_args *)))portal_enotsupp) 56153846Spendry #define portal_close ((int (*) __P((struct vop_close_args *)))nullop) 56253846Spendry #define portal_access ((int (*) __P((struct vop_access_args *)))nullop) 56353846Spendry #define portal_read ((int (*) __P((struct vop_read_args *)))portal_enotsupp) 56453846Spendry #define portal_write ((int (*) __P((struct vop_write_args *)))portal_enotsupp) 56553846Spendry #define portal_ioctl ((int (*) __P((struct vop_ioctl_args *)))portal_enotsupp) 56655027Smckusick #define portal_select ((int (*) __P((struct vop_select_args *)))portal_enotsupp) 56753846Spendry #define portal_mmap ((int (*) __P((struct vop_mmap_args *)))portal_enotsupp) 56853846Spendry #define portal_fsync ((int (*) __P((struct vop_fsync_args *)))nullop) 56953846Spendry #define portal_seek ((int (*) __P((struct vop_seek_args *)))nullop) 57055027Smckusick #define portal_remove ((int (*) __P((struct vop_remove_args *)))portal_enotsupp) 57153846Spendry #define portal_link ((int (*) __P((struct vop_link_args *)))portal_enotsupp) 57255027Smckusick #define portal_rename ((int (*) __P((struct vop_rename_args *)))portal_enotsupp) 57353846Spendry #define portal_mkdir ((int (*) __P((struct vop_mkdir_args *)))portal_enotsupp) 57453846Spendry #define portal_rmdir ((int (*) __P((struct vop_rmdir_args *)))portal_enotsupp) 57555171Spendry #define portal_symlink \ 57655027Smckusick ((int (*) __P((struct vop_symlink_args *)))portal_enotsupp) 57755171Spendry #define portal_readlink \ 57855027Smckusick ((int (*) __P((struct vop_readlink_args *)))portal_enotsupp) 57953846Spendry #define portal_abortop ((int (*) __P((struct vop_abortop_args *)))nullop) 58053846Spendry #define portal_lock ((int (*) __P((struct vop_lock_args *)))nullop) 58153846Spendry #define portal_unlock ((int (*) __P((struct vop_unlock_args *)))nullop) 58253846Spendry #define portal_bmap ((int (*) __P((struct vop_bmap_args *)))portal_badop) 58355171Spendry #define portal_strategy \ 58455027Smckusick ((int (*) __P((struct vop_strategy_args *)))portal_badop) 58553846Spendry #define portal_islocked ((int (*) __P((struct vop_islocked_args *)))nullop) 58655171Spendry #define portal_advlock \ 58755027Smckusick ((int (*) __P((struct vop_advlock_args *)))portal_enotsupp) 58855171Spendry #define portal_blkatoff \ 58955027Smckusick ((int (*) __P((struct vop_blkatoff_args *)))portal_enotsupp) 59053846Spendry #define portal_valloc ((int(*) __P(( \ 59153846Spendry struct vnode *pvp, \ 59253846Spendry int mode, \ 59353846Spendry struct ucred *cred, \ 59453846Spendry struct vnode **vpp))) portal_enotsupp) 59555171Spendry #define portal_truncate \ 59655027Smckusick ((int (*) __P((struct vop_truncate_args *)))portal_enotsupp) 59755027Smckusick #define portal_update ((int (*) __P((struct vop_update_args *)))portal_enotsupp) 59855027Smckusick #define portal_bwrite ((int (*) __P((struct vop_bwrite_args *)))portal_enotsupp) 59953846Spendry 60053846Spendry int (**portal_vnodeop_p)(); 60153846Spendry struct vnodeopv_entry_desc portal_vnodeop_entries[] = { 60253846Spendry { &vop_default_desc, vn_default_error }, 60353846Spendry { &vop_lookup_desc, portal_lookup }, /* lookup */ 60453846Spendry { &vop_create_desc, portal_create }, /* create */ 60553846Spendry { &vop_mknod_desc, portal_mknod }, /* mknod */ 60653846Spendry { &vop_open_desc, portal_open }, /* open */ 60753846Spendry { &vop_close_desc, portal_close }, /* close */ 60853846Spendry { &vop_access_desc, portal_access }, /* access */ 60953846Spendry { &vop_getattr_desc, portal_getattr }, /* getattr */ 61053846Spendry { &vop_setattr_desc, portal_setattr }, /* setattr */ 61153846Spendry { &vop_read_desc, portal_read }, /* read */ 61253846Spendry { &vop_write_desc, portal_write }, /* write */ 61353846Spendry { &vop_ioctl_desc, portal_ioctl }, /* ioctl */ 61453846Spendry { &vop_select_desc, portal_select }, /* select */ 61553846Spendry { &vop_mmap_desc, portal_mmap }, /* mmap */ 61653846Spendry { &vop_fsync_desc, portal_fsync }, /* fsync */ 61753846Spendry { &vop_seek_desc, portal_seek }, /* seek */ 61853846Spendry { &vop_remove_desc, portal_remove }, /* remove */ 61953846Spendry { &vop_link_desc, portal_link }, /* link */ 62053846Spendry { &vop_rename_desc, portal_rename }, /* rename */ 62153846Spendry { &vop_mkdir_desc, portal_mkdir }, /* mkdir */ 62253846Spendry { &vop_rmdir_desc, portal_rmdir }, /* rmdir */ 62353846Spendry { &vop_symlink_desc, portal_symlink }, /* symlink */ 62453846Spendry { &vop_readdir_desc, portal_readdir }, /* readdir */ 62553846Spendry { &vop_readlink_desc, portal_readlink }, /* readlink */ 62653846Spendry { &vop_abortop_desc, portal_abortop }, /* abortop */ 62753846Spendry { &vop_inactive_desc, portal_inactive }, /* inactive */ 62853846Spendry { &vop_reclaim_desc, portal_reclaim }, /* reclaim */ 62953846Spendry { &vop_lock_desc, portal_lock }, /* lock */ 63053846Spendry { &vop_unlock_desc, portal_unlock }, /* unlock */ 63153846Spendry { &vop_bmap_desc, portal_bmap }, /* bmap */ 63253846Spendry { &vop_strategy_desc, portal_strategy }, /* strategy */ 63353846Spendry { &vop_print_desc, portal_print }, /* print */ 63453846Spendry { &vop_islocked_desc, portal_islocked }, /* islocked */ 63553846Spendry { &vop_advlock_desc, portal_advlock }, /* advlock */ 63653846Spendry { &vop_blkatoff_desc, portal_blkatoff }, /* blkatoff */ 63753846Spendry { &vop_valloc_desc, portal_valloc }, /* valloc */ 63853846Spendry { &vop_vfree_desc, portal_vfree }, /* vfree */ 63953846Spendry { &vop_truncate_desc, portal_truncate }, /* truncate */ 64053846Spendry { &vop_update_desc, portal_update }, /* update */ 64153846Spendry { &vop_bwrite_desc, portal_bwrite }, /* bwrite */ 64253846Spendry { (struct vnodeop_desc*)NULL, (int(*)())NULL } 64353846Spendry }; 64453846Spendry struct vnodeopv_desc portal_vnodeop_opv_desc = 64553846Spendry { &portal_vnodeop_p, portal_vnodeop_entries }; 646