summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_lockf.c
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>2008-04-01 16:07:01 +0000
committerdfr <dfr@FreeBSD.org>2008-04-01 16:07:01 +0000
commit60db59bdb1a7859559d4e0d0d64243a9fdf89b25 (patch)
tree71e618f70857419059fd68a9229c7451e6419835 /sys/kern/kern_lockf.c
parentb6386e8a8accdb775fe70bf2065cc0367003cfbb (diff)
downloadFreeBSD-src-60db59bdb1a7859559d4e0d0d64243a9fdf89b25.zip
FreeBSD-src-60db59bdb1a7859559d4e0d0d64243a9fdf89b25.tar.gz
Don't try to use an SX lock while holding the vnode interlock.
Sponsored by: Isilon Systems
Diffstat (limited to 'sys/kern/kern_lockf.c')
-rw-r--r--sys/kern/kern_lockf.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/sys/kern/kern_lockf.c b/sys/kern/kern_lockf.c
index 9ccee35..64805ed 100644
--- a/sys/kern/kern_lockf.c
+++ b/sys/kern/kern_lockf.c
@@ -584,6 +584,7 @@ lf_advlockasync(struct vop_advlockasync_args *ap, struct lockf **statep,
sx_init(&ls->ls_lock, "ls_lock");
LIST_INIT(&ls->ls_active);
LIST_INIT(&ls->ls_pending);
+ ls->ls_threads = 1;
sx_xlock(&lf_lock_states_lock);
LIST_INSERT_HEAD(&lf_lock_states, ls, ls_link);
@@ -595,19 +596,23 @@ lf_advlockasync(struct vop_advlockasync_args *ap, struct lockf **statep,
*/
VI_LOCK(vp);
if ((*statep) == NULL) {
- (*statep) = ls;
+ state = *statep = ls;
+ VI_UNLOCK(vp);
} else {
+ state = *statep;
+ state->ls_threads++;
+ VI_UNLOCK(vp);
+
sx_xlock(&lf_lock_states_lock);
LIST_REMOVE(ls, ls_link);
sx_xunlock(&lf_lock_states_lock);
sx_destroy(&ls->ls_lock);
free(ls, M_LOCKF);
}
+ } else {
+ state->ls_threads++;
+ VI_UNLOCK(vp);
}
- state = *statep;
- state->ls_threads++;
-
- VI_UNLOCK(vp);
sx_xlock(&state->ls_lock);
switch(ap->a_op) {
OpenPOWER on IntegriCloud