diff options
Diffstat (limited to 'drivers/block/loop.c')
-rw-r--r-- | drivers/block/loop.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 54046e51160a..ae1251270624 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
@@ -463,6 +463,7 @@ out: | |||
463 | */ | 463 | */ |
464 | static void loop_add_bio(struct loop_device *lo, struct bio *bio) | 464 | static void loop_add_bio(struct loop_device *lo, struct bio *bio) |
465 | { | 465 | { |
466 | lo->lo_bio_count++; | ||
466 | bio_list_add(&lo->lo_bio_list, bio); | 467 | bio_list_add(&lo->lo_bio_list, bio); |
467 | } | 468 | } |
468 | 469 | ||
@@ -471,6 +472,7 @@ static void loop_add_bio(struct loop_device *lo, struct bio *bio) | |||
471 | */ | 472 | */ |
472 | static struct bio *loop_get_bio(struct loop_device *lo) | 473 | static struct bio *loop_get_bio(struct loop_device *lo) |
473 | { | 474 | { |
475 | lo->lo_bio_count--; | ||
474 | return bio_list_pop(&lo->lo_bio_list); | 476 | return bio_list_pop(&lo->lo_bio_list); |
475 | } | 477 | } |
476 | 478 | ||
@@ -489,6 +491,10 @@ static void loop_make_request(struct request_queue *q, struct bio *old_bio) | |||
489 | goto out; | 491 | goto out; |
490 | if (unlikely(rw == WRITE && (lo->lo_flags & LO_FLAGS_READ_ONLY))) | 492 | if (unlikely(rw == WRITE && (lo->lo_flags & LO_FLAGS_READ_ONLY))) |
491 | goto out; | 493 | goto out; |
494 | if (lo->lo_bio_count >= q->nr_congestion_on) | ||
495 | wait_event_lock_irq(lo->lo_req_wait, | ||
496 | lo->lo_bio_count < q->nr_congestion_off, | ||
497 | lo->lo_lock); | ||
492 | loop_add_bio(lo, old_bio); | 498 | loop_add_bio(lo, old_bio); |
493 | wake_up(&lo->lo_event); | 499 | wake_up(&lo->lo_event); |
494 | spin_unlock_irq(&lo->lo_lock); | 500 | spin_unlock_irq(&lo->lo_lock); |
@@ -546,6 +552,8 @@ static int loop_thread(void *data) | |||
546 | continue; | 552 | continue; |
547 | spin_lock_irq(&lo->lo_lock); | 553 | spin_lock_irq(&lo->lo_lock); |
548 | bio = loop_get_bio(lo); | 554 | bio = loop_get_bio(lo); |
555 | if (lo->lo_bio_count < lo->lo_queue->nr_congestion_off) | ||
556 | wake_up(&lo->lo_req_wait); | ||
549 | spin_unlock_irq(&lo->lo_lock); | 557 | spin_unlock_irq(&lo->lo_lock); |
550 | 558 | ||
551 | BUG_ON(!bio); | 559 | BUG_ON(!bio); |
@@ -873,6 +881,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, | |||
873 | lo->transfer = transfer_none; | 881 | lo->transfer = transfer_none; |
874 | lo->ioctl = NULL; | 882 | lo->ioctl = NULL; |
875 | lo->lo_sizelimit = 0; | 883 | lo->lo_sizelimit = 0; |
884 | lo->lo_bio_count = 0; | ||
876 | lo->old_gfp_mask = mapping_gfp_mask(mapping); | 885 | lo->old_gfp_mask = mapping_gfp_mask(mapping); |
877 | mapping_set_gfp_mask(mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS)); | 886 | mapping_set_gfp_mask(mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS)); |
878 | 887 | ||
@@ -1673,6 +1682,7 @@ static int loop_add(struct loop_device **l, int i) | |||
1673 | lo->lo_number = i; | 1682 | lo->lo_number = i; |
1674 | lo->lo_thread = NULL; | 1683 | lo->lo_thread = NULL; |
1675 | init_waitqueue_head(&lo->lo_event); | 1684 | init_waitqueue_head(&lo->lo_event); |
1685 | init_waitqueue_head(&lo->lo_req_wait); | ||
1676 | spin_lock_init(&lo->lo_lock); | 1686 | spin_lock_init(&lo->lo_lock); |
1677 | disk->major = LOOP_MAJOR; | 1687 | disk->major = LOOP_MAJOR; |
1678 | disk->first_minor = i << part_shift; | 1688 | disk->first_minor = i << part_shift; |