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 9dc294a74953..3c74ea729fc7 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 bf3d2345ce99..e76c7611d6cc 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; |
