* Release a buffer back to the appropriate queue but do not try to free * it. The buffer is expected to be used again soon. * * bqrelse() is used by bdwrite() to requeue a delayed write, and used by * biodone() to requeue an async I/O on completion. It is also used when * known good buffers need to be requeued but we think we may need the data * again soon. * * XXX we should be able to l
| 2816 | * XXX we should be able to leave the B_RELBUF hint set on completion. |
| 2817 | */ |
| 2818 | void |
| 2819 | bqrelse(struct buf *bp) |
| 2820 | { |
| 2821 | int qindex; |
| 2822 | |
| 2823 | CTR3(KTR_BUF, "bqrelse(%p) vp %p flags %X", bp, bp->b_vp, bp->b_flags); |
| 2824 | KASSERT(!(bp->b_flags & (B_CLUSTER|B_PAGING)), |
| 2825 | ("bqrelse: inappropriate B_PAGING or B_CLUSTER bp %p", bp)); |
| 2826 | |
| 2827 | qindex = QUEUE_NONE; |
| 2828 | if (BUF_LOCKRECURSED(bp)) { |
| 2829 | /* do not release to free list */ |
| 2830 | BUF_UNLOCK(bp); |
| 2831 | return; |
| 2832 | } |
| 2833 | bp->b_flags &= ~(B_ASYNC | B_NOCACHE | B_AGE | B_RELBUF); |
| 2834 | bp->b_xflags &= ~(BX_CVTENXIO); |
| 2835 | |
| 2836 | if (LIST_EMPTY(&bp->b_dep)) { |
| 2837 | bp->b_flags &= ~B_IOSTARTED; |
| 2838 | } else { |
| 2839 | KASSERT((bp->b_flags & B_IOSTARTED) == 0, |
| 2840 | ("bqrelse: SU io not finished bp %p", bp)); |
| 2841 | } |
| 2842 | |
| 2843 | if (bp->b_flags & B_MANAGED) { |
| 2844 | if (bp->b_flags & B_REMFREE) |
| 2845 | bremfreef(bp); |
| 2846 | goto out; |
| 2847 | } |
| 2848 | |
| 2849 | /* buffers with stale but valid contents */ |
| 2850 | if ((bp->b_flags & B_DELWRI) != 0 || (bp->b_vflags & (BV_BKGRDINPROG | |
| 2851 | BV_BKGRDERR)) == BV_BKGRDERR) { |
| 2852 | BO_LOCK(bp->b_bufobj); |
| 2853 | bp->b_vflags &= ~BV_BKGRDERR; |
| 2854 | BO_UNLOCK(bp->b_bufobj); |
| 2855 | qindex = QUEUE_DIRTY; |
| 2856 | } else { |
| 2857 | if ((bp->b_flags & B_DELWRI) == 0 && |
| 2858 | (bp->b_xflags & BX_VNDIRTY)) |
| 2859 | panic("bqrelse: not dirty"); |
| 2860 | if ((bp->b_flags & B_NOREUSE) != 0) { |
| 2861 | brelse(bp); |
| 2862 | return; |
| 2863 | } |
| 2864 | qindex = QUEUE_CLEAN; |
| 2865 | } |
| 2866 | buf_track(bp, __func__); |
| 2867 | /* binsfree unlocks bp. */ |
| 2868 | binsfree(bp, qindex); |
| 2869 | return; |
| 2870 | |
| 2871 | out: |
| 2872 | buf_track(bp, __func__); |
| 2873 | /* unlock */ |
| 2874 | BUF_UNLOCK(bp); |
| 2875 | } |
no test coverage detected