Annotation of XNU/bsd/miscfs/portal/portal_vnops.c, revision 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.