summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordg <dg@FreeBSD.org>1995-07-17 06:26:07 +0000
committerdg <dg@FreeBSD.org>1995-07-17 06:26:07 +0000
commit8114a421df73c488312fca17568e3d15a6536745 (patch)
tree4909183dea0a69efee4030e4ecfe6bd23a97dea3
parent01b1cf2502e22e9c8f9edd1d353c3d94e8c8ff24 (diff)
downloadFreeBSD-src-8114a421df73c488312fca17568e3d15a6536745.zip
FreeBSD-src-8114a421df73c488312fca17568e3d15a6536745.tar.gz
Fixed "bufspace" calculation. It was lossy in some circumstances of the
buffer resizing and caused a "newbuf" deadlock. Reviewed by: John Dyson & David Greenman Submitted by: Peter Wemm
-rw-r--r--sys/kern/vfs_bio.c19
1 files changed, 5 insertions, 14 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index 6a7d27d..231cbed 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -18,7 +18,7 @@
* 5. Modifications may be freely made to this file if the above conditions
* are met.
*
- * $Id: vfs_bio.c,v 1.47 1995/06/28 12:00:54 davidg Exp $
+ * $Id: vfs_bio.c,v 1.48 1995/07/15 16:01:46 davidg Exp $
*/
/*
@@ -934,21 +934,16 @@ allocbuf(struct buf * bp, int size)
mbsize = ((size + DEV_BSIZE - 1) / DEV_BSIZE) * DEV_BSIZE;
newbsize = round_page(size);
- if (newbsize == bp->b_bufsize) {
- bp->b_bcount = size;
- return 1;
- } else if (newbsize < bp->b_bufsize) {
+ if (newbsize < bp->b_bufsize) {
vm_hold_free_pages(
bp,
(vm_offset_t) bp->b_data + newbsize,
(vm_offset_t) bp->b_data + bp->b_bufsize);
- bufspace -= (bp->b_bufsize - newbsize);
} else if (newbsize > bp->b_bufsize) {
vm_hold_load_pages(
bp,
(vm_offset_t) bp->b_data + bp->b_bufsize,
(vm_offset_t) bp->b_data + newbsize);
- bufspace += (newbsize - bp->b_bufsize);
}
} else {
vm_page_t m;
@@ -957,10 +952,7 @@ allocbuf(struct buf * bp, int size)
newbsize = ((size + DEV_BSIZE - 1) / DEV_BSIZE) * DEV_BSIZE;
desiredpages = round_page(newbsize) / PAGE_SIZE;
- if (newbsize == bp->b_bufsize) {
- bp->b_bcount = size;
- return 1;
- } else if (newbsize < bp->b_bufsize) {
+ if (newbsize < bp->b_bufsize) {
if (desiredpages < bp->b_npages) {
pmap_qremove((vm_offset_t) trunc_page(bp->b_data) +
desiredpages * PAGE_SIZE, (bp->b_npages - desiredpages));
@@ -985,9 +977,8 @@ allocbuf(struct buf * bp, int size)
bp->b_pages[i] = NULL;
}
bp->b_npages = desiredpages;
- bufspace -= (bp->b_bufsize - newbsize);
}
- } else {
+ } else if (newbsize > bp->b_bufsize) {
vm_object_t obj;
vm_offset_t tinc, off, toff, objoff;
int pageindex, curbpnpages;
@@ -1102,9 +1093,9 @@ allocbuf(struct buf * bp, int size)
pmap_qenter((vm_offset_t) bp->b_data, bp->b_pages, bp->b_npages);
bp->b_data += off % PAGE_SIZE;
}
- bufspace += (newbsize - bp->b_bufsize);
}
}
+ bufspace += (newbsize - bp->b_bufsize);
bp->b_bufsize = newbsize;
bp->b_bcount = size;
return 1;
OpenPOWER on IntegriCloud