Annotation of XNU/bsd/miscfs/portal/portal_vnops.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.