aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorSerge E. Hallyn <serue@us.ibm.com>2006-09-29 04:59:11 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-09-29 12:18:06 -0400
commit6c9979185c7ef4feeb7f8d29be032b8f032a1838 (patch)
treedd6d45dc21adf280164ba840ae0c954dd0c94233 /drivers/block
parent5b217fa75c3aea381f1f5fa7ff09e7b4019ea374 (diff)
[PATCH] kthread: convert loop.c to kthread
Convert loop.c from the deprecated kernel_thread to kthread. This patch simplifies the code quite a bit and passes similar testing to the previous submission on both emulated x86 and s390. Changes since last submission: switched to using a rather simple loop based on wait_event_interruptible. Signed-off-by: Serge E. Hallyn <serue@us.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/loop.c69
1 files changed, 24 insertions, 45 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index c774121684d7..e87b88731adc 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -72,6 +72,7 @@
72#include <linux/completion.h> 72#include <linux/completion.h>
73#include <linux/highmem.h> 73#include <linux/highmem.h>
74#include <linux/gfp.h> 74#include <linux/gfp.h>
75#include <linux/kthread.h>
75 76
76#include <asm/uaccess.h> 77#include <asm/uaccess.h>
77 78
@@ -522,15 +523,12 @@ static int loop_make_request(request_queue_t *q, struct bio *old_bio)
522 goto out; 523 goto out;
523 if (unlikely(rw == WRITE && (lo->lo_flags & LO_FLAGS_READ_ONLY))) 524 if (unlikely(rw == WRITE && (lo->lo_flags & LO_FLAGS_READ_ONLY)))
524 goto out; 525 goto out;
525 lo->lo_pending++;
526 loop_add_bio(lo, old_bio); 526 loop_add_bio(lo, old_bio);
527 wake_up(&lo->lo_event);
527 spin_unlock_irq(&lo->lo_lock); 528 spin_unlock_irq(&lo->lo_lock);
528 complete(&lo->lo_bh_done);
529 return 0; 529 return 0;
530 530
531out: 531out:
532 if (lo->lo_pending == 0)
533 complete(&lo->lo_bh_done);
534 spin_unlock_irq(&lo->lo_lock); 532 spin_unlock_irq(&lo->lo_lock);
535 bio_io_error(old_bio, old_bio->bi_size); 533 bio_io_error(old_bio, old_bio->bi_size);
536 return 0; 534 return 0;
@@ -570,14 +568,18 @@ static inline void loop_handle_bio(struct loop_device *lo, struct bio *bio)
570 * to avoid blocking in our make_request_fn. it also does loop decrypting 568 * to avoid blocking in our make_request_fn. it also does loop decrypting
571 * on reads for block backed loop, as that is too heavy to do from 569 * on reads for block backed loop, as that is too heavy to do from
572 * b_end_io context where irqs may be disabled. 570 * b_end_io context where irqs may be disabled.
571 *
572 * Loop explanation: loop_clr_fd() sets lo_state to Lo_rundown before
573 * calling kthread_stop(). Therefore once kthread_should_stop() is
574 * true, make_request will not place any more requests. Therefore
575 * once kthread_should_stop() is true and lo_bio is NULL, we are
576 * done with the loop.
573 */ 577 */
574static int loop_thread(void *data) 578static int loop_thread(void *data)
575{ 579{
576 struct loop_device *lo = data; 580 struct loop_device *lo = data;
577 struct bio *bio; 581 struct bio *bio;
578 582
579 daemonize("loop%d", lo->lo_number);
580
581 /* 583 /*
582 * loop can be used in an encrypted device, 584 * loop can be used in an encrypted device,
583 * hence, it mustn't be stopped at all 585 * hence, it mustn't be stopped at all
@@ -587,47 +589,21 @@ static int loop_thread(void *data)
587 589
588 set_user_nice(current, -20); 590 set_user_nice(current, -20);
589 591
590 lo->lo_state = Lo_bound; 592 while (!kthread_should_stop() || lo->lo_bio) {
591 lo->lo_pending = 1;
592
593 /*
594 * complete it, we are running
595 */
596 complete(&lo->lo_done);
597 593
598 for (;;) { 594 wait_event_interruptible(lo->lo_event,
599 int pending; 595 lo->lo_bio || kthread_should_stop());
600 596
601 if (wait_for_completion_interruptible(&lo->lo_bh_done)) 597 if (!lo->lo_bio)
602 continue; 598 continue;
603
604 spin_lock_irq(&lo->lo_lock); 599 spin_lock_irq(&lo->lo_lock);
605
606 /*
607 * could be completed because of tear-down, not pending work
608 */
609 if (unlikely(!lo->lo_pending)) {
610 spin_unlock_irq(&lo->lo_lock);
611 break;
612 }
613
614 bio = loop_get_bio(lo); 600 bio = loop_get_bio(lo);
615 lo->lo_pending--;
616 pending = lo->lo_pending;
617 spin_unlock_irq(&lo->lo_lock); 601 spin_unlock_irq(&lo->lo_lock);
618 602
619 BUG_ON(!bio); 603 BUG_ON(!bio);
620 loop_handle_bio(lo, bio); 604 loop_handle_bio(lo, bio);
621
622 /*
623 * upped both for pending work and tear-down, lo_pending
624 * will hit zero then
625 */
626 if (unlikely(!pending))
627 break;
628 } 605 }
629 606
630 complete(&lo->lo_done);
631 return 0; 607 return 0;
632} 608}
633 609
@@ -840,10 +816,15 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
840 816
841 set_blocksize(bdev, lo_blocksize); 817 set_blocksize(bdev, lo_blocksize);
842 818
843 error = kernel_thread(loop_thread, lo, CLONE_KERNEL); 819 lo->lo_thread = kthread_create(loop_thread, lo, "loop%d",
844 if (error < 0) 820 lo->lo_number);
821 if (IS_ERR(lo->lo_thread)) {
822 error = PTR_ERR(lo->lo_thread);
823 lo->lo_thread = NULL;
845 goto out_putf; 824 goto out_putf;
846 wait_for_completion(&lo->lo_done); 825 }
826 lo->lo_state = Lo_bound;
827 wake_up_process(lo->lo_thread);
847 return 0; 828 return 0;
848 829
849 out_putf: 830 out_putf:
@@ -907,12 +888,9 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
907 888
908 spin_lock_irq(&lo->lo_lock); 889 spin_lock_irq(&lo->lo_lock);
909 lo->lo_state = Lo_rundown; 890 lo->lo_state = Lo_rundown;
910 lo->lo_pending--;
911 if (!lo->lo_pending)
912 complete(&lo->lo_bh_done);
913 spin_unlock_irq(&lo->lo_lock); 891 spin_unlock_irq(&lo->lo_lock);
914 892
915 wait_for_completion(&lo->lo_done); 893 kthread_stop(lo->lo_thread);
916 894
917 lo->lo_backing_file = NULL; 895 lo->lo_backing_file = NULL;
918 896
@@ -925,6 +903,7 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
925 lo->lo_sizelimit = 0; 903 lo->lo_sizelimit = 0;
926 lo->lo_encrypt_key_size = 0; 904 lo->lo_encrypt_key_size = 0;
927 lo->lo_flags = 0; 905 lo->lo_flags = 0;
906 lo->lo_thread = NULL;
928 memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE); 907 memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
929 memset(lo->lo_crypt_name, 0, LO_NAME_SIZE); 908 memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
930 memset(lo->lo_file_name, 0, LO_NAME_SIZE); 909 memset(lo->lo_file_name, 0, LO_NAME_SIZE);
@@ -1287,9 +1266,9 @@ static int __init loop_init(void)
1287 if (!lo->lo_queue) 1266 if (!lo->lo_queue)
1288 goto out_mem4; 1267 goto out_mem4;
1289 mutex_init(&lo->lo_ctl_mutex); 1268 mutex_init(&lo->lo_ctl_mutex);
1290 init_completion(&lo->lo_done);
1291 init_completion(&lo->lo_bh_done);
1292 lo->lo_number = i; 1269 lo->lo_number = i;
1270 lo->lo_thread = NULL;
1271 init_waitqueue_head(&lo->lo_event);
1293 spin_lock_init(&lo->lo_lock); 1272 spin_lock_init(&lo->lo_lock);
1294 disk->major = LOOP_MAJOR; 1273 disk->major = LOOP_MAJOR;
1295 disk->first_minor = i; 1274 disk->first_minor = i;