* This code constitutes the buffer memory from either anonymous system * memory (in the case of non-VMIO operations) or from an associated * VM object (in the case of VMIO operations). This code is able to * resize a buffer up or down. * * Note that this code is tricky, and has many complications to resolve * deadlock or inconsistent data situations. Tread lightly!!! * There are B_CACHE
| 4274 | * B_CACHE for the non-VMIO case. |
| 4275 | */ |
| 4276 | int |
| 4277 | allocbuf(struct buf *bp, int size) |
| 4278 | { |
| 4279 | int newbsize; |
| 4280 | |
| 4281 | if (bp->b_bcount == size) |
| 4282 | return (1); |
| 4283 | |
| 4284 | if (bp->b_kvasize != 0 && bp->b_kvasize < size) |
| 4285 | panic("allocbuf: buffer too small"); |
| 4286 | |
| 4287 | newbsize = roundup2(size, DEV_BSIZE); |
| 4288 | if ((bp->b_flags & B_VMIO) == 0) { |
| 4289 | if ((bp->b_flags & B_MALLOC) == 0) |
| 4290 | newbsize = round_page(newbsize); |
| 4291 | /* |
| 4292 | * Just get anonymous memory from the kernel. Don't |
| 4293 | * mess with B_CACHE. |
| 4294 | */ |
| 4295 | if (newbsize < bp->b_bufsize) |
| 4296 | vfs_nonvmio_truncate(bp, newbsize); |
| 4297 | else if (newbsize > bp->b_bufsize) |
| 4298 | vfs_nonvmio_extend(bp, newbsize); |
| 4299 | } else { |
| 4300 | int desiredpages; |
| 4301 | |
| 4302 | desiredpages = (size == 0) ? 0 : |
| 4303 | num_pages((bp->b_offset & PAGE_MASK) + newbsize); |
| 4304 | |
| 4305 | if (bp->b_flags & B_MALLOC) |
| 4306 | panic("allocbuf: VMIO buffer can't be malloced"); |
| 4307 | /* |
| 4308 | * Set B_CACHE initially if buffer is 0 length or will become |
| 4309 | * 0-length. |
| 4310 | */ |
| 4311 | if (size == 0 || bp->b_bufsize == 0) |
| 4312 | bp->b_flags |= B_CACHE; |
| 4313 | |
| 4314 | if (newbsize < bp->b_bufsize) |
| 4315 | vfs_vmio_truncate(bp, desiredpages); |
| 4316 | /* XXX This looks as if it should be newbsize > b_bufsize */ |
| 4317 | else if (size > bp->b_bcount) |
| 4318 | vfs_vmio_extend(bp, desiredpages, size); |
| 4319 | bufspace_adjust(bp, newbsize); |
| 4320 | } |
| 4321 | bp->b_bcount = size; /* requested buffer size. */ |
| 4322 | return (1); |
| 4323 | } |
| 4324 | |
| 4325 | extern int inflight_transient_maps; |
| 4326 |
no test coverage detected