Annotation of kernel/bsd/miscfs/kernfs/kernfs_vnops.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
        !             7:  * Reserved.  This file contains Original Code and/or Modifications of
        !             8:  * Original Code as defined in and that are subject to the Apple Public
        !             9:  * Source License Version 1.1 (the "License").  You may not use this file
        !            10:  * except in compliance with the License.  Please obtain a copy of the
        !            11:  * License at http://www.apple.com/publicsource and read it before using
        !            12:  * this file.
        !            13:  * 
        !            14:  * The Original Code and all software distributed under the License are
        !            15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            19:  * License for the specific language governing rights and limitations
        !            20:  * under the License.
        !            21:  * 
        !            22:  * @APPLE_LICENSE_HEADER_END@
        !            23:  */
        !            24: 
        !            25: /*     $NetBSD: kernfs_vnops.c,v 1.35 1995/02/03 16:18:46 mycroft Exp $        */
        !            26: 
        !            27: /*
        !            28:  * Copyright (c) 1992, 1993
        !            29:  *     The Regents of the University of California.  All rights reserved.
        !            30:  *
        !            31:  * This code is derived from software donated to Berkeley by
        !            32:  * Jan-Simon Pendry.
        !            33:  *
        !            34:  * Redistribution and use in source and binary forms, with or without
        !            35:  * modification, are permitted provided that the following conditions
        !            36:  * are met:
        !            37:  * 1. Redistributions of source code must retain the above copyright
        !            38:  *    notice, this list of conditions and the following disclaimer.
        !            39:  * 2. Redistributions in binary form must reproduce the above copyright
        !            40:  *    notice, this list of conditions and the following disclaimer in the
        !            41:  *    documentation and/or other materials provided with the distribution.
        !            42:  * 3. All advertising materials mentioning features or use of this software
        !            43:  *    must display the following acknowledgement:
        !            44:  *     This product includes software developed by the University of
        !            45:  *     California, Berkeley and its contributors.
        !            46:  * 4. Neither the name of the University nor the names of its contributors
        !            47:  *    may be used to endorse or promote products derived from this software
        !            48:  *    without specific prior written permission.
        !            49:  *
        !            50:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            51:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            52:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            53:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            54:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            55:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            56:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            57:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            58:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            59:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            60:  * SUCH DAMAGE.
        !            61:  *
        !            62:  *     @(#)kernfs_vnops.c      8.9 (Berkeley) 6/15/94
        !            63:  */
        !            64: 
        !            65: /*
        !            66:  * Kernel parameter filesystem (/kern)
        !            67:  */
        !            68: 
        !            69: #include <sys/param.h>
        !            70: #include <sys/systm.h>
        !            71: #include <sys/kernel.h>
        !            72: #include <sys/vmmeter.h>
        !            73: #include <sys/types.h>
        !            74: #include <sys/time.h>
        !            75: #include <sys/proc.h>
        !            76: #include <sys/vnode.h>
        !            77: #include <sys/malloc.h>
        !            78: #include <sys/file.h>
        !            79: #include <sys/stat.h>
        !            80: #include <sys/mount.h>
        !            81: #include <sys/namei.h>
        !            82: #include <sys/buf.h>
        !            83: #include <sys/dirent.h>
        !            84: #include <sys/msgbuf.h>
        !            85: #include <miscfs/kernfs/kernfs.h>
        !            86: 
        !            87: #define KSTRING        256             /* Largest I/O available via this filesystem */
        !            88: #define        UIO_MX 32
        !            89: 
        !            90: #define        READ_MODE       (S_IRUSR|S_IRGRP|S_IROTH)
        !            91: #define        WRITE_MODE      (S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH)
        !            92: #define DIR_MODE       (S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
        !            93: 
        !            94: struct kern_target {
        !            95:        u_char kt_type;
        !            96:        u_char kt_namlen;
        !            97:        char *kt_name;
        !            98:        void *kt_data;
        !            99: #define        KTT_NULL         1
        !           100: #define        KTT_TIME         5
        !           101: #define KTT_INT                17
        !           102: #define        KTT_STRING      31
        !           103: #define KTT_HOSTNAME   47
        !           104: #define KTT_AVENRUN    53
        !           105: #define KTT_DEVICE     71
        !           106: #define        KTT_MSGBUF      89
        !           107:        u_char kt_tag;
        !           108:        u_char kt_vtype;
        !           109:        mode_t kt_mode;
        !           110: } kern_targets[] = {
        !           111: /* NOTE: The name must be less than UIO_MX-16 chars in length */
        !           112: #define N(s) sizeof(s)-1, s
        !           113:      /*        name            data          tag           type  ro/rw */
        !           114:      { DT_DIR, N("."),         0,            KTT_NULL,     VDIR, DIR_MODE   },
        !           115:      { DT_DIR, N(".."),        0,            KTT_NULL,     VDIR, DIR_MODE   },
        !           116:      { DT_REG, N("boottime"),  &boottime.tv_sec, KTT_INT,  VREG, READ_MODE  },
        !           117:      { DT_REG, N("copyright"), copyright,    KTT_STRING,   VREG, READ_MODE  },
        !           118:      { DT_REG, N("hostname"),  0,            KTT_HOSTNAME, VREG, WRITE_MODE },
        !           119:      { DT_REG, N("hz"),        &hz,          KTT_INT,      VREG, READ_MODE  },
        !           120:      { DT_REG, N("loadavg"),   0,            KTT_AVENRUN,  VREG, READ_MODE  },
        !           121:      { DT_REG, N("msgbuf"),    0,           KTT_MSGBUF,   VREG, READ_MODE  },
        !           122:      { DT_REG, N("pagesize"),  &cnt.v_page_size, KTT_INT,  VREG, READ_MODE  },
        !           123:      { DT_REG, N("physmem"),   &physmem,     KTT_INT,      VREG, READ_MODE  },
        !           124: #if 0
        !           125:      { DT_DIR, N("root"),      0,            KTT_NULL,     VDIR, DIR_MODE   },
        !           126: #endif
        !           127:      { DT_BLK, N("rootdev"),   &rootdev,     KTT_DEVICE,   VBLK, READ_MODE  },
        !           128:      { DT_CHR, N("rrootdev"),  &rrootdev,    KTT_DEVICE,   VCHR, READ_MODE  },
        !           129:      { DT_REG, N("time"),      0,            KTT_TIME,     VREG, READ_MODE  },
        !           130:      { DT_REG, N("version"),   version,      KTT_STRING,   VREG, READ_MODE  },
        !           131: #undef N
        !           132: };
        !           133: static int nkern_targets = sizeof(kern_targets) / sizeof(kern_targets[0]);
        !           134: 
        !           135: int
        !           136: kernfs_xread(kt, off, bufp, len)
        !           137:        struct kern_target *kt;
        !           138:        int off;
        !           139:        char **bufp;
        !           140:        int len;
        !           141: {
        !           142: 
        !           143:        switch (kt->kt_tag) {
        !           144:        case KTT_TIME: {
        !           145:                struct timeval tv;
        !           146: 
        !           147:                microtime(&tv);
        !           148:                sprintf(*bufp, "%d %d\n", tv.tv_sec, tv.tv_usec);
        !           149:                break;
        !           150:        }
        !           151: 
        !           152:        case KTT_INT: {
        !           153:                int *ip = kt->kt_data;
        !           154: 
        !           155:                sprintf(*bufp, "%d\n", *ip);
        !           156:                break;
        !           157:        }
        !           158: 
        !           159:        case KTT_STRING: {
        !           160:                char *cp = kt->kt_data;
        !           161: 
        !           162:                *bufp = cp;
        !           163:                break;
        !           164:        }
        !           165: 
        !           166:        case KTT_MSGBUF: {
        !           167:                extern struct msgbuf *msgbufp;
        !           168:                long n;
        !           169: 
        !           170:                if (off >= MSG_BSIZE)
        !           171:                        return (0);
        !           172:                n = msgbufp->msg_bufx + off;
        !           173:                if (n >= MSG_BSIZE)
        !           174:                        n -= MSG_BSIZE;
        !           175:                len = min(MSG_BSIZE - n, MSG_BSIZE - off);
        !           176:                *bufp = msgbufp->msg_bufc + n;
        !           177:                return (len);
        !           178:        }
        !           179: 
        !           180:        case KTT_HOSTNAME: {
        !           181:                char *cp = hostname;
        !           182:                int xlen = hostnamelen;
        !           183: 
        !           184:                if (xlen >= (len-2))
        !           185:                        return (EINVAL);
        !           186: 
        !           187:                bcopy(cp, *bufp, xlen);
        !           188:                (*bufp)[xlen] = '\n';
        !           189:                (*bufp)[xlen+1] = '\0';
        !           190:                break;
        !           191:        }
        !           192: 
        !           193:        case KTT_AVENRUN:
        !           194:                averunnable.fscale = FSCALE;
        !           195:                sprintf(*bufp, "%ld %ld %ld %ld\n",
        !           196:                    averunnable.ldavg[0], averunnable.ldavg[1],
        !           197:                    averunnable.ldavg[2], averunnable.fscale);
        !           198:                break;
        !           199: 
        !           200:        default:
        !           201:                return (0);
        !           202:        }
        !           203: 
        !           204:        len = strlen(*bufp);
        !           205:        if (len <= off)
        !           206:                return (0);
        !           207:        *bufp += off;
        !           208:        return (len - off);
        !           209: }
        !           210: 
        !           211: int
        !           212: kernfs_xwrite(kt, buf, len)
        !           213:        struct kern_target *kt;
        !           214:        char *buf;
        !           215:        int len;
        !           216: {
        !           217: 
        !           218:        switch (kt->kt_tag) {
        !           219:        case KTT_HOSTNAME:
        !           220:                if (buf[len-1] == '\n')
        !           221:                        --len;
        !           222:                bcopy(buf, hostname, len);
        !           223:                hostname[len] = '\0';
        !           224:                hostnamelen = len;
        !           225:                return (0);
        !           226: 
        !           227:        default:
        !           228:                return (EIO);
        !           229:        }
        !           230: }
        !           231: 
        !           232: 
        !           233: /*
        !           234:  * vp is the current namei directory
        !           235:  * ndp is the name to locate in that directory...
        !           236:  */
        !           237: kernfs_lookup(ap)
        !           238:        struct vop_lookup_args /* {
        !           239:                struct vnode * a_dvp;
        !           240:                struct vnode ** a_vpp;
        !           241:                struct componentname * a_cnp;
        !           242:        } */ *ap;
        !           243: {
        !           244:        struct componentname *cnp = ap->a_cnp;
        !           245:        struct vnode **vpp = ap->a_vpp;
        !           246:        struct vnode *dvp = ap->a_dvp;
        !           247:        char *pname = cnp->cn_nameptr;
        !           248:        struct kern_target *kt;
        !           249:        struct vnode *fvp;
        !           250:        int error, i;
        !           251: 
        !           252: #ifdef KERNFS_DIAGNOSTIC
        !           253:        printf("kernfs_lookup(%x)\n", ap);
        !           254:        printf("kernfs_lookup(dp = %x, vpp = %x, cnp = %x)\n", dvp, vpp, ap->a_cnp);
        !           255:        printf("kernfs_lookup(%s)\n", pname);
        !           256: #endif
        !           257: 
        !           258:        *vpp = NULLVP;
        !           259: 
        !           260:        if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)
        !           261:                return (EROFS);
        !           262: 
        !           263:        if (cnp->cn_namelen == 1 && *pname == '.') {
        !           264:                *vpp = dvp;
        !           265:                VREF(dvp);
        !           266:                /*VOP_LOCK(dvp);*/
        !           267:                return (0);
        !           268:        }
        !           269: 
        !           270: #if 0
        !           271:        if (cnp->cn_namelen == 4 && bcmp(pname, "root", 4) == 0) {
        !           272:                *vpp = rootdir;
        !           273:                VREF(rootdir);
        !           274:                VOP_LOCK(rootdir);
        !           275:                return (0);
        !           276:        }
        !           277: #endif
        !           278: 
        !           279:        for (kt = kern_targets, i = 0; i < nkern_targets; kt++, i++) {
        !           280:                if (cnp->cn_namelen == kt->kt_namlen &&
        !           281:                    bcmp(kt->kt_name, pname, cnp->cn_namelen) == 0)
        !           282:                        goto found;
        !           283:        }
        !           284: 
        !           285: #ifdef KERNFS_DIAGNOSTIC
        !           286:        printf("kernfs_lookup: i = %d, failed", i);
        !           287: #endif
        !           288: 
        !           289:        return (cnp->cn_nameiop == LOOKUP ? ENOENT : EROFS);
        !           290: 
        !           291: found:
        !           292:        if (kt->kt_tag == KTT_DEVICE) {
        !           293:                dev_t *dp = kt->kt_data;
        !           294:        loop:
        !           295:                if (*dp == NODEV || !vfinddev(*dp, kt->kt_vtype, &fvp))
        !           296:                        return (ENOENT);
        !           297:                *vpp = fvp;
        !           298:                if (vget(fvp, 1))
        !           299:                        goto loop;
        !           300:                return (0);
        !           301:        }
        !           302: 
        !           303: #ifdef KERNFS_DIAGNOSTIC
        !           304:        printf("kernfs_lookup: allocate new vnode\n");
        !           305: #endif
        !           306:        if (error = getnewvnode(VT_KERNFS, dvp->v_mount, kernfs_vnodeop_p,
        !           307:            &fvp))
        !           308:                return (error);
        !           309: 
        !           310:        MALLOC(fvp->v_data, void *, sizeof(struct kernfs_node), M_TEMP,
        !           311:            M_WAITOK);
        !           312:        VTOKERN(fvp)->kf_kt = kt;
        !           313:        fvp->v_type = kt->kt_vtype;
        !           314:        *vpp = fvp;
        !           315: 
        !           316: #ifdef KERNFS_DIAGNOSTIC
        !           317:        printf("kernfs_lookup: newvp = %x\n", fvp);
        !           318: #endif
        !           319:        return (0);
        !           320: }
        !           321: 
        !           322: kernfs_open(ap)
        !           323:        struct vop_open_args /* {
        !           324:                struct vnode *a_vp;
        !           325:                int  a_mode;
        !           326:                struct ucred *a_cred;
        !           327:                struct proc *a_p;
        !           328:        } */ *ap;
        !           329: {
        !           330: 
        !           331:        /* Only need to check access permissions. */
        !           332:        return (0);
        !           333: }
        !           334: 
        !           335: int
        !           336: kernfs_access(ap)
        !           337:        struct vop_access_args /* {
        !           338:                struct vnode *a_vp;
        !           339:                int a_mode;
        !           340:                struct ucred *a_cred;
        !           341:                struct proc *a_p;
        !           342:        } */ *ap;
        !           343: {
        !           344:        struct vnode *vp = ap->a_vp;
        !           345:        mode_t fmode =
        !           346:            (vp->v_flag & VROOT) ? DIR_MODE : VTOKERN(vp)->kf_kt->kt_mode;
        !           347: 
        !           348:        return (vaccess(fmode, (uid_t)0, (gid_t)0, ap->a_mode, ap->a_cred));
        !           349: }
        !           350: 
        !           351: kernfs_getattr(ap)
        !           352:        struct vop_getattr_args /* {
        !           353:                struct vnode *a_vp;
        !           354:                struct vattr *a_vap;
        !           355:                struct ucred *a_cred;
        !           356:                struct proc *a_p;
        !           357:        } */ *ap;
        !           358: {
        !           359:        struct vnode *vp = ap->a_vp;
        !           360:        struct vattr *vap = ap->a_vap;
        !           361:        int error = 0;
        !           362:        char strbuf[KSTRING], *buf;
        !           363: 
        !           364:        bzero((caddr_t) vap, sizeof(*vap));
        !           365:        vattr_null(vap);
        !           366:        vap->va_uid = 0;
        !           367:        vap->va_gid = 0;
        !           368:        vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
        !           369:        vap->va_size = 0;
        !           370:        vap->va_blocksize = DEV_BSIZE;
        !           371:        microtime(&vap->va_atime);
        !           372:        vap->va_mtime = vap->va_atime;
        !           373:        vap->va_ctime = vap->va_ctime;
        !           374:        vap->va_gen = 0;
        !           375:        vap->va_flags = 0;
        !           376:        vap->va_rdev = 0;
        !           377:        vap->va_bytes = 0;
        !           378: 
        !           379:        if (vp->v_flag & VROOT) {
        !           380: #ifdef KERNFS_DIAGNOSTIC
        !           381:                printf("kernfs_getattr: stat rootdir\n");
        !           382: #endif
        !           383:                vap->va_type = VDIR;
        !           384:                vap->va_mode = DIR_MODE;
        !           385:                vap->va_nlink = 2;
        !           386:                vap->va_fileid = 2;
        !           387:                vap->va_size = DEV_BSIZE;
        !           388:        } else {
        !           389:                struct kern_target *kt = VTOKERN(vp)->kf_kt;
        !           390:                int nbytes, total;
        !           391: #ifdef KERNFS_DIAGNOSTIC
        !           392:                printf("kernfs_getattr: stat target %s\n", kt->kt_name);
        !           393: #endif
        !           394:                vap->va_type = kt->kt_vtype;
        !           395:                vap->va_mode = kt->kt_mode;
        !           396:                vap->va_nlink = 1;
        !           397:                vap->va_fileid = 1 + (kt - kern_targets) / sizeof(*kt);
        !           398:                total = 0;
        !           399:                while (buf = strbuf,
        !           400:                       nbytes = kernfs_xread(kt, total, &buf, sizeof(strbuf)))
        !           401:                        total += nbytes;
        !           402:                vap->va_size = total;
        !           403:        }
        !           404: 
        !           405: #ifdef KERNFS_DIAGNOSTIC
        !           406:        printf("kernfs_getattr: return error %d\n", error);
        !           407: #endif
        !           408:        return (error);
        !           409: }
        !           410: 
        !           411: kernfs_setattr(ap)
        !           412:        struct vop_setattr_args /* {
        !           413:                struct vnode *a_vp;
        !           414:                struct vattr *a_vap;
        !           415:                struct ucred *a_cred;
        !           416:                struct proc *a_p;
        !           417:        } */ *ap;
        !           418: {
        !           419: 
        !           420:        /*
        !           421:         * Silently ignore attribute changes.
        !           422:         * This allows for open with truncate to have no
        !           423:         * effect until some data is written.  I want to
        !           424:         * do it this way because all writes are atomic.
        !           425:         */
        !           426:        return (0);
        !           427: }
        !           428: 
        !           429: int
        !           430: kernfs_read(ap)
        !           431:        struct vop_read_args /* {
        !           432:                struct vnode *a_vp;
        !           433:                struct uio *a_uio;
        !           434:                int  a_ioflag;
        !           435:                struct ucred *a_cred;
        !           436:        } */ *ap;
        !           437: {
        !           438:        struct vnode *vp = ap->a_vp;
        !           439:        struct uio *uio = ap->a_uio;
        !           440:        struct kern_target *kt;
        !           441:        char strbuf[KSTRING], *buf;
        !           442:        int off, len;
        !           443:        int error;
        !           444: 
        !           445:        if (vp->v_type == VDIR)
        !           446:                return (EOPNOTSUPP);
        !           447: 
        !           448:        kt = VTOKERN(vp)->kf_kt;
        !           449: 
        !           450: #ifdef KERNFS_DIAGNOSTIC
        !           451:        printf("kern_read %s\n", kt->kt_name);
        !           452: #endif
        !           453: 
        !           454:        off = uio->uio_offset;
        !           455: #if 0
        !           456:        while (buf = strbuf,
        !           457: #else
        !           458:        if (buf = strbuf,
        !           459: #endif
        !           460:            len = kernfs_xread(kt, off, &buf, sizeof(strbuf))) {
        !           461:                if (error = uiomove(buf, len, uio))
        !           462:                        return (error);
        !           463:                off += len;
        !           464:        }
        !           465:        return (0);
        !           466: }
        !           467: 
        !           468: int
        !           469: kernfs_write(ap)
        !           470:        struct vop_write_args /* {
        !           471:                struct vnode *a_vp;
        !           472:                struct uio *a_uio;
        !           473:                int  a_ioflag;
        !           474:                struct ucred *a_cred;
        !           475:        } */ *ap;
        !           476: {
        !           477:        struct vnode *vp = ap->a_vp;
        !           478:        struct uio *uio = ap->a_uio;
        !           479:        struct kern_target *kt;
        !           480:        int error, xlen;
        !           481:        char strbuf[KSTRING];
        !           482: 
        !           483:        if (vp->v_type == VDIR)
        !           484:                return (EOPNOTSUPP);
        !           485: 
        !           486:        kt = VTOKERN(vp)->kf_kt;
        !           487: 
        !           488:        if (uio->uio_offset != 0)
        !           489:                return (EINVAL);
        !           490: 
        !           491:        xlen = min(uio->uio_resid, KSTRING-1);
        !           492:        if (error = uiomove(strbuf, xlen, uio))
        !           493:                return (error);
        !           494: 
        !           495:        if (uio->uio_resid != 0)
        !           496:                return (EIO);
        !           497: 
        !           498:        strbuf[xlen] = '\0';
        !           499:        xlen = strlen(strbuf);
        !           500:        return (kernfs_xwrite(kt, strbuf, xlen));
        !           501: }
        !           502: 
        !           503: kernfs_readdir(ap)
        !           504:        struct vop_readdir_args /* {
        !           505:                struct vnode *a_vp;
        !           506:                struct uio *a_uio;
        !           507:                struct ucred *a_cred;
        !           508:                int *a_eofflag;
        !           509:                u_long *a_cookies;
        !           510:                int a_ncookies;
        !           511:        } */ *ap;
        !           512: {
        !           513:        struct uio *uio = ap->a_uio;
        !           514:        struct kern_target *kt;
        !           515:        struct dirent d;
        !           516:        int i;
        !           517:        int error;
        !           518: 
        !           519:        if (ap->a_vp->v_type != VDIR)
        !           520:                return (ENOTDIR);
        !           521: 
        !           522:        /*
        !           523:         * We don't allow exporting kernfs mounts, and currently local
        !           524:         * requests do not need cookies.
        !           525:         */
        !           526:        if (ap->a_ncookies != NULL)
        !           527:                panic("kernfs_readdir: not hungry");
        !           528: 
        !           529:        i = uio->uio_offset / UIO_MX;
        !           530:        error = 0;
        !           531:        for (kt = &kern_targets[i];
        !           532:             uio->uio_resid >= UIO_MX && i < nkern_targets; kt++, i++) {
        !           533:                struct dirent *dp = &d;
        !           534: #ifdef KERNFS_DIAGNOSTIC
        !           535:                printf("kernfs_readdir: i = %d\n", i);
        !           536: #endif
        !           537: 
        !           538:                if (kt->kt_tag == KTT_DEVICE) {
        !           539:                        dev_t *dp = kt->kt_data;
        !           540:                        struct vnode *fvp;
        !           541: 
        !           542:                        if (*dp == NODEV || !vfinddev(*dp, kt->kt_vtype, &fvp))
        !           543:                                continue;
        !           544:                }
        !           545: 
        !           546:                bzero((caddr_t)dp, UIO_MX);
        !           547:                dp->d_namlen = kt->kt_namlen;
        !           548:                bcopy(kt->kt_name, dp->d_name, kt->kt_namlen+1);
        !           549: 
        !           550: #ifdef KERNFS_DIAGNOSTIC
        !           551:                printf("kernfs_readdir: name = %s, len = %d\n",
        !           552:                                dp->d_name, dp->d_namlen);
        !           553: #endif
        !           554:                /*
        !           555:                 * Fill in the remaining fields
        !           556:                 */
        !           557:                dp->d_reclen = UIO_MX;
        !           558:                dp->d_fileno = i + 3;
        !           559:                dp->d_type = kt->kt_type;
        !           560:                /*
        !           561:                 * And ship to userland
        !           562:                 */
        !           563:                if (error = uiomove((caddr_t)dp, UIO_MX, uio))
        !           564:                        break;
        !           565:        }
        !           566: 
        !           567:        uio->uio_offset = i * UIO_MX;
        !           568: 
        !           569:        return (error);
        !           570: }
        !           571: 
        !           572: kernfs_inactive(ap)
        !           573:        struct vop_inactive_args /* {
        !           574:                struct vnode *a_vp;
        !           575:        } */ *ap;
        !           576: {
        !           577:        struct vnode *vp = ap->a_vp;
        !           578: 
        !           579: #ifdef KERNFS_DIAGNOSTIC
        !           580:        printf("kernfs_inactive(%x)\n", vp);
        !           581: #endif
        !           582:        /*
        !           583:         * Clear out the v_type field to avoid
        !           584:         * nasty things happening in vgone().
        !           585:         */
        !           586:        vp->v_type = VNON;
        !           587:        return (0);
        !           588: }
        !           589: 
        !           590: kernfs_reclaim(ap)
        !           591:        struct vop_reclaim_args /* {
        !           592:                struct vnode *a_vp;
        !           593:        } */ *ap;
        !           594: {
        !           595:        struct vnode *vp = ap->a_vp;
        !           596: 
        !           597: #ifdef KERNFS_DIAGNOSTIC
        !           598:        printf("kernfs_reclaim(%x)\n", vp);
        !           599: #endif
        !           600:        if (vp->v_data) {
        !           601:                FREE(vp->v_data, M_TEMP);
        !           602:                vp->v_data = 0;
        !           603:        }
        !           604:        return (0);
        !           605: }
        !           606: 
        !           607: /*
        !           608:  * Return POSIX pathconf information applicable to special devices.
        !           609:  */
        !           610: kernfs_pathconf(ap)
        !           611:        struct vop_pathconf_args /* {
        !           612:                struct vnode *a_vp;
        !           613:                int a_name;
        !           614:                register_t *a_retval;
        !           615:        } */ *ap;
        !           616: {
        !           617: 
        !           618:        switch (ap->a_name) {
        !           619:        case _PC_LINK_MAX:
        !           620:                *ap->a_retval = LINK_MAX;
        !           621:                return (0);
        !           622:        case _PC_MAX_CANON:
        !           623:                *ap->a_retval = MAX_CANON;
        !           624:                return (0);
        !           625:        case _PC_MAX_INPUT:
        !           626:                *ap->a_retval = MAX_INPUT;
        !           627:                return (0);
        !           628:        case _PC_PIPE_BUF:
        !           629:                *ap->a_retval = PIPE_BUF;
        !           630:                return (0);
        !           631:        case _PC_CHOWN_RESTRICTED:
        !           632:                *ap->a_retval = 1;
        !           633:                return (0);
        !           634:        case _PC_VDISABLE:
        !           635:                *ap->a_retval = _POSIX_VDISABLE;
        !           636:                return (0);
        !           637:        default:
        !           638:                return (EINVAL);
        !           639:        }
        !           640:        /* NOTREACHED */
        !           641: }
        !           642: 
        !           643: /*
        !           644:  * Print out the contents of a /dev/fd vnode.
        !           645:  */
        !           646: /* ARGSUSED */
        !           647: kernfs_print(ap)
        !           648:        struct vop_print_args /* {
        !           649:                struct vnode *a_vp;
        !           650:        } */ *ap;
        !           651: {
        !           652: 
        !           653:        printf("tag VT_KERNFS, kernfs vnode\n");
        !           654:        return (0);
        !           655: }
        !           656: 
        !           657: /*void*/
        !           658: kernfs_vfree(ap)
        !           659:        struct vop_vfree_args /* {
        !           660:                struct vnode *a_pvp;
        !           661:                ino_t a_ino;
        !           662:                int a_mode;
        !           663:        } */ *ap;
        !           664: {
        !           665: 
        !           666:        return (0);
        !           667: }
        !           668: 
        !           669: /*
        !           670:  * /dev/fd vnode unsupported operation
        !           671:  */
        !           672: kernfs_enotsupp()
        !           673: {
        !           674: 
        !           675:        return (EOPNOTSUPP);
        !           676: }
        !           677: 
        !           678: /*
        !           679:  * /dev/fd "should never get here" operation
        !           680:  */
        !           681: kernfs_badop()
        !           682: {
        !           683: 
        !           684:        panic("kernfs: bad op");
        !           685:        /* NOTREACHED */
        !           686: }
        !           687: 
        !           688: /*
        !           689:  * kernfs vnode null operation
        !           690:  */
        !           691: kernfs_nullop()
        !           692: {
        !           693: 
        !           694:        return (0);
        !           695: }
        !           696: 
        !           697: #define kernfs_create ((int (*) __P((struct  vop_create_args *)))kernfs_enotsupp)
        !           698: #define kernfs_mknod ((int (*) __P((struct  vop_mknod_args *)))kernfs_enotsupp)
        !           699: #define kernfs_close ((int (*) __P((struct  vop_close_args *)))nullop)
        !           700: #define kernfs_ioctl ((int (*) __P((struct  vop_ioctl_args *)))kernfs_enotsupp)
        !           701: #define kernfs_select ((int (*) __P((struct  vop_select_args *)))kernfs_enotsupp)
        !           702: #define kernfs_mmap ((int (*) __P((struct  vop_mmap_args *)))kernfs_enotsupp)
        !           703: #define kernfs_fsync ((int (*) __P((struct  vop_fsync_args *)))nullop)
        !           704: #define kernfs_seek ((int (*) __P((struct  vop_seek_args *)))nullop)
        !           705: #define kernfs_remove ((int (*) __P((struct  vop_remove_args *)))kernfs_enotsupp)
        !           706: #define kernfs_link ((int (*) __P((struct  vop_link_args *)))kernfs_enotsupp)
        !           707: #define kernfs_rename ((int (*) __P((struct  vop_rename_args *)))kernfs_enotsupp)
        !           708: #define kernfs_mkdir ((int (*) __P((struct  vop_mkdir_args *)))kernfs_enotsupp)
        !           709: #define kernfs_rmdir ((int (*) __P((struct  vop_rmdir_args *)))kernfs_enotsupp)
        !           710: #define kernfs_symlink ((int (*) __P((struct vop_symlink_args *)))kernfs_enotsupp)
        !           711: #define kernfs_readlink \
        !           712:        ((int (*) __P((struct  vop_readlink_args *)))kernfs_enotsupp)
        !           713: #define kernfs_abortop ((int (*) __P((struct  vop_abortop_args *)))nullop)
        !           714: #define kernfs_lock ((int (*) __P((struct  vop_lock_args *)))nullop)
        !           715: #define kernfs_unlock ((int (*) __P((struct  vop_unlock_args *)))nullop)
        !           716: #define kernfs_bmap ((int (*) __P((struct  vop_bmap_args *)))kernfs_badop)
        !           717: #define kernfs_strategy ((int (*) __P((struct  vop_strategy_args *)))kernfs_badop)
        !           718: #define kernfs_islocked ((int (*) __P((struct  vop_islocked_args *)))nullop)
        !           719: #define kernfs_advlock ((int (*) __P((struct vop_advlock_args *)))kernfs_enotsupp)
        !           720: #define kernfs_blkatoff \
        !           721:        ((int (*) __P((struct  vop_blkatoff_args *)))kernfs_enotsupp)
        !           722: #define kernfs_valloc ((int(*) __P(( \
        !           723:                struct vnode *pvp, \
        !           724:                int mode, \
        !           725:                struct ucred *cred, \
        !           726:                struct vnode **vpp))) kernfs_enotsupp)
        !           727: #define kernfs_truncate \
        !           728:        ((int (*) __P((struct  vop_truncate_args *)))kernfs_enotsupp)
        !           729: #define kernfs_update ((int (*) __P((struct  vop_update_args *)))kernfs_enotsupp)
        !           730: #define kernfs_bwrite ((int (*) __P((struct  vop_bwrite_args *)))kernfs_enotsupp)
        !           731: 
        !           732: int (**kernfs_vnodeop_p)();
        !           733: struct vnodeopv_entry_desc kernfs_vnodeop_entries[] = {
        !           734:        { &vop_default_desc, vn_default_error },
        !           735:        { &vop_lookup_desc, kernfs_lookup },    /* lookup */
        !           736:        { &vop_create_desc, kernfs_create },    /* create */
        !           737:        { &vop_mknod_desc, kernfs_mknod },      /* mknod */
        !           738:        { &vop_open_desc, kernfs_open },        /* open */
        !           739:        { &vop_close_desc, kernfs_close },      /* close */
        !           740:        { &vop_access_desc, kernfs_access },    /* access */
        !           741:        { &vop_getattr_desc, kernfs_getattr },  /* getattr */
        !           742:        { &vop_setattr_desc, kernfs_setattr },  /* setattr */
        !           743:        { &vop_read_desc, kernfs_read },        /* read */
        !           744:        { &vop_write_desc, kernfs_write },      /* write */
        !           745:        { &vop_ioctl_desc, kernfs_ioctl },      /* ioctl */
        !           746:        { &vop_select_desc, kernfs_select },    /* select */
        !           747:        { &vop_mmap_desc, kernfs_mmap },        /* mmap */
        !           748:        { &vop_fsync_desc, kernfs_fsync },      /* fsync */
        !           749:        { &vop_seek_desc, kernfs_seek },        /* seek */
        !           750:        { &vop_remove_desc, kernfs_remove },    /* remove */
        !           751:        { &vop_link_desc, kernfs_link },        /* link */
        !           752:        { &vop_rename_desc, kernfs_rename },    /* rename */
        !           753:        { &vop_mkdir_desc, kernfs_mkdir },      /* mkdir */
        !           754:        { &vop_rmdir_desc, kernfs_rmdir },      /* rmdir */
        !           755:        { &vop_symlink_desc, kernfs_symlink },  /* symlink */
        !           756:        { &vop_readdir_desc, kernfs_readdir },  /* readdir */
        !           757:        { &vop_readlink_desc, kernfs_readlink },/* readlink */
        !           758:        { &vop_abortop_desc, kernfs_abortop },  /* abortop */
        !           759:        { &vop_inactive_desc, kernfs_inactive },/* inactive */
        !           760:        { &vop_reclaim_desc, kernfs_reclaim },  /* reclaim */
        !           761:        { &vop_lock_desc, kernfs_lock },        /* lock */
        !           762:        { &vop_unlock_desc, kernfs_unlock },    /* unlock */
        !           763:        { &vop_bmap_desc, kernfs_bmap },        /* bmap */
        !           764:        { &vop_strategy_desc, kernfs_strategy },/* strategy */
        !           765:        { &vop_print_desc, kernfs_print },      /* print */
        !           766:        { &vop_islocked_desc, kernfs_islocked },/* islocked */
        !           767:        { &vop_pathconf_desc, kernfs_pathconf },/* pathconf */
        !           768:        { &vop_advlock_desc, kernfs_advlock },  /* advlock */
        !           769:        { &vop_blkatoff_desc, kernfs_blkatoff },/* blkatoff */
        !           770:        { &vop_valloc_desc, kernfs_valloc },    /* valloc */
        !           771:        { &vop_vfree_desc, kernfs_vfree },      /* vfree */
        !           772:        { &vop_truncate_desc, kernfs_truncate },/* truncate */
        !           773:        { &vop_update_desc, kernfs_update },    /* update */
        !           774:        { &vop_bwrite_desc, kernfs_bwrite },    /* bwrite */
        !           775:        { (struct vnodeop_desc*)NULL, (int(*)())NULL }
        !           776: };
        !           777: struct vnodeopv_desc kernfs_vnodeop_opv_desc =
        !           778:        { &kernfs_vnodeop_p, kernfs_vnodeop_entries };

unix.superglobalmegacorp.com

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