Make autofs(4) use shared lock for lookups, instead of exclusive one.

MFC after:	1 month
Sponsored by:	The FreeBSD Foundation
This commit is contained in:
trasz 2014-10-03 09:58:05 +00:00
parent 0edcf4b22f
commit cd1d9d476d
4 changed files with 25 additions and 22 deletions

View File

@ -297,9 +297,9 @@ autofs_cached(struct autofs_node *anp, const char *component, int componentlen)
* is necessary for wildcard indirect map keys to work.
*/
if (anp->an_parent == NULL && componentlen != 0) {
AUTOFS_LOCK(amp);
AUTOFS_SLOCK(amp);
error = autofs_node_find(anp, component, componentlen, NULL);
AUTOFS_UNLOCK(amp);
AUTOFS_SUNLOCK(amp);
if (error != 0)
return (false);
}

View File

@ -53,9 +53,12 @@ extern int autofs_mount_on_stat;
__func__, ## __VA_ARGS__); \
} while (0)
#define AUTOFS_LOCK(X) sx_xlock(&X->am_lock)
#define AUTOFS_UNLOCK(X) sx_xunlock(&X->am_lock)
#define AUTOFS_ASSERT_LOCKED(X) sx_assert(&X->am_lock, SA_XLOCKED)
#define AUTOFS_SLOCK(X) sx_slock(&X->am_lock)
#define AUTOFS_XLOCK(X) sx_xlock(&X->am_lock)
#define AUTOFS_SUNLOCK(X) sx_sunlock(&X->am_lock)
#define AUTOFS_XUNLOCK(X) sx_xunlock(&X->am_lock)
#define AUTOFS_ASSERT_LOCKED(X) sx_assert(&X->am_lock, SA_LOCKED)
#define AUTOFS_ASSERT_XLOCKED(X) sx_assert(&X->am_lock, SA_XLOCKED)
#define AUTOFS_ASSERT_UNLOCKED(X) sx_assert(&X->am_lock, SA_UNLOCKED)
struct autofs_node {

View File

@ -88,14 +88,14 @@ autofs_mount(struct mount *mp)
vfs_getnewfsid(mp);
AUTOFS_LOCK(amp);
AUTOFS_XLOCK(amp);
error = autofs_node_new(NULL, amp, ".", -1, &amp->am_root);
if (error != 0) {
AUTOFS_UNLOCK(amp);
AUTOFS_XUNLOCK(amp);
free(amp, M_AUTOFS);
return (error);
}
AUTOFS_UNLOCK(amp);
AUTOFS_XUNLOCK(amp);
vfs_mountedfrom(mp, from);
@ -146,7 +146,7 @@ autofs_unmount(struct mount *mp, int mntflags)
pause("autofs_umount", 1);
}
AUTOFS_LOCK(amp);
AUTOFS_XLOCK(amp);
/*
* Not terribly efficient, but at least not recursive.
@ -160,7 +160,7 @@ autofs_unmount(struct mount *mp, int mntflags)
autofs_node_delete(amp->am_root);
mp->mnt_data = NULL;
AUTOFS_UNLOCK(amp);
AUTOFS_XUNLOCK(amp);
sx_destroy(&amp->am_lock);

View File

@ -277,22 +277,22 @@ autofs_lookup(struct vop_lookup_args *ap)
}
}
AUTOFS_LOCK(amp);
AUTOFS_SLOCK(amp);
error = autofs_node_find(anp, cnp->cn_nameptr, cnp->cn_namelen, &child);
if (error != 0) {
if ((cnp->cn_flags & ISLASTCN) && cnp->cn_nameiop == CREATE) {
AUTOFS_UNLOCK(amp);
AUTOFS_SUNLOCK(amp);
return (EJUSTRETURN);
}
AUTOFS_UNLOCK(amp);
AUTOFS_SUNLOCK(amp);
return (ENOENT);
}
/*
* XXX: Dropping the node here is ok, because we never remove nodes.
*/
AUTOFS_UNLOCK(amp);
AUTOFS_SUNLOCK(amp);
error = autofs_node_vn(child, mp, vpp);
if (error != 0) {
@ -325,14 +325,14 @@ autofs_mkdir(struct vop_mkdir_args *ap)
if (autofs_ignore_thread(curthread) == false)
return (EPERM);
AUTOFS_LOCK(amp);
AUTOFS_XLOCK(amp);
error = autofs_node_new(anp, amp, ap->a_cnp->cn_nameptr,
ap->a_cnp->cn_namelen, &child);
if (error != 0) {
AUTOFS_UNLOCK(amp);
AUTOFS_XUNLOCK(amp);
return (error);
}
AUTOFS_UNLOCK(amp);
AUTOFS_XUNLOCK(amp);
error = autofs_node_vn(child, vp->v_mount, ap->a_vpp);
@ -427,7 +427,7 @@ autofs_readdir(struct vop_readdir_args *ap)
}
i = 2; /* Account for "." and "..". */
AUTOFS_LOCK(amp);
AUTOFS_SLOCK(amp);
TAILQ_FOREACH(child, &anp->an_children, an_next) {
if (resid < AUTOFS_DELEN) {
if (ap->a_eofflag != NULL)
@ -445,14 +445,14 @@ autofs_readdir(struct vop_readdir_args *ap)
error = autofs_readdir_one(uio, child->an_name,
child->an_fileno);
if (error != 0) {
AUTOFS_UNLOCK(amp);
AUTOFS_SUNLOCK(amp);
return (error);
}
offset += AUTOFS_DELEN;
resid -= AUTOFS_DELEN;
}
AUTOFS_UNLOCK(amp);
AUTOFS_SUNLOCK(amp);
return (0);
}
@ -505,7 +505,7 @@ autofs_node_new(struct autofs_node *parent, struct autofs_mount *amp,
struct autofs_node *anp;
if (parent != NULL)
AUTOFS_ASSERT_LOCKED(parent->an_mount);
AUTOFS_ASSERT_XLOCKED(parent->an_mount);
anp = uma_zalloc(autofs_node_zone, M_WAITOK | M_ZERO);
if (namelen >= 0)
@ -567,7 +567,7 @@ autofs_node_delete(struct autofs_node *anp)
{
struct autofs_node *parent;
AUTOFS_ASSERT_LOCKED(anp->an_mount);
AUTOFS_ASSERT_XLOCKED(anp->an_mount);
KASSERT(TAILQ_EMPTY(&anp->an_children), ("have children"));
callout_drain(&anp->an_callout);