mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-29 21:26:51 +00:00
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.
This commit is contained in:
parent
6d0cab6541
commit
1168ab0815
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=48556
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue