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

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.9     ! cgd        36:  *     $Id: kernfs_vnops.c,v 1.8 1993/05/28 14:12:17 cgd 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
                    240:        error = getnewvnode(VT_UFS, dvp->v_mount, &kernfs_vnodeops, &fvp);
                    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:
                    559: kernfs_readdir(vp, uio, cred, eofflagp)
                    560:        struct vnode *vp;
                    561:        struct uio *uio;
                    562:        struct ucred *cred;
                    563:        int *eofflagp;
                    564: {
                    565:        struct filedesc *fdp;
                    566:        int i;
                    567:        int error;
                    568:
                    569:        i = uio->uio_offset / UIO_MX;
                    570:        error = 0;
                    571:        while (uio->uio_resid > 0) {
                    572: #ifdef KERNFS_DIAGNOSTIC
                    573:                printf("kernfs_readdir: i = %d\n", i);
                    574: #endif
1.9     ! cgd       575:                if (i >= nkernfs_targets) {
1.1       cgd       576:                        *eofflagp = 1;
                    577:                        break;
                    578:                }
                    579:                {
                    580:                        struct direct d;
                    581:                        struct direct *dp = &d;
1.9     ! cgd       582:                        struct kernfs_target *kt = &kernfs_targets[i];
1.1       cgd       583:
                    584:                        bzero((caddr_t) dp, UIO_MX);
                    585:
                    586:                        dp->d_namlen = strlen(kt->kt_name);
                    587:                        bcopy(kt->kt_name, dp->d_name, dp->d_namlen+1);
                    588:
                    589: #ifdef KERNFS_DIAGNOSTIC
                    590:                        printf("kernfs_readdir: name = %s, len = %d\n",
                    591:                                        dp->d_name, dp->d_namlen);
                    592: #endif
                    593:                        /*
                    594:                         * Fill in the remaining fields
                    595:                         */
                    596:                        dp->d_reclen = UIO_MX;
                    597:                        dp->d_ino = i + 3;
                    598:                        /*
                    599:                         * And ship to userland
                    600:                         */
                    601:                        error = uiomove((caddr_t) dp, UIO_MX, uio);
                    602:                        if (error)
                    603:                                break;
                    604:                }
                    605:                i++;
                    606:        }
                    607:
                    608:        uio->uio_offset = i * UIO_MX;
                    609:
                    610:        return (error);
                    611: }
                    612:
                    613: kernfs_inactive(vp, p)
                    614:        struct vnode *vp;
                    615:        struct proc *p;
                    616: {
                    617:        /*
                    618:         * Clear out the v_type field to avoid
                    619:         * nasty things happening in vgone().
                    620:         */
                    621:        vp->v_type = VNON;
                    622: #ifdef KERNFS_DIAGNOSTIC
                    623:        printf("kernfs_inactive(%x)\n", vp);
                    624: #endif
                    625:        return (0);
                    626: }
                    627:
                    628: /*
                    629:  * Print out the contents of a kernfs vnode.
                    630:  */
                    631: /* ARGSUSED */
                    632: kernfs_print(vp)
                    633:        struct vnode *vp;
                    634: {
                    635:        printf("tag VT_NON, kernfs vnode\n");
                    636: }
                    637:
                    638: /*
                    639:  * kernfs vnode unsupported operation
                    640:  */
                    641: kernfs_enotsupp()
                    642: {
                    643:        return (EOPNOTSUPP);
                    644: }
                    645:
                    646: /*
                    647:  * kernfs "should never get here" operation
                    648:  */
                    649: kernfs_badop()
                    650: {
                    651:        panic("kernfs: bad op");
                    652:        /* NOTREACHED */
                    653: }
                    654:
                    655: /*
                    656:  * kernfs vnode null operation
                    657:  */
                    658: kernfs_nullop()
                    659: {
                    660:        return (0);
                    661: }
                    662:
                    663: #define kernfs_create ((int (*) __P(( \
                    664:                struct nameidata *ndp, \
                    665:                struct vattr *vap, \
                    666:                struct proc *p))) kernfs_enotsupp)
                    667: #define kernfs_mknod ((int (*) __P(( \
                    668:                struct nameidata *ndp, \
                    669:                struct vattr *vap, \
                    670:                struct ucred *cred, \
                    671:                struct proc *p))) kernfs_enotsupp)
                    672: #define kernfs_close ((int (*) __P(( \
                    673:                struct vnode *vp, \
                    674:                int fflag, \
                    675:                struct ucred *cred, \
                    676:                struct proc *p))) nullop)
                    677: #define        kernfs_ioctl ((int (*) __P(( \
                    678:                struct vnode *vp, \
                    679:                int command, \
                    680:                caddr_t data, \
                    681:                int fflag, \
                    682:                struct ucred *cred, \
                    683:                struct proc *p))) kernfs_enotsupp)
                    684: #define        kernfs_select ((int (*) __P(( \
                    685:                struct vnode *vp, \
                    686:                int which, \
                    687:                int fflags, \
                    688:                struct ucred *cred, \
                    689:                struct proc *p))) kernfs_enotsupp)
                    690: #define kernfs_mmap ((int (*) __P(( \
                    691:                struct vnode *vp, \
                    692:                int fflags, \
                    693:                struct ucred *cred, \
                    694:                struct proc *p))) kernfs_enotsupp)
                    695: #define kernfs_fsync ((int (*) __P(( \
                    696:                struct vnode *vp, \
                    697:                int fflags, \
                    698:                struct ucred *cred, \
                    699:                int waitfor, \
                    700:                struct proc *p))) nullop)
                    701: #define kernfs_seek ((int (*) __P(( \
                    702:                struct vnode *vp, \
                    703:                off_t oldoff, \
                    704:                off_t newoff, \
                    705:                struct ucred *cred))) nullop)
                    706: #define kernfs_remove ((int (*) __P(( \
                    707:                struct nameidata *ndp, \
                    708:                struct proc *p))) kernfs_enotsupp)
                    709: #define kernfs_link ((int (*) __P(( \
                    710:                struct vnode *vp, \
                    711:                struct nameidata *ndp, \
                    712:                struct proc *p))) kernfs_enotsupp)
                    713: #define kernfs_rename ((int (*) __P(( \
                    714:                struct nameidata *fndp, \
                    715:                struct nameidata *tdnp, \
                    716:                struct proc *p))) kernfs_enotsupp)
                    717: #define kernfs_mkdir ((int (*) __P(( \
                    718:                struct nameidata *ndp, \
                    719:                struct vattr *vap, \
                    720:                struct proc *p))) kernfs_enotsupp)
                    721: #define kernfs_rmdir ((int (*) __P(( \
                    722:                struct nameidata *ndp, \
                    723:                struct proc *p))) kernfs_enotsupp)
                    724: #define kernfs_symlink ((int (*) __P(( \
                    725:                struct nameidata *ndp, \
                    726:                struct vattr *vap, \
                    727:                char *target, \
                    728:                struct proc *p))) kernfs_enotsupp)
                    729: #define kernfs_readlink ((int (*) __P(( \
                    730:                struct vnode *vp, \
                    731:                struct uio *uio, \
                    732:                struct ucred *cred))) kernfs_enotsupp)
                    733: #define kernfs_abortop ((int (*) __P(( \
                    734:                struct nameidata *ndp))) nullop)
                    735: #ifdef KERNFS_DIAGNOSTIC
                    736: int kernfs_reclaim(vp)
                    737: struct vnode *vp;
                    738: {
                    739:        printf("kernfs_reclaim(%x)\n", vp);
                    740:        return (0);
                    741: }
                    742: #else
                    743: #define kernfs_reclaim ((int (*) __P(( \
                    744:                struct vnode *vp))) nullop)
                    745: #endif
                    746: #define        kernfs_lock ((int (*) __P(( \
                    747:                struct vnode *vp))) nullop)
                    748: #define kernfs_unlock ((int (*) __P(( \
                    749:                struct vnode *vp))) nullop)
                    750: #define        kernfs_bmap ((int (*) __P(( \
                    751:                struct vnode *vp, \
                    752:                daddr_t bn, \
                    753:                struct vnode **vpp, \
                    754:                daddr_t *bnp))) kernfs_badop)
                    755: #define        kernfs_strategy ((int (*) __P(( \
                    756:                struct buf *bp))) kernfs_badop)
                    757: #define kernfs_islocked ((int (*) __P(( \
                    758:                struct vnode *vp))) nullop)
                    759: #define kernfs_advlock ((int (*) __P(( \
                    760:                struct vnode *vp, \
                    761:                caddr_t id, \
                    762:                int op, \
                    763:                struct flock *fl, \
                    764:                int flags))) kernfs_enotsupp)
                    765:
                    766: struct vnodeops kernfs_vnodeops = {
                    767:        kernfs_lookup,  /* lookup */
                    768:        kernfs_create,  /* create */
                    769:        kernfs_mknod,   /* mknod */
                    770:        kernfs_open,    /* open */
                    771:        kernfs_close,   /* close */
                    772:        kernfs_access,  /* access */
                    773:        kernfs_getattr, /* getattr */
                    774:        kernfs_setattr, /* setattr */
                    775:        kernfs_read,    /* read */
                    776:        kernfs_write,   /* write */
                    777:        kernfs_ioctl,   /* ioctl */
                    778:        kernfs_select,  /* select */
                    779:        kernfs_mmap,    /* mmap */
                    780:        kernfs_fsync,   /* fsync */
                    781:        kernfs_seek,    /* seek */
                    782:        kernfs_remove,  /* remove */
                    783:        kernfs_link,    /* link */
                    784:        kernfs_rename,  /* rename */
                    785:        kernfs_mkdir,   /* mkdir */
                    786:        kernfs_rmdir,   /* rmdir */
                    787:        kernfs_symlink, /* symlink */
                    788:        kernfs_readdir, /* readdir */
                    789:        kernfs_readlink,        /* readlink */
                    790:        kernfs_abortop, /* abortop */
                    791:        kernfs_inactive,        /* inactive */
                    792:        kernfs_reclaim, /* reclaim */
                    793:        kernfs_lock,    /* lock */
                    794:        kernfs_unlock,  /* unlock */
                    795:        kernfs_bmap,    /* bmap */
                    796:        kernfs_strategy,        /* strategy */
                    797:        kernfs_print,   /* print */
                    798:        kernfs_islocked,        /* islocked */
                    799:        kernfs_advlock, /* advlock */
                    800: };

CVSweb <webmaster@jp.NetBSD.org>