diff options
author | NeilBrown <neilb@suse.de> | 2012-07-31 03:08:14 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2012-07-31 03:08:14 -0400 |
commit | 9cbb17508808f8a6bdd83354b61e126ac4fa6fed (patch) | |
tree | bc797d1b5cd829751a333115e6e6d52799fb6df2 /drivers/block | |
parent | 0021b7bc045e4b0b85d8c53614342aaf84ca96a5 (diff) |
blk: centralize non-request unplug handling.
Both md and umem has similar code for getting notified on an
blk_finish_plug event.
Centralize this code in block/ and allow each driver to
provide its distinctive difference.
Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/umem.c | 35 |
1 files changed, 6 insertions, 29 deletions
diff --git a/drivers/block/umem.c b/drivers/block/umem.c index 9a72277a31df..6ef3489568e3 100644 --- a/drivers/block/umem.c +++ b/drivers/block/umem.c | |||
@@ -513,42 +513,19 @@ static void process_page(unsigned long data) | |||
513 | } | 513 | } |
514 | } | 514 | } |
515 | 515 | ||
516 | struct mm_plug_cb { | ||
517 | struct blk_plug_cb cb; | ||
518 | struct cardinfo *card; | ||
519 | }; | ||
520 | |||
521 | static void mm_unplug(struct blk_plug_cb *cb) | 516 | static void mm_unplug(struct blk_plug_cb *cb) |
522 | { | 517 | { |
523 | struct mm_plug_cb *mmcb = container_of(cb, struct mm_plug_cb, cb); | 518 | struct cardinfo *card = cb->data; |
524 | 519 | ||
525 | spin_lock_irq(&mmcb->card->lock); | 520 | spin_lock_irq(&card->lock); |
526 | activate(mmcb->card); | 521 | activate(card); |
527 | spin_unlock_irq(&mmcb->card->lock); | 522 | spin_unlock_irq(&card->lock); |
528 | kfree(mmcb); | 523 | kfree(cb); |
529 | } | 524 | } |
530 | 525 | ||
531 | static int mm_check_plugged(struct cardinfo *card) | 526 | static int mm_check_plugged(struct cardinfo *card) |
532 | { | 527 | { |
533 | struct blk_plug *plug = current->plug; | 528 | return !!blk_check_plugged(mm_unplug, card, sizeof(struct blk_plug_cb)); |
534 | struct mm_plug_cb *mmcb; | ||
535 | |||
536 | if (!plug) | ||
537 | return 0; | ||
538 | |||
539 | list_for_each_entry(mmcb, &plug->cb_list, cb.list) { | ||
540 | if (mmcb->cb.callback == mm_unplug && mmcb->card == card) | ||
541 | return 1; | ||
542 | } | ||
543 | /* Not currently on the callback list */ | ||
544 | mmcb = kmalloc(sizeof(*mmcb), GFP_ATOMIC); | ||
545 | if (!mmcb) | ||
546 | return 0; | ||
547 | |||
548 | mmcb->card = card; | ||
549 | mmcb->cb.callback = mm_unplug; | ||
550 | list_add(&mmcb->cb.list, &plug->cb_list); | ||
551 | return 1; | ||
552 | } | 529 | } |
553 | 530 | ||
554 | static void mm_make_request(struct request_queue *q, struct bio *bio) | 531 | static void mm_make_request(struct request_queue *q, struct bio *bio) |