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