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

Reply via email to