* Cleanup after a clustered read or write. * This is complicated by the fact that any of the buffers might have * extra memory (if there were no empty buffer headers at allocbuf time) * that we will need to shift around. */
| 563 | * that we will need to shift around. |
| 564 | */ |
| 565 | static void |
| 566 | cluster_callback(struct buf *bp) |
| 567 | { |
| 568 | struct buf *nbp, *tbp; |
| 569 | int error = 0; |
| 570 | |
| 571 | /* |
| 572 | * Must propagate errors to all the components. |
| 573 | */ |
| 574 | if (bp->b_ioflags & BIO_ERROR) |
| 575 | error = bp->b_error; |
| 576 | |
| 577 | if (buf_mapped(bp)) { |
| 578 | pmap_qremove(trunc_page((vm_offset_t) bp->b_data), |
| 579 | bp->b_npages); |
| 580 | } |
| 581 | /* |
| 582 | * Move memory from the large cluster buffer into the component |
| 583 | * buffers and mark IO as done on these. |
| 584 | */ |
| 585 | for (tbp = TAILQ_FIRST(&bp->b_cluster.cluster_head); |
| 586 | tbp; tbp = nbp) { |
| 587 | nbp = TAILQ_NEXT(&tbp->b_cluster, cluster_entry); |
| 588 | if (error) { |
| 589 | tbp->b_ioflags |= BIO_ERROR; |
| 590 | tbp->b_error = error; |
| 591 | } else { |
| 592 | tbp->b_dirtyoff = tbp->b_dirtyend = 0; |
| 593 | tbp->b_flags &= ~B_INVAL; |
| 594 | tbp->b_ioflags &= ~BIO_ERROR; |
| 595 | /* |
| 596 | * XXX the bdwrite()/bqrelse() issued during |
| 597 | * cluster building clears B_RELBUF (see bqrelse() |
| 598 | * comment). If direct I/O was specified, we have |
| 599 | * to restore it here to allow the buffer and VM |
| 600 | * to be freed. |
| 601 | */ |
| 602 | if (tbp->b_flags & B_DIRECT) |
| 603 | tbp->b_flags |= B_RELBUF; |
| 604 | } |
| 605 | bufdone(tbp); |
| 606 | } |
| 607 | pbrelvp(bp); |
| 608 | uma_zfree(cluster_pbuf_zone, bp); |
| 609 | } |
| 610 | |
| 611 | /* |
| 612 | * cluster_wbuild_wb: |
nothing calls this directly
no test coverage detected