summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorAlfred Perlstein <alfred@FreeBSD.org>1999-09-16 01:50:29 +0000
committerAlfred Perlstein <alfred@FreeBSD.org>1999-09-16 01:50:29 +0000
commitecb11b29b4a2b9b494b666faf327fd1c81553bae (patch)
tree3bca4b7f5b07a160d3f543e28883a183d74d0d08 /sys
parente786515e14b50b1814d548c513348a0f59926a17 (diff)
Notes
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/vfs_bio.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index 1dbb1b68fd1f..501febb833a2 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -1053,9 +1053,13 @@ trytofreespace:
* Certain layered filesystems can recursively re-enter the vfs_bio
* code, due to delayed writes. This helps keep the system from
* deadlocking.
+ * This hack to avoid premature panic is courtesy of alfred
+ * (alfred@freebsd.org)
*/
if (writerecursion > 0) {
if (writerecursion > 5) {
+ int loop = 0;
+norecurse:
bp = TAILQ_FIRST(&bufqueues[QUEUE_AGE]);
while (bp) {
if ((bp->b_flags & B_DELWRI) == 0)
@@ -1070,8 +1074,17 @@ trytofreespace:
bp = TAILQ_NEXT(bp, b_freelist);
}
}
- if (bp == NULL)
- panic("getnewbuf: cannot get buffer, infinite recursion failure");
+ if (bp == NULL) {
+ needsbuffer |= VFS_BIO_NEED_ANY;
+ if (tsleep(&needsbuffer,
+ (PRIBIO + 4) | slpflag,
+ "nbufhack", slptimeo+1))
+ return (NULL);
+ if (loop++ < 5)
+ goto norecurse;
+ else
+ goto start;
+ }
} else {
bremfree(bp);
bp->b_flags |= B_BUSY | B_AGE | B_ASYNC;