[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.23

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
        !            37:  *     $Id: $
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.1       cgd       229:
1.23    ! mycroft   230:        for (error = ENOENT, kt = kern_targets, i = 0; i < nkern_targets;
        !           231:             kt++, i++) {
        !           232:                if (cnp->cn_namelen == strlen(kt->kt_name) &&
        !           233:                    bcmp(kt->kt_name, pname, cnp->cn_namelen) == 0) {
1.1       cgd       234:                        error = 0;
                    235:                        break;
                    236:                }
                    237:        }
                    238:
                    239: #ifdef KERNFS_DIAGNOSTIC
                    240:        printf("kernfs_lookup: i = %d, error = %d\n", i, error);
                    241: #endif
                    242:
                    243:        if (error)
1.23    ! mycroft   244:                return (error);
        !           245:
        !           246:        if (kt->kt_tag == KTT_DEVICE) {
        !           247:                dev_t *dp = kt->kt_data;
        !           248:                if (*dp == NODEV || !vfinddev(*dp, kt->kt_vtype, &fvp))
        !           249:                        return (ENXIO);
        !           250:                *vpp = fvp;
        !           251:                VREF(fvp);
        !           252:                VOP_LOCK(fvp);
        !           253:                return (0);
        !           254:        }
1.1       cgd       255:
                    256: #ifdef KERNFS_DIAGNOSTIC
                    257:        printf("kernfs_lookup: allocate new vnode\n");
                    258: #endif
1.23    ! mycroft   259:        if (error = getnewvnode(VT_KERNFS, dvp->v_mount, kernfs_vnodeop_p,
        !           260:            &fvp))
        !           261:                return (error);
        !           262:
        !           263:        MALLOC(fvp->v_data, void *, sizeof(struct kernfs_node), M_TEMP,
        !           264:            M_WAITOK);
        !           265:        VTOKERN(fvp)->kf_kt = kt;
        !           266:        fvp->v_type = kt->kt_vtype;
        !           267:        *vpp = fvp;
        !           268:
1.1       cgd       269: #ifdef KERNFS_DIAGNOSTIC
                    270:        printf("kernfs_lookup: newvp = %x\n", fvp);
                    271: #endif
                    272:        return (0);
                    273: }
                    274:
1.23    ! mycroft   275: kernfs_open(ap)
        !           276:        struct vop_open_args /* {
        !           277:                struct vnode *a_vp;
        !           278:                int  a_mode;
        !           279:                struct ucred *a_cred;
        !           280:                struct proc *a_p;
        !           281:        } */ *ap;
1.1       cgd       282: {
                    283:
1.23    ! mycroft   284:        /* Only need to check access permissions. */
        !           285:        return (0);
        !           286: }
1.1       cgd       287:
1.23    ! mycroft   288: static int
        !           289: kernfs_access(ap)
        !           290:        struct vop_access_args /* {
        !           291:                struct vnode *a_vp;
        !           292:                int  a_mode;
        !           293:                struct ucred *a_cred;
        !           294:                struct proc *a_p;
        !           295:        } */ *ap;
        !           296: {
        !           297:        register struct vnode *vp = ap->a_vp;
        !           298:        register struct ucred *cred = ap->a_cred;
        !           299:        mode_t amode = ap->a_mode;
        !           300:        mode_t fmode =
        !           301:            (vp->v_flag & VROOT) ? DIR_MODE : VTOKERN(vp)->kf_kt->kt_mode;
        !           302:        mode_t mask = 0;
        !           303:        register gid_t *gp;
        !           304:        int i;
1.17      cgd       305:
1.23    ! mycroft   306:        /* Some files are simply not modifiable. */
        !           307:        if ((amode & VWRITE) && (fmode & (S_IWUSR|S_IWGRP|S_IWOTH)) == 0)
        !           308:                return (EPERM);
1.17      cgd       309:
1.23    ! mycroft   310:        /* Root can do anything else. */
        !           311:        if (cred->cr_uid == 0)
        !           312:                return (0);
1.17      cgd       313:
1.23    ! mycroft   314:        /* Check for group 0 (wheel) permissions. */
        !           315:        for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++)
        !           316:                if (*gp == 0) {
        !           317:                        if (amode & VEXEC)
        !           318:                                mask |= S_IXGRP;
        !           319:                        if (amode & VREAD)
        !           320:                                mask |= S_IRGRP;
        !           321:                        if (amode & VWRITE)
        !           322:                                mask |= S_IWGRP;
        !           323:                        return ((fmode & mask) == mask ?  0 : EACCES);
        !           324:                }
1.8       cgd       325:
1.23    ! mycroft   326:         /* Otherwise, check everyone else. */
        !           327:        if (amode & VEXEC)
        !           328:                mask |= S_IXOTH;
        !           329:        if (amode & VREAD)
        !           330:                mask |= S_IROTH;
        !           331:        if (amode & VWRITE)
        !           332:                mask |= S_IWOTH;
        !           333:        return ((fmode & mask) == mask ? 0 : EACCES);
        !           334: }
        !           335:
        !           336: kernfs_getattr(ap)
        !           337:        struct vop_getattr_args /* {
        !           338:                struct vnode *a_vp;
        !           339:                struct vattr *a_vap;
        !           340:                struct ucred *a_cred;
        !           341:                struct proc *a_p;
        !           342:        } */ *ap;
1.1       cgd       343: {
1.23    ! mycroft   344:        struct vnode *vp = ap->a_vp;
        !           345:        struct vattr *vap = ap->a_vap;
1.1       cgd       346:        int error = 0;
                    347:        char strbuf[KSTRING];
                    348:
                    349:        bzero((caddr_t) vap, sizeof(*vap));
                    350:        vattr_null(vap);
1.17      cgd       351:        vap->va_uid = 0;
                    352:        vap->va_gid = 0;
1.1       cgd       353:        vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
1.23    ! mycroft   354:        vap->va_size = 0;
1.1       cgd       355:        vap->va_blocksize = DEV_BSIZE;
                    356:        microtime(&vap->va_atime);
                    357:        vap->va_mtime = vap->va_atime;
                    358:        vap->va_ctime = vap->va_ctime;
                    359:        vap->va_gen = 0;
                    360:        vap->va_flags = 0;
                    361:        vap->va_rdev = 0;
                    362:        vap->va_bytes = 0;
                    363:
                    364:        if (vp->v_flag & VROOT) {
                    365: #ifdef KERNFS_DIAGNOSTIC
                    366:                printf("kernfs_getattr: stat rootdir\n");
                    367: #endif
1.17      cgd       368:                vap->va_type = VDIR;
1.23    ! mycroft   369:                vap->va_mode = DIR_MODE;
1.1       cgd       370:                vap->va_nlink = 2;
                    371:                vap->va_fileid = 2;
                    372:                vap->va_size = DEV_BSIZE;
                    373:        } else {
1.23    ! mycroft   374:                struct kern_target *kt = VTOKERN(vp)->kf_kt;
1.22      mycroft   375:                int nbytes;
1.1       cgd       376: #ifdef KERNFS_DIAGNOSTIC
                    377:                printf("kernfs_getattr: stat target %s\n", kt->kt_name);
                    378: #endif
1.17      cgd       379:                vap->va_type = kt->kt_vtype;
1.23    ! mycroft   380:                vap->va_mode = kt->kt_mode;
1.1       cgd       381:                vap->va_nlink = 1;
1.23    ! mycroft   382:                vap->va_fileid = 1 + (kt - kern_targets) / sizeof(*kt);
1.22      mycroft   383:                error = kernfs_xread(kt, strbuf, sizeof(strbuf), &nbytes);
                    384:                vap->va_size = nbytes;
1.1       cgd       385:        }
                    386:
                    387: #ifdef KERNFS_DIAGNOSTIC
                    388:        printf("kernfs_getattr: return error %d\n", error);
                    389: #endif
                    390:        return (error);
                    391: }
                    392:
1.23    ! mycroft   393: kernfs_setattr(ap)
        !           394:        struct vop_setattr_args /* {
        !           395:                struct vnode *a_vp;
        !           396:                struct vattr *a_vap;
        !           397:                struct ucred *a_cred;
        !           398:                struct proc *a_p;
        !           399:        } */ *ap;
1.1       cgd       400: {
                    401:
                    402:        /*
1.17      cgd       403:         * Silently ignore attribute changes.
                    404:         * This allows for open with truncate to have no
                    405:         * effect until some data is written.  I want to
                    406:         * do it this way because all writes are atomic.
1.1       cgd       407:         */
1.17      cgd       408:        return (0);
1.1       cgd       409: }
                    410:
                    411: static int
1.23    ! mycroft   412: kernfs_read(ap)
        !           413:        struct vop_read_args /* {
        !           414:                struct vnode *a_vp;
        !           415:                struct uio *a_uio;
        !           416:                int  a_ioflag;
        !           417:                struct ucred *a_cred;
        !           418:        } */ *ap;
1.1       cgd       419: {
1.23    ! mycroft   420:        struct vnode *vp = ap->a_vp;
        !           421:        struct uio *uio = ap->a_uio;
        !           422:        struct kern_target *kt;
1.1       cgd       423:        char strbuf[KSTRING];
                    424:        int off = uio->uio_offset;
1.23    ! mycroft   425:        int error, len;
        !           426:        char *cp;
        !           427:
        !           428:        if (vp->v_type == VDIR)
        !           429:                return (EOPNOTSUPP);
        !           430:
        !           431:        kt = VTOKERN(vp)->kf_kt;
        !           432:
1.1       cgd       433: #ifdef KERNFS_DIAGNOSTIC
                    434:        printf("kern_read %s\n", kt->kt_name);
                    435: #endif
1.18      cgd       436:
1.23    ! mycroft   437:        len = 0;
        !           438:        if (error = kernfs_xread(kt, strbuf, sizeof(strbuf), &len))
1.1       cgd       439:                return (error);
1.23    ! mycroft   440:        if (len <= off)
        !           441:                return (0);
        !           442:        return (uiomove(&strbuf[off], len - off, uio));
1.1       cgd       443: }
                    444:
                    445: static int
1.23    ! mycroft   446: kernfs_write(ap)
        !           447:        struct vop_write_args /* {
        !           448:                struct vnode *a_vp;
        !           449:                struct uio *a_uio;
        !           450:                int  a_ioflag;
        !           451:                struct ucred *a_cred;
        !           452:        } */ *ap;
1.1       cgd       453: {
1.23    ! mycroft   454:        struct vnode *vp = ap->a_vp;
        !           455:        struct uio *uio = ap->a_uio;
        !           456:        struct kern_target *kt;
        !           457:        int error, xlen;
1.1       cgd       458:        char strbuf[KSTRING];
1.23    ! mycroft   459:
        !           460:        if (vp->v_type == VDIR)
        !           461:                return (EOPNOTSUPP);
        !           462:
        !           463:        kt = VTOKERN(vp)->kf_kt;
1.1       cgd       464:
                    465:        if (uio->uio_offset != 0)
                    466:                return (EINVAL);
                    467:
                    468:        xlen = min(uio->uio_resid, KSTRING-1);
1.23    ! mycroft   469:        if (error = uiomove(strbuf, xlen, uio))
1.1       cgd       470:                return (error);
                    471:
                    472:        if (uio->uio_resid != 0)
                    473:                return (EIO);
                    474:
                    475:        strbuf[xlen] = '\0';
1.17      cgd       476:        xlen = strlen(strbuf);
1.1       cgd       477:        return (kernfs_xwrite(kt, strbuf, xlen));
                    478: }
                    479:
1.23    ! mycroft   480: kernfs_readdir(ap)
        !           481:        struct vop_readdir_args /* {
        !           482:                struct vnode *a_vp;
        !           483:                struct uio *a_uio;
        !           484:                struct ucred *a_cred;
        !           485:        } */ *ap;
        !           486: {
        !           487:        struct uio *uio = ap->a_uio;
        !           488:        register struct kern_target *kt;
        !           489:        struct dirent d;
1.1       cgd       490:        int i;
                    491:        int error;
                    492:
1.23    ! mycroft   493:        if (ap->a_vp->v_type != VDIR)
        !           494:                return (ENOTDIR);
        !           495:
1.1       cgd       496:        i = uio->uio_offset / UIO_MX;
                    497:        error = 0;
1.23    ! mycroft   498:        for (kt = &kern_targets[i];
        !           499:             uio->uio_resid >= UIO_MX && i < nkern_targets; kt++, i++) {
        !           500:                register struct dirent *dp = &d;
1.1       cgd       501: #ifdef KERNFS_DIAGNOSTIC
                    502:                printf("kernfs_readdir: i = %d\n", i);
                    503: #endif
1.23    ! mycroft   504:                if (kt->kt_tag == KTT_DEVICE) {
        !           505:                        register dev_t *dp = kt->kt_data;
        !           506:                        struct vnode *fvp;
        !           507:                        if (*dp == NODEV || !vfinddev(*dp, kt->kt_vtype, &fvp))
        !           508:                                continue;
        !           509:                }
        !           510:                bzero((caddr_t)dp, UIO_MX);
        !           511:                dp->d_namlen = kt->kt_namlen;
        !           512:                bcopy(kt->kt_name, dp->d_name, kt->kt_namlen + 1);
        !           513: #ifdef KERNFS_DIAGNOSTIC
        !           514:                printf("kernfs_readdir: name = %s, len = %d\n",
        !           515:                                dp->d_name, dp->d_namlen);
        !           516: #endif
        !           517:                /*
        !           518:                 * Fill in the remaining fields
        !           519:                 */
        !           520:                dp->d_reclen = UIO_MX;
        !           521:                dp->d_fileno = i + 3;
        !           522:                dp->d_type = kt->kt_type;
        !           523:                /*
        !           524:                 * And ship to userland
        !           525:                 */
        !           526:                if (error = uiomove((caddr_t)dp, UIO_MX, uio))
1.1       cgd       527:                        break;
                    528:        }
                    529:
                    530:        uio->uio_offset = i * UIO_MX;
                    531:
                    532:        return (error);
                    533: }
                    534:
1.23    ! mycroft   535: kernfs_inactive(ap)
        !           536:        struct vop_inactive_args /* {
        !           537:                struct vnode *a_vp;
        !           538:        } */ *ap;
1.1       cgd       539: {
1.23    ! mycroft   540:        struct vnode *vp = ap->a_vp;
        !           541:
        !           542: #ifdef KERNFS_DIAGNOSTIC
        !           543:        printf("kernfs_inactive(%x)\n", vp);
        !           544: #endif
1.1       cgd       545:        /*
                    546:         * Clear out the v_type field to avoid
                    547:         * nasty things happening in vgone().
                    548:         */
                    549:        vp->v_type = VNON;
1.23    ! mycroft   550:        return (0);
        !           551: }
        !           552:
        !           553: kernfs_reclaim(ap)
        !           554:        struct vop_reclaim_args /* {
        !           555:                struct vnode *a_vp;
        !           556:        } */ *ap;
        !           557: {
        !           558:        struct vnode *vp = ap->a_vp;
        !           559:
1.1       cgd       560: #ifdef KERNFS_DIAGNOSTIC
1.23    ! mycroft   561:        printf("kernfs_reclaim(%x)\n", vp);
1.1       cgd       562: #endif
1.23    ! mycroft   563:        if (vp->v_data) {
        !           564:                FREE(vp->v_data, M_TEMP);
        !           565:                vp->v_data = 0;
        !           566:        }
1.1       cgd       567:        return (0);
                    568: }
                    569:
                    570: /*
1.23    ! mycroft   571:  * Return POSIX pathconf information applicable to special devices.
        !           572:  */
        !           573: kernfs_pathconf(ap)
        !           574:        struct vop_pathconf_args /* {
        !           575:                struct vnode *a_vp;
        !           576:                int a_name;
        !           577:                int *a_retval;
        !           578:        } */ *ap;
        !           579: {
        !           580:
        !           581:        switch (ap->a_name) {
        !           582:        case _PC_LINK_MAX:
        !           583:                *ap->a_retval = LINK_MAX;
        !           584:                return (0);
        !           585:        case _PC_MAX_CANON:
        !           586:                *ap->a_retval = MAX_CANON;
        !           587:                return (0);
        !           588:        case _PC_MAX_INPUT:
        !           589:                *ap->a_retval = MAX_INPUT;
        !           590:                return (0);
        !           591:        case _PC_PIPE_BUF:
        !           592:                *ap->a_retval = PIPE_BUF;
        !           593:                return (0);
        !           594:        case _PC_CHOWN_RESTRICTED:
        !           595:                *ap->a_retval = 1;
        !           596:                return (0);
        !           597:        case _PC_VDISABLE:
        !           598:                *ap->a_retval = _POSIX_VDISABLE;
        !           599:                return (0);
        !           600:        default:
        !           601:                return (EINVAL);
        !           602:        }
        !           603:        /* NOTREACHED */
        !           604: }
        !           605:
        !           606: /*
        !           607:  * Print out the contents of a /dev/fd vnode.
1.1       cgd       608:  */
                    609: /* ARGSUSED */
1.23    ! mycroft   610: kernfs_print(ap)
        !           611:        struct vop_print_args /* {
        !           612:                struct vnode *a_vp;
        !           613:        } */ *ap;
        !           614: {
        !           615:
        !           616:        printf("tag VT_KERNFS, kernfs vnode\n");
        !           617:        return (0);
        !           618: }
        !           619:
        !           620: /*void*/
        !           621: kernfs_vfree(ap)
        !           622:        struct vop_vfree_args /* {
        !           623:                struct vnode *a_pvp;
        !           624:                ino_t a_ino;
        !           625:                int a_mode;
        !           626:        } */ *ap;
1.1       cgd       627: {
1.23    ! mycroft   628:
        !           629:        return (0);
1.1       cgd       630: }
                    631:
                    632: /*
1.23    ! mycroft   633:  * /dev/fd vnode unsupported operation
1.1       cgd       634:  */
                    635: kernfs_enotsupp()
                    636: {
1.23    ! mycroft   637:
1.1       cgd       638:        return (EOPNOTSUPP);
                    639: }
                    640:
                    641: /*
1.23    ! mycroft   642:  * /dev/fd "should never get here" operation
1.1       cgd       643:  */
                    644: kernfs_badop()
                    645: {
1.23    ! mycroft   646:
1.1       cgd       647:        panic("kernfs: bad op");
                    648:        /* NOTREACHED */
                    649: }
                    650:
                    651: /*
                    652:  * kernfs vnode null operation
                    653:  */
                    654: kernfs_nullop()
                    655: {
1.23    ! mycroft   656:
1.1       cgd       657:        return (0);
                    658: }
                    659:
1.23    ! mycroft   660: #define kernfs_create ((int (*) __P((struct  vop_create_args *)))kernfs_enotsupp)
        !           661: #define kernfs_mknod ((int (*) __P((struct  vop_mknod_args *)))kernfs_enotsupp)
        !           662: #define kernfs_close ((int (*) __P((struct  vop_close_args *)))nullop)
        !           663: #define kernfs_ioctl ((int (*) __P((struct  vop_ioctl_args *)))kernfs_enotsupp)
        !           664: #define kernfs_select ((int (*) __P((struct  vop_select_args *)))kernfs_enotsupp)
        !           665: #define kernfs_mmap ((int (*) __P((struct  vop_mmap_args *)))kernfs_enotsupp)
        !           666: #define kernfs_fsync ((int (*) __P((struct  vop_fsync_args *)))nullop)
        !           667: #define kernfs_seek ((int (*) __P((struct  vop_seek_args *)))nullop)
        !           668: #define kernfs_remove ((int (*) __P((struct  vop_remove_args *)))kernfs_enotsupp)
        !           669: #define kernfs_link ((int (*) __P((struct  vop_link_args *)))kernfs_enotsupp)
        !           670: #define kernfs_rename ((int (*) __P((struct  vop_rename_args *)))kernfs_enotsupp)
        !           671: #define kernfs_mkdir ((int (*) __P((struct  vop_mkdir_args *)))kernfs_enotsupp)
        !           672: #define kernfs_rmdir ((int (*) __P((struct  vop_rmdir_args *)))kernfs_enotsupp)
        !           673: #define kernfs_symlink ((int (*) __P((struct vop_symlink_args *)))kernfs_enotsupp)
        !           674: #define kernfs_readlink \
        !           675:        ((int (*) __P((struct  vop_readlink_args *)))kernfs_enotsupp)
        !           676: #define kernfs_abortop ((int (*) __P((struct  vop_abortop_args *)))nullop)
        !           677: #define kernfs_lock ((int (*) __P((struct  vop_lock_args *)))nullop)
        !           678: #define kernfs_unlock ((int (*) __P((struct  vop_unlock_args *)))nullop)
        !           679: #define kernfs_bmap ((int (*) __P((struct  vop_bmap_args *)))kernfs_badop)
        !           680: #define kernfs_strategy ((int (*) __P((struct  vop_strategy_args *)))kernfs_badop)
        !           681: #define kernfs_islocked ((int (*) __P((struct  vop_islocked_args *)))nullop)
        !           682: #define kernfs_advlock ((int (*) __P((struct vop_advlock_args *)))kernfs_enotsupp)
        !           683: #define kernfs_blkatoff \
        !           684:        ((int (*) __P((struct  vop_blkatoff_args *)))kernfs_enotsupp)
        !           685: #define kernfs_valloc ((int(*) __P(( \
        !           686:                struct vnode *pvp, \
        !           687:                int mode, \
1.1       cgd       688:                struct ucred *cred, \
1.23    ! mycroft   689:                struct vnode **vpp))) kernfs_enotsupp)
        !           690: #define kernfs_truncate \
        !           691:        ((int (*) __P((struct  vop_truncate_args *)))kernfs_enotsupp)
        !           692: #define kernfs_update ((int (*) __P((struct  vop_update_args *)))kernfs_enotsupp)
        !           693: #define kernfs_bwrite ((int (*) __P((struct  vop_bwrite_args *)))kernfs_enotsupp)
        !           694:
        !           695: int (**kernfs_vnodeop_p)();
        !           696: struct vnodeopv_entry_desc kernfs_vnodeop_entries[] = {
        !           697:        { &vop_default_desc, vn_default_error },
        !           698:        { &vop_lookup_desc, kernfs_lookup },    /* lookup */
        !           699:        { &vop_create_desc, kernfs_create },    /* create */
        !           700:        { &vop_mknod_desc, kernfs_mknod },      /* mknod */
        !           701:        { &vop_open_desc, kernfs_open },        /* open */
        !           702:        { &vop_close_desc, kernfs_close },      /* close */
        !           703:        { &vop_access_desc, kernfs_access },    /* access */
        !           704:        { &vop_getattr_desc, kernfs_getattr },  /* getattr */
        !           705:        { &vop_setattr_desc, kernfs_setattr },  /* setattr */
        !           706:        { &vop_read_desc, kernfs_read },        /* read */
        !           707:        { &vop_write_desc, kernfs_write },      /* write */
        !           708:        { &vop_ioctl_desc, kernfs_ioctl },      /* ioctl */
        !           709:        { &vop_select_desc, kernfs_select },    /* select */
        !           710:        { &vop_mmap_desc, kernfs_mmap },        /* mmap */
        !           711:        { &vop_fsync_desc, kernfs_fsync },      /* fsync */
        !           712:        { &vop_seek_desc, kernfs_seek },        /* seek */
        !           713:        { &vop_remove_desc, kernfs_remove },    /* remove */
        !           714:        { &vop_link_desc, kernfs_link },        /* link */
        !           715:        { &vop_rename_desc, kernfs_rename },    /* rename */
        !           716:        { &vop_mkdir_desc, kernfs_mkdir },      /* mkdir */
        !           717:        { &vop_rmdir_desc, kernfs_rmdir },      /* rmdir */
        !           718:        { &vop_symlink_desc, kernfs_symlink },  /* symlink */
        !           719:        { &vop_readdir_desc, kernfs_readdir },  /* readdir */
        !           720:        { &vop_readlink_desc, kernfs_readlink },/* readlink */
        !           721:        { &vop_abortop_desc, kernfs_abortop },  /* abortop */
        !           722:        { &vop_inactive_desc, kernfs_inactive },/* inactive */
        !           723:        { &vop_reclaim_desc, kernfs_reclaim },  /* reclaim */
        !           724:        { &vop_lock_desc, kernfs_lock },        /* lock */
        !           725:        { &vop_unlock_desc, kernfs_unlock },    /* unlock */
        !           726:        { &vop_bmap_desc, kernfs_bmap },        /* bmap */
        !           727:        { &vop_strategy_desc, kernfs_strategy },/* strategy */
        !           728:        { &vop_print_desc, kernfs_print },      /* print */
        !           729:        { &vop_islocked_desc, kernfs_islocked },/* islocked */
        !           730:        { &vop_pathconf_desc, kernfs_pathconf },/* pathconf */
        !           731:        { &vop_advlock_desc, kernfs_advlock },  /* advlock */
        !           732:        { &vop_blkatoff_desc, kernfs_blkatoff },/* blkatoff */
        !           733:        { &vop_valloc_desc, kernfs_valloc },    /* valloc */
        !           734:        { &vop_vfree_desc, kernfs_vfree },      /* vfree */
        !           735:        { &vop_truncate_desc, kernfs_truncate },/* truncate */
        !           736:        { &vop_update_desc, kernfs_update },    /* update */
        !           737:        { &vop_bwrite_desc, kernfs_bwrite },    /* bwrite */
        !           738:        { (struct vnodeop_desc*)NULL, (int(*)())NULL }
1.1       cgd       739: };
1.23    ! mycroft   740: struct vnodeopv_desc kernfs_vnodeop_opv_desc =
        !           741:        { &kernfs_vnodeop_p, kernfs_vnodeop_entries };

CVSweb <webmaster@jp.NetBSD.org>