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

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

CVSweb <webmaster@jp.NetBSD.org>