diff options
author | trasz <trasz@FreeBSD.org> | 2014-11-07 15:47:22 +0000 |
---|---|---|
committer | trasz <trasz@FreeBSD.org> | 2014-11-07 15:47:22 +0000 |
commit | a6df93e354d8150ab4b055289fbea5eccb9a8cc7 (patch) | |
tree | eeda22c29be31e9e4aaef094124aa9b9c4b3d11b /sys/fs | |
parent | f72fde1ec0f21680f8aea663d9c35f9df8d5bbd4 (diff) | |
download | FreeBSD-src-a6df93e354d8150ab4b055289fbea5eccb9a8cc7.zip FreeBSD-src-a6df93e354d8150ab4b055289fbea5eccb9a8cc7.tar.gz |
MFC r272512:
Make autofs use shared vnode locks.
Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'sys/fs')
-rw-r--r-- | sys/fs/autofs/autofs.h | 2 | ||||
-rw-r--r-- | sys/fs/autofs/autofs_vfsops.c | 6 | ||||
-rw-r--r-- | sys/fs/autofs/autofs_vnops.c | 17 |
3 files changed, 16 insertions, 9 deletions
diff --git a/sys/fs/autofs/autofs.h b/sys/fs/autofs/autofs.h index 0713307..dc33eef 100644 --- a/sys/fs/autofs/autofs.h +++ b/sys/fs/autofs/autofs.h @@ -138,6 +138,6 @@ int autofs_node_find(struct autofs_node *parent, const char *name, int namelen, struct autofs_node **anpp); void autofs_node_delete(struct autofs_node *anp); int autofs_node_vn(struct autofs_node *anp, struct mount *mp, - struct vnode **vpp); + int flags, struct vnode **vpp); #endif /* !AUTOFS_H */ diff --git a/sys/fs/autofs/autofs_vfsops.c b/sys/fs/autofs/autofs_vfsops.c index 21a49d9..13a5a89 100644 --- a/sys/fs/autofs/autofs_vfsops.c +++ b/sys/fs/autofs/autofs_vfsops.c @@ -88,6 +88,10 @@ autofs_mount(struct mount *mp) vfs_getnewfsid(mp); + MNT_ILOCK(mp); + mp->mnt_kern_flag |= MNTK_LOOKUP_SHARED; + MNT_IUNLOCK(mp); + AUTOFS_XLOCK(amp); error = autofs_node_new(NULL, amp, ".", -1, &->am_root); if (error != 0) { @@ -177,7 +181,7 @@ autofs_root(struct mount *mp, int flags, struct vnode **vpp) amp = VFSTOAUTOFS(mp); - error = autofs_node_vn(amp->am_root, mp, vpp); + error = autofs_node_vn(amp->am_root, mp, flags, vpp); return (error); } diff --git a/sys/fs/autofs/autofs_vnops.c b/sys/fs/autofs/autofs_vnops.c index 53490b3..72d6bff 100644 --- a/sys/fs/autofs/autofs_vnops.c +++ b/sys/fs/autofs/autofs_vnops.c @@ -198,12 +198,12 @@ mounted: } static int -autofs_vget_callback(struct mount *mp, void *arg, int lkflags __unused, +autofs_vget_callback(struct mount *mp, void *arg, int flags, struct vnode **vpp) { - return (autofs_node_vn(arg, mp, vpp)); + return (autofs_node_vn(arg, mp, flags, vpp)); } static int @@ -233,7 +233,7 @@ autofs_lookup(struct vop_lookup_args *ap) * use vn_vget_ino_gen() which takes care of all that. */ error = vn_vget_ino_gen(dvp, autofs_vget_callback, - anp->an_parent, 0, vpp); + anp->an_parent, cnp->cn_lkflags, vpp); if (error != 0) { AUTOFS_WARN("vn_vget_ino_gen() failed with error %d", error); @@ -294,7 +294,7 @@ autofs_lookup(struct vop_lookup_args *ap) */ AUTOFS_SUNLOCK(amp); - error = autofs_node_vn(child, mp, vpp); + error = autofs_node_vn(child, mp, cnp->cn_lkflags, vpp); if (error != 0) { if ((cnp->cn_flags & ISLASTCN) && cnp->cn_nameiop == CREATE) return (EJUSTRETURN); @@ -334,7 +334,7 @@ autofs_mkdir(struct vop_mkdir_args *ap) } AUTOFS_XUNLOCK(amp); - error = autofs_node_vn(child, vp->v_mount, ap->a_vpp); + error = autofs_node_vn(child, vp->v_mount, LK_EXCLUSIVE, ap->a_vpp); return (error); } @@ -581,7 +581,8 @@ autofs_node_delete(struct autofs_node *anp) } int -autofs_node_vn(struct autofs_node *anp, struct mount *mp, struct vnode **vpp) +autofs_node_vn(struct autofs_node *anp, struct mount *mp, int flags, + struct vnode **vpp) { struct vnode *vp; int error; @@ -592,7 +593,7 @@ autofs_node_vn(struct autofs_node *anp, struct mount *mp, struct vnode **vpp) vp = anp->an_vnode; if (vp != NULL) { - error = vget(vp, LK_EXCLUSIVE | LK_RETRY, curthread); + error = vget(vp, flags | LK_RETRY, curthread); if (error != 0) { AUTOFS_WARN("vget failed with error %d", error); sx_xunlock(&anp->an_vnode_lock); @@ -632,6 +633,8 @@ autofs_node_vn(struct autofs_node *anp, struct mount *mp, struct vnode **vpp) vp->v_vflag |= VV_ROOT; vp->v_data = anp; + VN_LOCK_ASHARE(vp); + error = insmntque(vp, mp); if (error != 0) { AUTOFS_WARN("insmntque() failed with error %d", error); |