summaryrefslogtreecommitdiffstats
path: root/sys/fs
diff options
context:
space:
mode:
authortrasz <trasz@FreeBSD.org>2014-11-07 15:47:22 +0000
committertrasz <trasz@FreeBSD.org>2014-11-07 15:47:22 +0000
commita6df93e354d8150ab4b055289fbea5eccb9a8cc7 (patch)
treeeeda22c29be31e9e4aaef094124aa9b9c4b3d11b /sys/fs
parentf72fde1ec0f21680f8aea663d9c35f9df8d5bbd4 (diff)
downloadFreeBSD-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.h2
-rw-r--r--sys/fs/autofs/autofs_vfsops.c6
-rw-r--r--sys/fs/autofs/autofs_vnops.c17
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, &amp->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);
OpenPOWER on IntegriCloud