diff options
author | dfr <dfr@FreeBSD.org> | 2008-04-01 16:07:01 +0000 |
---|---|---|
committer | dfr <dfr@FreeBSD.org> | 2008-04-01 16:07:01 +0000 |
commit | 60db59bdb1a7859559d4e0d0d64243a9fdf89b25 (patch) | |
tree | 71e618f70857419059fd68a9229c7451e6419835 /sys/kern/kern_lockf.c | |
parent | b6386e8a8accdb775fe70bf2065cc0367003cfbb (diff) | |
download | FreeBSD-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.c | 15 |
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) { |