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>
This commit is contained in:
NeilBrown
2012-07-31 09:08:14 +02:00
committed by Jens Axboe
parent 0021b7bc04
commit 9cbb175088
5 changed files with 49 additions and 83 deletions
+6 -29
View File
@@ -513,42 +513,19 @@ static void process_page(unsigned long data)
}
}
struct mm_plug_cb {
struct blk_plug_cb cb;
struct cardinfo *card;
};
static void mm_unplug(struct blk_plug_cb *cb)
{
struct mm_plug_cb *mmcb = container_of(cb, struct mm_plug_cb, cb);
struct cardinfo *card = cb->data;
spin_lock_irq(&mmcb->card->lock);
activate(mmcb->card);
spin_unlock_irq(&mmcb->card->lock);
kfree(mmcb);
spin_lock_irq(&card->lock);
activate(card);
spin_unlock_irq(&card->lock);
kfree(cb);
}
static int mm_check_plugged(struct cardinfo *card)
{
struct blk_plug *plug = current->plug;
struct mm_plug_cb *mmcb;
if (!plug)
return 0;
list_for_each_entry(mmcb, &plug->cb_list, cb.list) {
if (mmcb->cb.callback == mm_unplug && mmcb->card == card)
return 1;
}
/* Not currently on the callback list */
mmcb = kmalloc(sizeof(*mmcb), GFP_ATOMIC);
if (!mmcb)
return 0;
mmcb->card = card;
mmcb->cb.callback = mm_unplug;
list_add(&mmcb->cb.list, &plug->cb_list);
return 1;
return !!blk_check_plugged(mm_unplug, card, sizeof(struct blk_plug_cb));
}
static void mm_make_request(struct request_queue *q, struct bio *bio)