diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-26 14:55:42 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-26 14:55:42 -0400 |
commit | 09c0dc68625c06f5b1e786aad0d5369b592179e6 (patch) | |
tree | 19fd06de08792a4c07ee8b61e5615ee35e8ccec0 | |
parent | 2a2ed2db353d949c06b6ef8b6913f65b39111eab (diff) |
Revert "[PATCH] kthread: update loop.c to use kthread"
This reverts commit c7b2eff059fcc2d1b7085ee3d84b79fd657a537b.
Hugh Dickins explains:
"It seems too little tested: "losetup -d /dev/loop0" fails with
EINVAL because nothing sets lo_thread; but even when you patch
loop_thread() to set lo->lo_thread = current, it can't survive
more than a few dozen iterations of the loop below (with a tmpfs
mounted on /tst):
j=0
cp /dev/zero /tst
while :
do
let j=j+1
echo "Doing pass $j"
losetup /dev/loop0 /tst/zero
mkfs -t ext2 -b 1024 /dev/loop0 >/dev/null 2>&1
mount -t ext2 /dev/loop0 /mnt
umount /mnt
losetup -d /dev/loop0
done
it collapses with failed ioctl then BUG_ON(!bio).
I think the original lo_done completion was more subtle and safe
than the kthread conversion has allowed for."
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | drivers/block/loop.c | 24 | ||||
-rw-r--r-- | include/linux/loop.h | 2 |
2 files changed, 14 insertions, 12 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 9dc294a7495..3c74ea729fc 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
@@ -74,7 +74,6 @@ | |||
74 | #include <linux/completion.h> | 74 | #include <linux/completion.h> |
75 | #include <linux/highmem.h> | 75 | #include <linux/highmem.h> |
76 | #include <linux/gfp.h> | 76 | #include <linux/gfp.h> |
77 | #include <linux/kthread.h> | ||
78 | 77 | ||
79 | #include <asm/uaccess.h> | 78 | #include <asm/uaccess.h> |
80 | 79 | ||
@@ -579,6 +578,8 @@ static int loop_thread(void *data) | |||
579 | struct loop_device *lo = data; | 578 | struct loop_device *lo = data; |
580 | struct bio *bio; | 579 | struct bio *bio; |
581 | 580 | ||
581 | daemonize("loop%d", lo->lo_number); | ||
582 | |||
582 | /* | 583 | /* |
583 | * loop can be used in an encrypted device, | 584 | * loop can be used in an encrypted device, |
584 | * hence, it mustn't be stopped at all | 585 | * hence, it mustn't be stopped at all |
@@ -591,6 +592,11 @@ static int loop_thread(void *data) | |||
591 | lo->lo_state = Lo_bound; | 592 | lo->lo_state = Lo_bound; |
592 | lo->lo_pending = 1; | 593 | lo->lo_pending = 1; |
593 | 594 | ||
595 | /* | ||
596 | * complete it, we are running | ||
597 | */ | ||
598 | complete(&lo->lo_done); | ||
599 | |||
594 | for (;;) { | 600 | for (;;) { |
595 | int pending; | 601 | int pending; |
596 | 602 | ||
@@ -623,6 +629,7 @@ static int loop_thread(void *data) | |||
623 | break; | 629 | break; |
624 | } | 630 | } |
625 | 631 | ||
632 | complete(&lo->lo_done); | ||
626 | return 0; | 633 | return 0; |
627 | } | 634 | } |
628 | 635 | ||
@@ -739,7 +746,6 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, | |||
739 | unsigned lo_blocksize; | 746 | unsigned lo_blocksize; |
740 | int lo_flags = 0; | 747 | int lo_flags = 0; |
741 | int error; | 748 | int error; |
742 | struct task_struct *tsk; | ||
743 | loff_t size; | 749 | loff_t size; |
744 | 750 | ||
745 | /* This is safe, since we have a reference from open(). */ | 751 | /* This is safe, since we have a reference from open(). */ |
@@ -833,11 +839,10 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, | |||
833 | 839 | ||
834 | set_blocksize(bdev, lo_blocksize); | 840 | set_blocksize(bdev, lo_blocksize); |
835 | 841 | ||
836 | tsk = kthread_run(loop_thread, lo, "loop%d", lo->lo_number); | 842 | error = kernel_thread(loop_thread, lo, CLONE_KERNEL); |
837 | if (IS_ERR(tsk)) { | 843 | if (error < 0) |
838 | error = PTR_ERR(tsk); | ||
839 | goto out_putf; | 844 | goto out_putf; |
840 | } | 845 | wait_for_completion(&lo->lo_done); |
841 | return 0; | 846 | return 0; |
842 | 847 | ||
843 | out_putf: | 848 | out_putf: |
@@ -893,9 +898,6 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) | |||
893 | if (lo->lo_state != Lo_bound) | 898 | if (lo->lo_state != Lo_bound) |
894 | return -ENXIO; | 899 | return -ENXIO; |
895 | 900 | ||
896 | if (!lo->lo_thread) | ||
897 | return -EINVAL; | ||
898 | |||
899 | if (lo->lo_refcnt > 1) /* we needed one fd for the ioctl */ | 901 | if (lo->lo_refcnt > 1) /* we needed one fd for the ioctl */ |
900 | return -EBUSY; | 902 | return -EBUSY; |
901 | 903 | ||
@@ -909,7 +911,7 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) | |||
909 | complete(&lo->lo_bh_done); | 911 | complete(&lo->lo_bh_done); |
910 | spin_unlock_irq(&lo->lo_lock); | 912 | spin_unlock_irq(&lo->lo_lock); |
911 | 913 | ||
912 | kthread_stop(lo->lo_thread); | 914 | wait_for_completion(&lo->lo_done); |
913 | 915 | ||
914 | lo->lo_backing_file = NULL; | 916 | lo->lo_backing_file = NULL; |
915 | 917 | ||
@@ -922,7 +924,6 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) | |||
922 | lo->lo_sizelimit = 0; | 924 | lo->lo_sizelimit = 0; |
923 | lo->lo_encrypt_key_size = 0; | 925 | lo->lo_encrypt_key_size = 0; |
924 | lo->lo_flags = 0; | 926 | lo->lo_flags = 0; |
925 | lo->lo_thread = NULL; | ||
926 | memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE); | 927 | memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE); |
927 | memset(lo->lo_crypt_name, 0, LO_NAME_SIZE); | 928 | memset(lo->lo_crypt_name, 0, LO_NAME_SIZE); |
928 | memset(lo->lo_file_name, 0, LO_NAME_SIZE); | 929 | memset(lo->lo_file_name, 0, LO_NAME_SIZE); |
@@ -1287,6 +1288,7 @@ static int __init loop_init(void) | |||
1287 | if (!lo->lo_queue) | 1288 | if (!lo->lo_queue) |
1288 | goto out_mem4; | 1289 | goto out_mem4; |
1289 | mutex_init(&lo->lo_ctl_mutex); | 1290 | mutex_init(&lo->lo_ctl_mutex); |
1291 | init_completion(&lo->lo_done); | ||
1290 | init_completion(&lo->lo_bh_done); | 1292 | init_completion(&lo->lo_bh_done); |
1291 | lo->lo_number = i; | 1293 | lo->lo_number = i; |
1292 | spin_lock_init(&lo->lo_lock); | 1294 | spin_lock_init(&lo->lo_lock); |
diff --git a/include/linux/loop.h b/include/linux/loop.h index bf3d2345ce9..e76c7611d6c 100644 --- a/include/linux/loop.h +++ b/include/linux/loop.h | |||
@@ -59,7 +59,7 @@ struct loop_device { | |||
59 | struct bio *lo_bio; | 59 | struct bio *lo_bio; |
60 | struct bio *lo_biotail; | 60 | struct bio *lo_biotail; |
61 | int lo_state; | 61 | int lo_state; |
62 | struct task_struct *lo_thread; | 62 | struct completion lo_done; |
63 | struct completion lo_bh_done; | 63 | struct completion lo_bh_done; |
64 | struct mutex lo_ctl_mutex; | 64 | struct mutex lo_ctl_mutex; |
65 | int lo_pending; | 65 | int lo_pending; |