diff options
-rw-r--r-- | drivers/block/loop.c | 10 | ||||
-rw-r--r-- | include/linux/loop.h | 3 |
2 files changed, 13 insertions, 0 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index e9d594fd12cb..800aec7927de 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 | ||
@@ -1660,6 +1669,7 @@ static int loop_add(struct loop_device **l, int i) | |||
1660 | lo->lo_number = i; | 1669 | lo->lo_number = i; |
1661 | lo->lo_thread = NULL; | 1670 | lo->lo_thread = NULL; |
1662 | init_waitqueue_head(&lo->lo_event); | 1671 | init_waitqueue_head(&lo->lo_event); |
1672 | init_waitqueue_head(&lo->lo_req_wait); | ||
1663 | spin_lock_init(&lo->lo_lock); | 1673 | spin_lock_init(&lo->lo_lock); |
1664 | disk->major = LOOP_MAJOR; | 1674 | disk->major = LOOP_MAJOR; |
1665 | disk->first_minor = i << part_shift; | 1675 | disk->first_minor = i << part_shift; |
diff --git a/include/linux/loop.h b/include/linux/loop.h index 6492181bcb1d..460b60fa7adf 100644 --- a/include/linux/loop.h +++ b/include/linux/loop.h | |||
@@ -53,10 +53,13 @@ struct loop_device { | |||
53 | 53 | ||
54 | spinlock_t lo_lock; | 54 | spinlock_t lo_lock; |
55 | struct bio_list lo_bio_list; | 55 | struct bio_list lo_bio_list; |
56 | unsigned int lo_bio_count; | ||
56 | int lo_state; | 57 | int lo_state; |
57 | struct mutex lo_ctl_mutex; | 58 | struct mutex lo_ctl_mutex; |
58 | struct task_struct *lo_thread; | 59 | struct task_struct *lo_thread; |
59 | wait_queue_head_t lo_event; | 60 | wait_queue_head_t lo_event; |
61 | /* wait queue for incoming requests */ | ||
62 | wait_queue_head_t lo_req_wait; | ||
60 | 63 | ||
61 | struct request_queue *lo_queue; | 64 | struct request_queue *lo_queue; |
62 | struct gendisk *lo_disk; | 65 | struct gendisk *lo_disk; |