diff options
author | dg <dg@FreeBSD.org> | 1995-07-17 06:26:07 +0000 |
---|---|---|
committer | dg <dg@FreeBSD.org> | 1995-07-17 06:26:07 +0000 |
commit | 8114a421df73c488312fca17568e3d15a6536745 (patch) | |
tree | 4909183dea0a69efee4030e4ecfe6bd23a97dea3 | |
parent | 01b1cf2502e22e9c8f9edd1d353c3d94e8c8ff24 (diff) | |
download | FreeBSD-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.c | 19 |
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; |