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