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

1.1       cgd         1: /*
                      2:  * Copyright (c) 1990, 1992 Jan-Simon Pendry
                      3:  * All rights reserved.
                      4:  *
1.2       cgd         5:  * This code is derived from software contributed 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:
                     18:  *      This product includes software developed by the University of
                     19:  *      California, Berkeley and its contributors.
                     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.12    ! ws         36:  *     $Id: kernfs_vnops.c,v 1.11 1993/08/02 23:00:57 mycroft Exp $
1.1       cgd        37:  */
                     38:
                     39: /*
                     40:  * Kernel parameter filesystem
                     41:  */
                     42:
                     43: #include "param.h"
                     44: #include "systm.h"
                     45: #include "kernel.h"
                     46: #include "types.h"
                     47: #include "time.h"
                     48: #include "proc.h"
                     49: #include "file.h"
                     50: #include "vnode.h"
                     51: #include "stat.h"
                     52: #include "mount.h"
                     53: #include "namei.h"
                     54: #include "buf.h"
                     55: #include "miscfs/kernfs/kernfs.h"
                     56:
                     57: #include "../ufs/dir.h"                /* For readdir() XXX */
                     58:
1.9       cgd        59: struct kernfs_target kernfs_targets[] = {
1.1       cgd        60: /* NOTE: The name must be less than UIO_MX-16 chars in length */
1.9       cgd        61: DIR_TARGET(".",                0,              KTT_NULL,       KTM_DIR_PERMS   )
                     62: DIR_TARGET("..",       0,              KTT_NULL,       KTM_DIR_PERMS   )
                     63: REG_TARGET("copyright",        copyright,      KTT_STRING,     KTM_RO_PERMS    )
                     64: REG_TARGET("hostname", 0,              KTT_HOSTNAME,   KTM_RW_PERMS    )
                     65: REG_TARGET("hz",       &hz,            KTT_INT,        KTM_RO_PERMS    )
                     66: REG_TARGET("loadavg",  0,              KTT_AVENRUN,    KTM_RO_PERMS    )
                     67: REG_TARGET("physmem",  &physmem,       KTT_INT,        KTM_RO_PERMS    )
                     68: DIR_TARGET("root",     0,              KTT_NULL,       KTM_DIR_PERMS   )
                     69: BLK_TARGET("rootdev",  0,              KTT_NULL,       KTM_RO_PERMS    )
                     70: CHR_TARGET("rrootdev", 0,              KTT_NULL,       KTM_RO_PERMS    )
                     71: REG_TARGET("time",     0,              KTT_TIME,       KTM_RO_PERMS    )
                     72: REG_TARGET("version",  version,        KTT_STRING,     KTM_RO_PERMS    )
1.1       cgd        73: };
                     74:
1.9       cgd        75: static int nkernfs_targets = sizeof(kernfs_targets) / sizeof(kernfs_targets[0]);
1.1       cgd        76:
                     77: static int
                     78: kernfs_xread(kt, buf, len, lenp)
1.9       cgd        79:        struct kernfs_target *kt;
1.1       cgd        80:        char *buf;
                     81:        int len;
                     82:        int *lenp;
                     83: {
                     84:        int xlen;
                     85:
                     86:        switch (kt->kt_tag) {
                     87:        case KTT_TIME: {
                     88:                struct timeval tv;
                     89:                microtime(&tv);
                     90:                sprintf(buf, "%d %d\n", tv.tv_sec, tv.tv_usec);
                     91:                break;
                     92:        }
                     93:
                     94:        case KTT_INT: {
                     95:                int *ip = kt->kt_data;
                     96:                sprintf(buf, "%d\n", *ip);
                     97:                break;
                     98:        }
                     99:
                    100:        case KTT_STRING: {
                    101:                char *cp = kt->kt_data;
                    102:                int xlen = strlen(cp) + 1;
                    103:
                    104:                if (xlen >= len)
                    105:                        return (EINVAL);
                    106:
                    107:                bcopy(cp, buf, xlen);
                    108:                break;
                    109:        }
                    110:
                    111:        case KTT_HOSTNAME: {
                    112:                char *cp = hostname;
                    113:                int xlen = hostnamelen;
                    114:
1.6       cgd       115:                if (xlen + 2 > len)     /* extra space for null and newline */
1.1       cgd       116:                        return (EINVAL);
                    117:
1.6       cgd       118:                bcopy(cp, buf, xlen);   /* safer than sprintf */
                    119:                buf[xlen] = '\n';
                    120:                buf[xlen+1] = '\0';
1.1       cgd       121:                break;
                    122:        }
                    123:
                    124:        case KTT_AVENRUN:
                    125:                sprintf(buf, "%d %d %d %d\n",
                    126:                                averunnable[0],
                    127:                                averunnable[1],
                    128:                                averunnable[2],
                    129:                                FSCALE);
                    130:                break;
                    131:
                    132:        default:
                    133:                return (EINVAL);
                    134:        }
                    135:
                    136:        *lenp = strlen(buf);
                    137:        return (0);
                    138: }
                    139:
                    140: static int
                    141: kernfs_xwrite(kt, buf, len)
1.9       cgd       142:        struct kernfs_target *kt;
1.1       cgd       143:        char *buf;
                    144:        int len;
                    145: {
                    146:        switch (kt->kt_tag) {
                    147:        case KTT_HOSTNAME: {
                    148:                if (buf[len-1] == '\n')
                    149:                        --len;
                    150:                bcopy(buf, hostname, len);
1.6       cgd       151:                /* kernfs_write set buf[value_passed_as_len] = \0.
                    152:                 * therefore, buf len (hostnamelen) = len.
                    153:                 */
                    154:                hostnamelen = len;
                    155:                hostname[hostnamelen] = '\0';   /* null end of string. */
1.1       cgd       156:                return (0);
                    157:        }
                    158:
                    159:        default:
                    160:                return (EIO);
                    161:        }
                    162: }
                    163:
                    164: /*
                    165:  * vp is the current namei directory
                    166:  * ndp is the name to locate in that directory...
                    167:  */
                    168: kernfs_lookup(dvp, ndp, p)
                    169:        struct vnode *dvp;
                    170:        struct nameidata *ndp;
                    171:        struct proc *p;
                    172: {
                    173:        char *pname = ndp->ni_ptr;
                    174:        int error = ENOENT;
                    175:        int i;
                    176:        struct vnode *fvp;
                    177:
                    178: #ifdef KERNFS_DIAGNOSTIC
                    179:        printf("kernfs_lookup(%s)\n", pname);
                    180: #endif
                    181:        if (ndp->ni_namelen == 1 && *pname == '.') {
                    182:                ndp->ni_dvp = dvp;
                    183:                ndp->ni_vp = dvp;
                    184:                VREF(dvp);
                    185:                /*VOP_LOCK(dvp);*/
                    186:                return (0);
                    187:        }
                    188:
                    189:        if (ndp->ni_namelen == 4 && bcmp(pname, "root", 4) == 0) {
1.3       cgd       190:                ndp->ni_dvp = dvp;
1.1       cgd       191:                ndp->ni_vp = rootdir;
                    192:                VREF(rootdir);
                    193:                VOP_LOCK(rootdir);
                    194:                return (0);
                    195:        }
                    196:
                    197:        /*
                    198:         * /kern/rootdev is the root device
                    199:         */
                    200:        if (ndp->ni_namelen == 7 && bcmp(pname, "rootdev", 7) == 0) {
                    201:                if (vfinddev(rootdev, VBLK, &fvp))
                    202:                        return (ENXIO);
                    203:                ndp->ni_dvp = dvp;
                    204:                ndp->ni_vp = fvp;
                    205:                VREF(fvp);
                    206:                VOP_LOCK(fvp);
1.4       cgd       207:                return (0);
                    208:        }
                    209:
                    210:        /*
                    211:         * /kern/rrootdev is the root device
                    212:         */
                    213:        if (ndp->ni_namelen == 8 && bcmp(pname, "rrootdev", 7) == 0) {
                    214:                ndp->ni_dvp = dvp;
                    215:                ndp->ni_vp = rrootdevvp;
                    216:                VREF(rrootdevvp);
                    217:                VOP_LOCK(rrootdevvp);
1.1       cgd       218:                return (0);
                    219:        }
                    220:
1.9       cgd       221:        for (i = 0; i < nkernfs_targets; i++) {
                    222:                struct kernfs_target *kt = &kernfs_targets[i];
1.1       cgd       223:                if (ndp->ni_namelen == strlen(kt->kt_name) &&
                    224:                    bcmp(kt->kt_name, pname, ndp->ni_namelen) == 0) {
                    225:                        error = 0;
                    226:                        break;
                    227:                }
                    228:        }
                    229:
                    230: #ifdef KERNFS_DIAGNOSTIC
                    231:        printf("kernfs_lookup: i = %d, error = %d\n", i, error);
                    232: #endif
                    233:
                    234:        if (error)
                    235:                goto bad;
                    236:
                    237: #ifdef KERNFS_DIAGNOSTIC
                    238:        printf("kernfs_lookup: allocate new vnode\n");
                    239: #endif
1.10      cgd       240:        error = getnewvnode(VT_KERNFS, dvp->v_mount, &kernfs_vnodeops, &fvp);
1.1       cgd       241:        if (error)
                    242:                goto bad;
1.9       cgd       243:        VTOKERN(fvp)->kf_kt = &kernfs_targets[i];
1.1       cgd       244:        fvp->v_type = VTOKERN(fvp)->kf_kt->kt_vtype;
                    245:        ndp->ni_dvp = dvp;
                    246:        ndp->ni_vp = fvp;
                    247: #ifdef KERNFS_DIAGNOSTIC
                    248:        printf("kernfs_lookup: newvp = %x\n", fvp);
                    249: #endif
                    250:        return (0);
                    251:
                    252: bad:;
                    253:        ndp->ni_dvp = dvp;
                    254:        ndp->ni_vp = NULL;
                    255: #ifdef KERNFS_DIAGNOSTIC
                    256:        printf("kernfs_lookup: error = %d\n", error);
                    257: #endif
                    258:        return (error);
                    259: }
                    260:
                    261: kernfs_open(vp, mode, cred, p)
                    262:        struct vnode *vp;
                    263:        int mode;
                    264:        struct ucred *cred;
                    265:        struct proc *p;
                    266: {
1.9       cgd       267:        /* if access succeeded, this always does, too */
1.1       cgd       268:
                    269:        return (0);
                    270: }
                    271:
1.8       cgd       272: /*
                    273:  * Check mode permission on target pointer. Mode is READ, WRITE or EXEC.
                    274:  * The mode is shifted to select the owner/group/other fields. The
                    275:  * super user is granted all permissions.
                    276:  */
                    277: kernfs_access(vp, mode, cred, p)
1.9       cgd       278:        struct vnode *vp;
                    279:        register int mode;
                    280:        struct ucred *cred;
                    281:        struct proc *p;
                    282: {
                    283:        struct kernfs_target *kt = VTOKERN(vp)->kf_kt;
                    284:        register gid_t *gp;
                    285:        int i, error;
1.8       cgd       286:
                    287: #ifdef KERN_DIAGNOSTIC
1.9       cgd       288:        if (!VOP_ISLOCKED(vp)) {
                    289:                vprint("kernfs_access: not locked", vp);
                    290:                panic("kernfs_access: not locked");
                    291:        }
                    292: #endif
                    293:        /*
                    294:         * If you're the super-user, you always get access.
                    295:         */
                    296:        if (cred->cr_uid == 0)
                    297:                return (0);
                    298:        /*
                    299:         * Access check is based on only one of owner, group, public.
                    300:         * If not owner, then check group. If not a member of the
                    301:         * group, then check public access.
                    302:         */
                    303:        if (cred->cr_uid != /* kt->kt_uid XXX */ 0) {
                    304:                mode >>= 3;
                    305:                gp = cred->cr_groups;
                    306:                for (i = 0; i < cred->cr_ngroups; i++, gp++)
                    307:                        if (/* kt->kt_gid XXX */ 0 == *gp)
                    308:                                goto found;
                    309:                mode >>= 3;
1.8       cgd       310: found:
1.9       cgd       311:                ;
                    312:        }
                    313:        if ((kt->kt_perms & mode) == mode)
                    314:                return (0);
                    315:        return (EACCES);
1.8       cgd       316: }
                    317:
1.1       cgd       318: kernfs_getattr(vp, vap, cred, p)
                    319:        struct vnode *vp;
                    320:        struct vattr *vap;
                    321:        struct ucred *cred;
                    322:        struct proc *p;
                    323: {
                    324:        int error = 0;
                    325:        char strbuf[KSTRING];
1.9       cgd       326:        struct kernfs_target *kt = VTOKERN(vp)->kf_kt;
1.1       cgd       327:
                    328:        bzero((caddr_t) vap, sizeof(*vap));
                    329:        vattr_null(vap);
1.9       cgd       330:        vap->va_uid = kt->kt_uid;
                    331:        vap->va_gid = kt->kt_gid;
1.1       cgd       332:        vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
                    333:        /* vap->va_qsize = 0; */
                    334:        vap->va_blocksize = DEV_BSIZE;
                    335:        microtime(&vap->va_atime);
                    336:        vap->va_mtime = vap->va_atime;
                    337:        vap->va_ctime = vap->va_ctime;
                    338:        vap->va_gen = 0;
                    339:        vap->va_flags = 0;
                    340:        vap->va_rdev = 0;
                    341:        /* vap->va_qbytes = 0; */
                    342:        vap->va_bytes = 0;
1.9       cgd       343:        vap->va_type = kt->kt_vtype;
                    344:        vap->va_mode = kt->kt_perms;
1.1       cgd       345:
                    346:        if (vp->v_flag & VROOT) {
                    347: #ifdef KERNFS_DIAGNOSTIC
                    348:                printf("kernfs_getattr: stat rootdir\n");
                    349: #endif
                    350:                vap->va_nlink = 2;
                    351:                vap->va_fileid = 2;
                    352:                vap->va_size = DEV_BSIZE;
                    353:        } else {
                    354: #ifdef KERNFS_DIAGNOSTIC
                    355:                printf("kernfs_getattr: stat target %s\n", kt->kt_name);
                    356: #endif
                    357:                vap->va_nlink = 1;
1.9       cgd       358:                vap->va_fileid = 3 + (kt - kernfs_targets) / sizeof(*kt);
1.1       cgd       359:                error = kernfs_xread(kt, strbuf, sizeof(strbuf), &vap->va_size);
                    360:        }
                    361:
                    362:        vp->v_type = vap->va_type;
                    363: #ifdef KERNFS_DIAGNOSTIC
                    364:        printf("kernfs_getattr: return error %d\n", error);
                    365: #endif
                    366:        return (error);
                    367: }
                    368:
1.9       cgd       369:
                    370: /*
                    371:  * Change the mode on a file.
                    372:  */
                    373: kernfs_chmod1(vp, mode, p)
                    374:        register struct vnode *vp;
                    375:        register int mode;
                    376:        struct proc *p;
                    377: {
                    378:        register struct ucred *cred = p->p_ucred;
                    379:        register struct kernfs_target *kt = VTOKERN(vp)->kf_kt;
                    380:        int error;
                    381:
                    382:        if ((mode & kt->kt_maxperms) != mode)   /* can't set ro var to rw */
                    383:                return (EPERM);
                    384:
                    385:        if (cred->cr_uid != kt->kt_uid &&
                    386:            (error = suser(cred, &p->p_acflag)))
                    387:                return (error);
                    388:        if (cred->cr_uid) {
                    389:                if (vp->v_type != VDIR && (mode & S_ISVTX))
                    390:                        return (EFTYPE);
                    391:                if (!groupmember(kt->kt_gid, cred) && (mode & S_ISGID))
                    392:                        return (EPERM);
                    393:        }
                    394:        kt->kt_perms &= ~07777;
                    395:        kt->kt_perms |= mode & 07777;
                    396: /*     ip->i_flag |= ICHG;*/
                    397:        return (0);
                    398: }
                    399:
                    400: /*
                    401:  * Perform chown operation on kernfs_target kt
                    402:  */
                    403: kernfs_chown1(vp, uid, gid, p)
                    404:        register struct vnode *vp;
                    405:        uid_t uid;
                    406:        gid_t gid;
                    407:        struct proc *p;
                    408: {
                    409:        register struct kernfs_target *kt = VTOKERN(vp)->kf_kt;
                    410:        register struct ucred *cred = p->p_ucred;
                    411:        uid_t ouid;
                    412:        gid_t ogid;
                    413:        int error = 0;
                    414:
                    415:        if (uid == (u_short)VNOVAL)
                    416:                uid = kt->kt_uid;
                    417:        if (gid == (u_short)VNOVAL)
                    418:                gid = kt->kt_gid;
                    419:        /*
                    420:         * If we don't own the file, are trying to change the owner
                    421:         * of the file, or are not a member of the target group,
                    422:         * the caller must be superuser or the call fails.
                    423:         */
                    424:        if ((cred->cr_uid != kt->kt_uid || uid != kt->kt_uid ||
                    425:            !groupmember((gid_t)gid, cred)) &&
                    426:            (error = suser(cred, &p->p_acflag)))
                    427:                return (error);
                    428:        ouid = kt->kt_uid;
                    429:        ogid = kt->kt_gid;
                    430:
                    431:        kt->kt_uid = uid;
                    432:        kt->kt_gid = gid;
                    433:
                    434: /*     if (ouid != uid || ogid != gid)
                    435:                ip->i_flag |= ICHG;*/
                    436:        if (ouid != uid && cred->cr_uid != 0)
                    437:                kt->kt_perms &= ~S_ISUID;
                    438:        if (ogid != gid && cred->cr_uid != 0)
                    439:                kt->kt_perms &= ~S_ISGID;
                    440:        return (0);
                    441: }
                    442:
                    443: /*
                    444:  * Set attribute vnode op. called from several syscalls
                    445:  */
1.1       cgd       446: kernfs_setattr(vp, vap, cred, p)
                    447:        struct vnode *vp;
                    448:        struct vattr *vap;
                    449:        struct ucred *cred;
                    450:        struct proc *p;
                    451: {
1.9       cgd       452:        int error = 0;
1.1       cgd       453:
                    454:        /*
1.9       cgd       455:         * Check for unsetable attributes.
1.1       cgd       456:         */
1.9       cgd       457:        if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) ||
                    458:            (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) ||
                    459:            (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) ||
                    460:            ((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) {
                    461:                return (EINVAL);
                    462:        }
                    463:        /*
                    464:         * Go through the fields and update iff not VNOVAL.
                    465:         */
                    466:        if (vap->va_uid != (u_short)VNOVAL || vap->va_gid != (u_short)VNOVAL)
                    467:                if (error = kernfs_chown1(vp, vap->va_uid, vap->va_gid, p))
                    468:                        return (error);
                    469:        if (vap->va_size != VNOVAL) {
                    470:                if (vp->v_type == VDIR)
                    471:                        return (EISDIR);
                    472:                /* else just nod and smile... */
                    473:        }
                    474:        if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) {
                    475: /*             if (cred->cr_uid != ip->i_uid &&
                    476:                    (error = suser(cred, &p->p_acflag)))
                    477:                        return (error);
                    478:                if (vap->va_atime.tv_sec != VNOVAL)
                    479:                        ip->i_flag |= IACC;
                    480:                if (vap->va_mtime.tv_sec != VNOVAL)
                    481:                        ip->i_flag |= IUPD;
                    482:                ip->i_flag |= ICHG;
                    483:                if (error = iupdat(ip, &vap->va_atime, &vap->va_mtime, 1))
                    484:                        return (error);
                    485: */
                    486:        }
                    487:        if (vap->va_mode != (u_short)VNOVAL)
                    488:                error = kernfs_chmod1(vp, (int)vap->va_mode, p);
                    489:        if (vap->va_flags != VNOVAL) {
                    490: /*             if (cred->cr_uid != ip->i_uid &&
                    491:                    (error = suser(cred, &p->p_acflag)))
                    492:                        return (error);
                    493:                if (cred->cr_uid == 0) {
                    494:                        ip->i_flags = vap->va_flags;
                    495:                } else {
                    496:                        ip->i_flags &= 0xffff0000;
                    497:                        ip->i_flags |= (vap->va_flags & 0xffff);
                    498:                }
                    499:                ip->i_flag |= ICHG;
                    500: */
                    501:        }
                    502:        return (error);
1.1       cgd       503: }
                    504:
                    505: static int
                    506: kernfs_read(vp, uio, ioflag, cred)
                    507:        struct vnode *vp;
                    508:        struct uio *uio;
                    509:        int ioflag;
                    510:        struct ucred *cred;
                    511: {
1.9       cgd       512:        struct kernfs_target *kt = VTOKERN(vp)->kf_kt;
1.1       cgd       513:        char strbuf[KSTRING];
                    514:        int off = uio->uio_offset;
                    515:        int len = 0;
                    516:        char *cp = strbuf;
                    517:        int error;
                    518: #ifdef KERNFS_DIAGNOSTIC
                    519:        printf("kern_read %s\n", kt->kt_name);
                    520: #endif
                    521:
                    522:        error = kernfs_xread(kt, strbuf, sizeof(strbuf), &len);
                    523:        if (error)
                    524:                return (error);
                    525:        cp = strbuf + off;
                    526:        len -= off;
                    527:        return (uiomove(cp, len, uio));
                    528: }
                    529:
                    530: static int
                    531: kernfs_write(vp, uio, ioflag, cred)
                    532:        struct vnode *vp;
                    533:        struct uio *uio;
                    534:        int ioflag;
                    535:        struct ucred *cred;
                    536: {
1.9       cgd       537:        struct kernfs_target *kt = VTOKERN(vp)->kf_kt;
1.1       cgd       538:        char strbuf[KSTRING];
                    539:        int len = uio->uio_resid;
                    540:        char *cp = strbuf;
                    541:        int xlen;
                    542:        int error;
                    543:
                    544:        if (uio->uio_offset != 0)
                    545:                return (EINVAL);
                    546:
                    547:        xlen = min(uio->uio_resid, KSTRING-1);
                    548:        error = uiomove(strbuf, xlen, uio);
                    549:        if (error)
                    550:                return (error);
                    551:
                    552:        if (uio->uio_resid != 0)
                    553:                return (EIO);
                    554:
                    555:        strbuf[xlen] = '\0';
                    556:        return (kernfs_xwrite(kt, strbuf, xlen));
                    557: }
                    558:
1.12    ! ws        559: kernfs_readdir(vp, uio, cred, eofflagp, cookies, ncookies)
1.1       cgd       560:        struct vnode *vp;
                    561:        struct uio *uio;
                    562:        struct ucred *cred;
                    563:        int *eofflagp;
1.12    ! ws        564:        u_int *cookies;
        !           565:        int ncookies;
1.1       cgd       566: {
                    567:        struct filedesc *fdp;
                    568:        int i;
                    569:        int error;
                    570:
                    571:        i = uio->uio_offset / UIO_MX;
                    572:        error = 0;
1.12    ! ws        573:        while (uio->uio_resid > 0 && (!cookies || ncookies > 0)) {
1.1       cgd       574: #ifdef KERNFS_DIAGNOSTIC
                    575:                printf("kernfs_readdir: i = %d\n", i);
                    576: #endif
1.9       cgd       577:                if (i >= nkernfs_targets) {
1.1       cgd       578:                        *eofflagp = 1;
                    579:                        break;
                    580:                }
                    581:                {
                    582:                        struct direct d;
                    583:                        struct direct *dp = &d;
1.9       cgd       584:                        struct kernfs_target *kt = &kernfs_targets[i];
1.1       cgd       585:
                    586:                        bzero((caddr_t) dp, UIO_MX);
                    587:
                    588:                        dp->d_namlen = strlen(kt->kt_name);
                    589:                        bcopy(kt->kt_name, dp->d_name, dp->d_namlen+1);
                    590:
                    591: #ifdef KERNFS_DIAGNOSTIC
                    592:                        printf("kernfs_readdir: name = %s, len = %d\n",
                    593:                                        dp->d_name, dp->d_namlen);
                    594: #endif
                    595:                        /*
                    596:                         * Fill in the remaining fields
                    597:                         */
                    598:                        dp->d_reclen = UIO_MX;
                    599:                        dp->d_ino = i + 3;
                    600:                        /*
                    601:                         * And ship to userland
                    602:                         */
                    603:                        error = uiomove((caddr_t) dp, UIO_MX, uio);
                    604:                        if (error)
                    605:                                break;
1.12    ! ws        606:                        if (cookies) {
        !           607:                                *cookies = (i + 1) * UIO_MX;
        !           608:                                ncookies--;
        !           609:                        }
1.1       cgd       610:                }
                    611:                i++;
                    612:        }
                    613:
                    614:        uio->uio_offset = i * UIO_MX;
                    615:
                    616:        return (error);
                    617: }
                    618:
                    619: kernfs_inactive(vp, p)
                    620:        struct vnode *vp;
                    621:        struct proc *p;
                    622: {
                    623:        /*
                    624:         * Clear out the v_type field to avoid
                    625:         * nasty things happening in vgone().
                    626:         */
                    627:        vp->v_type = VNON;
                    628: #ifdef KERNFS_DIAGNOSTIC
                    629:        printf("kernfs_inactive(%x)\n", vp);
                    630: #endif
                    631:        return (0);
                    632: }
                    633:
                    634: /*
                    635:  * Print out the contents of a kernfs vnode.
                    636:  */
                    637: /* ARGSUSED */
1.11      mycroft   638: void
1.1       cgd       639: kernfs_print(vp)
                    640:        struct vnode *vp;
                    641: {
1.10      cgd       642:        printf("tag VT_KERNFS, kernfs vnode\n");
1.1       cgd       643: }
                    644:
                    645: /*
                    646:  * kernfs vnode unsupported operation
                    647:  */
                    648: kernfs_enotsupp()
                    649: {
                    650:        return (EOPNOTSUPP);
                    651: }
                    652:
                    653: /*
                    654:  * kernfs "should never get here" operation
                    655:  */
                    656: kernfs_badop()
                    657: {
                    658:        panic("kernfs: bad op");
                    659:        /* NOTREACHED */
                    660: }
                    661:
                    662: /*
                    663:  * kernfs vnode null operation
                    664:  */
                    665: kernfs_nullop()
                    666: {
                    667:        return (0);
                    668: }
                    669:
                    670: #define kernfs_create ((int (*) __P(( \
                    671:                struct nameidata *ndp, \
                    672:                struct vattr *vap, \
                    673:                struct proc *p))) kernfs_enotsupp)
                    674: #define kernfs_mknod ((int (*) __P(( \
                    675:                struct nameidata *ndp, \
                    676:                struct vattr *vap, \
                    677:                struct ucred *cred, \
                    678:                struct proc *p))) kernfs_enotsupp)
                    679: #define kernfs_close ((int (*) __P(( \
                    680:                struct vnode *vp, \
                    681:                int fflag, \
                    682:                struct ucred *cred, \
                    683:                struct proc *p))) nullop)
                    684: #define        kernfs_ioctl ((int (*) __P(( \
                    685:                struct vnode *vp, \
                    686:                int command, \
                    687:                caddr_t data, \
                    688:                int fflag, \
                    689:                struct ucred *cred, \
                    690:                struct proc *p))) kernfs_enotsupp)
                    691: #define        kernfs_select ((int (*) __P(( \
                    692:                struct vnode *vp, \
                    693:                int which, \
                    694:                int fflags, \
                    695:                struct ucred *cred, \
                    696:                struct proc *p))) kernfs_enotsupp)
                    697: #define kernfs_mmap ((int (*) __P(( \
                    698:                struct vnode *vp, \
                    699:                int fflags, \
                    700:                struct ucred *cred, \
                    701:                struct proc *p))) kernfs_enotsupp)
                    702: #define kernfs_fsync ((int (*) __P(( \
                    703:                struct vnode *vp, \
                    704:                int fflags, \
                    705:                struct ucred *cred, \
                    706:                int waitfor, \
                    707:                struct proc *p))) nullop)
                    708: #define kernfs_seek ((int (*) __P(( \
                    709:                struct vnode *vp, \
                    710:                off_t oldoff, \
                    711:                off_t newoff, \
                    712:                struct ucred *cred))) nullop)
                    713: #define kernfs_remove ((int (*) __P(( \
                    714:                struct nameidata *ndp, \
                    715:                struct proc *p))) kernfs_enotsupp)
                    716: #define kernfs_link ((int (*) __P(( \
                    717:                struct vnode *vp, \
                    718:                struct nameidata *ndp, \
                    719:                struct proc *p))) kernfs_enotsupp)
                    720: #define kernfs_rename ((int (*) __P(( \
                    721:                struct nameidata *fndp, \
                    722:                struct nameidata *tdnp, \
                    723:                struct proc *p))) kernfs_enotsupp)
                    724: #define kernfs_mkdir ((int (*) __P(( \
                    725:                struct nameidata *ndp, \
                    726:                struct vattr *vap, \
                    727:                struct proc *p))) kernfs_enotsupp)
                    728: #define kernfs_rmdir ((int (*) __P(( \
                    729:                struct nameidata *ndp, \
                    730:                struct proc *p))) kernfs_enotsupp)
                    731: #define kernfs_symlink ((int (*) __P(( \
                    732:                struct nameidata *ndp, \
                    733:                struct vattr *vap, \
                    734:                char *target, \
                    735:                struct proc *p))) kernfs_enotsupp)
                    736: #define kernfs_readlink ((int (*) __P(( \
                    737:                struct vnode *vp, \
                    738:                struct uio *uio, \
                    739:                struct ucred *cred))) kernfs_enotsupp)
                    740: #define kernfs_abortop ((int (*) __P(( \
                    741:                struct nameidata *ndp))) nullop)
                    742: #ifdef KERNFS_DIAGNOSTIC
                    743: int kernfs_reclaim(vp)
                    744: struct vnode *vp;
                    745: {
                    746:        printf("kernfs_reclaim(%x)\n", vp);
                    747:        return (0);
                    748: }
                    749: #else
                    750: #define kernfs_reclaim ((int (*) __P(( \
                    751:                struct vnode *vp))) nullop)
                    752: #endif
                    753: #define        kernfs_lock ((int (*) __P(( \
                    754:                struct vnode *vp))) nullop)
                    755: #define kernfs_unlock ((int (*) __P(( \
                    756:                struct vnode *vp))) nullop)
                    757: #define        kernfs_bmap ((int (*) __P(( \
                    758:                struct vnode *vp, \
                    759:                daddr_t bn, \
                    760:                struct vnode **vpp, \
                    761:                daddr_t *bnp))) kernfs_badop)
                    762: #define        kernfs_strategy ((int (*) __P(( \
                    763:                struct buf *bp))) kernfs_badop)
                    764: #define kernfs_islocked ((int (*) __P(( \
                    765:                struct vnode *vp))) nullop)
                    766: #define kernfs_advlock ((int (*) __P(( \
                    767:                struct vnode *vp, \
                    768:                caddr_t id, \
                    769:                int op, \
                    770:                struct flock *fl, \
                    771:                int flags))) kernfs_enotsupp)
                    772:
                    773: struct vnodeops kernfs_vnodeops = {
                    774:        kernfs_lookup,  /* lookup */
                    775:        kernfs_create,  /* create */
                    776:        kernfs_mknod,   /* mknod */
                    777:        kernfs_open,    /* open */
                    778:        kernfs_close,   /* close */
                    779:        kernfs_access,  /* access */
                    780:        kernfs_getattr, /* getattr */
                    781:        kernfs_setattr, /* setattr */
                    782:        kernfs_read,    /* read */
                    783:        kernfs_write,   /* write */
                    784:        kernfs_ioctl,   /* ioctl */
                    785:        kernfs_select,  /* select */
                    786:        kernfs_mmap,    /* mmap */
                    787:        kernfs_fsync,   /* fsync */
                    788:        kernfs_seek,    /* seek */
                    789:        kernfs_remove,  /* remove */
                    790:        kernfs_link,    /* link */
                    791:        kernfs_rename,  /* rename */
                    792:        kernfs_mkdir,   /* mkdir */
                    793:        kernfs_rmdir,   /* rmdir */
                    794:        kernfs_symlink, /* symlink */
                    795:        kernfs_readdir, /* readdir */
                    796:        kernfs_readlink,        /* readlink */
                    797:        kernfs_abortop, /* abortop */
                    798:        kernfs_inactive,        /* inactive */
                    799:        kernfs_reclaim, /* reclaim */
                    800:        kernfs_lock,    /* lock */
                    801:        kernfs_unlock,  /* unlock */
                    802:        kernfs_bmap,    /* bmap */
                    803:        kernfs_strategy,        /* strategy */
                    804:        kernfs_print,   /* print */
                    805:        kernfs_islocked,        /* islocked */
                    806:        kernfs_advlock, /* advlock */
                    807: };

CVSweb <webmaster@jp.NetBSD.org>