diff options
Diffstat (limited to 'fs/bio.c')
| -rw-r--r-- | fs/bio.c | 87 |
1 files changed, 46 insertions, 41 deletions
| @@ -248,7 +248,7 @@ void bio_free(struct bio *bio, struct bio_set *bs) | |||
| 248 | bvec_free_bs(bs, bio->bi_io_vec, BIO_POOL_IDX(bio)); | 248 | bvec_free_bs(bs, bio->bi_io_vec, BIO_POOL_IDX(bio)); |
| 249 | 249 | ||
| 250 | if (bio_integrity(bio)) | 250 | if (bio_integrity(bio)) |
| 251 | bio_integrity_free(bio, bs); | 251 | bio_integrity_free(bio); |
| 252 | 252 | ||
| 253 | /* | 253 | /* |
| 254 | * If we have front padding, adjust the bio pointer before freeing | 254 | * If we have front padding, adjust the bio pointer before freeing |
| @@ -301,48 +301,51 @@ void bio_init(struct bio *bio) | |||
| 301 | **/ | 301 | **/ |
| 302 | struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs) | 302 | struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs) |
| 303 | { | 303 | { |
| 304 | struct bio_vec *bvl = NULL; | ||
| 304 | struct bio *bio = NULL; | 305 | struct bio *bio = NULL; |
| 305 | void *uninitialized_var(p); | 306 | unsigned long idx = 0; |
| 307 | void *p = NULL; | ||
| 306 | 308 | ||
| 307 | if (bs) { | 309 | if (bs) { |
| 308 | p = mempool_alloc(bs->bio_pool, gfp_mask); | 310 | p = mempool_alloc(bs->bio_pool, gfp_mask); |
| 309 | 311 | if (!p) | |
| 310 | if (p) | 312 | goto err; |
| 311 | bio = p + bs->front_pad; | 313 | bio = p + bs->front_pad; |
| 312 | } else | 314 | } else { |
| 313 | bio = kmalloc(sizeof(*bio), gfp_mask); | 315 | bio = kmalloc(sizeof(*bio), gfp_mask); |
| 316 | if (!bio) | ||
| 317 | goto err; | ||
| 318 | } | ||
| 314 | 319 | ||
| 315 | if (likely(bio)) { | 320 | bio_init(bio); |
| 316 | struct bio_vec *bvl = NULL; | 321 | |
| 317 | 322 | if (unlikely(!nr_iovecs)) | |
| 318 | bio_init(bio); | 323 | goto out_set; |
| 319 | if (likely(nr_iovecs)) { | 324 | |
| 320 | unsigned long uninitialized_var(idx); | 325 | if (nr_iovecs <= BIO_INLINE_VECS) { |
| 321 | 326 | bvl = bio->bi_inline_vecs; | |
| 322 | if (nr_iovecs <= BIO_INLINE_VECS) { | 327 | nr_iovecs = BIO_INLINE_VECS; |
| 323 | idx = 0; | 328 | } else { |
| 324 | bvl = bio->bi_inline_vecs; | 329 | bvl = bvec_alloc_bs(gfp_mask, nr_iovecs, &idx, bs); |
| 325 | nr_iovecs = BIO_INLINE_VECS; | 330 | if (unlikely(!bvl)) |
| 326 | } else { | 331 | goto err_free; |
| 327 | bvl = bvec_alloc_bs(gfp_mask, nr_iovecs, &idx, | 332 | |
| 328 | bs); | 333 | nr_iovecs = bvec_nr_vecs(idx); |
| 329 | nr_iovecs = bvec_nr_vecs(idx); | ||
| 330 | } | ||
| 331 | if (unlikely(!bvl)) { | ||
| 332 | if (bs) | ||
| 333 | mempool_free(p, bs->bio_pool); | ||
| 334 | else | ||
| 335 | kfree(bio); | ||
| 336 | bio = NULL; | ||
| 337 | goto out; | ||
| 338 | } | ||
| 339 | bio->bi_flags |= idx << BIO_POOL_OFFSET; | ||
| 340 | bio->bi_max_vecs = nr_iovecs; | ||
| 341 | } | ||
| 342 | bio->bi_io_vec = bvl; | ||
| 343 | } | 334 | } |
| 344 | out: | 335 | bio->bi_flags |= idx << BIO_POOL_OFFSET; |
| 336 | bio->bi_max_vecs = nr_iovecs; | ||
| 337 | out_set: | ||
| 338 | bio->bi_io_vec = bvl; | ||
| 339 | |||
| 345 | return bio; | 340 | return bio; |
| 341 | |||
| 342 | err_free: | ||
| 343 | if (bs) | ||
| 344 | mempool_free(p, bs->bio_pool); | ||
| 345 | else | ||
| 346 | kfree(bio); | ||
| 347 | err: | ||
| 348 | return NULL; | ||
| 346 | } | 349 | } |
| 347 | 350 | ||
| 348 | struct bio *bio_alloc(gfp_t gfp_mask, int nr_iovecs) | 351 | struct bio *bio_alloc(gfp_t gfp_mask, int nr_iovecs) |
| @@ -463,7 +466,7 @@ struct bio *bio_clone(struct bio *bio, gfp_t gfp_mask) | |||
| 463 | if (bio_integrity(bio)) { | 466 | if (bio_integrity(bio)) { |
| 464 | int ret; | 467 | int ret; |
| 465 | 468 | ||
| 466 | ret = bio_integrity_clone(b, bio, gfp_mask, fs_bio_set); | 469 | ret = bio_integrity_clone(b, bio, gfp_mask); |
| 467 | 470 | ||
| 468 | if (ret < 0) { | 471 | if (ret < 0) { |
| 469 | bio_put(b); | 472 | bio_put(b); |
| @@ -1526,7 +1529,6 @@ void bioset_free(struct bio_set *bs) | |||
| 1526 | if (bs->bio_pool) | 1529 | if (bs->bio_pool) |
| 1527 | mempool_destroy(bs->bio_pool); | 1530 | mempool_destroy(bs->bio_pool); |
| 1528 | 1531 | ||
| 1529 | bioset_integrity_free(bs); | ||
| 1530 | biovec_free_pools(bs); | 1532 | biovec_free_pools(bs); |
| 1531 | bio_put_slab(bs); | 1533 | bio_put_slab(bs); |
| 1532 | 1534 | ||
| @@ -1567,9 +1569,6 @@ struct bio_set *bioset_create(unsigned int pool_size, unsigned int front_pad) | |||
| 1567 | if (!bs->bio_pool) | 1569 | if (!bs->bio_pool) |
| 1568 | goto bad; | 1570 | goto bad; |
| 1569 | 1571 | ||
| 1570 | if (bioset_integrity_create(bs, pool_size)) | ||
| 1571 | goto bad; | ||
| 1572 | |||
| 1573 | if (!biovec_create_pools(bs, pool_size)) | 1572 | if (!biovec_create_pools(bs, pool_size)) |
| 1574 | return bs; | 1573 | return bs; |
| 1575 | 1574 | ||
| @@ -1586,6 +1585,13 @@ static void __init biovec_init_slabs(void) | |||
| 1586 | int size; | 1585 | int size; |
| 1587 | struct biovec_slab *bvs = bvec_slabs + i; | 1586 | struct biovec_slab *bvs = bvec_slabs + i; |
| 1588 | 1587 | ||
| 1588 | #ifndef CONFIG_BLK_DEV_INTEGRITY | ||
| 1589 | if (bvs->nr_vecs <= BIO_INLINE_VECS) { | ||
| 1590 | bvs->slab = NULL; | ||
| 1591 | continue; | ||
| 1592 | } | ||
| 1593 | #endif | ||
| 1594 | |||
| 1589 | size = bvs->nr_vecs * sizeof(struct bio_vec); | 1595 | size = bvs->nr_vecs * sizeof(struct bio_vec); |
| 1590 | bvs->slab = kmem_cache_create(bvs->name, size, 0, | 1596 | bvs->slab = kmem_cache_create(bvs->name, size, 0, |
| 1591 | SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); | 1597 | SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); |
| @@ -1600,7 +1606,6 @@ static int __init init_bio(void) | |||
| 1600 | if (!bio_slabs) | 1606 | if (!bio_slabs) |
| 1601 | panic("bio: can't allocate bios\n"); | 1607 | panic("bio: can't allocate bios\n"); |
| 1602 | 1608 | ||
| 1603 | bio_integrity_init_slab(); | ||
| 1604 | biovec_init_slabs(); | 1609 | biovec_init_slabs(); |
| 1605 | 1610 | ||
| 1606 | fs_bio_set = bioset_create(BIO_POOL_SIZE, 0); | 1611 | fs_bio_set = bioset_create(BIO_POOL_SIZE, 0); |
