Hi, The following diff is a bit large. it could be splitted for easy review, but I tought having the full view would be good too.
It moves the current vnode lock mecanism, implemented inside FS specific struct, to `struct vnode`. I used `vop_generic_lock`, `vop_generic_unlock` and `vop_generic_islocked` functions for this generic implementation (see kern/vfs_default.c for implementation and kern/vfs_subr.c for initialisation). As usual, `struct vops` controls which functions are called when using VOP wrappers. It makes possible to move FS to generic implementation slowly. FS implementation part is mostly about removing the current code (rrw_init, lock/unlock functions, vop_{lock,unlock} setting). As part of the diff, ntfs and mfs are using the generic vnode lock (set vop_{lock,unlock,islocked} in vops). There is one tricky part is vget() FS implementation for special devices. The aliases mecanism is a bit tricky as it replaces the v_data from one vnode to another. With new code, the lock isn't moved anymore (as it is part of vnode, and is not inside v_data) and it should be reacquired. It makes me to unlock old vnode, and lock the new vnode. I think this part might be wrong and/or racy (but I am unsure the current version would be right), but we don't have a way to properly "move" the lock (WITNESS is tracking pointers, so just copying the data doesn't work with WITNESS). Comments would be welcome. -- Sebastien Marie diff 0def1dfbf35c717f500a4280ac4e33a8e31279e2 767ac1f1e81fa96b73dd2a7955e4eb5bbce3e538 blob - 5082a7ad64a7c73a250023dd9e833b7ff91893b2 blob + 368b0a5b1252ba6b57401f28a8e0aad585828abb --- sys/isofs/cd9660/cd9660_node.h +++ sys/isofs/cd9660/cd9660_node.h @@ -65,7 +65,6 @@ struct iso_node { doff_t i_diroff; /* offset in dir, where we found last entry */ doff_t i_offset; /* offset of free space in directory */ cdino_t i_ino; /* inode number of found directory */ - struct rrwlock i_lock; /* node lock */ doff_t iso_extent; /* extent of file */ doff_t i_size; @@ -110,11 +109,8 @@ int cd9660_reclaim(void *); int cd9660_link(void *); int cd9660_symlink(void *); int cd9660_bmap(void *); -int cd9660_lock(void *); -int cd9660_unlock(void *); int cd9660_strategy(void *); int cd9660_print(void *); -int cd9660_islocked(void *); int cd9660_pathconf(void *); int cd9660_bufatoff(struct iso_node *, off_t, char **, struct buf **); blob - 0bcfbd0270d8276b3569ade303fdd9b6d90a9505 blob + 8ca74c6685f468f3856f82fad2993065488bdaea --- sys/isofs/cd9660/cd9660_vfsops.c +++ sys/isofs/cd9660/cd9660_vfsops.c @@ -715,7 +715,6 @@ retry: return (error); } ip = malloc(sizeof(*ip), M_ISOFSNODE, M_WAITOK | M_ZERO); - rrw_init_flags(&ip->i_lock, "isoinode", RWL_DUPOK | RWL_IS_VNODE); vp->v_data = ip; ip->i_vnode = vp; ip->i_dev = dev; @@ -867,10 +866,10 @@ retry: if ((nvp = checkalias(vp, ip->inode.iso_rdev, mp)) != NULL) { /* * Discard unneeded vnode, but save its iso_node. - * Note that the lock is carried over in the iso_node */ nvp->v_data = vp->v_data; vp->v_data = NULL; + VOP_UNLOCK(vp); /* unlock before changing v_op */ vp->v_op = &spec_vops; vrele(vp); vgone(vp); @@ -879,6 +878,7 @@ retry: */ vp = nvp; ip->i_vnode = vp; + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); } break; case VLNK: blob - ed1b5f39c7122cdcb37c133fae35d243a2995d90 blob + e9f20249ac4825abe12d206ac25d52c98af7ad29 --- sys/isofs/cd9660/cd9660_vnops.c +++ sys/isofs/cd9660/cd9660_vnops.c @@ -684,31 +684,6 @@ cd9660_symlink(void *v) } /* - * Lock an inode. - */ -int -cd9660_lock(void *v) -{ - struct vop_lock_args *ap = v; - struct vnode *vp = ap->a_vp; - - return rrw_enter(&VTOI(vp)->i_lock, ap->a_flags & LK_RWFLAGS); -} - -/* - * Unlock an inode. - */ -int -cd9660_unlock(void *v) -{ - struct vop_unlock_args *ap = v; - struct vnode *vp = ap->a_vp; - - rrw_exit(&VTOI(vp)->i_lock); - return 0; -} - -/* * Calculate the logical to physical mapping if not done already, * then call the device strategy routine. */ @@ -762,17 +737,6 @@ cd9660_print(void *v) } /* - * Check for a locked inode. - */ -int -cd9660_islocked(void *v) -{ - struct vop_islocked_args *ap = v; - - return rrw_status(&VTOI(ap->a_vp)->i_lock); -} - -/* * Return POSIX pathconf information applicable to cd9660 filesystems. */ int @@ -840,12 +804,12 @@ const struct vops cd9660_vops = { .vop_abortop = vop_generic_abortop, .vop_inactive = cd9660_inactive, .vop_reclaim = cd9660_reclaim, - .vop_lock = cd9660_lock, - .vop_unlock = cd9660_unlock, + .vop_lock = vop_generic_lock, + .vop_unlock = vop_generic_unlock, + .vop_islocked = vop_generic_islocked, .vop_bmap = cd9660_bmap, .vop_strategy = cd9660_strategy, .vop_print = cd9660_print, - .vop_islocked = cd9660_islocked, .vop_pathconf = cd9660_pathconf, .vop_advlock = eopnotsupp, .vop_bwrite = vop_generic_bwrite, @@ -858,10 +822,10 @@ const struct vops cd9660_specvops = { .vop_setattr = cd9660_setattr, .vop_inactive = cd9660_inactive, .vop_reclaim = cd9660_reclaim, - .vop_lock = cd9660_lock, - .vop_unlock = cd9660_unlock, + .vop_lock = vop_generic_lock, + .vop_unlock = vop_generic_unlock, + .vop_islocked = vop_generic_islocked, .vop_print = cd9660_print, - .vop_islocked = cd9660_islocked, /* XXX: Keep in sync with spec_vops. */ .vop_lookup = vop_generic_lookup, @@ -899,10 +863,10 @@ const struct vops cd9660_fifovops = { .vop_setattr = cd9660_setattr, .vop_inactive = cd9660_inactive, .vop_reclaim = cd9660_reclaim, - .vop_lock = cd9660_lock, - .vop_unlock = cd9660_unlock, + .vop_lock = vop_generic_lock, + .vop_unlock = vop_generic_unlock, + .vop_islocked = vop_generic_islocked, .vop_print = cd9660_print, - .vop_islocked = cd9660_islocked, .vop_bwrite = vop_generic_bwrite, /* XXX: Keep in sync with fifo_vops. */ blob - f6dc2adc294d87489255e47bbb0fc5c102032dc6 blob + 501ccbf6296fa60eff237a582ea02824213d3190 --- sys/isofs/udf/udf.h +++ sys/isofs/udf/udf.h @@ -41,7 +41,6 @@ struct unode { struct vnode *u_vnode; struct vnode *u_devvp; struct umount *u_ump; - struct rrwlock u_lock; dev_t u_dev; udfino_t u_ino; union { blob - fb5166d14d69b04c65c75dcb18ad90dcf157e1c5 blob + e558f74531d6ce0491e73537666957ed0f750fae --- sys/isofs/udf/udf_extern.h +++ sys/isofs/udf/udf_extern.h @@ -48,10 +48,7 @@ int udf_bmap(void *v); int udf_lookup(void *v); int udf_inactive(void *v); int udf_reclaim(void *v); -int udf_lock(void *v); -int udf_unlock(void *v); int udf_pathconf(void *); -int udf_islocked(void *v); int udf_print(void *v); int udf_transname(char *, char *, int, struct umount *); int udf_readatoffset(struct unode *, int *, off_t, struct buf **, blob - 2ba23e9686edc0b075e33e73407dcc3e226b4cdb blob + 3dde700cb00809c78853c1d4dc98f89534153235 --- sys/isofs/udf/udf_vfsops.c +++ sys/isofs/udf/udf_vfsops.c @@ -638,8 +638,6 @@ udf_vget(struct mount *mp, ino_t ino, struct vnode **v vp->v_data = up; vref(ump->um_devvp); - rrw_init_flags(&up->u_lock, "unode", RWL_DUPOK | RWL_IS_VNODE); - /* * udf_hashins() will lock the vnode for us. */ @@ -680,10 +678,10 @@ udf_vget(struct mount *mp, ino_t ino, struct vnode **v printf("found a vnode alias\n"); /* * Discard unneeded vnode, but save its udf_node. - * Note that the lock is carried over in the udf_node */ nvp->v_data = vp->v_data; vp->v_data = NULL; + VOP_UNLOCK(vp); /* unlock before changing v_op */ vp->v_op = &spec_vops; vrele(vp); vgone(vp); @@ -692,6 +690,7 @@ udf_vget(struct mount *mp, ino_t ino, struct vnode **v */ vp = nvp; ump->um_devvp = vp; + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); } *vpp = vp; blob - 181fb6219339ac9d539993054a617346a3798aa2 blob + 9eaa09630c15c03f0dd2f72e17d4b50e738d3848 --- sys/isofs/udf/udf_vnops.c +++ sys/isofs/udf/udf_vnops.c @@ -72,10 +72,10 @@ const struct vops udf_vops = { .vop_inactive = udf_inactive, .vop_reclaim = udf_reclaim, .vop_strategy = udf_strategy, - .vop_lock = udf_lock, - .vop_unlock = udf_unlock, + .vop_lock = vop_generic_lock, + .vop_unlock = vop_generic_unlock, + .vop_islocked = vop_generic_islocked, .vop_pathconf = udf_pathconf, - .vop_islocked = udf_islocked, .vop_print = udf_print }; @@ -893,33 +893,6 @@ udf_strategy(void *v) } int -udf_lock(void *v) -{ - struct vop_lock_args *ap = v; - struct vnode *vp = ap->a_vp; - - return rrw_enter(&VTOU(vp)->u_lock, ap->a_flags & LK_RWFLAGS); -} - -int -udf_unlock(void *v) -{ - struct vop_unlock_args *ap = v; - struct vnode *vp = ap->a_vp; - - rrw_exit(&VTOU(vp)->u_lock); - return 0; -} - -int -udf_islocked(void *v) -{ - struct vop_islocked_args *ap = v; - - return rrw_status(&VTOU(ap->a_vp)->u_lock); -} - -int udf_print(void *v) { struct vop_print_args *ap = v; 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 - 5b30b1544aa4802e8b42a5fe2d1a115d35ffcaee blob + 96559811ede1b1761d7c3705731eb9fd84f6a1ce --- sys/miscfs/fuse/fuse_vfsops.c +++ sys/miscfs/fuse/fuse_vfsops.c @@ -290,8 +290,6 @@ retry: } ip = malloc(sizeof(*ip), M_FUSEFS, M_WAITOK | M_ZERO); - rrw_init_flags(&ip->ufs_ino.i_lock, "fuseinode", - RWL_DUPOK | RWL_IS_VNODE); nvp->v_data = ip; ip->ufs_ino.i_vnode = nvp; ip->ufs_ino.i_dev = fmp->dev; blob - e95ceb6c7031b008524303297df22e9b96610c71 blob + a9d78bfff8ca4082520812cabc4c9e506ecca59c --- sys/miscfs/fuse/fuse_vnops.c +++ sys/miscfs/fuse/fuse_vnops.c @@ -63,9 +63,6 @@ int fusefs_rename(void *); int fusefs_mkdir(void *); int fusefs_rmdir(void *); int fusefs_strategy(void *); -int fusefs_lock(void *); -int fusefs_unlock(void *); -int fusefs_islocked(void *); int fusefs_advlock(void *); int fusefs_fsync(void *); @@ -102,12 +99,12 @@ const struct vops fusefs_vops = { .vop_abortop = vop_generic_abortop, .vop_inactive = fusefs_inactive, .vop_reclaim = fusefs_reclaim, - .vop_lock = fusefs_lock, - .vop_unlock = fusefs_unlock, + .vop_lock = vop_generic_lock, + .vop_unlock = vop_generic_unlock, + .vop_islocked = vop_generic_islocked, .vop_bmap = vop_generic_bmap, .vop_strategy = fusefs_strategy, .vop_print = fusefs_print, - .vop_islocked = fusefs_islocked, .vop_pathconf = spec_pathconf, .vop_advlock = fusefs_advlock, .vop_bwrite = NULL, @@ -1551,33 +1548,6 @@ fusefs_strategy(void *v) } int -fusefs_lock(void *v) -{ - struct vop_lock_args *ap = v; - struct vnode *vp = ap->a_vp; - - return rrw_enter(&VTOI(vp)->ufs_ino.i_lock, ap->a_flags & LK_RWFLAGS); -} - -int -fusefs_unlock(void *v) -{ - struct vop_unlock_args *ap = v; - struct vnode *vp = ap->a_vp; - - rrw_exit(&VTOI(vp)->ufs_ino.i_lock); - return 0; -} - -int -fusefs_islocked(void *v) -{ - struct vop_islocked_args *ap = v; - - return rrw_status(&VTOI(ap->a_vp)->ufs_ino.i_lock); -} - -int fusefs_advlock(void *v) { struct vop_advlock_args *ap = v; blob - 3a3f629df52510a701060d5138e3385e6407fa9f blob + e6b695c1c3567e9b0b2125b563e89cbce3521f53 --- sys/msdosfs/denode.h +++ sys/msdosfs/denode.h @@ -149,7 +149,6 @@ struct denode { long de_refcnt; /* reference count */ struct msdosfsmount *de_pmp; /* addr of our mount struct */ struct lockf_state *de_lockf; /* byte level lock list */ - struct rrwlock de_lock; /* denode lock */ u_char de_Name[11]; /* name, from DOS directory entry */ u_char de_Attributes; /* attributes, from directory entry */ u_char de_CTimeHundredth; /* creation time, 1/100th of a sec */ @@ -283,12 +282,9 @@ int msdosfs_readdir(void *); int msdosfs_readlink(void *); int msdosfs_inactive(void *); int msdosfs_reclaim(void *); -int msdosfs_lock(void *); -int msdosfs_unlock(void *); int msdosfs_bmap(void *); int msdosfs_strategy(void *); int msdosfs_print(void *); -int msdosfs_islocked(void *); int msdosfs_advlock(void *); int msdosfs_pathconf(void *); blob - 466ac47a0bc759dd1a8d100969fd644ffba2a91d blob + 3b13678956eaae40870aca4456589fb279b33d31 --- sys/msdosfs/msdosfs_denode.c +++ sys/msdosfs/msdosfs_denode.c @@ -231,7 +231,6 @@ retry: return (error); } ldep = malloc(sizeof(*ldep), M_MSDOSFSNODE, M_WAITOK | M_ZERO); - rrw_init_flags(&ldep->de_lock, "denode", RWL_DUPOK | RWL_IS_VNODE); nvp->v_data = ldep; ldep->de_vnode = nvp; ldep->de_flag = 0; blob - 142db65b7196fca4e849863cbd4de45421691c8c blob + 0bc76ced84294f559a464d6d625983da21518d56 --- sys/msdosfs/msdosfs_vnops.c +++ sys/msdosfs/msdosfs_vnops.c @@ -1680,33 +1680,6 @@ msdosfs_readlink(void *v) return (EINVAL); } -int -msdosfs_lock(void *v) -{ - struct vop_lock_args *ap = v; - struct vnode *vp = ap->a_vp; - - return rrw_enter(&VTODE(vp)->de_lock, ap->a_flags & LK_RWFLAGS); -} - -int -msdosfs_unlock(void *v) -{ - struct vop_unlock_args *ap = v; - struct vnode *vp = ap->a_vp; - - rrw_exit(&VTODE(vp)->de_lock); - return 0; -} - -int -msdosfs_islocked(void *v) -{ - struct vop_islocked_args *ap = v; - - return rrw_status(&VTODE(ap->a_vp)->de_lock); -} - /* * vp - address of vnode file the file * bn - which cluster we are interested in mapping to a filesystem block number @@ -1924,12 +1897,12 @@ const struct vops msdosfs_vops = { .vop_abortop = vop_generic_abortop, .vop_inactive = msdosfs_inactive, .vop_reclaim = msdosfs_reclaim, - .vop_lock = msdosfs_lock, - .vop_unlock = msdosfs_unlock, + .vop_lock = vop_generic_lock, + .vop_unlock = vop_generic_unlock, + .vop_islocked = vop_generic_islocked, .vop_bmap = msdosfs_bmap, .vop_strategy = msdosfs_strategy, .vop_print = msdosfs_print, - .vop_islocked = msdosfs_islocked, .vop_pathconf = msdosfs_pathconf, .vop_advlock = msdosfs_advlock, .vop_bwrite = vop_generic_bwrite, blob - eb97355ddb4b4701f270cb7348310b7947245d32 blob + 7d1f3e0446e1548f0cafa3f7be37f0e76d2a3b00 --- sys/nfs/nfs_node.c +++ sys/nfs/nfs_node.c @@ -133,7 +133,6 @@ loop: } vp = nvp; - rrw_init_flags(&np->n_lock, "nfsnode", RWL_DUPOK | RWL_IS_VNODE); vp->v_data = np; /* we now have an nfsnode on this vnode */ vp->v_flag &= ~VLARVAL; blob - 2c6a0cc1c3f9bc6f929c99a99ec87b97559d96da blob + 04f946c928932db98cd503cbf06e4152912e2b49 --- sys/nfs/nfs_subs.c +++ sys/nfs/nfs_subs.c @@ -1004,12 +1004,11 @@ nfs_loadattrcache(struct vnode **vpp, struct mbuf **md if (nvp) { /* * Discard unneeded vnode, but save its nfsnode. - * Since the nfsnode does not have a lock, its - * vnode lock has to be carried over. */ nvp->v_data = vp->v_data; vp->v_data = NULL; + VOP_UNLOCK(vp); /* unlock before changing v_op */ vp->v_op = &spec_vops; vrele(vp); vgone(vp); @@ -1018,6 +1017,7 @@ nfs_loadattrcache(struct vnode **vpp, struct mbuf **md */ np->n_vnode = nvp; *vpp = vp = nvp; + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); } } np->n_mtime = mtime; blob - 69fe85b41cdf3a220a0ac6578efd3904fd0d54fd blob + c8ea1ba911b554350df2fd5157328a745faa2dd2 --- sys/nfs/nfs_vnops.c +++ sys/nfs/nfs_vnops.c @@ -88,9 +88,7 @@ int nfs_flush(struct vnode *, struct ucred *, int, str int nfs_fsync(void *); int nfs_getattr(void *); int nfs_getreq(struct nfsrv_descript *, struct nfsd *, int); -int nfs_islocked(void *); int nfs_link(void *); -int nfs_lock(void *); int nfs_lookitup(struct vnode *, char *, int, struct ucred *, struct proc *, struct nfsnode **); int nfs_lookup(void *); @@ -122,7 +120,6 @@ int nfs_sillyrename(struct vnode *, struct vnode *, struct componentname *); int nfs_strategy(void *); int nfs_symlink(void *); -int nfs_unlock(void *); void nfs_cache_enter(struct vnode *, struct vnode *, struct componentname *); @@ -164,12 +161,12 @@ const struct vops nfs_vops = { .vop_abortop = vop_generic_abortop, .vop_inactive = nfs_inactive, .vop_reclaim = nfs_reclaim, - .vop_lock = nfs_lock, - .vop_unlock = nfs_unlock, + .vop_lock = vop_generic_lock, + .vop_unlock = vop_generic_unlock, + .vop_islocked = vop_generic_islocked, .vop_bmap = nfs_bmap, .vop_strategy = nfs_strategy, .vop_print = nfs_print, - .vop_islocked = nfs_islocked, .vop_pathconf = nfs_pathconf, .vop_advlock = nfs_advlock, .vop_bwrite = nfs_bwrite @@ -186,10 +183,10 @@ const struct vops nfs_specvops = { .vop_fsync = nfs_fsync, .vop_inactive = nfs_inactive, .vop_reclaim = nfs_reclaim, - .vop_lock = nfs_lock, - .vop_unlock = nfs_unlock, + .vop_lock = vop_generic_lock, + .vop_unlock = vop_generic_unlock, + .vop_islocked = vop_generic_islocked, .vop_print = nfs_print, - .vop_islocked = nfs_islocked, /* XXX: Keep in sync with spec_vops. */ .vop_lookup = vop_generic_lookup, @@ -227,10 +224,10 @@ const struct vops nfs_fifovops = { .vop_fsync = nfs_fsync, .vop_inactive = nfs_inactive, .vop_reclaim = nfsfifo_reclaim, - .vop_lock = nfs_lock, - .vop_unlock = nfs_unlock, + .vop_lock = vop_generic_lock, + .vop_unlock = vop_generic_unlock, + .vop_islocked = vop_generic_islocked, .vop_print = nfs_print, - .vop_islocked = nfs_islocked, .vop_bwrite = vop_generic_bwrite, /* XXX: Keep in sync with fifo_vops. */ @@ -1037,42 +1034,6 @@ nfs_readlink(void *v) } /* - * Lock an inode. - */ -int -nfs_lock(void *v) -{ - struct vop_lock_args *ap = v; - struct vnode *vp = ap->a_vp; - - return rrw_enter(&VTONFS(vp)->n_lock, ap->a_flags & LK_RWFLAGS); -} - -/* - * Unlock an inode. - */ -int -nfs_unlock(void *v) -{ - struct vop_unlock_args *ap = v; - struct vnode *vp = ap->a_vp; - - rrw_exit(&VTONFS(vp)->n_lock); - return 0; -} - -/* - * Check for a locked inode. - */ -int -nfs_islocked(void *v) -{ - struct vop_islocked_args *ap = v; - - return rrw_status(&VTONFS(ap->a_vp)->n_lock); -} - -/* * Do a readlink rpc. * Called by nfs_doio() from below the buffer cache. */ blob - c8a635dfbd1ed879997f01a2605ffe2fdaae734f blob + 73d63de69670cc6a19222c8bf038f9a6b14720d8 --- sys/nfs/nfsnode.h +++ sys/nfs/nfsnode.h @@ -79,7 +79,6 @@ struct nfsnode { nfsfh_t *n_fhp; /* NFS File Handle */ struct vnode *n_vnode; /* associated vnode */ struct lockf_state *n_lockf; /* Locking record of file */ - struct rrwlock n_lock; /* NFSnode lock */ int n_error; /* Save write error value */ union { struct timespec nf_atim; /* Special file times */ blob - d239112e991fe0f365d124a35ce52765fe959114 blob + a654936b5ace84f68a6cf1243545929ad33123a9 --- sys/ntfs/ntfs_vnops.c +++ sys/ntfs/ntfs_vnops.c @@ -668,9 +668,9 @@ const struct vops ntfs_vops = { .vop_reclaim = ntfs_reclaim, .vop_print = ntfs_print, .vop_pathconf = ntfs_pathconf, - .vop_lock = nullop, - .vop_unlock = nullop, - .vop_islocked = nullop, + .vop_lock = vop_generic_lock, + .vop_unlock = vop_generic_unlock, + .vop_islocked = vop_generic_islocked, .vop_lookup = ntfs_lookup, .vop_access = ntfs_access, .vop_close = ntfs_close, 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 *); blob - 36a20a29267d5b05ea90be1b4b1d04602f29f68b blob + 6b06cfc613a00b2bec486d53e7be989419d7d422 --- sys/tmpfs/tmpfs.h +++ sys/tmpfs/tmpfs.h @@ -94,7 +94,6 @@ typedef struct tmpfs_node { * no vnode has been allocated or it has been reclaimed). */ struct rwlock tn_nlock; /* node lock */ - struct rrwlock tn_vlock; /* vnode lock */ struct vnode * tn_vnode; /* Directory entry. Only a hint, since hard link can have multiple. */ blob - dbb92492c53a54519a767cc3f262e370d4761c4b blob + 4caa73899bbda3a09e11dba88b8ac9cf9e64b993 --- sys/tmpfs/tmpfs_fifoops.c +++ sys/tmpfs/tmpfs_fifoops.c @@ -79,12 +79,12 @@ const struct vops tmpfs_fifovops = { .vop_abortop = vop_generic_badop, .vop_inactive = tmpfs_inactive, .vop_reclaim = tmpfs_reclaim, - .vop_lock = tmpfs_lock, - .vop_unlock = tmpfs_unlock, + .vop_lock = vop_generic_lock, + .vop_unlock = vop_generic_unlock, + .vop_islocked = vop_generic_islocked, .vop_bmap = vop_generic_bmap, .vop_strategy = vop_generic_badop, .vop_print = tmpfs_print, - .vop_islocked = tmpfs_islocked, .vop_pathconf = fifo_pathconf, .vop_advlock = fifo_advlock, .vop_bwrite = tmpfs_bwrite, blob - 1c3069d9cd6ab90fca213f07048a54b581ed5583 blob + f0155b5253fde5990cea57df7a7b88f307326154 --- sys/tmpfs/tmpfs_specops.c +++ sys/tmpfs/tmpfs_specops.c @@ -60,10 +60,10 @@ const struct vops tmpfs_specvops = { .vop_fsync = spec_fsync, .vop_inactive = tmpfs_inactive, .vop_reclaim = tmpfs_reclaim, - .vop_lock = tmpfs_lock, - .vop_unlock = tmpfs_unlock, + .vop_lock = vop_generic_lock, + .vop_unlock = vop_generic_unlock, + .vop_islocked = vop_generic_islocked, .vop_print = tmpfs_print, - .vop_islocked = tmpfs_islocked, /* keep in sync with spec_vops */ .vop_lookup = vop_generic_lookup, blob - 757c90c0908e5373273ab9cb70e1a665651952db blob + 8aeaabbb7afd1094fedad47f76d54563aab80323 --- sys/tmpfs/tmpfs_subr.c +++ sys/tmpfs/tmpfs_subr.c @@ -313,7 +313,6 @@ again: return error; } - rrw_init_flags(&node->tn_vlock, "tnode", RWL_DUPOK | RWL_IS_VNODE); vp->v_type = node->tn_type; /* Type-specific initialization. */ @@ -324,11 +323,13 @@ again: if ((nvp = checkalias(vp, node->tn_spec.tn_dev.tn_rdev, mp))) { nvp->v_data = vp->v_data; vp->v_data = NULL; + VOP_UNLOCK(vp); /* unlock before changing v_op */ vp->v_op = &spec_vops; vrele(vp); vgone(vp); vp = nvp; node->tn_vnode = vp; + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); } break; case VDIR: blob - daeb1344e51b1b17aa174da38f2a769bb8dbbc10 blob + 6637c253574d0bc5af3d6c64da6f49ddaab2716f --- sys/tmpfs/tmpfs_vnops.c +++ sys/tmpfs/tmpfs_vnops.c @@ -85,12 +85,12 @@ const struct vops tmpfs_vops = { .vop_abortop = vop_generic_abortop, .vop_inactive = tmpfs_inactive, .vop_reclaim = tmpfs_reclaim, - .vop_lock = tmpfs_lock, - .vop_unlock = tmpfs_unlock, + .vop_lock = vop_generic_lock, + .vop_unlock = vop_generic_unlock, + .vop_islocked = vop_generic_islocked, .vop_bmap = vop_generic_bmap, .vop_strategy = tmpfs_strategy, .vop_print = tmpfs_print, - .vop_islocked = tmpfs_islocked, .vop_pathconf = tmpfs_pathconf, .vop_advlock = tmpfs_advlock, .vop_bwrite = tmpfs_bwrite, @@ -1194,34 +1194,6 @@ tmpfs_ioctl(void *v) return ENOTTY; } -int -tmpfs_lock(void *v) -{ - struct vop_lock_args *ap = v; - tmpfs_node_t *tnp = VP_TO_TMPFS_NODE(ap->a_vp); - - return rrw_enter(&tnp->tn_vlock, ap->a_flags & LK_RWFLAGS); -} - -int -tmpfs_unlock(void *v) -{ - struct vop_unlock_args *ap = v; - tmpfs_node_t *tnp = VP_TO_TMPFS_NODE(ap->a_vp); - - rrw_exit(&tnp->tn_vlock); - return 0; -} - -int -tmpfs_islocked(void *v) -{ - struct vop_islocked_args *ap = v; - tmpfs_node_t *tnp = VP_TO_TMPFS_NODE(ap->a_vp); - - return rrw_status(&tnp->tn_vlock); -} - /* * tmpfs_rename: rename routine, the hairiest system call, with the * insane API. blob - 9ef283d4da4c40a4e9b134ea0f8f50994a32684f blob + 90ca893399c1b0e6348dd208a09e5574cca6f196 --- sys/tmpfs/tmpfs_vnops.h +++ sys/tmpfs/tmpfs_vnops.h @@ -67,9 +67,6 @@ int tmpfs_readdir (void *); int tmpfs_readlink (void *); int tmpfs_inactive (void *); int tmpfs_reclaim (void *); -int tmpfs_lock (void *); -int tmpfs_unlock (void *); -int tmpfs_islocked (void *); int tmpfs_strategy (void *); int tmpfs_print (void *); int tmpfs_pathconf (void *); blob - dc20e6494c1702ed4fecea0af6b580f7c61da64f blob + 3e29437c2e22dc7311b863120d40cb06e18a91fe --- sys/ufs/ext2fs/ext2fs_subr.c +++ sys/ufs/ext2fs/ext2fs_subr.c @@ -163,18 +163,18 @@ ext2fs_vinit(struct mount *mp, struct vnode **vpp) nvp = checkalias(vp, letoh32(ip->i_e2din->e2di_rdev), mp); if (nvp != NULL) { /* - * Discard unneeded vnode, but save its inode. Note - * that the lock is carried over in the inode to the - * replacement vnode. + * Discard unneeded vnode, but save its inode. */ nvp->v_data = vp->v_data; vp->v_data = NULL; + VOP_UNLOCK(vp); /* unlock before changing v_op */ vp->v_op = &spec_vops; vrele(vp); vgone(vp); /* Reinitialize aliased vnode. */ vp = nvp; ip->i_vnode = vp; + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); } break; blob - 371ca53f096ecc2150cdab5831043f14e2a57319 blob + 5850ff10c0830692b300a0b460cbd8eff4962fab --- sys/ufs/ext2fs/ext2fs_vfsops.c +++ sys/ufs/ext2fs/ext2fs_vfsops.c @@ -854,7 +854,6 @@ ext2fs_vget(struct mount *mp, ino_t ino, struct vnode } ip = pool_get(&ext2fs_inode_pool, PR_WAITOK|PR_ZERO); - rrw_init_flags(&ip->i_lock, "inode", RWL_DUPOK | RWL_IS_VNODE); vp->v_data = ip; ip->i_vnode = vp; ip->i_ump = ump; blob - 2fd55f2dc631e0dbf54ce69ed8baaed2c489a0fa blob + 273042d16bafb38adb37cbcc10f06051db4a79ff --- sys/ufs/ext2fs/ext2fs_vnops.c +++ sys/ufs/ext2fs/ext2fs_vnops.c @@ -1293,12 +1293,12 @@ const struct vops ext2fs_vops = { .vop_abortop = vop_generic_abortop, .vop_inactive = ext2fs_inactive, .vop_reclaim = ext2fs_reclaim, - .vop_lock = ufs_lock, - .vop_unlock = ufs_unlock, + .vop_lock = vop_generic_lock, + .vop_unlock = vop_generic_unlock, + .vop_islocked = vop_generic_islocked, .vop_bmap = ext2fs_bmap, .vop_strategy = ufs_strategy, .vop_print = ufs_print, - .vop_islocked = ufs_islocked, .vop_pathconf = ext2fs_pathconf, .vop_advlock = ext2fs_advlock, .vop_bwrite = vop_generic_bwrite, @@ -1314,10 +1314,10 @@ const struct vops ext2fs_specvops = { .vop_fsync = ext2fs_fsync, .vop_inactive = ext2fs_inactive, .vop_reclaim = ext2fs_reclaim, - .vop_lock = ufs_lock, - .vop_unlock = ufs_unlock, + .vop_lock = vop_generic_lock, + .vop_unlock = vop_generic_unlock, + .vop_islocked = vop_generic_islocked, .vop_print = ufs_print, - .vop_islocked = ufs_islocked, /* XXX: Keep in sync with spec_vops. */ .vop_lookup = vop_generic_lookup, @@ -1355,10 +1355,10 @@ const struct vops ext2fs_fifovops = { .vop_fsync = ext2fs_fsync, .vop_inactive = ext2fs_inactive, .vop_reclaim = ext2fsfifo_reclaim, - .vop_lock = ufs_lock, - .vop_unlock = ufs_unlock, + .vop_lock = vop_generic_lock, + .vop_unlock = vop_generic_unlock, + .vop_islocked = vop_generic_islocked, .vop_print = ufs_print, - .vop_islocked = ufs_islocked, .vop_bwrite = vop_generic_bwrite, /* XXX: Keep in sync with fifo_vops */ blob - abd8a784c08566d550c28028270ce9a193e564c7 blob + 05b0a47c8c2dfb6ff8f01f4c6c59a9c89854f6ea --- sys/ufs/ffs/ffs_subr.c +++ sys/ufs/ffs/ffs_subr.c @@ -266,11 +266,10 @@ ffs_vinit(struct mount *mntp, struct vnode **vpp) if ((nvp = checkalias(vp, DIP(ip, rdev), mntp)) != NULL) { /* * Discard unneeded vnode, but save its inode. - * Note that the lock is carried over in the inode - * to the replacement vnode. */ nvp->v_data = vp->v_data; vp->v_data = NULL; + VOP_UNLOCK(vp); /* unlock before changing v_op */ vp->v_op = &spec_vops; vrele(vp); vgone(vp); @@ -279,6 +278,7 @@ ffs_vinit(struct mount *mntp, struct vnode **vpp) */ vp = nvp; ip->i_vnode = vp; + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); } break; case VFIFO: blob - 8851ff395f2b92a688f65868aaf7f75a0fc70903 blob + 0c97e88d588ccb5bb666afb97bf006d267bf3ecc --- sys/ufs/ffs/ffs_vfsops.c +++ sys/ufs/ffs/ffs_vfsops.c @@ -1325,7 +1325,6 @@ retry: } ip = pool_get(&ffs_ino_pool, PR_WAITOK|PR_ZERO); - rrw_init_flags(&ip->i_lock, "inode", RWL_DUPOK | RWL_IS_VNODE); ip->i_ump = ump; vref(ip->i_devvp); vp->v_data = ip; blob - 4f488043d9d587886a9a8580fc677f6d00050395 blob + 8d6a8a42ffcb0c976d2c52590643b73210a72b08 --- sys/ufs/ffs/ffs_vnops.c +++ sys/ufs/ffs/ffs_vnops.c @@ -84,12 +84,12 @@ const struct vops ffs_vops = { .vop_abortop = vop_generic_abortop, .vop_inactive = ufs_inactive, .vop_reclaim = ffs_reclaim, - .vop_lock = ufs_lock, - .vop_unlock = ufs_unlock, + .vop_lock = vop_generic_lock, + .vop_unlock = vop_generic_unlock, + .vop_islocked = vop_generic_islocked, .vop_bmap = ufs_bmap, .vop_strategy = ufs_strategy, .vop_print = ufs_print, - .vop_islocked = ufs_islocked, .vop_pathconf = ufs_pathconf, .vop_advlock = ufs_advlock, .vop_bwrite = vop_generic_bwrite @@ -105,10 +105,10 @@ const struct vops ffs_specvops = { .vop_fsync = ffs_fsync, .vop_inactive = ufs_inactive, .vop_reclaim = ffs_reclaim, - .vop_lock = ufs_lock, - .vop_unlock = ufs_unlock, + .vop_lock = vop_generic_lock, + .vop_unlock = vop_generic_unlock, + .vop_islocked = vop_generic_islocked, .vop_print = ufs_print, - .vop_islocked = ufs_islocked, /* XXX: Keep in sync with spec_vops */ .vop_lookup = vop_generic_lookup, @@ -146,10 +146,10 @@ const struct vops ffs_fifovops = { .vop_fsync = ffs_fsync, .vop_inactive = ufs_inactive, .vop_reclaim = ffsfifo_reclaim, - .vop_lock = ufs_lock, - .vop_unlock = ufs_unlock, + .vop_lock = vop_generic_lock, + .vop_unlock = vop_generic_unlock, + .vop_islocked = vop_generic_islocked, .vop_print = ufs_print, - .vop_islocked = ufs_islocked, .vop_bwrite = vop_generic_bwrite, /* XXX: Keep in sync with fifo_vops */ blob - eba90ab9131715c7d9a1d726932ce97286df9477 blob + 3e254adc042eade839b7d426ab5d0590b45f690c --- sys/ufs/mfs/mfs_vnops.c +++ sys/ufs/mfs/mfs_vnops.c @@ -74,9 +74,9 @@ const struct vops mfs_vops = { .vop_abortop = vop_generic_badop, .vop_inactive = mfs_inactive, .vop_reclaim = mfs_reclaim, - .vop_lock = nullop, - .vop_unlock = nullop, - .vop_islocked = nullop, + .vop_lock = vop_generic_lock, + .vop_unlock = vop_generic_unlock, + .vop_islocked = vop_generic_islocked, .vop_bmap = vop_generic_bmap, .vop_strategy = mfs_strategy, .vop_print = mfs_print, blob - 36661588139da4fe09325dc2e8072397093e3c33 blob + 62b9cac118d30cbf52c54d4a046f033723693c15 --- sys/ufs/ufs/inode.h +++ sys/ufs/ufs/inode.h @@ -86,7 +86,6 @@ struct inode { struct dquot *i_dquot[MAXQUOTAS]; /* Dquot structures. */ u_quad_t i_modrev; /* Revision level for NFS lease. */ struct lockf_state *i_lockf; /* Byte-level lock state. */ - struct rrwlock i_lock;/* Inode lock */ /* * Side effects; used during directory lookup. blob - 967d6ab1e45a55c043d28c79be8ddf4c9e00c8b7 blob + 2df437434547f3d37fd9ce5e3d206a11e8831739 --- sys/ufs/ufs/ufs_extern.h +++ sys/ufs/ufs/ufs_extern.h @@ -61,9 +61,7 @@ int ufs_create(void *); int ufs_getattr(void *); int ufs_inactive(void *); int ufs_ioctl(void *); -int ufs_islocked(void *); int ufs_link(void *); -int ufs_lock(void *); int ufs_lookup(void *); int ufs_mkdir(void *); int ufs_mknod(void *); @@ -81,7 +79,6 @@ int ufs_kqfilter(void *); int ufs_setattr(void *); int ufs_strategy(void *); int ufs_symlink(void *); -int ufs_unlock(void *); int ufsspec_close(void *); int ufsspec_read(void *); int ufsspec_write(void *); blob - 0652945fee6c71bf0d692080fd576627f457f0b1 blob + e0c665c1d20555c38aaf7f9446e07a7f748acdff --- sys/ufs/ufs/ufs_vnops.c +++ sys/ufs/ufs/ufs_vnops.c @@ -1534,42 +1534,6 @@ ufs_readlink(void *v) } /* - * Lock an inode. If its already locked, set the WANT bit and sleep. - */ -int -ufs_lock(void *v) -{ - struct vop_lock_args *ap = v; - struct vnode *vp = ap->a_vp; - - return rrw_enter(&VTOI(vp)->i_lock, ap->a_flags & LK_RWFLAGS); -} - -/* - * Unlock an inode. If WANT bit is on, wakeup. - */ -int -ufs_unlock(void *v) -{ - struct vop_unlock_args *ap = v; - struct vnode *vp = ap->a_vp; - - rrw_exit(&VTOI(vp)->i_lock); - return 0; -} - -/* - * Check for a locked inode. - */ -int -ufs_islocked(void *v) -{ - struct vop_islocked_args *ap = v; - - return rrw_status(&VTOI(ap->a_vp)->i_lock); -} - -/* * Calculate the logical to physical mapping if not done already, * then call the device strategy routine. */