diff options
author | Kent Overstreet <koverstreet@google.com> | 2012-09-06 18:34:55 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2012-09-09 04:35:38 -0400 |
commit | 395c72a707d966b36d5a42fe12c3a237ded3a0d9 (patch) | |
tree | 79e4450a4f31409815d80ee8e1a7e1490a140f22 /fs | |
parent | eeea3ac912207dcf759b95b2b4c36f96bce583bf (diff) |
block: Generalized bio pool freeing
With the old code, when you allocate a bio from a bio pool you have to
implement your own destructor that knows how to find the bio pool the
bio was originally allocated from.
This adds a new field to struct bio (bi_pool) and changes
bio_alloc_bioset() to use it. This makes various bio destructors
unnecessary, so they're then deleted.
v6: Explain the temporary if statement in bio_put
Signed-off-by: Kent Overstreet <koverstreet@google.com>
CC: Jens Axboe <axboe@kernel.dk>
CC: NeilBrown <neilb@suse.de>
CC: Alasdair Kergon <agk@redhat.com>
CC: Nicholas Bellinger <nab@linux-iscsi.org>
CC: Lars Ellenberg <lars.ellenberg@linbit.com>
Acked-by: Tejun Heo <tj@kernel.org>
Acked-by: Nicholas Bellinger <nab@linux-iscsi.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/bio.c | 31 |
1 files changed, 13 insertions, 18 deletions
@@ -272,10 +272,6 @@ EXPORT_SYMBOL(bio_init); | |||
272 | * bio_alloc_bioset will try its own mempool to satisfy the allocation. | 272 | * bio_alloc_bioset will try its own mempool to satisfy the allocation. |
273 | * If %__GFP_WAIT is set then we will block on the internal pool waiting | 273 | * If %__GFP_WAIT is set then we will block on the internal pool waiting |
274 | * for a &struct bio to become free. | 274 | * for a &struct bio to become free. |
275 | * | ||
276 | * Note that the caller must set ->bi_destructor on successful return | ||
277 | * of a bio, to do the appropriate freeing of the bio once the reference | ||
278 | * count drops to zero. | ||
279 | **/ | 275 | **/ |
280 | struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs) | 276 | struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs) |
281 | { | 277 | { |
@@ -290,6 +286,7 @@ struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs) | |||
290 | bio = p + bs->front_pad; | 286 | bio = p + bs->front_pad; |
291 | 287 | ||
292 | bio_init(bio); | 288 | bio_init(bio); |
289 | bio->bi_pool = bs; | ||
293 | 290 | ||
294 | if (unlikely(!nr_iovecs)) | 291 | if (unlikely(!nr_iovecs)) |
295 | goto out_set; | 292 | goto out_set; |
@@ -316,11 +313,6 @@ err_free: | |||
316 | } | 313 | } |
317 | EXPORT_SYMBOL(bio_alloc_bioset); | 314 | EXPORT_SYMBOL(bio_alloc_bioset); |
318 | 315 | ||
319 | static void bio_fs_destructor(struct bio *bio) | ||
320 | { | ||
321 | bio_free(bio, fs_bio_set); | ||
322 | } | ||
323 | |||
324 | /** | 316 | /** |
325 | * bio_alloc - allocate a new bio, memory pool backed | 317 | * bio_alloc - allocate a new bio, memory pool backed |
326 | * @gfp_mask: allocation mask to use | 318 | * @gfp_mask: allocation mask to use |
@@ -342,12 +334,7 @@ static void bio_fs_destructor(struct bio *bio) | |||
342 | */ | 334 | */ |
343 | struct bio *bio_alloc(gfp_t gfp_mask, unsigned int nr_iovecs) | 335 | struct bio *bio_alloc(gfp_t gfp_mask, unsigned int nr_iovecs) |
344 | { | 336 | { |
345 | struct bio *bio = bio_alloc_bioset(gfp_mask, nr_iovecs, fs_bio_set); | 337 | return bio_alloc_bioset(gfp_mask, nr_iovecs, fs_bio_set); |
346 | |||
347 | if (bio) | ||
348 | bio->bi_destructor = bio_fs_destructor; | ||
349 | |||
350 | return bio; | ||
351 | } | 338 | } |
352 | EXPORT_SYMBOL(bio_alloc); | 339 | EXPORT_SYMBOL(bio_alloc); |
353 | 340 | ||
@@ -423,7 +410,16 @@ void bio_put(struct bio *bio) | |||
423 | if (atomic_dec_and_test(&bio->bi_cnt)) { | 410 | if (atomic_dec_and_test(&bio->bi_cnt)) { |
424 | bio_disassociate_task(bio); | 411 | bio_disassociate_task(bio); |
425 | bio->bi_next = NULL; | 412 | bio->bi_next = NULL; |
426 | bio->bi_destructor(bio); | 413 | |
414 | /* | ||
415 | * This if statement is temporary - bi_pool is replacing | ||
416 | * bi_destructor, but bi_destructor will be taken out in another | ||
417 | * patch. | ||
418 | */ | ||
419 | if (bio->bi_pool) | ||
420 | bio_free(bio, bio->bi_pool); | ||
421 | else | ||
422 | bio->bi_destructor(bio); | ||
427 | } | 423 | } |
428 | } | 424 | } |
429 | EXPORT_SYMBOL(bio_put); | 425 | EXPORT_SYMBOL(bio_put); |
@@ -474,12 +470,11 @@ EXPORT_SYMBOL(__bio_clone); | |||
474 | */ | 470 | */ |
475 | struct bio *bio_clone(struct bio *bio, gfp_t gfp_mask) | 471 | struct bio *bio_clone(struct bio *bio, gfp_t gfp_mask) |
476 | { | 472 | { |
477 | struct bio *b = bio_alloc_bioset(gfp_mask, bio->bi_max_vecs, fs_bio_set); | 473 | struct bio *b = bio_alloc(gfp_mask, bio->bi_max_vecs); |
478 | 474 | ||
479 | if (!b) | 475 | if (!b) |
480 | return NULL; | 476 | return NULL; |
481 | 477 | ||
482 | b->bi_destructor = bio_fs_destructor; | ||
483 | __bio_clone(b, bio); | 478 | __bio_clone(b, bio); |
484 | 479 | ||
485 | if (bio_integrity(bio)) { | 480 | if (bio_integrity(bio)) { |