[BACK]Return to portal_vnops.c CVS log [TXT][DIR] Up to [local] / sys / miscfs / portal

Annotation of sys/miscfs/portal/portal_vnops.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: portal_vnops.c,v 1.24 2007/06/18 08:30:07 jasper Exp $        */
                      2: /*     $NetBSD: portal_vnops.c,v 1.17 1996/02/13 13:12:57 mycroft Exp $        */
                      3:
                      4: /*
                      5:  * Copyright (c) 1992, 1993
                      6:  *     The Regents of the University of California.  All rights reserved.
                      7:  *
                      8:  * This code is derived from software donated to Berkeley by
                      9:  * Jan-Simon Pendry.
                     10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  * 3. Neither the name of the University nor the names of its contributors
                     20:  *    may be used to endorse or promote products derived from this software
                     21:  *    without specific prior written permission.
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     24:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     25:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     26:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     27:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     28:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     29:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     30:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     31:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     32:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     33:  * SUCH DAMAGE.
                     34:  *
                     35:  *     from: Id: portal_vnops.c,v 1.4 1992/05/30 10:05:24 jsp Exp
                     36:  *     @(#)portal_vnops.c      8.8 (Berkeley) 1/21/94
                     37:  */
                     38:
                     39: /*
                     40:  * Portal Filesystem
                     41:  */
                     42:
                     43: #include <sys/param.h>
                     44: #include <sys/systm.h>
                     45: #include <sys/kernel.h>
                     46: #include <sys/types.h>
                     47: #include <sys/time.h>
                     48: #include <sys/proc.h>
                     49: #include <sys/filedesc.h>
                     50: #include <sys/vnode.h>
                     51: #include <sys/file.h>
                     52: #include <sys/stat.h>
                     53: #include <sys/mount.h>
                     54: #include <sys/malloc.h>
                     55: #include <sys/namei.h>
                     56: #include <sys/mbuf.h>
                     57: #include <sys/poll.h>
                     58: #include <sys/socket.h>
                     59: #include <sys/socketvar.h>
                     60: #include <sys/un.h>
                     61: #include <sys/unpcb.h>
                     62: #include <sys/syscallargs.h>
                     63: #include <miscfs/portal/portal.h>
                     64:
                     65: static int portal_fileid = PORTAL_ROOTFILEID+1;
                     66:
                     67: static void    portal_closefd(struct proc *, int);
                     68: static int     portal_connect(struct socket *, struct socket *);
                     69:
                     70:
                     71: int portal_badop(void *);
                     72:
                     73: int    portal_lookup(void *);
                     74: #define        portal_create   eopnotsupp
                     75: #define        portal_mknod    eopnotsupp
                     76: int    portal_open(void *);
                     77: #define        portal_close    nullop
                     78: #define        portal_access   nullop
                     79: int    portal_getattr(void *);
                     80: int    portal_setattr(void *);
                     81: #define        portal_read     eopnotsupp
                     82: #define        portal_write    eopnotsupp
                     83: #define        portal_ioctl    (int (*)(void *))enoioctl
                     84: #define        portal_fsync    nullop
                     85: #define        portal_remove   eopnotsupp
                     86: int    portal_link(void *);
                     87: #define        portal_rename   eopnotsupp
                     88: #define        portal_mkdir    eopnotsupp
                     89: #define        portal_rmdir    eopnotsupp
                     90: int    portal_symlink(void *);
                     91: int    portal_readdir(void *);
                     92: #define portal_revoke   vop_generic_revoke
                     93: #define        portal_readlink eopnotsupp
                     94: int    portal_inactive(void *);
                     95: int    portal_reclaim(void *);
                     96: #define        portal_lock     vop_generic_lock
                     97: #define        portal_unlock   vop_generic_unlock
                     98: #define        portal_bmap     portal_badop
                     99: #define        portal_strategy portal_badop
                    100: int    portal_print(void *);
                    101: #define        portal_islocked vop_generic_islocked
                    102: int    portal_pathconf(void *);
                    103: #define        portal_advlock  eopnotsupp
                    104: #define        portal_bwrite   eopnotsupp
                    105: int    portal_poll(void *);
                    106:
                    107: int (**portal_vnodeop_p)(void *);
                    108: struct vnodeopv_entry_desc portal_vnodeop_entries[] = {
                    109:        { &vop_default_desc, vn_default_error },
                    110:        { &vop_lookup_desc, portal_lookup },            /* lookup */
                    111:        { &vop_create_desc, portal_create },            /* create */
                    112:        { &vop_mknod_desc, portal_mknod },              /* mknod */
                    113:        { &vop_open_desc, portal_open },                /* open */
                    114:        { &vop_close_desc, portal_close },              /* close */
                    115:        { &vop_access_desc, portal_access },            /* access */
                    116:        { &vop_getattr_desc, portal_getattr },          /* getattr */
                    117:        { &vop_setattr_desc, portal_setattr },          /* setattr */
                    118:        { &vop_read_desc, portal_read },                /* read */
                    119:        { &vop_write_desc, portal_write },              /* write */
                    120:        { &vop_ioctl_desc, portal_ioctl },              /* ioctl */
                    121:        { &vop_poll_desc, portal_poll },                /* poll */
                    122:        { &vop_revoke_desc, portal_revoke },            /* revoke */
                    123:        { &vop_fsync_desc, portal_fsync },              /* fsync */
                    124:        { &vop_remove_desc, portal_remove },            /* remove */
                    125:        { &vop_link_desc, portal_link },                /* link */
                    126:        { &vop_rename_desc, portal_rename },            /* rename */
                    127:        { &vop_mkdir_desc, portal_mkdir },              /* mkdir */
                    128:        { &vop_rmdir_desc, portal_rmdir },              /* rmdir */
                    129:        { &vop_symlink_desc, portal_symlink },          /* symlink */
                    130:        { &vop_readdir_desc, portal_readdir },          /* readdir */
                    131:        { &vop_readlink_desc, portal_readlink },        /* readlink */
                    132:        { &vop_abortop_desc, vop_generic_abortop },             /* abortop */
                    133:        { &vop_inactive_desc, portal_inactive },        /* inactive */
                    134:        { &vop_reclaim_desc, portal_reclaim },          /* reclaim */
                    135:        { &vop_lock_desc, portal_lock },                /* lock */
                    136:        { &vop_unlock_desc, portal_unlock },            /* unlock */
                    137:        { &vop_bmap_desc, portal_bmap },                /* bmap */
                    138:        { &vop_strategy_desc, portal_strategy },        /* strategy */
                    139:        { &vop_print_desc, portal_print },              /* print */
                    140:        { &vop_islocked_desc, portal_islocked },        /* islocked */
                    141:        { &vop_pathconf_desc, portal_pathconf },        /* pathconf */
                    142:        { &vop_advlock_desc, portal_advlock },          /* advlock */
                    143:        { &vop_bwrite_desc, portal_bwrite },            /* bwrite */
                    144:        { NULL, NULL }
                    145: };
                    146: struct vnodeopv_desc portal_vnodeop_opv_desc =
                    147:        { &portal_vnodeop_p, portal_vnodeop_entries };
                    148:
                    149: static void
                    150: portal_closefd(struct proc *p, int fd)
                    151: {
                    152:        struct sys_close_args /* {
                    153:                syscallarg(int) fd;
                    154:        } */ ua;
                    155:        register_t retval[2];
                    156:        int error;
                    157:
                    158:        SCARG(&ua, fd) = fd;
                    159:        error = sys_close(p, &ua, retval);
                    160:        /*
                    161:         * We should never get an error, and there isn't anything
                    162:         * we could do if we got one, so just print a message.
                    163:         */
                    164:        if (error)
                    165:                printf("portal_closefd: error = %d\n", error);
                    166: }
                    167:
                    168: /*
                    169:  * vp is the current namei directory
                    170:  * cnp is the name to locate in that directory...
                    171:  */
                    172: int
                    173: portal_lookup(void *v)
                    174: {
                    175:        struct vop_lookup_args *ap = v;
                    176:        struct componentname *cnp = ap->a_cnp;
                    177:        struct vnode **vpp = ap->a_vpp;
                    178:        struct vnode *dvp = ap->a_dvp;
                    179:        char *pname = cnp->cn_nameptr;
                    180:        struct proc *p = cnp->cn_proc;
                    181:        struct portalnode *pt;
                    182:        int error;
                    183:        struct vnode *fvp = 0;
                    184:        char *path;
                    185:        int size;
                    186:
                    187:        *vpp = NULLVP;
                    188:
                    189:        if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)
                    190:                return (EROFS);
                    191:
                    192:        if (cnp->cn_namelen == 1 && *pname == '.') {
                    193:                *vpp = dvp;
                    194:                VREF(dvp);
                    195:                return (0);
                    196:        }
                    197:
                    198:        error = getnewvnode(VT_PORTAL, dvp->v_mount, portal_vnodeop_p, &fvp);
                    199:        if (error)
                    200:                goto bad;
                    201:        fvp->v_type = VREG;
                    202:        MALLOC(fvp->v_data, void *, sizeof(struct portalnode), M_TEMP,
                    203:            M_WAITOK);
                    204:
                    205:        pt = VTOPORTAL(fvp);
                    206:        /*
                    207:         * Save all of the remaining pathname and
                    208:         * advance the namei next pointer to the end
                    209:         * of the string.
                    210:         */
                    211:        for (size = 0, path = pname; *path; path++)
                    212:                size++;
                    213:        cnp->cn_consume = size - cnp->cn_namelen;
                    214:
                    215:        pt->pt_arg = malloc(size+1, M_TEMP, M_WAITOK);
                    216:        pt->pt_size = size+1;
                    217:        bcopy(pname, pt->pt_arg, pt->pt_size);
                    218:        pt->pt_fileid = portal_fileid++;
                    219:
                    220:        *vpp = fvp;
                    221:        VOP_LOCK(fvp, LK_EXCLUSIVE, p);
                    222:        /*
                    223:         * As we are the last component of the path name, fix up
                    224:         * the locking on the directory node.
                    225:         */
                    226:        if ((cnp->cn_flags & LOCKPARENT) == 0) {
                    227:                VOP_UNLOCK(dvp, 0, p);
                    228:                cnp->cn_flags |= PDIRUNLOCK;
                    229:        }
                    230:        return (0);
                    231:
                    232: bad:;
                    233:        if (fvp)
                    234:                vrele(fvp);
                    235:        return (error);
                    236: }
                    237:
                    238: static int
                    239: portal_connect(struct socket *so, struct socket *so2)
                    240: {
                    241:        /* from unp_connect, bypassing the namei stuff... */
                    242:        struct socket *so3;
                    243:        struct unpcb *unp2;
                    244:        struct unpcb *unp3;
                    245:
                    246:        if (so2 == 0)
                    247:                return (ECONNREFUSED);
                    248:
                    249:        if (so->so_type != so2->so_type)
                    250:                return (EPROTOTYPE);
                    251:
                    252:        if ((so2->so_options & SO_ACCEPTCONN) == 0)
                    253:                return (ECONNREFUSED);
                    254:
                    255:        if ((so3 = sonewconn(so2, 0)) == 0)
                    256:                return (ECONNREFUSED);
                    257:
                    258:        unp2 = sotounpcb(so2);
                    259:        unp3 = sotounpcb(so3);
                    260:        if (unp2->unp_addr)
                    261:                unp3->unp_addr = m_copy(unp2->unp_addr, 0, (int)M_COPYALL);
                    262:
                    263:        so2 = so3;
                    264:
                    265:
                    266:        return (unp_connect2(so, so2));
                    267: }
                    268:
                    269: int
                    270: portal_open(void *v)
                    271: {
                    272:        struct vop_open_args *ap = v;
                    273:        struct socket *so = 0;
                    274:        struct portalnode *pt;
                    275:        struct proc *p = ap->a_p;
                    276:        struct vnode *vp = ap->a_vp;
                    277:        int s;
                    278:        struct uio auio;
                    279:        struct iovec aiov[2];
                    280:        int res;
                    281:        struct mbuf *cm = 0;
                    282:        struct cmsghdr *cmsg;
                    283:        int newfds;
                    284:        int *ip;
                    285:        int fd;
                    286:        int error;
                    287:        int len;
                    288:        struct portalmount *fmp;
                    289:        struct file *fp;
                    290:        struct portal_cred pcred;
                    291:
                    292:        /*
                    293:         * Nothing to do when opening the root node.
                    294:         */
                    295:        if (vp->v_flag & VROOT)
                    296:                return (0);
                    297:
                    298:        /*
                    299:         * Can't be opened unless the caller is set up
                    300:         * to deal with the side effects.  Check for this
                    301:         * by testing whether the p_dupfd has been set.
                    302:         */
                    303:        if (p->p_dupfd >= 0)
                    304:                return (ENODEV);
                    305:
                    306:        pt = VTOPORTAL(vp);
                    307:        fmp = VFSTOPORTAL(vp->v_mount);
                    308:
                    309:        /*
                    310:         * Create a new socket.
                    311:         */
                    312:        error = socreate(AF_UNIX, &so, SOCK_STREAM, 0);
                    313:        if (error)
                    314:                goto bad;
                    315:
                    316:        /*
                    317:         * Reserve some buffer space
                    318:         */
                    319:        res = pt->pt_size + sizeof(pcred) + 512;        /* XXX */
                    320:        error = soreserve(so, res, res);
                    321:        if (error)
                    322:                goto bad;
                    323:
                    324:        /*
                    325:         * Kick off connection
                    326:         */
                    327:        s = splsoftnet();
                    328:        error = portal_connect(so, (struct socket *)fmp->pm_server->f_data);
                    329:        splx(s);
                    330:        if (error)
                    331:                goto bad;
                    332:
                    333:        /*
                    334:         * Wait for connection to complete
                    335:         */
                    336:        /*
                    337:         * XXX: Since the mount point is holding a reference on the
                    338:         * underlying server socket, it is not easy to find out whether
                    339:         * the server process is still running.  To handle this problem
                    340:         * we loop waiting for the new socket to be connected (something
                    341:         * which will only happen if the server is still running) or for
                    342:         * the reference count on the server socket to drop to 1, which
                    343:         * will happen if the server dies.  Sleep for 5 second intervals
                    344:         * and keep polling the reference count.   XXX.
                    345:         */
                    346:        s = splsoftnet();
                    347:        while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
                    348:                if (fmp->pm_server->f_count == 1) {
                    349:                        error = ECONNREFUSED;
                    350:                        splx(s);
                    351:                        goto bad;
                    352:                }
                    353:                (void) tsleep(&so->so_timeo, PSOCK, "portalcon", 5 * hz);
                    354:        }
                    355:        splx(s);
                    356:
                    357:        if (so->so_error) {
                    358:                error = so->so_error;
                    359:                goto bad;
                    360:        }
                    361:
                    362:        /*
                    363:         * Set miscellaneous flags
                    364:         */
                    365:        so->so_rcv.sb_timeo = 0;
                    366:        so->so_snd.sb_timeo = 0;
                    367:        so->so_rcv.sb_flags |= SB_NOINTR;
                    368:        so->so_snd.sb_flags |= SB_NOINTR;
                    369:
                    370:
                    371:        pcred.pcr_flag = ap->a_mode;
                    372:        pcred.pcr_uid = ap->a_cred->cr_uid;
                    373:        pcred.pcr_gid = ap->a_cred->cr_gid;
                    374:        pcred.pcr_ngroups = ap->a_cred->cr_ngroups;
                    375:        bcopy(ap->a_cred->cr_groups, pcred.pcr_groups, NGROUPS * sizeof(gid_t));
                    376:        aiov[0].iov_base = &pcred;
                    377:        aiov[0].iov_len = sizeof(pcred);
                    378:        aiov[1].iov_base = pt->pt_arg;
                    379:        aiov[1].iov_len = pt->pt_size;
                    380:        auio.uio_iov = aiov;
                    381:        auio.uio_iovcnt = 2;
                    382:        auio.uio_rw = UIO_WRITE;
                    383:        auio.uio_segflg = UIO_SYSSPACE;
                    384:        auio.uio_procp = p;
                    385:        auio.uio_offset = 0;
                    386:        auio.uio_resid = aiov[0].iov_len + aiov[1].iov_len;
                    387:
                    388:        error = sosend(so, (struct mbuf *) 0, &auio,
                    389:                        (struct mbuf *) 0, (struct mbuf *) 0, 0);
                    390:        if (error)
                    391:                goto bad;
                    392:
                    393:        len = auio.uio_resid = sizeof(int);
                    394:        do {
                    395:                struct mbuf *m = 0;
                    396:                int flags = MSG_WAITALL;
                    397:                fdpunlock(p->p_fd);
                    398:                error = soreceive(so, (struct mbuf **) 0, &auio,
                    399:                                        &m, &cm, &flags);
                    400:                fdplock(p->p_fd);
                    401:                if (error)
                    402:                        goto bad;
                    403:
                    404:                /*
                    405:                 * Grab an error code from the mbuf.
                    406:                 */
                    407:                if (m) {
                    408:                        m = m_pullup(m, sizeof(int));   /* Needed? */
                    409:                        if (m) {
                    410:                                error = *(mtod(m, int *));
                    411:                                m_freem(m);
                    412:                        } else {
                    413:                                error = EINVAL;
                    414:                        }
                    415:                } else {
                    416:                        if (cm == 0) {
                    417:                                error = ECONNRESET;      /* XXX */
                    418: #ifdef notdef
                    419:                                break;
                    420: #endif
                    421:                        }
                    422:                }
                    423:        } while (cm == 0 && auio.uio_resid == len && !error);
                    424:
                    425:        if (cm == 0)
                    426:                goto bad;
                    427:
                    428:        if (auio.uio_resid) {
                    429:                error = 0;
                    430: #ifdef notdef
                    431:                error = EMSGSIZE;
                    432:                goto bad;
                    433: #endif
                    434:        }
                    435:
                    436:        /*
                    437:         * XXX: Break apart the control message, and retrieve the
                    438:         * received file descriptor.  Note that more than one descriptor
                    439:         * may have been received, or that the rights chain may have more
                    440:         * than a single mbuf in it.  What to do?
                    441:         */
                    442:        cmsg = mtod(cm, struct cmsghdr *);
                    443:        newfds = (cmsg->cmsg_len - sizeof(*cmsg)) / sizeof (int);
                    444:        if (newfds == 0) {
                    445:                error = ECONNREFUSED;
                    446:                goto bad;
                    447:        }
                    448:        /*
                    449:         * At this point the rights message consists of a control message
                    450:         * header, followed by a data region containing a vector of
                    451:         * integer file descriptors.  The fds were allocated by the action
                    452:         * of receiving the control message.
                    453:         */
                    454:        ip = (int *)(cmsg + 1);
                    455:        fd = *ip++;
                    456:        if (newfds > 1) {
                    457:                /*
                    458:                 * Close extra fds.
                    459:                 */
                    460:                int i;
                    461:                printf("portal_open: %d extra fds\n", newfds - 1);
                    462:                for (i = 1; i < newfds; i++) {
                    463:                        portal_closefd(p, *ip);
                    464:                        ip++;
                    465:                }
                    466:        }
                    467:
                    468:        /*
                    469:         * Check that the mode the file is being opened for is a subset
                    470:         * of the mode of the existing descriptor.
                    471:         */
                    472:        if ((fp = fd_getfile(p->p_fd, fd)) == NULL) {
                    473:                error = EBADF;
                    474:                goto bad;
                    475:        }
                    476:        if (((ap->a_mode & (FREAD|FWRITE)) | fp->f_flag) != fp->f_flag) {
                    477:                portal_closefd(p, fd);
                    478:                error = EACCES;
                    479:                goto bad;
                    480:        }
                    481:
                    482:        /*
                    483:         * Save the dup fd in the proc structure then return the
                    484:         * special error code (ENXIO) which causes magic things to
                    485:         * happen in vn_open.  The whole concept is, well, hmmm.
                    486:         */
                    487:        p->p_dupfd = fd;
                    488:        error = ENXIO;
                    489:
                    490: bad:;
                    491:        /*
                    492:         * And discard the control message.
                    493:         */
                    494:        if (cm) {
                    495:                m_freem(cm);
                    496:        }
                    497:
                    498:        if (so) {
                    499:                soshutdown(so, 2);
                    500:                soclose(so);
                    501:        }
                    502:        return (error);
                    503: }
                    504:
                    505: int
                    506: portal_getattr(void *v)
                    507: {
                    508:        struct vop_getattr_args *ap = v;
                    509:        struct vnode *vp = ap->a_vp;
                    510:        struct vattr *vap = ap->a_vap;
                    511:
                    512:        bzero(vap, sizeof(*vap));
                    513:        vattr_null(vap);
                    514:        vap->va_uid = 0;
                    515:        vap->va_gid = 0;
                    516:        vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
                    517:        vap->va_size = DEV_BSIZE;
                    518:        vap->va_blocksize = DEV_BSIZE;
                    519:        getnanotime(&vap->va_atime);
                    520:        vap->va_mtime = vap->va_atime;
                    521:        vap->va_ctime = vap->va_atime;
                    522:        vap->va_gen = 0;
                    523:        vap->va_flags = 0;
                    524:        vap->va_rdev = 0;
                    525:        /* vap->va_qbytes = 0; */
                    526:        vap->va_bytes = 0;
                    527:        /* vap->va_qsize = 0; */
                    528:        if (vp->v_flag & VROOT) {
                    529:                vap->va_type = VDIR;
                    530:                vap->va_mode = S_IRUSR|S_IWUSR|S_IXUSR|
                    531:                                S_IRGRP|S_IWGRP|S_IXGRP|
                    532:                                S_IROTH|S_IWOTH|S_IXOTH;
                    533:                vap->va_nlink = 2;
                    534:                vap->va_fileid = 2;
                    535:        } else {
                    536:                vap->va_type = VREG;
                    537:                vap->va_mode = S_IRUSR|S_IWUSR|
                    538:                                S_IRGRP|S_IWGRP|
                    539:                                S_IROTH|S_IWOTH;
                    540:                vap->va_nlink = 1;
                    541:                vap->va_fileid = VTOPORTAL(vp)->pt_fileid;
                    542:        }
                    543:        return (0);
                    544: }
                    545:
                    546: int
                    547: portal_setattr(void *v)
                    548: {
                    549:        struct vop_setattr_args *ap = v;
                    550:
                    551:        /*
                    552:         * Can't mess with the root vnode
                    553:         */
                    554:        if (ap->a_vp->v_flag & VROOT)
                    555:                return (EACCES);
                    556:
                    557:        if (ap->a_vap->va_flags != VNOVAL)
                    558:                return (EOPNOTSUPP);
                    559:
                    560:        return (0);
                    561: }
                    562:
                    563: /*
                    564:  * Fake readdir, just return empty directory.
                    565:  * It is hard to deal with '.' and '..' so don't bother.
                    566:  */
                    567: /*ARGSUSED*/
                    568: int
                    569: portal_readdir(void *v)
                    570: {
                    571:        return (0);
                    572: }
                    573:
                    574: /*ARGSUSED*/
                    575: int
                    576: portal_inactive(void *v)
                    577: {
                    578:        struct vop_inactive_args *ap = v;
                    579:
                    580:        VOP_UNLOCK(ap->a_vp, 0, ap->a_p);
                    581:        return (0);
                    582: }
                    583:
                    584: int
                    585: portal_reclaim(void *v)
                    586: {
                    587:        struct vop_reclaim_args *ap = v;
                    588:        struct portalnode *pt = VTOPORTAL(ap->a_vp);
                    589:
                    590:        if (pt->pt_arg) {
                    591:                free(pt->pt_arg, M_TEMP);
                    592:                pt->pt_arg = 0;
                    593:        }
                    594:        FREE(ap->a_vp->v_data, M_TEMP);
                    595:        ap->a_vp->v_data = 0;
                    596:
                    597:        return (0);
                    598: }
                    599:
                    600: /*
                    601:  * Return POSIX pathconf information applicable to special devices.
                    602:  */
                    603: int
                    604: portal_pathconf(void *v)
                    605: {
                    606:        struct vop_pathconf_args *ap = v;
                    607:
                    608:        switch (ap->a_name) {
                    609:        case _PC_LINK_MAX:
                    610:                *ap->a_retval = LINK_MAX;
                    611:                return (0);
                    612:        case _PC_MAX_CANON:
                    613:                *ap->a_retval = MAX_CANON;
                    614:                return (0);
                    615:        case _PC_MAX_INPUT:
                    616:                *ap->a_retval = MAX_INPUT;
                    617:                return (0);
                    618:        case _PC_PIPE_BUF:
                    619:                *ap->a_retval = PIPE_BUF;
                    620:                return (0);
                    621:        case _PC_CHOWN_RESTRICTED:
                    622:                *ap->a_retval = 1;
                    623:                return (0);
                    624:        case _PC_VDISABLE:
                    625:                *ap->a_retval = _POSIX_VDISABLE;
                    626:                return (0);
                    627:        default:
                    628:                return (EINVAL);
                    629:        }
                    630:        /* NOTREACHED */
                    631: }
                    632:
                    633: /*
                    634:  * Print out the contents of a Portal vnode.
                    635:  */
                    636: /* ARGSUSED */
                    637: int
                    638: portal_print(void *v)
                    639: {
                    640:        printf("tag VT_PORTAL, portal vnode\n");
                    641:        return (0);
                    642: }
                    643:
                    644: int
                    645: portal_link(void *v)
                    646: {
                    647:        struct vop_link_args *ap = v;
                    648:
                    649:        VOP_ABORTOP(ap->a_dvp, ap->a_cnp);
                    650:        vput(ap->a_dvp);
                    651:        return (EROFS);
                    652: }
                    653:
                    654: int
                    655: portal_symlink(void *v)
                    656: {
                    657:        struct vop_symlink_args *ap = v;
                    658:
                    659:        VOP_ABORTOP(ap->a_dvp, ap->a_cnp);
                    660:        vput(ap->a_dvp);
                    661:        return (EROFS);
                    662: }
                    663:
                    664: int
                    665: portal_badop(void *v)
                    666: {
                    667:        panic ("portal: bad op");
                    668:        return (0);
                    669: }
                    670:
                    671: int
                    672: portal_poll(void *v)
                    673: {
                    674:        struct vop_poll_args *ap = v;
                    675:
                    676:        return (ap->a_events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
                    677: }

CVSweb