Home | History | Annotate | Line # | Download | only in genfs
genfs_vnops.c revision 1.158.6.2
      1  1.158.6.2        ad /*	$NetBSD: genfs_vnops.c,v 1.158.6.2 2007/12/08 17:57:51 ad Exp $	*/
      2        1.6      fvdl 
      3        1.6      fvdl /*
      4        1.6      fvdl  * Copyright (c) 1982, 1986, 1989, 1993
      5        1.6      fvdl  *	The Regents of the University of California.  All rights reserved.
      6        1.6      fvdl  *
      7        1.6      fvdl  * Redistribution and use in source and binary forms, with or without
      8        1.6      fvdl  * modification, are permitted provided that the following conditions
      9        1.6      fvdl  * are met:
     10        1.6      fvdl  * 1. Redistributions of source code must retain the above copyright
     11        1.6      fvdl  *    notice, this list of conditions and the following disclaimer.
     12        1.6      fvdl  * 2. Redistributions in binary form must reproduce the above copyright
     13        1.6      fvdl  *    notice, this list of conditions and the following disclaimer in the
     14        1.6      fvdl  *    documentation and/or other materials provided with the distribution.
     15       1.81       agc  * 3. Neither the name of the University nor the names of its contributors
     16        1.6      fvdl  *    may be used to endorse or promote products derived from this software
     17        1.6      fvdl  *    without specific prior written permission.
     18        1.6      fvdl  *
     19        1.6      fvdl  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     20        1.6      fvdl  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21        1.6      fvdl  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22        1.6      fvdl  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     23        1.6      fvdl  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24        1.6      fvdl  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     25        1.6      fvdl  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26        1.6      fvdl  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27        1.6      fvdl  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28        1.6      fvdl  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29        1.6      fvdl  * SUCH DAMAGE.
     30        1.6      fvdl  *
     31        1.6      fvdl  */
     32       1.40     lukem 
     33       1.40     lukem #include <sys/cdefs.h>
     34  1.158.6.2        ad __KERNEL_RCSID(0, "$NetBSD: genfs_vnops.c,v 1.158.6.2 2007/12/08 17:57:51 ad Exp $");
     35        1.8   thorpej 
     36        1.1   mycroft #include <sys/param.h>
     37        1.1   mycroft #include <sys/systm.h>
     38        1.6      fvdl #include <sys/proc.h>
     39        1.1   mycroft #include <sys/kernel.h>
     40        1.1   mycroft #include <sys/mount.h>
     41        1.1   mycroft #include <sys/namei.h>
     42        1.1   mycroft #include <sys/vnode.h>
     43       1.13  wrstuden #include <sys/fcntl.h>
     44      1.135      yamt #include <sys/kmem.h>
     45        1.3   mycroft #include <sys/poll.h>
     46       1.37       chs #include <sys/mman.h>
     47       1.66  jdolecek #include <sys/file.h>
     48      1.125      elad #include <sys/kauth.h>
     49      1.143   hannken #include <sys/fstrans.h>
     50        1.1   mycroft 
     51        1.1   mycroft #include <miscfs/genfs/genfs.h>
     52       1.37       chs #include <miscfs/genfs/genfs_node.h>
     53        1.6      fvdl #include <miscfs/specfs/specdev.h>
     54        1.1   mycroft 
     55       1.21       chs #include <uvm/uvm.h>
     56       1.21       chs #include <uvm/uvm_pager.h>
     57       1.21       chs 
     58       1.70  christos static void filt_genfsdetach(struct knote *);
     59       1.70  christos static int filt_genfsread(struct knote *, long);
     60       1.70  christos static int filt_genfsvnode(struct knote *, long);
     61       1.70  christos 
     62        1.1   mycroft int
     63       1.53     enami genfs_poll(void *v)
     64        1.1   mycroft {
     65        1.3   mycroft 	struct vop_poll_args /* {
     66        1.1   mycroft 		struct vnode *a_vp;
     67        1.3   mycroft 		int a_events;
     68      1.116  christos 		struct lwp *a_l;
     69        1.1   mycroft 	} */ *ap = v;
     70        1.1   mycroft 
     71        1.3   mycroft 	return (ap->a_events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
     72        1.1   mycroft }
     73        1.1   mycroft 
     74        1.1   mycroft int
     75       1.53     enami genfs_seek(void *v)
     76        1.4    kleink {
     77        1.4    kleink 	struct vop_seek_args /* {
     78        1.4    kleink 		struct vnode *a_vp;
     79        1.4    kleink 		off_t a_oldoff;
     80        1.4    kleink 		off_t a_newoff;
     81      1.125      elad 		kauth_cred_t cred;
     82        1.4    kleink 	} */ *ap = v;
     83        1.4    kleink 
     84        1.4    kleink 	if (ap->a_newoff < 0)
     85        1.4    kleink 		return (EINVAL);
     86        1.4    kleink 
     87        1.4    kleink 	return (0);
     88        1.4    kleink }
     89        1.4    kleink 
     90        1.4    kleink int
     91       1.53     enami genfs_abortop(void *v)
     92        1.1   mycroft {
     93        1.1   mycroft 	struct vop_abortop_args /* {
     94        1.1   mycroft 		struct vnode *a_dvp;
     95        1.1   mycroft 		struct componentname *a_cnp;
     96        1.1   mycroft 	} */ *ap = v;
     97       1.53     enami 
     98        1.1   mycroft 	if ((ap->a_cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF)
     99       1.19   thorpej 		PNBUF_PUT(ap->a_cnp->cn_pnbuf);
    100        1.1   mycroft 	return (0);
    101       1.13  wrstuden }
    102       1.13  wrstuden 
    103       1.13  wrstuden int
    104       1.53     enami genfs_fcntl(void *v)
    105       1.13  wrstuden {
    106       1.13  wrstuden 	struct vop_fcntl_args /* {
    107       1.13  wrstuden 		struct vnode *a_vp;
    108       1.13  wrstuden 		u_int a_command;
    109      1.150  christos 		void *a_data;
    110       1.13  wrstuden 		int a_fflag;
    111      1.125      elad 		kauth_cred_t a_cred;
    112      1.116  christos 		struct lwp *a_l;
    113       1.13  wrstuden 	} */ *ap = v;
    114       1.13  wrstuden 
    115       1.13  wrstuden 	if (ap->a_command == F_SETFL)
    116       1.13  wrstuden 		return (0);
    117       1.13  wrstuden 	else
    118       1.13  wrstuden 		return (EOPNOTSUPP);
    119        1.1   mycroft }
    120        1.1   mycroft 
    121        1.1   mycroft /*ARGSUSED*/
    122        1.1   mycroft int
    123      1.138  christos genfs_badop(void *v)
    124        1.1   mycroft {
    125        1.1   mycroft 
    126        1.1   mycroft 	panic("genfs: bad op");
    127        1.1   mycroft }
    128        1.1   mycroft 
    129        1.1   mycroft /*ARGSUSED*/
    130        1.1   mycroft int
    131      1.138  christos genfs_nullop(void *v)
    132        1.1   mycroft {
    133        1.1   mycroft 
    134        1.1   mycroft 	return (0);
    135       1.10    kleink }
    136       1.10    kleink 
    137       1.10    kleink /*ARGSUSED*/
    138       1.10    kleink int
    139      1.138  christos genfs_einval(void *v)
    140       1.10    kleink {
    141       1.10    kleink 
    142       1.10    kleink 	return (EINVAL);
    143        1.1   mycroft }
    144        1.1   mycroft 
    145       1.12  wrstuden /*
    146       1.74  jdolecek  * Called when an fs doesn't support a particular vop.
    147       1.74  jdolecek  * This takes care to vrele, vput, or vunlock passed in vnodes.
    148       1.12  wrstuden  */
    149       1.12  wrstuden int
    150       1.75  jdolecek genfs_eopnotsupp(void *v)
    151       1.12  wrstuden {
    152       1.12  wrstuden 	struct vop_generic_args /*
    153       1.12  wrstuden 		struct vnodeop_desc *a_desc;
    154       1.53     enami 		/ * other random data follows, presumably * /
    155       1.12  wrstuden 	} */ *ap = v;
    156       1.12  wrstuden 	struct vnodeop_desc *desc = ap->a_desc;
    157       1.74  jdolecek 	struct vnode *vp, *vp_last = NULL;
    158       1.12  wrstuden 	int flags, i, j, offset;
    159       1.12  wrstuden 
    160       1.12  wrstuden 	flags = desc->vdesc_flags;
    161       1.12  wrstuden 	for (i = 0; i < VDESC_MAX_VPS; flags >>=1, i++) {
    162       1.12  wrstuden 		if ((offset = desc->vdesc_vp_offsets[i]) == VDESC_NO_OFFSET)
    163       1.12  wrstuden 			break;	/* stop at end of list */
    164       1.12  wrstuden 		if ((j = flags & VDESC_VP0_WILLPUT)) {
    165       1.53     enami 			vp = *VOPARG_OFFSETTO(struct vnode **, offset, ap);
    166       1.74  jdolecek 
    167       1.74  jdolecek 			/* Skip if NULL */
    168       1.74  jdolecek 			if (!vp)
    169       1.74  jdolecek 				continue;
    170       1.74  jdolecek 
    171       1.12  wrstuden 			switch (j) {
    172       1.12  wrstuden 			case VDESC_VP0_WILLPUT:
    173       1.74  jdolecek 				/* Check for dvp == vp cases */
    174       1.74  jdolecek 				if (vp == vp_last)
    175       1.74  jdolecek 					vrele(vp);
    176       1.74  jdolecek 				else {
    177       1.74  jdolecek 					vput(vp);
    178       1.74  jdolecek 					vp_last = vp;
    179       1.74  jdolecek 				}
    180       1.12  wrstuden 				break;
    181       1.12  wrstuden 			case VDESC_VP0_WILLUNLOCK:
    182       1.12  wrstuden 				VOP_UNLOCK(vp, 0);
    183       1.12  wrstuden 				break;
    184       1.12  wrstuden 			case VDESC_VP0_WILLRELE:
    185       1.12  wrstuden 				vrele(vp);
    186       1.12  wrstuden 				break;
    187       1.12  wrstuden 			}
    188       1.12  wrstuden 		}
    189       1.12  wrstuden 	}
    190       1.12  wrstuden 
    191       1.12  wrstuden 	return (EOPNOTSUPP);
    192       1.12  wrstuden }
    193       1.12  wrstuden 
    194        1.1   mycroft /*ARGSUSED*/
    195        1.1   mycroft int
    196      1.138  christos genfs_ebadf(void *v)
    197        1.1   mycroft {
    198        1.1   mycroft 
    199        1.1   mycroft 	return (EBADF);
    200        1.9  matthias }
    201        1.9  matthias 
    202        1.9  matthias /* ARGSUSED */
    203        1.9  matthias int
    204      1.138  christos genfs_enoioctl(void *v)
    205        1.9  matthias {
    206        1.9  matthias 
    207       1.51    atatat 	return (EPASSTHROUGH);
    208        1.6      fvdl }
    209        1.6      fvdl 
    210        1.6      fvdl 
    211        1.6      fvdl /*
    212       1.15      fvdl  * Eliminate all activity associated with the requested vnode
    213        1.6      fvdl  * and with all vnodes aliased to the requested vnode.
    214        1.6      fvdl  */
    215        1.6      fvdl int
    216       1.53     enami genfs_revoke(void *v)
    217        1.6      fvdl {
    218        1.6      fvdl 	struct vop_revoke_args /* {
    219        1.6      fvdl 		struct vnode *a_vp;
    220        1.6      fvdl 		int a_flags;
    221        1.6      fvdl 	} */ *ap = v;
    222  1.158.6.1        ad 	struct vnode *vp, *vq, **vpp;
    223  1.158.6.1        ad 	enum vtype type;
    224  1.158.6.1        ad 	dev_t dev;
    225        1.6      fvdl 
    226        1.6      fvdl #ifdef DIAGNOSTIC
    227        1.6      fvdl 	if ((ap->a_flags & REVOKEALL) == 0)
    228        1.6      fvdl 		panic("genfs_revoke: not revokeall");
    229        1.6      fvdl #endif
    230        1.6      fvdl 	vp = ap->a_vp;
    231        1.6      fvdl 
    232  1.158.6.1        ad 	mutex_enter(&vp->v_interlock);
    233  1.158.6.1        ad 	if ((vp->v_iflag & VI_CLEAN) != 0) {
    234  1.158.6.1        ad 		mutex_exit(&vp->v_interlock);
    235  1.158.6.1        ad 		return (0);
    236  1.158.6.1        ad 	} else {
    237  1.158.6.1        ad 		dev = vp->v_rdev;
    238  1.158.6.1        ad 		type = vp->v_type;
    239  1.158.6.1        ad 		mutex_exit(&vp->v_interlock);
    240  1.158.6.1        ad 	}
    241  1.158.6.1        ad 
    242  1.158.6.1        ad 	if (type != VBLK && type != VCHR)
    243  1.158.6.1        ad 		return (0);
    244  1.158.6.1        ad 
    245  1.158.6.1        ad 	vpp = &speclisth[SPECHASH(dev)];
    246  1.158.6.1        ad 	mutex_enter(&spechash_lock);
    247  1.158.6.1        ad 	for (vq = *vpp; vq != NULL;) {
    248  1.158.6.1        ad 		if (vq->v_rdev != dev || vq->v_type != type) {
    249  1.158.6.1        ad 			vq = vq->v_specnext;
    250  1.158.6.1        ad 			continue;
    251        1.6      fvdl 		}
    252  1.158.6.1        ad 		mutex_enter(&vq->v_interlock);
    253  1.158.6.1        ad 		mutex_exit(&spechash_lock);
    254  1.158.6.1        ad 		vq->v_usecount++;
    255  1.158.6.1        ad 		vclean(vq, DOCLOSE);
    256  1.158.6.1        ad 		vrelel(vq, 1, 0);
    257  1.158.6.1        ad 		mutex_enter(&spechash_lock);
    258  1.158.6.1        ad 		vq = *vpp;
    259        1.6      fvdl 	}
    260  1.158.6.1        ad 	mutex_exit(&spechash_lock);
    261  1.158.6.1        ad 
    262        1.6      fvdl 	return (0);
    263        1.6      fvdl }
    264        1.6      fvdl 
    265        1.6      fvdl /*
    266       1.12  wrstuden  * Lock the node.
    267        1.6      fvdl  */
    268        1.6      fvdl int
    269       1.53     enami genfs_lock(void *v)
    270        1.6      fvdl {
    271        1.6      fvdl 	struct vop_lock_args /* {
    272        1.6      fvdl 		struct vnode *a_vp;
    273        1.6      fvdl 		int a_flags;
    274        1.6      fvdl 	} */ *ap = v;
    275        1.6      fvdl 	struct vnode *vp = ap->a_vp;
    276        1.6      fvdl 
    277       1.86   hannken 	return (lockmgr(vp->v_vnlock, ap->a_flags, &vp->v_interlock));
    278        1.6      fvdl }
    279        1.6      fvdl 
    280        1.6      fvdl /*
    281       1.12  wrstuden  * Unlock the node.
    282        1.6      fvdl  */
    283        1.6      fvdl int
    284       1.53     enami genfs_unlock(void *v)
    285        1.6      fvdl {
    286        1.6      fvdl 	struct vop_unlock_args /* {
    287        1.6      fvdl 		struct vnode *a_vp;
    288        1.6      fvdl 		int a_flags;
    289        1.6      fvdl 	} */ *ap = v;
    290        1.6      fvdl 	struct vnode *vp = ap->a_vp;
    291        1.6      fvdl 
    292       1.86   hannken 	return (lockmgr(vp->v_vnlock, ap->a_flags | LK_RELEASE,
    293       1.53     enami 	    &vp->v_interlock));
    294        1.6      fvdl }
    295        1.6      fvdl 
    296        1.6      fvdl /*
    297       1.12  wrstuden  * Return whether or not the node is locked.
    298        1.6      fvdl  */
    299        1.6      fvdl int
    300       1.53     enami genfs_islocked(void *v)
    301        1.6      fvdl {
    302        1.6      fvdl 	struct vop_islocked_args /* {
    303        1.6      fvdl 		struct vnode *a_vp;
    304        1.6      fvdl 	} */ *ap = v;
    305        1.6      fvdl 	struct vnode *vp = ap->a_vp;
    306        1.6      fvdl 
    307       1.86   hannken 	return (lockstatus(vp->v_vnlock));
    308       1.12  wrstuden }
    309       1.12  wrstuden 
    310       1.12  wrstuden /*
    311       1.12  wrstuden  * Stubs to use when there is no locking to be done on the underlying object.
    312       1.12  wrstuden  */
    313       1.12  wrstuden int
    314       1.53     enami genfs_nolock(void *v)
    315       1.12  wrstuden {
    316       1.12  wrstuden 	struct vop_lock_args /* {
    317       1.12  wrstuden 		struct vnode *a_vp;
    318       1.12  wrstuden 		int a_flags;
    319      1.116  christos 		struct lwp *a_l;
    320       1.12  wrstuden 	} */ *ap = v;
    321       1.12  wrstuden 
    322       1.12  wrstuden 	/*
    323       1.12  wrstuden 	 * Since we are not using the lock manager, we must clear
    324       1.12  wrstuden 	 * the interlock here.
    325       1.12  wrstuden 	 */
    326       1.12  wrstuden 	if (ap->a_flags & LK_INTERLOCK)
    327  1.158.6.1        ad 		mutex_exit(&ap->a_vp->v_interlock);
    328       1.12  wrstuden 	return (0);
    329       1.12  wrstuden }
    330       1.12  wrstuden 
    331       1.12  wrstuden int
    332      1.138  christos genfs_nounlock(void *v)
    333       1.12  wrstuden {
    334       1.53     enami 
    335       1.12  wrstuden 	return (0);
    336       1.12  wrstuden }
    337       1.12  wrstuden 
    338       1.12  wrstuden int
    339      1.138  christos genfs_noislocked(void *v)
    340       1.12  wrstuden {
    341       1.53     enami 
    342       1.12  wrstuden 	return (0);
    343        1.8   thorpej }
    344        1.8   thorpej 
    345        1.8   thorpej /*
    346      1.142      yamt  * Local lease check.
    347        1.8   thorpej  */
    348        1.8   thorpej int
    349       1.53     enami genfs_lease_check(void *v)
    350        1.8   thorpej {
    351        1.8   thorpej 
    352        1.8   thorpej 	return (0);
    353       1.34       chs }
    354       1.34       chs 
    355       1.34       chs int
    356      1.138  christos genfs_mmap(void *v)
    357       1.34       chs {
    358       1.53     enami 
    359       1.53     enami 	return (0);
    360       1.21       chs }
    361       1.21       chs 
    362       1.37       chs void
    363       1.98      yamt genfs_node_init(struct vnode *vp, const struct genfs_ops *ops)
    364       1.37       chs {
    365       1.37       chs 	struct genfs_node *gp = VTOG(vp);
    366       1.37       chs 
    367      1.146        ad 	rw_init(&gp->g_glock);
    368       1.37       chs 	gp->g_op = ops;
    369       1.37       chs }
    370       1.37       chs 
    371       1.37       chs void
    372      1.147        ad genfs_node_destroy(struct vnode *vp)
    373      1.147        ad {
    374      1.147        ad 	struct genfs_node *gp = VTOG(vp);
    375      1.147        ad 
    376      1.147        ad 	rw_destroy(&gp->g_glock);
    377      1.147        ad }
    378      1.147        ad 
    379      1.147        ad void
    380      1.138  christos genfs_size(struct vnode *vp, off_t size, off_t *eobp, int flags)
    381       1.21       chs {
    382       1.21       chs 	int bsize;
    383       1.21       chs 
    384       1.37       chs 	bsize = 1 << vp->v_mount->mnt_fs_bshift;
    385       1.37       chs 	*eobp = (size + bsize - 1) & ~(bsize - 1);
    386       1.43       chs }
    387       1.43       chs 
    388       1.66  jdolecek static void
    389       1.66  jdolecek filt_genfsdetach(struct knote *kn)
    390       1.66  jdolecek {
    391       1.66  jdolecek 	struct vnode *vp = (struct vnode *)kn->kn_hook;
    392       1.66  jdolecek 
    393       1.66  jdolecek 	/* XXXLUKEM lock the struct? */
    394       1.66  jdolecek 	SLIST_REMOVE(&vp->v_klist, kn, knote, kn_selnext);
    395       1.66  jdolecek }
    396       1.66  jdolecek 
    397       1.66  jdolecek static int
    398       1.66  jdolecek filt_genfsread(struct knote *kn, long hint)
    399       1.66  jdolecek {
    400       1.66  jdolecek 	struct vnode *vp = (struct vnode *)kn->kn_hook;
    401       1.66  jdolecek 
    402       1.66  jdolecek 	/*
    403       1.66  jdolecek 	 * filesystem is gone, so set the EOF flag and schedule
    404       1.66  jdolecek 	 * the knote for deletion.
    405       1.66  jdolecek 	 */
    406       1.66  jdolecek 	if (hint == NOTE_REVOKE) {
    407       1.66  jdolecek 		kn->kn_flags |= (EV_EOF | EV_ONESHOT);
    408       1.66  jdolecek 		return (1);
    409       1.66  jdolecek 	}
    410       1.66  jdolecek 
    411       1.66  jdolecek 	/* XXXLUKEM lock the struct? */
    412       1.66  jdolecek 	kn->kn_data = vp->v_size - kn->kn_fp->f_offset;
    413       1.66  jdolecek         return (kn->kn_data != 0);
    414       1.66  jdolecek }
    415       1.66  jdolecek 
    416       1.66  jdolecek static int
    417       1.66  jdolecek filt_genfsvnode(struct knote *kn, long hint)
    418       1.66  jdolecek {
    419       1.66  jdolecek 
    420       1.66  jdolecek 	if (kn->kn_sfflags & hint)
    421       1.66  jdolecek 		kn->kn_fflags |= hint;
    422       1.66  jdolecek 	if (hint == NOTE_REVOKE) {
    423       1.66  jdolecek 		kn->kn_flags |= EV_EOF;
    424       1.66  jdolecek 		return (1);
    425       1.66  jdolecek 	}
    426       1.66  jdolecek 	return (kn->kn_fflags != 0);
    427       1.66  jdolecek }
    428       1.66  jdolecek 
    429       1.96     perry static const struct filterops genfsread_filtops =
    430       1.66  jdolecek 	{ 1, NULL, filt_genfsdetach, filt_genfsread };
    431       1.96     perry static const struct filterops genfsvnode_filtops =
    432       1.66  jdolecek 	{ 1, NULL, filt_genfsdetach, filt_genfsvnode };
    433       1.66  jdolecek 
    434       1.66  jdolecek int
    435       1.66  jdolecek genfs_kqfilter(void *v)
    436       1.66  jdolecek {
    437       1.66  jdolecek 	struct vop_kqfilter_args /* {
    438       1.66  jdolecek 		struct vnode	*a_vp;
    439       1.66  jdolecek 		struct knote	*a_kn;
    440       1.66  jdolecek 	} */ *ap = v;
    441       1.66  jdolecek 	struct vnode *vp;
    442       1.66  jdolecek 	struct knote *kn;
    443       1.66  jdolecek 
    444       1.66  jdolecek 	vp = ap->a_vp;
    445       1.66  jdolecek 	kn = ap->a_kn;
    446       1.66  jdolecek 	switch (kn->kn_filter) {
    447       1.66  jdolecek 	case EVFILT_READ:
    448       1.66  jdolecek 		kn->kn_fop = &genfsread_filtops;
    449       1.66  jdolecek 		break;
    450       1.66  jdolecek 	case EVFILT_VNODE:
    451       1.66  jdolecek 		kn->kn_fop = &genfsvnode_filtops;
    452       1.66  jdolecek 		break;
    453       1.66  jdolecek 	default:
    454  1.158.6.2        ad 		return (EINVAL);
    455       1.66  jdolecek 	}
    456       1.66  jdolecek 
    457       1.66  jdolecek 	kn->kn_hook = vp;
    458       1.66  jdolecek 
    459       1.66  jdolecek 	/* XXXLUKEM lock the struct? */
    460       1.66  jdolecek 	SLIST_INSERT_HEAD(&vp->v_klist, kn, kn_selnext);
    461       1.66  jdolecek 
    462       1.66  jdolecek 	return (0);
    463        1.1   mycroft }
    464      1.136      yamt 
    465      1.136      yamt void
    466      1.136      yamt genfs_node_wrlock(struct vnode *vp)
    467      1.136      yamt {
    468      1.136      yamt 	struct genfs_node *gp = VTOG(vp);
    469      1.136      yamt 
    470      1.146        ad 	rw_enter(&gp->g_glock, RW_WRITER);
    471      1.136      yamt }
    472      1.136      yamt 
    473      1.136      yamt void
    474      1.136      yamt genfs_node_rdlock(struct vnode *vp)
    475      1.136      yamt {
    476      1.136      yamt 	struct genfs_node *gp = VTOG(vp);
    477      1.136      yamt 
    478      1.146        ad 	rw_enter(&gp->g_glock, RW_READER);
    479      1.136      yamt }
    480      1.136      yamt 
    481      1.136      yamt void
    482      1.136      yamt genfs_node_unlock(struct vnode *vp)
    483      1.136      yamt {
    484      1.136      yamt 	struct genfs_node *gp = VTOG(vp);
    485      1.136      yamt 
    486      1.146        ad 	rw_exit(&gp->g_glock);
    487      1.136      yamt }
    488