* getnewbuf: * * Find and initialize a new buffer header, freeing up existing buffers * in the bufqueues as necessary. The new buffer is returned locked. * * We block if: * We have insufficient buffer headers * We have insufficient buffer space * buffer_arena is too fragmented ( space reservation fails ) * If we have to flush dirty buffers ( but we try to avoid this ) * * The calle
| 3274 | * allocbuf() is called. |
| 3275 | */ |
| 3276 | static struct buf * |
| 3277 | getnewbuf(struct vnode *vp, int slpflag, int slptimeo, int maxsize, int gbflags) |
| 3278 | { |
| 3279 | struct bufdomain *bd; |
| 3280 | struct buf *bp; |
| 3281 | bool metadata, reserved; |
| 3282 | |
| 3283 | bp = NULL; |
| 3284 | KASSERT((gbflags & (GB_UNMAPPED | GB_KVAALLOC)) != GB_KVAALLOC, |
| 3285 | ("GB_KVAALLOC only makes sense with GB_UNMAPPED")); |
| 3286 | if (!unmapped_buf_allowed) |
| 3287 | gbflags &= ~(GB_UNMAPPED | GB_KVAALLOC); |
| 3288 | |
| 3289 | if (vp == NULL || (vp->v_vflag & (VV_MD | VV_SYSTEM)) != 0 || |
| 3290 | vp->v_type == VCHR) |
| 3291 | metadata = true; |
| 3292 | else |
| 3293 | metadata = false; |
| 3294 | if (vp == NULL) |
| 3295 | bd = &bdomain[0]; |
| 3296 | else |
| 3297 | bd = &bdomain[vp->v_bufobj.bo_domain]; |
| 3298 | |
| 3299 | counter_u64_add(getnewbufcalls, 1); |
| 3300 | reserved = false; |
| 3301 | do { |
| 3302 | if (reserved == false && |
| 3303 | bufspace_reserve(bd, maxsize, metadata) != 0) { |
| 3304 | counter_u64_add(getnewbufrestarts, 1); |
| 3305 | continue; |
| 3306 | } |
| 3307 | reserved = true; |
| 3308 | if ((bp = buf_alloc(bd)) == NULL) { |
| 3309 | counter_u64_add(getnewbufrestarts, 1); |
| 3310 | continue; |
| 3311 | } |
| 3312 | if (getnewbuf_kva(bp, gbflags, maxsize) == 0) |
| 3313 | return (bp); |
| 3314 | break; |
| 3315 | } while (buf_recycle(bd, false) == 0); |
| 3316 | |
| 3317 | if (reserved) |
| 3318 | bufspace_release(bd, maxsize); |
| 3319 | if (bp != NULL) { |
| 3320 | bp->b_flags |= B_INVAL; |
| 3321 | brelse(bp); |
| 3322 | } |
| 3323 | bufspace_wait(bd, vp, gbflags, slpflag, slptimeo); |
| 3324 | |
| 3325 | return (NULL); |
| 3326 | } |
| 3327 | |
| 3328 | /* |
| 3329 | * buf_daemon: |
no test coverage detected