diff options
| -rw-r--r-- | drivers/block/umem.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/drivers/block/umem.c b/drivers/block/umem.c index aa2712060bfb..9a72277a31df 100644 --- a/drivers/block/umem.c +++ b/drivers/block/umem.c | |||
| @@ -513,6 +513,44 @@ 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) | ||
| 522 | { | ||
| 523 | struct mm_plug_cb *mmcb = container_of(cb, struct mm_plug_cb, cb); | ||
| 524 | |||
| 525 | spin_lock_irq(&mmcb->card->lock); | ||
| 526 | activate(mmcb->card); | ||
| 527 | spin_unlock_irq(&mmcb->card->lock); | ||
| 528 | kfree(mmcb); | ||
| 529 | } | ||
| 530 | |||
| 531 | static int mm_check_plugged(struct cardinfo *card) | ||
| 532 | { | ||
| 533 | struct blk_plug *plug = current->plug; | ||
| 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 | } | ||
| 553 | |||
| 516 | static void mm_make_request(struct request_queue *q, struct bio *bio) | 554 | static void mm_make_request(struct request_queue *q, struct bio *bio) |
| 517 | { | 555 | { |
| 518 | struct cardinfo *card = q->queuedata; | 556 | struct cardinfo *card = q->queuedata; |
| @@ -523,6 +561,8 @@ static void mm_make_request(struct request_queue *q, struct bio *bio) | |||
| 523 | *card->biotail = bio; | 561 | *card->biotail = bio; |
| 524 | bio->bi_next = NULL; | 562 | bio->bi_next = NULL; |
| 525 | card->biotail = &bio->bi_next; | 563 | card->biotail = &bio->bi_next; |
| 564 | if (bio->bi_rw & REQ_SYNC || !mm_check_plugged(card)) | ||
| 565 | activate(card); | ||
| 526 | spin_unlock_irq(&card->lock); | 566 | spin_unlock_irq(&card->lock); |
| 527 | 567 | ||
| 528 | return; | 568 | return; |
