* brelse: * * Release a busy buffer and, if requested, free its resources. The * buffer will be stashed in the appropriate bufqueue[] allowing it * to be accessed later as a cache entity or reused for other purposes. */
| 2607 | * to be accessed later as a cache entity or reused for other purposes. |
| 2608 | */ |
| 2609 | void |
| 2610 | brelse(struct buf *bp) |
| 2611 | { |
| 2612 | struct mount *v_mnt; |
| 2613 | int qindex; |
| 2614 | |
| 2615 | /* |
| 2616 | * Many functions erroneously call brelse with a NULL bp under rare |
| 2617 | * error conditions. Simply return when called with a NULL bp. |
| 2618 | */ |
| 2619 | if (bp == NULL) |
| 2620 | return; |
| 2621 | CTR3(KTR_BUF, "brelse(%p) vp %p flags %X", |
| 2622 | bp, bp->b_vp, bp->b_flags); |
| 2623 | KASSERT(!(bp->b_flags & (B_CLUSTER|B_PAGING)), |
| 2624 | ("brelse: inappropriate B_PAGING or B_CLUSTER bp %p", bp)); |
| 2625 | KASSERT((bp->b_flags & B_VMIO) != 0 || (bp->b_flags & B_NOREUSE) == 0, |
| 2626 | ("brelse: non-VMIO buffer marked NOREUSE")); |
| 2627 | |
| 2628 | if (BUF_LOCKRECURSED(bp)) { |
| 2629 | /* |
| 2630 | * Do not process, in particular, do not handle the |
| 2631 | * B_INVAL/B_RELBUF and do not release to free list. |
| 2632 | */ |
| 2633 | BUF_UNLOCK(bp); |
| 2634 | return; |
| 2635 | } |
| 2636 | |
| 2637 | if (bp->b_flags & B_MANAGED) { |
| 2638 | bqrelse(bp); |
| 2639 | return; |
| 2640 | } |
| 2641 | |
| 2642 | if (LIST_EMPTY(&bp->b_dep)) { |
| 2643 | bp->b_flags &= ~B_IOSTARTED; |
| 2644 | } else { |
| 2645 | KASSERT((bp->b_flags & B_IOSTARTED) == 0, |
| 2646 | ("brelse: SU io not finished bp %p", bp)); |
| 2647 | } |
| 2648 | |
| 2649 | if ((bp->b_vflags & (BV_BKGRDINPROG | BV_BKGRDERR)) == BV_BKGRDERR) { |
| 2650 | BO_LOCK(bp->b_bufobj); |
| 2651 | bp->b_vflags &= ~BV_BKGRDERR; |
| 2652 | BO_UNLOCK(bp->b_bufobj); |
| 2653 | bdirty(bp); |
| 2654 | } |
| 2655 | |
| 2656 | if (bp->b_iocmd == BIO_WRITE && (bp->b_ioflags & BIO_ERROR) && |
| 2657 | (bp->b_flags & B_INVALONERR)) { |
| 2658 | /* |
| 2659 | * Forced invalidation of dirty buffer contents, to be used |
| 2660 | * after a failed write in the rare case that the loss of the |
| 2661 | * contents is acceptable. The buffer is invalidated and |
| 2662 | * freed. |
| 2663 | */ |
| 2664 | bp->b_flags |= B_INVAL | B_RELBUF | B_NOCACHE; |
| 2665 | bp->b_flags &= ~(B_ASYNC | B_CACHE); |
| 2666 | } |
no test coverage detected