Commit 09c0dc68 authored by Linus Torvalds's avatar Linus Torvalds

Revert "[PATCH] kthread: update loop.c to use kthread"

This reverts commit c7b2eff0.

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: default avatarLinus Torvalds <torvalds@osdl.org>
parent 2a2ed2db
...@@ -74,7 +74,6 @@ ...@@ -74,7 +74,6 @@
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/highmem.h> #include <linux/highmem.h>
#include <linux/gfp.h> #include <linux/gfp.h>
#include <linux/kthread.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -579,6 +578,8 @@ static int loop_thread(void *data) ...@@ -579,6 +578,8 @@ static int loop_thread(void *data)
struct loop_device *lo = data; struct loop_device *lo = data;
struct bio *bio; struct bio *bio;
daemonize("loop%d", lo->lo_number);
/* /*
* loop can be used in an encrypted device, * loop can be used in an encrypted device,
* hence, it mustn't be stopped at all * hence, it mustn't be stopped at all
...@@ -591,6 +592,11 @@ static int loop_thread(void *data) ...@@ -591,6 +592,11 @@ static int loop_thread(void *data)
lo->lo_state = Lo_bound; lo->lo_state = Lo_bound;
lo->lo_pending = 1; lo->lo_pending = 1;
/*
* complete it, we are running
*/
complete(&lo->lo_done);
for (;;) { for (;;) {
int pending; int pending;
...@@ -623,6 +629,7 @@ static int loop_thread(void *data) ...@@ -623,6 +629,7 @@ static int loop_thread(void *data)
break; break;
} }
complete(&lo->lo_done);
return 0; return 0;
} }
...@@ -739,7 +746,6 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, ...@@ -739,7 +746,6 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
unsigned lo_blocksize; unsigned lo_blocksize;
int lo_flags = 0; int lo_flags = 0;
int error; int error;
struct task_struct *tsk;
loff_t size; loff_t size;
/* This is safe, since we have a reference from open(). */ /* 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,11 +839,10 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
set_blocksize(bdev, lo_blocksize); set_blocksize(bdev, lo_blocksize);
tsk = kthread_run(loop_thread, lo, "loop%d", lo->lo_number); error = kernel_thread(loop_thread, lo, CLONE_KERNEL);
if (IS_ERR(tsk)) { if (error < 0)
error = PTR_ERR(tsk);
goto out_putf; goto out_putf;
} wait_for_completion(&lo->lo_done);
return 0; return 0;
out_putf: out_putf:
...@@ -893,9 +898,6 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) ...@@ -893,9 +898,6 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
if (lo->lo_state != Lo_bound) if (lo->lo_state != Lo_bound)
return -ENXIO; return -ENXIO;
if (!lo->lo_thread)
return -EINVAL;
if (lo->lo_refcnt > 1) /* we needed one fd for the ioctl */ if (lo->lo_refcnt > 1) /* we needed one fd for the ioctl */
return -EBUSY; return -EBUSY;
...@@ -909,7 +911,7 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) ...@@ -909,7 +911,7 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
complete(&lo->lo_bh_done); complete(&lo->lo_bh_done);
spin_unlock_irq(&lo->lo_lock); spin_unlock_irq(&lo->lo_lock);
kthread_stop(lo->lo_thread); wait_for_completion(&lo->lo_done);
lo->lo_backing_file = NULL; lo->lo_backing_file = NULL;
...@@ -922,7 +924,6 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) ...@@ -922,7 +924,6 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
lo->lo_sizelimit = 0; lo->lo_sizelimit = 0;
lo->lo_encrypt_key_size = 0; lo->lo_encrypt_key_size = 0;
lo->lo_flags = 0; lo->lo_flags = 0;
lo->lo_thread = NULL;
memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE); memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
memset(lo->lo_crypt_name, 0, LO_NAME_SIZE); memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
memset(lo->lo_file_name, 0, LO_NAME_SIZE); memset(lo->lo_file_name, 0, LO_NAME_SIZE);
...@@ -1287,6 +1288,7 @@ static int __init loop_init(void) ...@@ -1287,6 +1288,7 @@ static int __init loop_init(void)
if (!lo->lo_queue) if (!lo->lo_queue)
goto out_mem4; goto out_mem4;
mutex_init(&lo->lo_ctl_mutex); mutex_init(&lo->lo_ctl_mutex);
init_completion(&lo->lo_done);
init_completion(&lo->lo_bh_done); init_completion(&lo->lo_bh_done);
lo->lo_number = i; lo->lo_number = i;
spin_lock_init(&lo->lo_lock); spin_lock_init(&lo->lo_lock);
......
...@@ -59,7 +59,7 @@ struct loop_device { ...@@ -59,7 +59,7 @@ struct loop_device {
struct bio *lo_bio; struct bio *lo_bio;
struct bio *lo_biotail; struct bio *lo_biotail;
int lo_state; int lo_state;
struct task_struct *lo_thread; struct completion lo_done;
struct completion lo_bh_done; struct completion lo_bh_done;
struct mutex lo_ctl_mutex; struct mutex lo_ctl_mutex;
int lo_pending; int lo_pending;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment