summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>2008-05-09 10:34:23 +0000
committerdfr <dfr@FreeBSD.org>2008-05-09 10:34:23 +0000
commitb95b50cdbb661f41d9cd4f45e1b3c3500258af64 (patch)
tree7744821a2eca12d81614672f81fff1d68c27812e
parenta902aa50c3687ffecbf55ea4959c4d215550af0c (diff)
downloadFreeBSD-src-b95b50cdbb661f41d9cd4f45e1b3c3500258af64.zip
FreeBSD-src-b95b50cdbb661f41d9cd4f45e1b3c3500258af64.tar.gz
When blocking on an F_FLOCK style lock request which is upgrading a
shared lock to exclusive, drop the shared lock before deadlock detection. MFC after: 2 days
-rw-r--r--sys/kern/kern_lockf.c23
1 files changed, 12 insertions, 11 deletions
diff --git a/sys/kern/kern_lockf.c b/sys/kern/kern_lockf.c
index 045a3ba..8cab502 100644
--- a/sys/kern/kern_lockf.c
+++ b/sys/kern/kern_lockf.c
@@ -1370,6 +1370,18 @@ lf_setlock(struct lockf *state, struct lockf_entry *lock, struct vnode *vp,
}
/*
+ * For flock type locks, we must first remove
+ * any shared locks that we hold before we sleep
+ * waiting for an exclusive lock.
+ */
+ if ((lock->lf_flags & F_FLOCK) &&
+ lock->lf_type == F_WRLCK) {
+ lock->lf_type = F_UNLCK;
+ lf_activate_lock(state, lock);
+ lock->lf_type = F_WRLCK;
+ }
+
+ /*
* We are blocked. Create edges to each blocking lock,
* checking for deadlock using the owner graph. For
* simplicity, we run deadlock detection for all
@@ -1389,17 +1401,6 @@ lf_setlock(struct lockf *state, struct lockf_entry *lock, struct vnode *vp,
}
/*
- * For flock type locks, we must first remove
- * any shared locks that we hold before we sleep
- * waiting for an exclusive lock.
- */
- if ((lock->lf_flags & F_FLOCK) &&
- lock->lf_type == F_WRLCK) {
- lock->lf_type = F_UNLCK;
- lf_activate_lock(state, lock);
- lock->lf_type = F_WRLCK;
- }
- /*
* We have added edges to everything that blocks
* us. Sleep until they all go away.
*/
OpenPOWER on IntegriCloud