Below is the part of the full diff which is adding generic vnode lock inside struct vnode.
blob - 7df5a5757b90244ab361f0687bd2eabf3e7093c2 blob + 53fb67ace69ada6faf768a6e7b20a48e2b6e9740 --- sys/kern/vfs_default.c +++ sys/kern/vfs_default.c @@ -167,6 +167,34 @@ vop_generic_abortop(void *v) return (0); } +int +vop_generic_lock(void *v) +{ + struct vop_lock_args *ap = v; + struct vnode *vp = ap->a_vp; + + return rrw_enter(&vp->v_lock, ap->a_flags & LK_RWFLAGS); +} + +int +vop_generic_unlock(void *v) +{ + struct vop_unlock_args *ap = v; + struct vnode *vp = ap->a_vp; + + rrw_exit(&vp->v_lock); + return 0; +} + +int +vop_generic_islocked(void *v) +{ + struct vop_islocked_args *ap = v; + struct vnode *vp = ap->a_vp; + + return rrw_status(&vp->v_lock); +} + const struct filterops generic_filtops = { .f_flags = FILTEROP_ISFD, .f_attach = NULL, blob - 4861468362592c649c579e0f3a47d630a39d051e blob + 1f7409235f4696765c6b8b22e65d953b1d6e5100 --- sys/kern/vfs_subr.c +++ sys/kern/vfs_subr.c @@ -408,6 +408,7 @@ getnewvnode(enum vtagtype tag, struct mount *mp, const ((TAILQ_FIRST(listhd = &vnode_hold_list) == NULL) || toggle))) { splx(s); vp = pool_get(&vnode_pool, PR_WAITOK | PR_ZERO); + rrw_init_flags(&vp->v_lock, "vnode", RWL_DUPOK | RWL_IS_VNODE); vp->v_uvm = pool_get(&uvm_vnode_pool, PR_WAITOK | PR_ZERO); vp->v_uvm->u_vnode = vp; RBT_INIT(buf_rb_bufs, &vp->v_bufs_tree); @@ -463,6 +464,10 @@ getnewvnode(enum vtagtype tag, struct mount *mp, const vp->v_op = vops; insmntque(vp, mp); *vpp = vp; +#ifdef DIAGNOSTIC + if (rrw_status(&vp->v_lock) != 0) + panic("%s: free vnode %p isn't lock free", __func__, vp); +#endif vp->v_usecount = 1; vp->v_data = 0; return (0); blob - 490f3e367cf322eff38ac7a184b7ea49a7cef7fa blob + 3a9ff1f58d50e005ea9f87c974647d1f56fcb397 --- sys/sys/vnode.h +++ sys/sys/vnode.h @@ -102,6 +102,7 @@ struct vnode { u_int v_uvcount; /* unveil references */ u_int v_writecount; /* reference count of writers */ u_int v_lockcount; /* [V] # threads waiting on lock */ + struct rrwlock v_lock; /* generic vnode lock */ /* Flags that can be read/written in interrupts */ u_int v_bioflag; @@ -632,6 +633,9 @@ int vop_generic_bwrite(void *); int vop_generic_revoke(void *); int vop_generic_kqfilter(void *); int vop_generic_lookup(void *); +int vop_generic_lock(void *); +int vop_generic_unlock(void *); +int vop_generic_islocked(void *); /* vfs_vnops.c */ int vn_isunder(struct vnode *, struct vnode *, struct proc *);