Home | History | Annotate | Line # | Download | only in genfs
genfs_vnops.c revision 1.150.2.15
      1  1.150.2.15        ad /*	$NetBSD: genfs_vnops.c,v 1.150.2.15 2007/10/23 20:17:15 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.150.2.15        ad __KERNEL_RCSID(0, "$NetBSD: genfs_vnops.c,v 1.150.2.15 2007/10/23 20:17:15 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.150.2.14        ad 	struct vnode *vp, *vq, **vpp;
    223  1.150.2.14        ad 	enum vtype type;
    224  1.150.2.14        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.150.2.14        ad 	mutex_enter(&vp->v_interlock);
    233  1.150.2.14        ad 	if ((vp->v_iflag & VI_CLEAN) != 0) {
    234   1.150.2.1        ad 		mutex_exit(&vp->v_interlock);
    235  1.150.2.14        ad 		return (0);
    236  1.150.2.14        ad 	} else {
    237  1.150.2.14        ad 		dev = vp->v_rdev;
    238  1.150.2.14        ad 		type = vp->v_type;
    239  1.150.2.14        ad 		mutex_exit(&vp->v_interlock);
    240  1.150.2.14        ad 	}
    241  1.150.2.14        ad 
    242  1.150.2.14        ad 	if (type != VBLK && type != VCHR)
    243  1.150.2.14        ad 		return (0);
    244  1.150.2.14        ad 
    245  1.150.2.14        ad 	vpp = &speclisth[SPECHASH(dev)];
    246  1.150.2.14        ad 	mutex_enter(&spechash_lock);
    247  1.150.2.14        ad 	for (vq = *vpp; vq != NULL;) {
    248  1.150.2.14        ad 		if (vq->v_rdev != dev || vq->v_type != type) {
    249  1.150.2.14        ad 			vq = vq->v_specnext;
    250  1.150.2.14        ad 			continue;
    251         1.6      fvdl 		}
    252  1.150.2.14        ad 		mutex_enter(&vq->v_interlock);
    253  1.150.2.14        ad 		mutex_exit(&spechash_lock);
    254  1.150.2.14        ad 		vq->v_usecount++;
    255  1.150.2.14        ad 		vclean(vq, DOCLOSE);
    256  1.150.2.14        ad 		vrelel(vq, 1, 0);
    257  1.150.2.14        ad 		mutex_enter(&spechash_lock);
    258  1.150.2.14        ad 		vq = *vpp;
    259         1.6      fvdl 	}
    260  1.150.2.14        ad 	mutex_exit(&spechash_lock);
    261  1.150.2.14        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.150.2.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.66  jdolecek 		return (1);
    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