* Allocate the KVA mapping for an existing buffer. * If an unmapped buffer is provided but a mapped buffer is requested, take * also care to properly setup mappings between pages and KVA. */
| 3767 | * also care to properly setup mappings between pages and KVA. |
| 3768 | */ |
| 3769 | static void |
| 3770 | bp_unmapped_get_kva(struct buf *bp, daddr_t blkno, int size, int gbflags) |
| 3771 | { |
| 3772 | int bsize, maxsize, need_mapping, need_kva; |
| 3773 | off_t offset; |
| 3774 | |
| 3775 | need_mapping = bp->b_data == unmapped_buf && |
| 3776 | (gbflags & GB_UNMAPPED) == 0; |
| 3777 | need_kva = bp->b_kvabase == unmapped_buf && |
| 3778 | bp->b_data == unmapped_buf && |
| 3779 | (gbflags & GB_KVAALLOC) != 0; |
| 3780 | if (!need_mapping && !need_kva) |
| 3781 | return; |
| 3782 | |
| 3783 | BUF_CHECK_UNMAPPED(bp); |
| 3784 | |
| 3785 | if (need_mapping && bp->b_kvabase != unmapped_buf) { |
| 3786 | /* |
| 3787 | * Buffer is not mapped, but the KVA was already |
| 3788 | * reserved at the time of the instantiation. Use the |
| 3789 | * allocated space. |
| 3790 | */ |
| 3791 | goto has_addr; |
| 3792 | } |
| 3793 | |
| 3794 | /* |
| 3795 | * Calculate the amount of the address space we would reserve |
| 3796 | * if the buffer was mapped. |
| 3797 | */ |
| 3798 | bsize = vn_isdisk(bp->b_vp) ? DEV_BSIZE : bp->b_bufobj->bo_bsize; |
| 3799 | KASSERT(bsize != 0, ("bsize == 0, check bo->bo_bsize")); |
| 3800 | offset = blkno * bsize; |
| 3801 | maxsize = size + (offset & PAGE_MASK); |
| 3802 | maxsize = imax(maxsize, bsize); |
| 3803 | |
| 3804 | while (bufkva_alloc(bp, maxsize, gbflags) != 0) { |
| 3805 | if ((gbflags & GB_NOWAIT_BD) != 0) { |
| 3806 | /* |
| 3807 | * XXXKIB: defragmentation cannot |
| 3808 | * succeed, not sure what else to do. |
| 3809 | */ |
| 3810 | panic("GB_NOWAIT_BD and GB_UNMAPPED %p", bp); |
| 3811 | } |
| 3812 | counter_u64_add(mappingrestarts, 1); |
| 3813 | bufspace_wait(bufdomain(bp), bp->b_vp, gbflags, 0, 0); |
| 3814 | } |
| 3815 | has_addr: |
| 3816 | if (need_mapping) { |
| 3817 | /* b_offset is handled by bpmap_qenter. */ |
| 3818 | bp->b_data = bp->b_kvabase; |
| 3819 | BUF_CHECK_MAPPED(bp); |
| 3820 | bpmap_qenter(bp); |
| 3821 | } |
| 3822 | } |
| 3823 | |
| 3824 | struct buf * |
| 3825 | getblk(struct vnode *vp, daddr_t blkno, int size, int slpflag, int slptimeo, |
no test coverage detected