aboutsummaryrefslogtreecommitdiffstats
path: root/fs/bio.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/bio.c')
-rw-r--r--fs/bio.c87
1 files changed, 46 insertions, 41 deletions
diff --git a/fs/bio.c b/fs/bio.c
index d4f06327c810..a040cde7f6fd 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -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 **/
302struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs) 302struct 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 }
344out: 335 bio->bi_flags |= idx << BIO_POOL_OFFSET;
336 bio->bi_max_vecs = nr_iovecs;
337out_set:
338 bio->bi_io_vec = bvl;
339
345 return bio; 340 return bio;
341
342err_free:
343 if (bs)
344 mempool_free(p, bs->bio_pool);
345 else
346 kfree(bio);
347err:
348 return NULL;
346} 349}
347 350
348struct bio *bio_alloc(gfp_t gfp_mask, int nr_iovecs) 351struct 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);