* Move the buffer between the clean and dirty lists of its vnode. */
| 2803 | * Move the buffer between the clean and dirty lists of its vnode. |
| 2804 | */ |
| 2805 | void |
| 2806 | reassignbuf(struct buf *bp) |
| 2807 | { |
| 2808 | struct vnode *vp; |
| 2809 | struct bufobj *bo; |
| 2810 | int delay; |
| 2811 | #ifdef INVARIANTS |
| 2812 | struct bufv *bv; |
| 2813 | #endif |
| 2814 | |
| 2815 | vp = bp->b_vp; |
| 2816 | bo = bp->b_bufobj; |
| 2817 | |
| 2818 | KASSERT((bp->b_flags & B_PAGING) == 0, |
| 2819 | ("%s: cannot reassign paging buffer %p", __func__, bp)); |
| 2820 | |
| 2821 | CTR3(KTR_BUF, "reassignbuf(%p) vp %p flags %X", |
| 2822 | bp, bp->b_vp, bp->b_flags); |
| 2823 | |
| 2824 | BO_LOCK(bo); |
| 2825 | buf_vlist_remove(bp); |
| 2826 | |
| 2827 | /* |
| 2828 | * If dirty, put on list of dirty buffers; otherwise insert onto list |
| 2829 | * of clean buffers. |
| 2830 | */ |
| 2831 | if (bp->b_flags & B_DELWRI) { |
| 2832 | if ((bo->bo_flag & BO_ONWORKLST) == 0) { |
| 2833 | switch (vp->v_type) { |
| 2834 | case VDIR: |
| 2835 | delay = dirdelay; |
| 2836 | break; |
| 2837 | case VCHR: |
| 2838 | delay = metadelay; |
| 2839 | break; |
| 2840 | default: |
| 2841 | delay = filedelay; |
| 2842 | } |
| 2843 | vn_syncer_add_to_worklist(bo, delay); |
| 2844 | } |
| 2845 | buf_vlist_add(bp, bo, BX_VNDIRTY); |
| 2846 | } else { |
| 2847 | buf_vlist_add(bp, bo, BX_VNCLEAN); |
| 2848 | |
| 2849 | if ((bo->bo_flag & BO_ONWORKLST) && bo->bo_dirty.bv_cnt == 0) { |
| 2850 | mtx_lock(&sync_mtx); |
| 2851 | LIST_REMOVE(bo, bo_synclist); |
| 2852 | syncer_worklist_len--; |
| 2853 | mtx_unlock(&sync_mtx); |
| 2854 | bo->bo_flag &= ~BO_ONWORKLST; |
| 2855 | } |
| 2856 | } |
| 2857 | #ifdef INVARIANTS |
| 2858 | bv = &bo->bo_clean; |
| 2859 | bp = TAILQ_FIRST(&bv->bv_hd); |
| 2860 | KASSERT(bp == NULL || bp->b_bufobj == bo, |
| 2861 | ("bp %p wrong b_bufobj %p should be %p", bp, bp->b_bufobj, bo)); |
| 2862 | bp = TAILQ_LAST(&bv->bv_hd, buflists); |
no test coverage detected