lkml.org 
[lkml]   [2006]   [Jun]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: please revert kthread from loop.c
Quoting Hugh Dickins (hugh@veritas.com):
> Please revert c7b2eff059fcc2d1b7085ee3d84b79fd657a537b
> [PATCH] kthread: update loop.c to use kthread
>
> 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): 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.
>
> 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

Very sorry.


Subject: [PATCH] kthread: convert loop.c to use kthread

Convert loop.c to use kthread in place of the deprecated
kernel_thread.

Update: Keep the lo_done completion to indicate when the
loop_thread is ready. Otherwise a user gets the
go-ahead early and may start an ioctl before
loop_thread is in fact ready.

Also fix some other bugs including misnaming the thread,
found by Andrew Morton, and not setting lo->thread as
pointed out by Hugh Dickins.

This version has passed parallel runs of the following
script (on different devices of course), i.e.

sh looptorture.sh 3 [ in screen 1 ]
sh looptorture.sh 5 [ in screen 2 ]

looptorture.sh contains the following script based
on the one sent by Hugh Dickins earlier today:

j=0
if [ $# > 0 ]; then
num=$1
else
num=0
fi
echo "starting loop ($num)"
if [ ! -d /mnt/$num ]; then
mkdir /mnt/$num
fi
dd if=/dev/zero of=/tst/zero$num bs=1M count=100
while [ $j -lt 100 ]; do
let j=j+1
echo "Doing pass $j"
losetup /dev/loop$num /tst/zero$num
mkfs -t ext2 -b 1024 /dev/loop$num >/dev/null 2>&1
mount -t ext2 /dev/loop$num /mnt/$num
umount /mnt/$num
losetup -d /dev/loop$num
done

Signed-off-by: Serge Hallyn <serue@us.ibm.com>

---

drivers/block/loop.c | 16 ++++++++++------
include/linux/loop.h | 1 +
2 files changed, 11 insertions(+), 6 deletions(-)

71c305041760195a3c96aedae52f7d8ce3982d72
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 3c74ea7..b3d1710 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -74,6 +74,7 @@
#include <linux/completion.h>
#include <linux/highmem.h>
#include <linux/gfp.h>
+#include <linux/kthread.h>

#include <asm/uaccess.h>

@@ -578,8 +579,7 @@ static int loop_thread(void *data)
struct loop_device *lo = data;
struct bio *bio;

- daemonize("loop%d", lo->lo_number);
-
+ lo->lo_thread = current;
/*
* loop can be used in an encrypted device,
* hence, it mustn't be stopped at all
@@ -629,7 +629,6 @@ static int loop_thread(void *data)
break;
}

- complete(&lo->lo_done);
return 0;
}

@@ -747,6 +746,7 @@ static int loop_set_fd(struct loop_devic
int lo_flags = 0;
int error;
loff_t size;
+ struct task_struct *tsk;

/* This is safe, since we have a reference from open(). */
__module_get(THIS_MODULE);
@@ -839,9 +839,11 @@ static int loop_set_fd(struct loop_devic

set_blocksize(bdev, lo_blocksize);

- error = kernel_thread(loop_thread, lo, CLONE_KERNEL);
- if (error < 0)
+ tsk = kthread_run(loop_thread, lo, "loop%d", lo->lo_number);
+ if (IS_ERR(tsk)) {
+ error = PTR_ERR(tsk);
goto out_putf;
+ }
wait_for_completion(&lo->lo_done);
return 0;

@@ -911,7 +913,7 @@ static int loop_clr_fd(struct loop_devic
complete(&lo->lo_bh_done);
spin_unlock_irq(&lo->lo_lock);

- wait_for_completion(&lo->lo_done);
+ kthread_stop(lo->lo_thread);

lo->lo_backing_file = NULL;

@@ -921,6 +923,7 @@ static int loop_clr_fd(struct loop_devic
lo->lo_device = NULL;
lo->lo_encryption = NULL;
lo->lo_offset = 0;
+ lo->lo_thread = NULL;
lo->lo_sizelimit = 0;
lo->lo_encrypt_key_size = 0;
lo->lo_flags = 0;
@@ -1288,6 +1291,7 @@ static int __init loop_init(void)
if (!lo->lo_queue)
goto out_mem4;
mutex_init(&lo->lo_ctl_mutex);
+ lo->lo_thread = NULL;
init_completion(&lo->lo_done);
init_completion(&lo->lo_bh_done);
lo->lo_number = i;
diff --git a/include/linux/loop.h b/include/linux/loop.h
index e76c761..4bd4cde 100644
--- a/include/linux/loop.h
+++ b/include/linux/loop.h
@@ -59,6 +59,7 @@ struct loop_device {
struct bio *lo_bio;
struct bio *lo_biotail;
int lo_state;
+ struct task_struct *lo_thread;
struct completion lo_done;
struct completion lo_bh_done;
struct mutex lo_ctl_mutex;
--
1.1.6
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
\
 
 \ /
  Last update: 2006-06-27 07:50    [W:0.591 / U:1.136 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site