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

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

CVSweb <webmaster@jp.NetBSD.org>