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.
*/