summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_lockf.c
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>1999-07-04 14:43:01 +0000
committerbde <bde@FreeBSD.org>1999-07-04 14:43:01 +0000
commit6b32f98934ea4ac96b2953cf3bb665bd55d509e7 (patch)
treec053b6f3fc63c9e87e6c4d560fdf01261f03dd64 /sys/kern/kern_lockf.c
parente643ff4664a9e2bc05242c6b194ce361c8bc4e14 (diff)
downloadFreeBSD-src-6b32f98934ea4ac96b2953cf3bb665bd55d509e7.zip
FreeBSD-src-6b32f98934ea4ac96b2953cf3bb665bd55d509e7.tar.gz
Fixed corruption of the "blocked" list in lf_setlock() when tsleep()
returns 0 after ptrace() attach and/or detach doesn't quite quite deliver a signal. Perhaps the process shouldn't be woken in this case, but avoiding the problem is easy. PR: 12247 Fixed a couple of places where mechanical fixing of compiler warnings caused misspelling of NOLOCKF as NULL.
Diffstat (limited to 'sys/kern/kern_lockf.c')
-rw-r--r--sys/kern/kern_lockf.c37
1 files changed, 20 insertions, 17 deletions
diff --git a/sys/kern/kern_lockf.c b/sys/kern/kern_lockf.c
index 4655f6a..21f38e2 100644
--- a/sys/kern/kern_lockf.c
+++ b/sys/kern/kern_lockf.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)ufs_lockf.c 8.3 (Berkeley) 1/6/94
- * $Id: kern_lockf.c,v 1.21 1999/01/27 21:49:56 dillon Exp $
+ * $Id: kern_lockf.c,v 1.22 1999/05/08 22:46:46 dt Exp $
*/
#include "opt_debug_lockf.h"
@@ -272,20 +272,22 @@ lf_setlock(lock)
lf_printlist("lf_setlock", block);
}
#endif /* LOCKF_DEBUG */
- if ((error = tsleep((caddr_t)lock, priority, lockstr, 0))) {
- /*
- * We may have been awakened by a signal (in
- * which case we must remove ourselves from the
- * blocked list) and/or by another process
- * releasing a lock (in which case we have already
- * been removed from the blocked list and our
- * lf_next field set to NOLOCKF).
- */
- if (lock->lf_next)
- TAILQ_REMOVE(&lock->lf_next->lf_blkhd, lock,
- lf_block);
- free(lock, M_LOCKF);
- return (error);
+ error = tsleep((caddr_t)lock, priority, lockstr, 0);
+ /*
+ * We may have been awakened by a signal and/or by a
+ * debugger continuing us (in which cases we must remove
+ * ourselves from the blocked list) and/or by another
+ * process releasing a lock (in which case we have
+ * already been removed from the blocked list and our
+ * lf_next field set to NOLOCKF).
+ */
+ if (lock->lf_next) {
+ TAILQ_REMOVE(&lock->lf_next->lf_blkhd, lock, lf_block);
+ lock->lf_next = NOLOCKF;
+ }
+ if (error) {
+ free(lock, M_LOCKF);
+ return (error);
}
}
/*
@@ -360,7 +362,8 @@ lf_setlock(lock)
overlap->lf_type == F_WRLCK) {
lf_wakelock(overlap);
} else {
- while ((ltmp = overlap->lf_blkhd.tqh_first) != NULL) {
+ while ((ltmp = overlap->lf_blkhd.tqh_first) !=
+ NOLOCKF) {
TAILQ_REMOVE(&overlap->lf_blkhd, ltmp,
lf_block);
TAILQ_INSERT_TAIL(&lock->lf_blkhd,
@@ -718,7 +721,7 @@ lf_wakelock(listhead)
{
register struct lockf *wakelock;
- while ((wakelock = listhead->lf_blkhd.tqh_first) != NULL) {
+ while ((wakelock = listhead->lf_blkhd.tqh_first) != NOLOCKF) {
TAILQ_REMOVE(&listhead->lf_blkhd, wakelock, lf_block);
wakelock->lf_next = NOLOCKF;
#ifdef LOCKF_DEBUG
OpenPOWER on IntegriCloud