[BACK]Return to kernfs_vnops.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / miscfs / kernfs

Annotation of src/sys/miscfs/kernfs/kernfs_vnops.c, Revision 1.25

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

CVSweb <webmaster@jp.NetBSD.org>