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

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

CVSweb <webmaster@jp.NetBSD.org>