diff options
-rw-r--r-- | drivers/block/loop.c | 27 | ||||
-rw-r--r-- | include/linux/loop.h | 4 |
2 files changed, 14 insertions, 17 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index bed9ad76c04c..864729046e22 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
@@ -527,12 +527,12 @@ static int loop_make_request(request_queue_t *q, struct bio *old_bio) | |||
527 | lo->lo_pending++; | 527 | lo->lo_pending++; |
528 | loop_add_bio(lo, old_bio); | 528 | loop_add_bio(lo, old_bio); |
529 | spin_unlock_irq(&lo->lo_lock); | 529 | spin_unlock_irq(&lo->lo_lock); |
530 | up(&lo->lo_bh_mutex); | 530 | complete(&lo->lo_bh_done); |
531 | return 0; | 531 | return 0; |
532 | 532 | ||
533 | out: | 533 | out: |
534 | if (lo->lo_pending == 0) | 534 | if (lo->lo_pending == 0) |
535 | up(&lo->lo_bh_mutex); | 535 | complete(&lo->lo_bh_done); |
536 | spin_unlock_irq(&lo->lo_lock); | 536 | spin_unlock_irq(&lo->lo_lock); |
537 | bio_io_error(old_bio, old_bio->bi_size); | 537 | bio_io_error(old_bio, old_bio->bi_size); |
538 | return 0; | 538 | return 0; |
@@ -593,23 +593,20 @@ static int loop_thread(void *data) | |||
593 | lo->lo_pending = 1; | 593 | lo->lo_pending = 1; |
594 | 594 | ||
595 | /* | 595 | /* |
596 | * up sem, we are running | 596 | * complete it, we are running |
597 | */ | 597 | */ |
598 | up(&lo->lo_sem); | 598 | complete(&lo->lo_done); |
599 | 599 | ||
600 | for (;;) { | 600 | for (;;) { |
601 | int pending; | 601 | int pending; |
602 | 602 | ||
603 | /* | 603 | if (wait_for_completion_interruptible(&lo->lo_bh_done)) |
604 | * interruptible just to not contribute to load avg | ||
605 | */ | ||
606 | if (down_interruptible(&lo->lo_bh_mutex)) | ||
607 | continue; | 604 | continue; |
608 | 605 | ||
609 | spin_lock_irq(&lo->lo_lock); | 606 | spin_lock_irq(&lo->lo_lock); |
610 | 607 | ||
611 | /* | 608 | /* |
612 | * could be upped because of tear-down, not pending work | 609 | * could be completed because of tear-down, not pending work |
613 | */ | 610 | */ |
614 | if (unlikely(!lo->lo_pending)) { | 611 | if (unlikely(!lo->lo_pending)) { |
615 | spin_unlock_irq(&lo->lo_lock); | 612 | spin_unlock_irq(&lo->lo_lock); |
@@ -632,7 +629,7 @@ static int loop_thread(void *data) | |||
632 | break; | 629 | break; |
633 | } | 630 | } |
634 | 631 | ||
635 | up(&lo->lo_sem); | 632 | complete(&lo->lo_done); |
636 | return 0; | 633 | return 0; |
637 | } | 634 | } |
638 | 635 | ||
@@ -843,7 +840,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, | |||
843 | set_blocksize(bdev, lo_blocksize); | 840 | set_blocksize(bdev, lo_blocksize); |
844 | 841 | ||
845 | kernel_thread(loop_thread, lo, CLONE_KERNEL); | 842 | kernel_thread(loop_thread, lo, CLONE_KERNEL); |
846 | down(&lo->lo_sem); | 843 | wait_for_completion(&lo->lo_done); |
847 | return 0; | 844 | return 0; |
848 | 845 | ||
849 | out_putf: | 846 | out_putf: |
@@ -909,10 +906,10 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) | |||
909 | lo->lo_state = Lo_rundown; | 906 | lo->lo_state = Lo_rundown; |
910 | lo->lo_pending--; | 907 | lo->lo_pending--; |
911 | if (!lo->lo_pending) | 908 | if (!lo->lo_pending) |
912 | up(&lo->lo_bh_mutex); | 909 | complete(&lo->lo_bh_done); |
913 | spin_unlock_irq(&lo->lo_lock); | 910 | spin_unlock_irq(&lo->lo_lock); |
914 | 911 | ||
915 | down(&lo->lo_sem); | 912 | wait_for_completion(&lo->lo_done); |
916 | 913 | ||
917 | lo->lo_backing_file = NULL; | 914 | lo->lo_backing_file = NULL; |
918 | 915 | ||
@@ -1289,8 +1286,8 @@ static int __init loop_init(void) | |||
1289 | if (!lo->lo_queue) | 1286 | if (!lo->lo_queue) |
1290 | goto out_mem4; | 1287 | goto out_mem4; |
1291 | init_MUTEX(&lo->lo_ctl_mutex); | 1288 | init_MUTEX(&lo->lo_ctl_mutex); |
1292 | init_MUTEX_LOCKED(&lo->lo_sem); | 1289 | init_completion(&lo->lo_done); |
1293 | init_MUTEX_LOCKED(&lo->lo_bh_mutex); | 1290 | init_completion(&lo->lo_bh_done); |
1294 | lo->lo_number = i; | 1291 | lo->lo_number = i; |
1295 | spin_lock_init(&lo->lo_lock); | 1292 | spin_lock_init(&lo->lo_lock); |
1296 | disk->major = LOOP_MAJOR; | 1293 | disk->major = LOOP_MAJOR; |
diff --git a/include/linux/loop.h b/include/linux/loop.h index 40f63c9879d2..f96506782ebe 100644 --- a/include/linux/loop.h +++ b/include/linux/loop.h | |||
@@ -58,9 +58,9 @@ struct loop_device { | |||
58 | struct bio *lo_bio; | 58 | struct bio *lo_bio; |
59 | struct bio *lo_biotail; | 59 | struct bio *lo_biotail; |
60 | int lo_state; | 60 | int lo_state; |
61 | struct semaphore lo_sem; | 61 | struct completion lo_done; |
62 | struct completion lo_bh_done; | ||
62 | struct semaphore lo_ctl_mutex; | 63 | struct semaphore lo_ctl_mutex; |
63 | struct semaphore lo_bh_mutex; | ||
64 | int lo_pending; | 64 | int lo_pending; |
65 | 65 | ||
66 | request_queue_t *lo_queue; | 66 | request_queue_t *lo_queue; |