Annotation of XNU/bsd/miscfs/kernfs/kernfs_vnops.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /*     $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.