1*53846Spendry /* 2*53846Spendry * Copyright (c) 1992 The Regents of the University of California 3*53846Spendry * Copyright (c) 1990, 1992 Jan-Simon Pendry 4*53846Spendry * All rights reserved. 5*53846Spendry * 6*53846Spendry * This code is derived from software donated to Berkeley by 7*53846Spendry * Jan-Simon Pendry. 8*53846Spendry * 9*53846Spendry * %sccs.include.redist.c% 10*53846Spendry * 11*53846Spendry * @(#)portal_vnops.c 1.1 (Berkeley) 06/03/92 12*53846Spendry * 13*53846Spendry * $Id: portal_vnops.c,v 1.4 1992/05/30 10:05:24 jsp Exp jsp $ 14*53846Spendry */ 15*53846Spendry 16*53846Spendry /* 17*53846Spendry * Portal Filesystem 18*53846Spendry */ 19*53846Spendry 20*53846Spendry #include <sys/param.h> 21*53846Spendry #include <sys/systm.h> 22*53846Spendry #include <sys/kernel.h> 23*53846Spendry #include <sys/types.h> 24*53846Spendry #include <sys/time.h> 25*53846Spendry #include <sys/proc.h> 26*53846Spendry /*#include <sys/resourcevar.h>*/ 27*53846Spendry #include <sys/filedesc.h> 28*53846Spendry #include <sys/vnode.h> 29*53846Spendry #include <sys/file.h> 30*53846Spendry #include <sys/stat.h> 31*53846Spendry #include <sys/mount.h> 32*53846Spendry #include <sys/malloc.h> 33*53846Spendry #include <sys/namei.h> 34*53846Spendry /*#include <sys/buf.h>*/ 35*53846Spendry #include <sys/mbuf.h> 36*53846Spendry #include <sys/socket.h> 37*53846Spendry #include <sys/socketvar.h> 38*53846Spendry #include <sys/un.h> 39*53846Spendry #include <sys/unpcb.h> 40*53846Spendry #include <portal/portal.h> 41*53846Spendry 42*53846Spendry static int portal_fileid = PORTAL_ROOTFILEID+1; 43*53846Spendry 44*53846Spendry static void 45*53846Spendry portal_closefd(p, fd) 46*53846Spendry struct proc *p; 47*53846Spendry int fd; 48*53846Spendry { 49*53846Spendry int error; 50*53846Spendry struct { 51*53846Spendry int fd; 52*53846Spendry } ua; 53*53846Spendry int rc; 54*53846Spendry 55*53846Spendry ua.fd = fd; 56*53846Spendry error = close(p, &ua, &rc); 57*53846Spendry /* 58*53846Spendry * We should never get an error, and there isn't anything 59*53846Spendry * we could do if we got one, so just print a message. 60*53846Spendry */ 61*53846Spendry if (error) 62*53846Spendry printf("portal_closefd: error = %d\n", error); 63*53846Spendry } 64*53846Spendry 65*53846Spendry /* 66*53846Spendry * vp is the current namei directory 67*53846Spendry * cnp is the name to locate in that directory... 68*53846Spendry */ 69*53846Spendry portal_lookup (ap) 70*53846Spendry struct vop_lookup_args *ap; 71*53846Spendry { 72*53846Spendry /*USES_VOP_LOCK;*/ 73*53846Spendry char *pname = ap->a_cnp->cn_nameptr; 74*53846Spendry struct portalnode *pt; 75*53846Spendry int error; 76*53846Spendry struct vnode *fvp = 0; 77*53846Spendry char *path; 78*53846Spendry int size; 79*53846Spendry 80*53846Spendry #ifdef PORTAL_DIAGNOSTIC 81*53846Spendry printf("portal_lookup(%s)\n", pname); 82*53846Spendry #endif 83*53846Spendry if (ap->a_cnp->cn_namelen == 1 && *pname == '.') { 84*53846Spendry *ap->a_vpp = ap->a_dvp; 85*53846Spendry VREF(ap->a_dvp); 86*53846Spendry /*VOP_LOCK(ap->a_dvp);*/ 87*53846Spendry return (0); 88*53846Spendry } 89*53846Spendry 90*53846Spendry 91*53846Spendry #ifdef PORTAL_DIAGNOSTIC 92*53846Spendry printf("portal_lookup: allocate new vnode\n"); 93*53846Spendry #endif 94*53846Spendry error = getnewvnode(VT_UFS, ap->a_dvp->v_mount, portal_vnodeop_p, &fvp); 95*53846Spendry if (error) 96*53846Spendry goto bad; 97*53846Spendry fvp->v_type = VREG; 98*53846Spendry MALLOC(fvp->v_data, void *, sizeof(struct portalnode), 99*53846Spendry M_TEMP, M_WAITOK); 100*53846Spendry 101*53846Spendry pt = VTOPORTAL(fvp); 102*53846Spendry /* 103*53846Spendry * Save all of the remaining pathname and 104*53846Spendry * advance the namei next pointer to the end 105*53846Spendry * of the string. 106*53846Spendry */ 107*53846Spendry #ifdef notyet 108*53846Spendry for (size = 0, path = pname; *path; path++) 109*53846Spendry size++; 110*53846Spendry ndp->ni_next = path; 111*53846Spendry ndp->ni_pathlen -= size - ndp->ni_namelen; 112*53846Spendry #endif 113*53846Spendry pt->pt_arg = malloc(size+1, M_TEMP, M_WAITOK); 114*53846Spendry pt->pt_size = size+1; 115*53846Spendry bcopy(pname, pt->pt_arg, pt->pt_size); 116*53846Spendry pt->pt_fileid = portal_fileid++; 117*53846Spendry 118*53846Spendry *ap->a_vpp = fvp; 119*53846Spendry /*VOP_LOCK(fvp);*/ 120*53846Spendry #ifdef PORTAL_DIAGNOSTIC 121*53846Spendry printf("portal_lookup: newvp = %x\n", fvp); 122*53846Spendry #endif 123*53846Spendry return (0); 124*53846Spendry 125*53846Spendry bad:; 126*53846Spendry if (fvp) { 127*53846Spendry #ifdef PORTAL_DIAGNOSTIC 128*53846Spendry printf("portal_lookup: vrele(%x)\n", fvp); 129*53846Spendry #endif 130*53846Spendry vrele(fvp); 131*53846Spendry } 132*53846Spendry *ap->a_vpp = NULL; 133*53846Spendry #ifdef PORTAL_DIAGNOSTIC 134*53846Spendry printf("portal_lookup: error = %d\n", error); 135*53846Spendry #endif 136*53846Spendry return (error); 137*53846Spendry } 138*53846Spendry 139*53846Spendry static int 140*53846Spendry portal_connect(so, so2) 141*53846Spendry struct socket *so; 142*53846Spendry struct socket *so2; 143*53846Spendry { 144*53846Spendry /* from unp_connect, bypassing the namei stuff... */ 145*53846Spendry 146*53846Spendry struct socket *so3; 147*53846Spendry struct unpcb *unp2; 148*53846Spendry struct unpcb *unp3; 149*53846Spendry 150*53846Spendry #ifdef PORTAL_DIAGNOSTIC 151*53846Spendry printf("portal_connect\n"); 152*53846Spendry #endif 153*53846Spendry 154*53846Spendry if (so2 == 0) 155*53846Spendry return (ECONNREFUSED); 156*53846Spendry 157*53846Spendry if (so->so_type != so2->so_type) 158*53846Spendry return (EPROTOTYPE); 159*53846Spendry 160*53846Spendry if ((so2->so_options & SO_ACCEPTCONN) == 0) 161*53846Spendry return (ECONNREFUSED); 162*53846Spendry 163*53846Spendry #ifdef PORTAL_DIAGNOSTIC 164*53846Spendry printf("portal_connect: calling sonewconn\n"); 165*53846Spendry #endif 166*53846Spendry 167*53846Spendry if ((so3 = sonewconn(so2, 0)) == 0) 168*53846Spendry return (ECONNREFUSED); 169*53846Spendry 170*53846Spendry unp2 = sotounpcb(so2); 171*53846Spendry unp3 = sotounpcb(so3); 172*53846Spendry if (unp2->unp_addr) 173*53846Spendry unp3->unp_addr = m_copy(unp2->unp_addr, 0, (int)M_COPYALL); 174*53846Spendry 175*53846Spendry so2 = so3; 176*53846Spendry 177*53846Spendry #ifdef PORTAL_DIAGNOSTIC 178*53846Spendry printf("portal_connect: calling unp_connect2\n"); 179*53846Spendry #endif 180*53846Spendry 181*53846Spendry return (unp_connect2(so, so2)); 182*53846Spendry } 183*53846Spendry 184*53846Spendry portal_open (ap) 185*53846Spendry struct vop_open_args *ap; 186*53846Spendry { 187*53846Spendry struct socket *so = 0; 188*53846Spendry struct portalnode *pt; 189*53846Spendry int s; 190*53846Spendry struct uio auio; 191*53846Spendry struct iovec aiov[2]; 192*53846Spendry int res; 193*53846Spendry struct mbuf *cm = 0; 194*53846Spendry struct cmsghdr *cmsg; 195*53846Spendry int newfds; 196*53846Spendry int *ip; 197*53846Spendry int fd; 198*53846Spendry int error; 199*53846Spendry int len; 200*53846Spendry struct portalmount *fmp; 201*53846Spendry struct file *fp; 202*53846Spendry struct portal_cred pcred; 203*53846Spendry 204*53846Spendry /* 205*53846Spendry * Nothing to do when opening the root node. 206*53846Spendry */ 207*53846Spendry if (ap->a_vp->v_flag & VROOT) 208*53846Spendry return (0); 209*53846Spendry 210*53846Spendry #ifdef PORTAL_DIAGNOSTIC 211*53846Spendry printf("portal_open(%x)\n", ap->a_vp); 212*53846Spendry #endif 213*53846Spendry 214*53846Spendry /* 215*53846Spendry * Can't be opened unless the caller is set up 216*53846Spendry * to deal with the side effects. Check for this 217*53846Spendry * by testing whether the p_dupfd has been set. 218*53846Spendry */ 219*53846Spendry if (ap->a_p->p_dupfd >= 0) 220*53846Spendry return (ENODEV); 221*53846Spendry 222*53846Spendry pt = VTOPORTAL(ap->a_vp); 223*53846Spendry fmp = VFSTOPORTAL(ap->a_vp->v_mount); 224*53846Spendry 225*53846Spendry /* 226*53846Spendry * Create a new socket. 227*53846Spendry */ 228*53846Spendry error = socreate(AF_UNIX, &so, SOCK_STREAM, 0); 229*53846Spendry if (error) 230*53846Spendry goto bad; 231*53846Spendry 232*53846Spendry /* 233*53846Spendry * Reserve some buffer space 234*53846Spendry */ 235*53846Spendry #ifdef PORTAL_DIAGNOSTIC 236*53846Spendry printf("portal_open: calling soreserve\n"); 237*53846Spendry #endif 238*53846Spendry res = max(512, pt->pt_size + 128); 239*53846Spendry error = soreserve(so, res, res); 240*53846Spendry if (error) 241*53846Spendry goto bad; 242*53846Spendry 243*53846Spendry /* 244*53846Spendry * Kick off connection 245*53846Spendry */ 246*53846Spendry #ifdef PORTAL_DIAGNOSTIC 247*53846Spendry printf("portal_open: calling portal_connect\n"); 248*53846Spendry #endif 249*53846Spendry error = portal_connect(so, (struct socket *)fmp->pm_server->f_data); 250*53846Spendry if (error) 251*53846Spendry goto bad; 252*53846Spendry 253*53846Spendry /* 254*53846Spendry * Wait for connection to complete 255*53846Spendry */ 256*53846Spendry #ifdef PORTAL_DIAGNOSTIC 257*53846Spendry printf("portal_open: waiting for connect\n"); 258*53846Spendry #endif 259*53846Spendry /* 260*53846Spendry * XXX: Since the mount point is holding a reference on the 261*53846Spendry * underlying server socket, it is not easy to find out whether 262*53846Spendry * the server process is still running. To handle this problem 263*53846Spendry * we loop waiting for the new socket to be connected (something 264*53846Spendry * which will only happen if the server is still running) or for 265*53846Spendry * the reference count on the server socket to drop to 1, which 266*53846Spendry * will happen if the server dies. Sleep for 5 second intervals 267*53846Spendry * and keep polling the reference count. XXX. 268*53846Spendry */ 269*53846Spendry s = splnet(); 270*53846Spendry while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) { 271*53846Spendry if (fmp->pm_server->f_count == 1) { 272*53846Spendry error = ECONNREFUSED; 273*53846Spendry splx(s); 274*53846Spendry #ifdef PORTAL_DIAGNOSTIC 275*53846Spendry printf("portal_open: server process has gone away\n"); 276*53846Spendry #endif 277*53846Spendry goto bad; 278*53846Spendry } 279*53846Spendry (void) tsleep((caddr_t) &so->so_timeo, PSOCK, "portalcon", 5 * hz); 280*53846Spendry } 281*53846Spendry splx(s); 282*53846Spendry 283*53846Spendry if (so->so_error) { 284*53846Spendry error = so->so_error; 285*53846Spendry goto bad; 286*53846Spendry } 287*53846Spendry 288*53846Spendry /* 289*53846Spendry * Set miscellaneous flags 290*53846Spendry */ 291*53846Spendry so->so_rcv.sb_timeo = 0; 292*53846Spendry so->so_snd.sb_timeo = 0; 293*53846Spendry so->so_rcv.sb_flags |= SB_NOINTR; 294*53846Spendry so->so_snd.sb_flags |= SB_NOINTR; 295*53846Spendry 296*53846Spendry #ifdef PORTAL_DIAGNOSTIC 297*53846Spendry printf("portal_open: constructing data uio\n"); 298*53846Spendry #endif 299*53846Spendry 300*53846Spendry pcred.pcr_uid = ap->a_cred->cr_uid; 301*53846Spendry pcred.pcr_gid = ap->a_cred->cr_gid; 302*53846Spendry aiov[0].iov_base = (caddr_t) &pcred; 303*53846Spendry aiov[0].iov_len = sizeof(pcred); 304*53846Spendry aiov[1].iov_base = pt->pt_arg; 305*53846Spendry aiov[1].iov_len = pt->pt_size; 306*53846Spendry auio.uio_iov = aiov; 307*53846Spendry auio.uio_iovcnt = 2; 308*53846Spendry auio.uio_rw = UIO_WRITE; 309*53846Spendry auio.uio_segflg = UIO_SYSSPACE; 310*53846Spendry auio.uio_procp = ap->a_p; 311*53846Spendry auio.uio_offset = 0; 312*53846Spendry auio.uio_resid = aiov[0].iov_len + aiov[1].iov_len; 313*53846Spendry 314*53846Spendry #ifdef PORTAL_DIAGNOSTIC 315*53846Spendry printf("portal_open: sending data to server\n"); 316*53846Spendry #endif 317*53846Spendry error = sosend(so, (struct sockaddr *) 0, &auio, 318*53846Spendry (struct mbuf *) 0, (struct mbuf *) 0, 0); 319*53846Spendry if (error) 320*53846Spendry goto bad; 321*53846Spendry 322*53846Spendry len = auio.uio_resid = sizeof(int); 323*53846Spendry do { 324*53846Spendry struct mbuf *m = 0; 325*53846Spendry int flags = MSG_WAITALL; 326*53846Spendry #ifdef PORTAL_DIAGNOSTIC 327*53846Spendry printf("portal_open: receiving data from server\n"); 328*53846Spendry printf("portal_open: so = %x, cm = %x, resid = %d\n", 329*53846Spendry so, cm, auio.uio_resid); 330*53846Spendry printf("portal_open, uio=%x, mp0=%x, controlp=%x\n", &auio, &cm); 331*53846Spendry #endif 332*53846Spendry error = soreceive(so, (struct mbuf **) 0, &auio, 333*53846Spendry &m, &cm, &flags); 334*53846Spendry #ifdef PORTAL_DIAGNOSTIC 335*53846Spendry printf("portal_open: after receiving data\n"); 336*53846Spendry printf("portal_open: so = %x, cm = %x, resid = %d\n", 337*53846Spendry so, cm, auio.uio_resid); 338*53846Spendry #endif 339*53846Spendry if (error) 340*53846Spendry goto bad; 341*53846Spendry 342*53846Spendry /* 343*53846Spendry * Grab an error code from the mbuf. 344*53846Spendry */ 345*53846Spendry if (m) { 346*53846Spendry m = m_pullup(m, sizeof(int)); /* Needed? */ 347*53846Spendry if (m) { 348*53846Spendry error = *(mtod(m, int *)); 349*53846Spendry m_freem(m); 350*53846Spendry } else { 351*53846Spendry error = EINVAL; 352*53846Spendry } 353*53846Spendry #ifdef PORTAL_DIAGNOSTIC 354*53846Spendry printf("portal_open: error returned is %d\n", error); 355*53846Spendry #endif 356*53846Spendry } else { 357*53846Spendry if (cm == 0) { 358*53846Spendry #ifdef PORTAL_DIAGNOSTIC 359*53846Spendry printf("portal_open: no rights received\n"); 360*53846Spendry #endif 361*53846Spendry error = ECONNRESET; /* XXX */ 362*53846Spendry #ifdef notdef 363*53846Spendry break; 364*53846Spendry #endif 365*53846Spendry } 366*53846Spendry } 367*53846Spendry } while (cm == 0 && auio.uio_resid == len && !error); 368*53846Spendry 369*53846Spendry if (cm == 0) 370*53846Spendry goto bad; 371*53846Spendry 372*53846Spendry if (auio.uio_resid) { 373*53846Spendry #ifdef PORTAL_DIAGNOSTIC 374*53846Spendry printf("portal_open: still need another %d bytes\n", auio.uio_resid); 375*53846Spendry #endif 376*53846Spendry error = 0; 377*53846Spendry #ifdef notdef 378*53846Spendry error = EMSGSIZE; 379*53846Spendry goto bad; 380*53846Spendry #endif 381*53846Spendry } 382*53846Spendry 383*53846Spendry /* 384*53846Spendry * XXX: Break apart the control message, and retrieve the 385*53846Spendry * received file descriptor. Note that more than one descriptor 386*53846Spendry * may have been received, or that the rights chain may have more 387*53846Spendry * than a single mbuf in it. What to do? 388*53846Spendry */ 389*53846Spendry #ifdef PORTAL_DIAGNOSTIC 390*53846Spendry printf("portal_open: about to break apart control message\n"); 391*53846Spendry #endif 392*53846Spendry cmsg = mtod(cm, struct cmsghdr *); 393*53846Spendry newfds = (cmsg->cmsg_len - sizeof(*cmsg)) / sizeof (int); 394*53846Spendry if (newfds == 0) { 395*53846Spendry #ifdef PORTAL_DIAGNOSTIC 396*53846Spendry printf("portal_open: received no fds\n"); 397*53846Spendry #endif 398*53846Spendry error = ECONNREFUSED; 399*53846Spendry goto bad; 400*53846Spendry } 401*53846Spendry /* 402*53846Spendry * At this point the rights message consists of a control message 403*53846Spendry * header, followed by a data region containing a vector of 404*53846Spendry * integer file descriptors. The fds were allocated by the action 405*53846Spendry * of receiving the control message. 406*53846Spendry */ 407*53846Spendry ip = (int *) (cmsg + 1); 408*53846Spendry fd = *ip++; 409*53846Spendry if (newfds > 1) { 410*53846Spendry /* 411*53846Spendry * Close extra fds. 412*53846Spendry */ 413*53846Spendry int i; 414*53846Spendry printf("portal_open: %d extra fds\n", newfds - 1); 415*53846Spendry for (i = 1; i < newfds; i++) { 416*53846Spendry portal_closefd(ap->a_p, *ip); 417*53846Spendry ip++; 418*53846Spendry } 419*53846Spendry } 420*53846Spendry 421*53846Spendry /* 422*53846Spendry * Check that the ap->a_mode the file is being opened for is a subset 423*53846Spendry * of the ap->a_mode of the existing descriptor. 424*53846Spendry */ 425*53846Spendry #ifdef PORTAL_DIAGNOSTIC 426*53846Spendry printf("portal_open: checking file flags, fd = %d\n", fd); 427*53846Spendry #endif 428*53846Spendry fp = ap->a_p->p_fd->fd_ofiles[fd]; 429*53846Spendry if (((ap->a_mode & (FREAD|FWRITE)) | fp->f_flag) != fp->f_flag) { 430*53846Spendry portal_closefd(ap->a_p, fd); 431*53846Spendry error = EACCES; 432*53846Spendry goto bad; 433*53846Spendry } 434*53846Spendry 435*53846Spendry #ifdef PORTAL_DIAGNOSTIC 436*53846Spendry printf("portal_open: got fd = %d\n", fd); 437*53846Spendry #endif 438*53846Spendry /* 439*53846Spendry * Save the dup fd in the proc structure then return the 440*53846Spendry * special error code (ENXIO) which causes magic things to 441*53846Spendry * happen in vn_open. The whole concept is, well, hmmm. 442*53846Spendry */ 443*53846Spendry ap->a_p->p_dupfd = fd; 444*53846Spendry error = ENXIO; 445*53846Spendry 446*53846Spendry bad:; 447*53846Spendry /* 448*53846Spendry * And discard the control message. 449*53846Spendry */ 450*53846Spendry if (cm) { 451*53846Spendry #ifdef PORTAL_DIAGNOSTIC 452*53846Spendry printf("portal_open: free'ing control message\n"); 453*53846Spendry #endif 454*53846Spendry m_freem(cm); 455*53846Spendry } 456*53846Spendry 457*53846Spendry if (so) { 458*53846Spendry #ifdef PORTAL_DIAGNOSTIC 459*53846Spendry printf("portal_open: calling soshutdown\n"); 460*53846Spendry #endif 461*53846Spendry soshutdown(so, 2); 462*53846Spendry #ifdef PORTAL_DIAGNOSTIC 463*53846Spendry printf("portal_open: calling soclose\n"); 464*53846Spendry #endif 465*53846Spendry soclose(so); 466*53846Spendry } 467*53846Spendry #ifdef PORTAL_DIAGNOSTIC 468*53846Spendry if (error != ENODEV) 469*53846Spendry printf("portal_open: error = %d\n", error); 470*53846Spendry #endif 471*53846Spendry return (error); 472*53846Spendry } 473*53846Spendry 474*53846Spendry portal_getattr (ap) 475*53846Spendry struct vop_getattr_args *ap; 476*53846Spendry { 477*53846Spendry unsigned fd; 478*53846Spendry int error; 479*53846Spendry 480*53846Spendry bzero((caddr_t) ap->a_vap, sizeof(*ap->a_vap)); 481*53846Spendry vattr_null(ap->a_vap); 482*53846Spendry ap->a_vap->va_uid = 0; 483*53846Spendry ap->a_vap->va_gid = 0; 484*53846Spendry ap->a_vap->va_fsid = ap->a_vp->v_mount->mnt_stat.f_fsid.val[0]; 485*53846Spendry ap->a_vap->va_size = DEV_BSIZE; 486*53846Spendry ap->a_vap->va_blocksize = DEV_BSIZE; 487*53846Spendry microtime(&ap->a_vap->va_atime); 488*53846Spendry ap->a_vap->va_mtime = ap->a_vap->va_atime; 489*53846Spendry ap->a_vap->va_ctime = ap->a_vap->va_ctime; 490*53846Spendry ap->a_vap->va_gen = 0; 491*53846Spendry ap->a_vap->va_flags = 0; 492*53846Spendry ap->a_vap->va_rdev = 0; 493*53846Spendry /* ap->a_vap->va_qbytes = 0; */ 494*53846Spendry ap->a_vap->va_bytes = 0; 495*53846Spendry /* ap->a_vap->va_qsize = 0; */ 496*53846Spendry if (ap->a_vp->v_flag & VROOT) { 497*53846Spendry #ifdef PORTAL_DIAGNOSTIC 498*53846Spendry printf("portal_getattr: stat rootdir\n"); 499*53846Spendry #endif 500*53846Spendry ap->a_vap->va_type = VDIR; 501*53846Spendry ap->a_vap->va_mode = S_IRUSR|S_IWUSR|S_IXUSR| 502*53846Spendry S_IRGRP|S_IWGRP|S_IXGRP| 503*53846Spendry S_IROTH|S_IWOTH|S_IXOTH; 504*53846Spendry ap->a_vap->va_nlink = 2; 505*53846Spendry ap->a_vap->va_fileid = 2; 506*53846Spendry } else { 507*53846Spendry #ifdef PORTAL_DIAGNOSTIC 508*53846Spendry printf("portal_getattr: stat portal\n"); 509*53846Spendry #endif 510*53846Spendry ap->a_vap->va_type = VREG; 511*53846Spendry ap->a_vap->va_mode = S_IRUSR|S_IWUSR| 512*53846Spendry S_IRGRP|S_IWGRP| 513*53846Spendry S_IROTH|S_IWOTH; 514*53846Spendry ap->a_vap->va_nlink = 1; 515*53846Spendry ap->a_vap->va_fileid = VTOPORTAL(ap->a_vp)->pt_fileid; 516*53846Spendry } 517*53846Spendry return (0); 518*53846Spendry } 519*53846Spendry 520*53846Spendry portal_setattr (ap) 521*53846Spendry struct vop_setattr_args *ap; 522*53846Spendry { 523*53846Spendry /* 524*53846Spendry * Can't mess with the root vnode 525*53846Spendry */ 526*53846Spendry if (ap->a_vp->v_flag & VROOT) 527*53846Spendry return (EACCES); 528*53846Spendry 529*53846Spendry return (0); 530*53846Spendry } 531*53846Spendry 532*53846Spendry /* 533*53846Spendry * Fake readdir, just return empty directory. 534*53846Spendry * It is hard to deal with '.' and '..' so don't bother. 535*53846Spendry */ 536*53846Spendry portal_readdir (ap) 537*53846Spendry struct vop_readdir_args *ap; 538*53846Spendry { 539*53846Spendry *ap->a_eofflagp = 1; 540*53846Spendry return (0); 541*53846Spendry } 542*53846Spendry 543*53846Spendry portal_inactive (ap) 544*53846Spendry struct vop_inactive_args *ap; 545*53846Spendry { 546*53846Spendry #ifdef PORTAL_DIAGNOSTIC 547*53846Spendry if (VTOPORTAL(ap->a_vp)->pt_arg) 548*53846Spendry printf("portal_inactive(%x, %s)\n", ap->a_vp, VTOPORTAL(ap->a_vp)->pt_arg); 549*53846Spendry else 550*53846Spendry printf("portal_inactive(%x)\n", ap->a_vp); 551*53846Spendry #endif 552*53846Spendry /*vgone(ap->a_vp);*/ 553*53846Spendry return (0); 554*53846Spendry } 555*53846Spendry 556*53846Spendry portal_reclaim (ap) 557*53846Spendry struct vop_reclaim_args *ap; 558*53846Spendry { 559*53846Spendry struct portalnode *pt = VTOPORTAL(ap->a_vp); 560*53846Spendry #ifdef PORTAL_DIAGOISTIC 561*53846Spendry printf("portal_reclaim(%x)\n", ap->a_vp); 562*53846Spendry #endif 563*53846Spendry if (pt->pt_arg) { 564*53846Spendry free((caddr_t) pt->pt_arg, M_TEMP); 565*53846Spendry pt->pt_arg = 0; 566*53846Spendry } 567*53846Spendry FREE(pt, M_TEMP); 568*53846Spendry return (0); 569*53846Spendry } 570*53846Spendry 571*53846Spendry /* 572*53846Spendry * Print out the contents of a Portal vnode. 573*53846Spendry */ 574*53846Spendry /* ARGSUSED */ 575*53846Spendry portal_print (ap) 576*53846Spendry struct vop_print_args *ap; 577*53846Spendry { 578*53846Spendry printf("tag VT_PORTAL, portal vnode\n"); 579*53846Spendry } 580*53846Spendry 581*53846Spendry /*void*/ 582*53846Spendry portal_vfree (ap) 583*53846Spendry struct vop_vfree_args *ap; 584*53846Spendry { 585*53846Spendry return; 586*53846Spendry } 587*53846Spendry 588*53846Spendry 589*53846Spendry /* 590*53846Spendry * Portal vnode unsupported operation 591*53846Spendry */ 592*53846Spendry portal_enotsupp() 593*53846Spendry { 594*53846Spendry return (EOPNOTSUPP); 595*53846Spendry } 596*53846Spendry 597*53846Spendry /* 598*53846Spendry * Portal "should never get here" operation 599*53846Spendry */ 600*53846Spendry portal_badop() 601*53846Spendry { 602*53846Spendry panic("portal: bad op"); 603*53846Spendry /* NOTREACHED */ 604*53846Spendry } 605*53846Spendry 606*53846Spendry /* 607*53846Spendry * Portal vnode null operation 608*53846Spendry */ 609*53846Spendry portal_nullop() 610*53846Spendry { 611*53846Spendry return (0); 612*53846Spendry } 613*53846Spendry 614*53846Spendry #define portal_create ((int (*) __P((struct vop_create_args *)))portal_enotsupp) 615*53846Spendry #define portal_mknod ((int (*) __P((struct vop_mknod_args *)))portal_enotsupp) 616*53846Spendry #define portal_close ((int (*) __P((struct vop_close_args *)))nullop) 617*53846Spendry #define portal_access ((int (*) __P((struct vop_access_args *)))nullop) 618*53846Spendry #define portal_read ((int (*) __P((struct vop_read_args *)))portal_enotsupp) 619*53846Spendry #define portal_write ((int (*) __P((struct vop_write_args *)))portal_enotsupp) 620*53846Spendry #define portal_ioctl ((int (*) __P((struct vop_ioctl_args *)))portal_enotsupp) 621*53846Spendry #define portal_select ((int (*) __P((struct vop_select_args *)))portal_enotsupp) 622*53846Spendry #define portal_mmap ((int (*) __P((struct vop_mmap_args *)))portal_enotsupp) 623*53846Spendry #define portal_fsync ((int (*) __P((struct vop_fsync_args *)))nullop) 624*53846Spendry #define portal_seek ((int (*) __P((struct vop_seek_args *)))nullop) 625*53846Spendry #define portal_remove ((int (*) __P((struct vop_remove_args *)))portal_enotsupp) 626*53846Spendry #define portal_link ((int (*) __P((struct vop_link_args *)))portal_enotsupp) 627*53846Spendry #define portal_rename ((int (*) __P((struct vop_rename_args *)))portal_enotsupp) 628*53846Spendry #define portal_mkdir ((int (*) __P((struct vop_mkdir_args *)))portal_enotsupp) 629*53846Spendry #define portal_rmdir ((int (*) __P((struct vop_rmdir_args *)))portal_enotsupp) 630*53846Spendry #define portal_symlink ((int (*) __P((struct vop_symlink_args *)))portal_enotsupp) 631*53846Spendry #define portal_readlink ((int (*) __P((struct vop_readlink_args *)))portal_enotsupp) 632*53846Spendry #define portal_abortop ((int (*) __P((struct vop_abortop_args *)))nullop) 633*53846Spendry #define portal_lock ((int (*) __P((struct vop_lock_args *)))nullop) 634*53846Spendry #define portal_unlock ((int (*) __P((struct vop_unlock_args *)))nullop) 635*53846Spendry #define portal_bmap ((int (*) __P((struct vop_bmap_args *)))portal_badop) 636*53846Spendry #define portal_strategy ((int (*) __P((struct vop_strategy_args *)))portal_badop) 637*53846Spendry #define portal_islocked ((int (*) __P((struct vop_islocked_args *)))nullop) 638*53846Spendry #define portal_advlock ((int (*) __P((struct vop_advlock_args *)))portal_enotsupp) 639*53846Spendry #define portal_blkatoff ((int (*) __P((struct vop_blkatoff_args *)))portal_enotsupp) 640*53846Spendry #define portal_vget ((int (*) __P((struct vop_vget_args *)))portal_enotsupp) 641*53846Spendry #define portal_valloc ((int(*) __P(( \ 642*53846Spendry struct vnode *pvp, \ 643*53846Spendry int mode, \ 644*53846Spendry struct ucred *cred, \ 645*53846Spendry struct vnode **vpp))) portal_enotsupp) 646*53846Spendry #define portal_truncate ((int (*) __P((struct vop_truncate_args *)))portal_enotsupp) 647*53846Spendry #define portal_update ((int (*) __P((struct vop_update_args *)))portal_enotsupp) 648*53846Spendry #define portal_bwrite ((int (*) __P((struct vop_bwrite_args *)))portal_enotsupp) 649*53846Spendry 650*53846Spendry int (**portal_vnodeop_p)(); 651*53846Spendry struct vnodeopv_entry_desc portal_vnodeop_entries[] = { 652*53846Spendry { &vop_default_desc, vn_default_error }, 653*53846Spendry { &vop_lookup_desc, portal_lookup }, /* lookup */ 654*53846Spendry { &vop_create_desc, portal_create }, /* create */ 655*53846Spendry { &vop_mknod_desc, portal_mknod }, /* mknod */ 656*53846Spendry { &vop_open_desc, portal_open }, /* open */ 657*53846Spendry { &vop_close_desc, portal_close }, /* close */ 658*53846Spendry { &vop_access_desc, portal_access }, /* access */ 659*53846Spendry { &vop_getattr_desc, portal_getattr }, /* getattr */ 660*53846Spendry { &vop_setattr_desc, portal_setattr }, /* setattr */ 661*53846Spendry { &vop_read_desc, portal_read }, /* read */ 662*53846Spendry { &vop_write_desc, portal_write }, /* write */ 663*53846Spendry { &vop_ioctl_desc, portal_ioctl }, /* ioctl */ 664*53846Spendry { &vop_select_desc, portal_select }, /* select */ 665*53846Spendry { &vop_mmap_desc, portal_mmap }, /* mmap */ 666*53846Spendry { &vop_fsync_desc, portal_fsync }, /* fsync */ 667*53846Spendry { &vop_seek_desc, portal_seek }, /* seek */ 668*53846Spendry { &vop_remove_desc, portal_remove }, /* remove */ 669*53846Spendry { &vop_link_desc, portal_link }, /* link */ 670*53846Spendry { &vop_rename_desc, portal_rename }, /* rename */ 671*53846Spendry { &vop_mkdir_desc, portal_mkdir }, /* mkdir */ 672*53846Spendry { &vop_rmdir_desc, portal_rmdir }, /* rmdir */ 673*53846Spendry { &vop_symlink_desc, portal_symlink }, /* symlink */ 674*53846Spendry { &vop_readdir_desc, portal_readdir }, /* readdir */ 675*53846Spendry { &vop_readlink_desc, portal_readlink }, /* readlink */ 676*53846Spendry { &vop_abortop_desc, portal_abortop }, /* abortop */ 677*53846Spendry { &vop_inactive_desc, portal_inactive }, /* inactive */ 678*53846Spendry { &vop_reclaim_desc, portal_reclaim }, /* reclaim */ 679*53846Spendry { &vop_lock_desc, portal_lock }, /* lock */ 680*53846Spendry { &vop_unlock_desc, portal_unlock }, /* unlock */ 681*53846Spendry { &vop_bmap_desc, portal_bmap }, /* bmap */ 682*53846Spendry { &vop_strategy_desc, portal_strategy }, /* strategy */ 683*53846Spendry { &vop_print_desc, portal_print }, /* print */ 684*53846Spendry { &vop_islocked_desc, portal_islocked }, /* islocked */ 685*53846Spendry { &vop_advlock_desc, portal_advlock }, /* advlock */ 686*53846Spendry { &vop_blkatoff_desc, portal_blkatoff }, /* blkatoff */ 687*53846Spendry { &vop_vget_desc, portal_vget }, /* vget */ 688*53846Spendry { &vop_valloc_desc, portal_valloc }, /* valloc */ 689*53846Spendry { &vop_vfree_desc, portal_vfree }, /* vfree */ 690*53846Spendry { &vop_truncate_desc, portal_truncate }, /* truncate */ 691*53846Spendry { &vop_update_desc, portal_update }, /* update */ 692*53846Spendry { &vop_bwrite_desc, portal_bwrite }, /* bwrite */ 693*53846Spendry { (struct vnodeop_desc*)NULL, (int(*)())NULL } 694*53846Spendry }; 695*53846Spendry struct vnodeopv_desc portal_vnodeop_opv_desc = 696*53846Spendry { &portal_vnodeop_p, portal_vnodeop_entries }; 697