linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* rootdelay
@ 2005-03-30 18:05 David N. Welton
  2005-04-01 18:27 ` rootdelay Daniel Drake
  2005-04-26 10:11 ` rootdelay Pekka Enberg
  0 siblings, 2 replies; 11+ messages in thread
From: David N. Welton @ 2005-03-30 18:05 UTC (permalink / raw)
  To: dsd; +Cc: linux-kernel


[ Please CC replies to me, thanks! ]

Hi, I was looking at your patch:

http://lkml.org/lkml/2005/1/21/132

Very small, which is nice.

I was wondering if there were any interest in my own efforts in that
direction:

http://dedasys.com/freesoftware/patches/blkdev_wakeup.patch

which is far more intrusive, and perhaps isn't good kernel programming
style, but, on the other hand, is the optimal solution in terms of
boot time because it wakes up the boot process right when the device
comes on line.

Since I saw your patch included, it looks like there is interest in
this, and I'd toot my own horn once more before just leaving my patch
to the bit rot of the ages...

Thanks!
-- 
David N. Welton
 - http://www.dedasys.com/davidw/

Apache, Linux, Tcl Consulting
 - http://www.dedasys.com/

Got the right list this time too...:-/

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: rootdelay
  2005-03-30 18:05 rootdelay David N. Welton
@ 2005-04-01 18:27 ` Daniel Drake
  2005-04-25  9:45   ` rootdelay David N. Welton
  2005-04-26 10:11 ` rootdelay Pekka Enberg
  1 sibling, 1 reply; 11+ messages in thread
From: Daniel Drake @ 2005-04-01 18:27 UTC (permalink / raw)
  To: David N. Welton; +Cc: linux-kernel, akpm, viro, helge.hafting, opengeometry

Hi David,

David N. Welton wrote:
> [ Please CC replies to me, thanks! ]
> 
> Hi, I was looking at your patch:
> 
> http://lkml.org/lkml/2005/1/21/132
> 
> Very small, which is nice.
> 
> I was wondering if there were any interest in my own efforts in that
> direction:
> 
> http://dedasys.com/freesoftware/patches/blkdev_wakeup.patch
> 
> which is far more intrusive, and perhaps isn't good kernel programming
> style, but, on the other hand, is the optimal solution in terms of
> boot time because it wakes up the boot process right when the device
> comes on line.
> 
> Since I saw your patch included, it looks like there is interest in
> this, and I'd toot my own horn once more before just leaving my patch
> to the bit rot of the ages...
> 
> Thanks!

As simple as it may be, it's a bit of a shame that we actually need rootdelay 
as its something that the kernel should do automatically. At the time when we 
last discussed it, we didn't come up with a better (and safe) way to handle 
it, but I don't think we considered anything like your implementation.

I've CC'd a few people who were involved the last time around to see if they 
have any input for you.

Daniel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: rootdelay
  2005-04-01 18:27 ` rootdelay Daniel Drake
@ 2005-04-25  9:45   ` David N. Welton
  2005-04-25 14:42     ` rootdelay William Park
  0 siblings, 1 reply; 11+ messages in thread
From: David N. Welton @ 2005-04-25  9:45 UTC (permalink / raw)
  To: Daniel Drake; +Cc: linux-kernel, akpm, viro, helge.hafting, opengeometry

Daniel Drake <dsd@gentoo.org> writes:

[ Please CC replies to me - thanks! ]

> Hi David,

> David N. Welton wrote:

> > [ Please CC replies to me, thanks! ]

> > Hi, I was looking at your patch:

> > http://lkml.org/lkml/2005/1/21/132 Very small, which is nice.  I

> > was wondering if there were any interest in my own efforts in that
> > direction:

> > http://dedasys.com/freesoftware/patches/blkdev_wakeup.patch which

> > is far more intrusive, and perhaps isn't good kernel programming
> > style, but, on the other hand, is the optimal solution in terms of
> > boot time because it wakes up the boot process right when the
> > device comes on line.  Since I saw your patch included, it looks
> > like there is interest in this, and I'd toot my own horn once more
> > before just leaving my patch to the bit rot of the ages...
> > Thanks!

> As simple as it may be, it's a bit of a shame that we actually need
> rootdelay as its something that the kernel should do
> automatically. At the time when we last discussed it, we didn't come
> up with a better (and safe) way to handle it, but I don't think we
> considered anything like your implementation.

> I've CC'd a few people who were involved the last time around to see
> if they have any input for you.

Thanks!  I don't wish to be a pest, but not having heard a "no", I'll
send another ping out.  Perhaps a simple description is better than
the patch for busy people:

    In init/do_mounts.c, mount_root does an interruptible_sleep_on a
    wait queue, and goes on about its business after register_blkdev
    in drivers/block/genhd.c does a wake_up_interruptible on it, so
    that mounting the root device happens exactly when it needs to, no
    sooner, no later, and doesn't depend on any fiddly timing issues.

Thankyou,
-- 
David N. Welton
 - http://www.dedasys.com/davidw/

Apache, Linux, Tcl Consulting
 - http://www.dedasys.com/

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: rootdelay
  2005-04-25  9:45   ` rootdelay David N. Welton
@ 2005-04-25 14:42     ` William Park
  2005-04-25 21:34       ` rootdelay David N. Welton
  0 siblings, 1 reply; 11+ messages in thread
From: William Park @ 2005-04-25 14:42 UTC (permalink / raw)
  To: David N. Welton; +Cc: Daniel Drake, linux-kernel, akpm, viro, helge.hafting

On Mon, Apr 25, 2005 at 11:45:59AM +0200, David N. Welton wrote:
> Daniel Drake <dsd@gentoo.org> writes:
> 
> [ Please CC replies to me - thanks! ]
> 
> > Hi David,
> 
> > David N. Welton wrote:
> 
> > > [ Please CC replies to me, thanks! ]
> 
> > > Hi, I was looking at your patch:
> 
> > > http://lkml.org/lkml/2005/1/21/132 Very small, which is nice.  I
> 
> > > was wondering if there were any interest in my own efforts in that
> > > direction:
> 
> > > http://dedasys.com/freesoftware/patches/blkdev_wakeup.patch which
> 
> > > is far more intrusive, and perhaps isn't good kernel programming
> > > style, but, on the other hand, is the optimal solution in terms of
> > > boot time because it wakes up the boot process right when the
> > > device comes on line.  Since I saw your patch included, it looks
> > > like there is interest in this, and I'd toot my own horn once more
> > > before just leaving my patch to the bit rot of the ages...
> > > Thanks!
> 
> > As simple as it may be, it's a bit of a shame that we actually need
> > rootdelay as its something that the kernel should do
> > automatically. At the time when we last discussed it, we didn't come
> > up with a better (and safe) way to handle it, but I don't think we
> > considered anything like your implementation.
> 
> > I've CC'd a few people who were involved the last time around to see
> > if they have any input for you.
> 
> Thanks!  I don't wish to be a pest, but not having heard a "no", I'll
> send another ping out.  Perhaps a simple description is better than
> the patch for busy people:
> 
>     In init/do_mounts.c, mount_root does an interruptible_sleep_on a
>     wait queue, and goes on about its business after register_blkdev
>     in drivers/block/genhd.c does a wake_up_interruptible on it, so
>     that mounting the root device happens exactly when it needs to, no
>     sooner, no later, and doesn't depend on any fiddly timing issues.

Post your patch to the list, and I'll get it from a newsgroup.

-- 
William Park <opengeometry@yahoo.ca>, Toronto, Canada
Slackware Linux -- because it works.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: rootdelay
  2005-04-25 14:42     ` rootdelay William Park
@ 2005-04-25 21:34       ` David N. Welton
  2005-04-29 18:34         ` rootdelay William Park
  0 siblings, 1 reply; 11+ messages in thread
From: David N. Welton @ 2005-04-25 21:34 UTC (permalink / raw)
  To: William Park; +Cc: Daniel Drake, linux-kernel, akpm, viro, helge.hafting

[-- Attachment #1: Type: text/plain, Size: 1135 bytes --]

William Park <opengeometry@yahoo.ca> writes:

> > > > was wondering if there were any interest in my own efforts in that
> > > > direction:
> > 
> > > > http://dedasys.com/freesoftware/patches/blkdev_wakeup.patch which

...

> > Thanks!  I don't wish to be a pest, but not having heard a "no",
> > I'll send another ping out.  Perhaps a simple description is
> > better than the patch for busy people:

> >     In init/do_mounts.c, mount_root does an interruptible_sleep_on
> >     a wait queue, and goes on about its business after
> >     register_blkdev in drivers/block/genhd.c does a
> >     wake_up_interruptible on it, so that mounting the root device
> >     happens exactly when it needs to, no sooner, no later, and
> >     doesn't depend on any fiddly timing issues.

> Post your patch to the list, and I'll get it from a newsgroup.

I sent the URL to the patch so as to avoid sending it around, but
since I don't know the etiquette of this list, I will attach the patch
for your perusal.

Thankyou once again,
-- 
David N. Welton
 - http://www.dedasys.com/davidw/

Apache, Linux, Tcl Consulting
 - http://www.dedasys.com/


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: blkdev_wakeup.patch --]
[-- Type: text/x-patch, Size: 5772 bytes --]

diff -ur -X dontdiff /usr/local/src/linux/arch/i386/kernel/reboot.c kernel/arch/i386/kernel/reboot.c
Only in /usr/local/src/linux/: config-2.6.5-1-686
Only in kernel/: do_mounts.patch
diff -ur -X dontdiff /usr/local/src/linux/drivers/block/genhd.c kernel/drivers/block/genhd.c
--- /usr/local/src/linux/drivers/block/genhd.c	2004-06-17 11:42:01.000000000 +0200
+++ kernel/drivers/block/genhd.c	2004-07-30 16:19:21.000000000 +0200
@@ -14,9 +14,14 @@
 #include <linux/slab.h>
 #include <linux/kmod.h>
 #include <linux/kobj_map.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
 
 #define MAX_PROBE_HASH 255	/* random */
 
+DECLARE_WAIT_QUEUE_HEAD(disk_wait_h);
+EXPORT_SYMBOL(disk_wait_h);
+
 static struct subsystem block_subsys;
 
 /*
@@ -57,6 +62,47 @@
 	return len;
 }
 
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * get_blkdevs --
+ *
+ * 	Returns an array of all the block device names.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+char **get_blkdevs(void)
+{
+    int i = 0;
+    int len = 0;
+    struct list_head *p;
+    char **names = NULL;
+    struct gendisk *sgp;
+    char buf[BDEVNAME_SIZE];
+
+    down_read(&block_subsys.rwsem);
+
+    list_for_each(p, &block_subsys.kset.list) {
+	len ++;
+    }
+
+    names = kmalloc(sizeof(char *) * len + 1, GFP_KERNEL);
+
+    list_for_each(p, &block_subsys.kset.list) {
+	sgp = list_entry(p, struct gendisk, kobj.entry);
+	names[i] = kmalloc(strlen(disk_name(sgp, 0, buf)), GFP_KERNEL);
+	strcpy(names[i], disk_name(sgp, 0, buf));
+	i ++;
+    }
+    names[i] = NULL;
+    up_read(&block_subsys.rwsem);
+
+    return names;
+}
+
+EXPORT_SYMBOL(get_blkdevs);
+
 int register_blkdev(unsigned int major, const char *name)
 {
 	struct blk_major_name **n, *p;
@@ -197,6 +243,11 @@
 			    disk->minors, NULL, exact_match, exact_lock, disk);
 	register_disk(disk);
 	blk_register_queue(disk);
+
+	/* Wake up queue in init/main.c. */
+	printk("Waking up queue on %s\n",
+	       disk->disk_name);
+	wake_up_interruptible(&disk_wait_h);
 }
 
 EXPORT_SYMBOL(add_disk);
diff -ur -X dontdiff /usr/local/src/linux/drivers/isdn/hardware/mISDN/hfc_multi.c kernel/drivers/isdn/hardware/mISDN/hfc_multi.c
Only in kernel/drivers/scsi: #sd.c#
diff -ur -X dontdiff /usr/local/src/linux/drivers/scsi/sd.c kernel/drivers/scsi/sd.c
diff -ur -X dontdiff /usr/local/src/linux/drivers/usb/storage/usb.c kernel/drivers/usb/storage/usb.c
diff -ur -X dontdiff /usr/local/src/linux/include/asm-i386/mach-default/mach_reboot.h kernel/include/asm-i386/mach-default/mach_reboot.h
Only in kernel/include/linux: #list.h#
diff -ur -X dontdiff /usr/local/src/linux/include/linux/genhd.h kernel/include/linux/genhd.h
--- /usr/local/src/linux/include/linux/genhd.h	2004-04-26 15:08:54.000000000 +0200
+++ kernel/include/linux/genhd.h	2004-07-30 16:29:45.000000000 +0200
@@ -16,6 +16,10 @@
 #include <linux/smp.h>
 #include <linux/string.h>
 #include <linux/fs.h>
+#include <linux/wait.h>
+
+/* Wait queue to wait on disks coming online. */
+extern wait_queue_head_t disk_wait_h;
 
 enum {
 /* These three have identical behaviour; use the second one if DOS FDISK gets
@@ -191,6 +195,7 @@
 
 extern void set_device_ro(struct block_device *bdev, int flag);
 extern void set_disk_ro(struct gendisk *disk, int flag);
+extern char **get_blkdevs(void);
 
 /* drivers/char/random.c */
 extern void add_disk_randomness(struct gendisk *disk);
diff -ur -X dontdiff /usr/local/src/linux/init/do_mounts.c kernel/init/do_mounts.c
--- /usr/local/src/linux/init/do_mounts.c	2004-05-19 10:22:22.000000000 +0200
+++ kernel/init/do_mounts.c	2004-07-30 16:32:26.000000000 +0200
@@ -11,6 +11,8 @@
 #include <linux/nfs_fs_sb.h>
 #include <linux/nfs_mount.h>
 
+#include <linux/genhd.h>
+
 #include "do_mounts.h"
 
 extern int get_filesystem_list(char * buf);
@@ -350,8 +360,41 @@
 }
 #endif
 
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * match_root_name --
+ *
+ * 	Returns 1 if the root_device_name appears amongst the list of
+ * 	block devices, 0 otherwise.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int __init match_root_name(void) {
+    char **names = NULL;
+    int i = 0;
+    int match = 0;
+
+    names = get_blkdevs();
+    while (names[i] != NULL) {
+	if (match == 0 && strncmp(names[i],
+				  root_device_name,
+				  strlen(names[i])) == 0) {
+	    match = 1;
+	    printk("Block device %s matches %s root_device_name, continuing\n",
+		   names[i], root_device_name);
+	}
+	kfree(names[i]);
+	i ++;
+    }
+    kfree(names);
+    return match;
+}
+
 void __init mount_root(void)
 {
+
 #ifdef CONFIG_ROOT_NFS
 	if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
 		if (mount_nfs_root())
@@ -373,6 +416,14 @@
 			change_floppy("root floppy");
 	}
 #endif
+
+	/* Here, we wait for the root device to show up, or if it's
+	 * already there, we just go on. */
+	while (match_root_name() == 0) {
+	    printk("Waiting for root device to wake us up\n");
+	    interruptible_sleep_on(&disk_wait_h);
+	}
+
 	create_dev("/dev/root", ROOT_DEV, root_device_name);
 	mount_block_root("/dev/root", root_mountflags);
 }
diff -ur -X dontdiff /usr/local/src/linux/init/main.c kernel/init/main.c
--- /usr/local/src/linux/init/main.c	2004-06-17 11:42:42.000000000 +0200
+++ kernel/init/main.c	2004-07-30 11:43:48.000000000 +0200
@@ -44,6 +44,11 @@
 #include <linux/unistd.h>
 #include <linux/rmap.h>
 
+#include <linux/genhd.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+
+
 #include <asm/io.h>
 #include <asm/bugs.h>
 
diff -ur -X dontdiff /usr/local/src/linux/kernel/printk.c kernel/kernel/printk.c
diff -ur -X dontdiff /usr/local/src/linux/kernel/sys.c kernel/kernel/sys.c

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: rootdelay
  2005-03-30 18:05 rootdelay David N. Welton
  2005-04-01 18:27 ` rootdelay Daniel Drake
@ 2005-04-26 10:11 ` Pekka Enberg
  2005-04-26 19:54   ` rootdelay David N. Welton
  1 sibling, 1 reply; 11+ messages in thread
From: Pekka Enberg @ 2005-04-26 10:11 UTC (permalink / raw)
  To: David N. Welton; +Cc: dsd, linux-kernel

Hi,

On 30 Mar 2005 20:05:36 +0200, David N. Welton <davidw@dedasys.com> wrote:
> I was wondering if there were any interest in my own efforts in that
> direction:
> 
> http://dedasys.com/freesoftware/patches/blkdev_wakeup.patch

Please read Documentation/CodingStyle and follow it if you want your
patches to be reviewed (or merged).

                                     Pekka

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: rootdelay
  2005-04-26 10:11 ` rootdelay Pekka Enberg
@ 2005-04-26 19:54   ` David N. Welton
  2005-04-27  8:01     ` rootdelay Pekka Enberg
  0 siblings, 1 reply; 11+ messages in thread
From: David N. Welton @ 2005-04-26 19:54 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: dsd, linux-kernel

Pekka Enberg <penberg@gmail.com> writes:

> Hi,
> 
> On 30 Mar 2005 20:05:36 +0200, David N. Welton <davidw@dedasys.com> wrote:
> > I was wondering if there were any interest in my own efforts in that
> > direction:
> > 
> > http://dedasys.com/freesoftware/patches/blkdev_wakeup.patch
> 
> Please read Documentation/CodingStyle and follow it if you want your
> patches to be reviewed (or merged).

Oh, I most certainly will polish the code as much as possible should
it prove of interest, but I think what needs vetting is the idea
itself, which I described clearly in english in a subsequent email.
If the idea itself stinks, I'm happy to drop it before spending time
playing around with indentation and other niceties.

Thankyou,
-- 
David N. Welton
 - http://www.dedasys.com/davidw/

Apache, Linux, Tcl Consulting
 - http://www.dedasys.com/

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: rootdelay
  2005-04-26 19:54   ` rootdelay David N. Welton
@ 2005-04-27  8:01     ` Pekka Enberg
  0 siblings, 0 replies; 11+ messages in thread
From: Pekka Enberg @ 2005-04-27  8:01 UTC (permalink / raw)
  To: David N. Welton; +Cc: dsd, linux-kernel

Hi David,

On 26 Apr 2005 21:54:35 +0200, David N. Welton <davidw@dedasys.com> wrote:
> Oh, I most certainly will polish the code as much as possible should
> it prove of interest, but I think what needs vetting is the idea
> itself, which I described clearly in english in a subsequent email.
> If the idea itself stinks, I'm happy to drop it before spending time
> playing around with indentation and other niceties.

But see, that's the problem. You think _other people_ should spend
time reviewing your work first so _you_ don't have to waste time.
Unfortunately, it looks to me like no one is willing to spend their
time reviewing a patch which (a) does not follow
Documentation/CodingStyle and (b) is not submitted as per
Documentation/SubmittingPatches.

I mean, how much work is it to run you code through scripts/Lindent
and drop those awful function banner comments and resend the patch?-)

                                 Pekka

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: rootdelay
  2005-04-25 21:34       ` rootdelay David N. Welton
@ 2005-04-29 18:34         ` William Park
  2005-05-03  8:07           ` rootdelay David N. Welton
  0 siblings, 1 reply; 11+ messages in thread
From: William Park @ 2005-04-29 18:34 UTC (permalink / raw)
  To: David N. Welton; +Cc: Daniel Drake, linux-kernel, akpm, viro, helge.hafting

On Mon, Apr 25, 2005 at 11:34:23PM +0200, David N. Welton wrote:
> > > > > http://dedasys.com/freesoftware/patches/blkdev_wakeup.patch

I patched it to 2.6.11, and it compiles okey.  On boot, it prints
    "Waiting for root device to wake us up."
then it waits for my USB key to register.  After USB partition info
prints to screen, above message is printed
    "Waiting for root device to wake us up."
again.  Then, it just hangs forever.

-- 
William Park <opengeometry@yahoo.ca>, Toronto, Canada
Slackware Linux -- because it works.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: rootdelay
  2005-04-29 18:34         ` rootdelay William Park
@ 2005-05-03  8:07           ` David N. Welton
  2005-05-03 11:13             ` rootdelay David Welton
  0 siblings, 1 reply; 11+ messages in thread
From: David N. Welton @ 2005-05-03  8:07 UTC (permalink / raw)
  To: William Park
  Cc: Daniel Drake, linux-kernel, akpm, viro, helge.hafting, davidnwelton

William Park <opengeometry@yahoo.ca> writes:

> On Mon, Apr 25, 2005 at 11:34:23PM +0200, David N. Welton wrote:
> > > > > > http://dedasys.com/freesoftware/patches/blkdev_wakeup.patch
> 
> I patched it to 2.6.11, and it compiles okey.  On boot, it prints
> "Waiting for root device to wake us up."  then it waits for my USB
> key to register.  After USB partition info prints to screen, above
> message is printed "Waiting for root device to wake us up."  again.
> Then, it just hangs forever.

Ok, I updated to 2.6.11.8, and indeed it does have problems that
weren't there before - although in my case it can't mount the root
partition because it's not quite ready yet.  In part, it seems to be
caused by the fact that the USB start up sequence introduces a new
thread that delays the scsi_host_scan by 5 seconds, which is long
enough to cause problems.  I added some code to wait for not only the
disk name to be online, but the partition, but even that doesn't seem
to be quite enough.

Is there anyplace generic that could be hooked that will report when a
device is actually online and ready to run?  Perhaps I was just lucky
in the past with add_disk :-/

Ciao,
-- 
David N. Welton
 - http://www.dedasys.com/davidw/

Apache, Linux, Tcl Consulting
 - http://www.dedasys.com/

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: rootdelay
  2005-05-03  8:07           ` rootdelay David N. Welton
@ 2005-05-03 11:13             ` David Welton
  0 siblings, 0 replies; 11+ messages in thread
From: David Welton @ 2005-05-03 11:13 UTC (permalink / raw)
  To: William Park, Daniel Drake, linux-kernel, akpm, viro, helge.hafting
  Cc: David N. Welton, mdharm-usb

[-- Attachment #1: Type: text/plain, Size: 7147 bytes --]

> Ok, I updated to 2.6.11.8, and indeed it does have problems that
> weren't there before - although in my case it can't mount the root
> partition because it's not quite ready yet.  In part, it seems to be
> caused by the fact that the USB start up sequence introduces a new
> thread that delays the scsi_host_scan by 5 seconds, which is long
> enough to cause problems.  I added some code to wait for not only the
> disk name to be online, but the partition, but even that doesn't seem
> to be quite enough.
 
> Is there anyplace generic that could be hooked that will report when a
> device is actually online and ready to run?  Perhaps I was just lucky
> in the past with add_disk :-/

I "fixed" the problem by not letting storage_probe in storage/usb.c
finish until the scan_thread is done.  That doesn't seem elegant -
perhaps there is a better place to put the
wait_for_completion(&us->scsi_scan_done) call so that the scanning
thread can go off and do its thing, but will still be waited on where
it counts?

I am including a copy of the patch inline, as well as attaching it.  I
suspect that gmail will mangle the inline version some...

Thankyou,
Dave

diff -uprN -X dontdiff linux-2.6.11.8/drivers/block/genhd.c
linux-wakeup/drivers/block/genhd.c
--- linux-2.6.11.8/drivers/block/genhd.c	2005-04-30 03:27:21.000000000 +0200
+++ linux-wakeup/drivers/block/genhd.c	2005-05-02 19:22:13.000000000 +0200
@@ -14,9 +14,14 @@
 #include <linux/slab.h>
 #include <linux/kmod.h>
 #include <linux/kobj_map.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
 
 #define MAX_PROBE_HASH 255	/* random */
 
+DECLARE_WAIT_QUEUE_HEAD(disk_wait_h);
+EXPORT_SYMBOL(disk_wait_h);
+
 static struct subsystem block_subsys;
 
 static DECLARE_MUTEX(block_subsys_sem);
@@ -58,6 +63,49 @@ int get_blkdev_list(char *p)
 }
 #endif
 
+/*
+ * Returns an array of all the block device names and partitions.
+ */
+
+char **get_blkdevs(void)
+{
+	int i = 0;
+	int n = 0;
+	int len = 0;
+	struct list_head *p;
+	char **names = NULL;
+	struct gendisk *sgp;
+	char buf[BDEVNAME_SIZE];
+
+	down_read(&block_subsys.rwsem);
+	
+	list_for_each(p, &block_subsys.kset.list) {
+		len ++;
+	}
+	
+	names = kmalloc(sizeof(char *) * len + 1, GFP_KERNEL);
+
+	list_for_each(p, &block_subsys.kset.list) {
+		sgp = list_entry(p, struct gendisk, kobj.entry);
+		names[i] = kmalloc(strlen(disk_name(sgp, 0, buf)), GFP_KERNEL);
+		strcpy(names[i], disk_name(sgp, 0, buf));
+		
+		for (n = 0; n < sgp->minors - 1; n++) {
+			struct hd_struct *hd = sgp->part[n];
+			if (hd && hd->nr_sects) {
+				names[i] = kmalloc(strlen(disk_name(sgp, n+1, buf)), GFP_KERNEL);
+				strcpy(names[i], disk_name(sgp, n+1, buf));
+				i ++;
+			}
+		}
+	}
+	names[i] = NULL;
+	up_read(&block_subsys.rwsem);
+	return names;
+}
+
+EXPORT_SYMBOL(get_blkdevs);
+
 int register_blkdev(unsigned int major, const char *name)
 {
 	struct blk_major_name **n, *p;
@@ -192,6 +240,11 @@ void add_disk(struct gendisk *disk)
 			    disk->minors, NULL, exact_match, exact_lock, disk);
 	register_disk(disk);
 	blk_register_queue(disk);
+
+	/* Wake up queue in init/main.c. */
+	printk("Waking up queue on %s\n",
+	       disk->disk_name);
+	wake_up_interruptible(&disk_wait_h);
 }
 
 EXPORT_SYMBOL(add_disk);
diff -uprN -X dontdiff linux-2.6.11.8/drivers/usb/storage/usb.c
linux-wakeup/drivers/usb/storage/usb.c
--- linux-2.6.11.8/drivers/usb/storage/usb.c	2005-04-30 03:25:25.000000000 +0200
+++ linux-wakeup/drivers/usb/storage/usb.c	2005-05-03 12:15:29.000000000 +0200
@@ -1009,6 +1009,7 @@ static int storage_probe(struct usb_inte
 
 	/* Start up the thread for delayed SCSI-device scanning */
 	result = kernel_thread(usb_stor_scan_thread, us, CLONE_VM);
+
 	if (result < 0) {
 		printk(KERN_WARNING USB_STORAGE 
 		       "Unable to start the device-scanning thread\n");
@@ -1016,6 +1017,8 @@ static int storage_probe(struct usb_inte
 		goto BadDevice;
 	}
 
+	wait_for_completion(&us->scsi_scan_done);
+
 	return 0;
 
 	/* We come here if there are any problems */
diff -uprN -X dontdiff linux-2.6.11.8/include/linux/genhd.h
linux-wakeup/include/linux/genhd.h
--- linux-2.6.11.8/include/linux/genhd.h	2005-04-30 03:24:13.000000000 +0200
+++ linux-wakeup/include/linux/genhd.h	2005-05-02 12:04:50.000000000 +0200
@@ -16,6 +16,10 @@
 #include <linux/smp.h>
 #include <linux/string.h>
 #include <linux/fs.h>
+#include <linux/wait.h>
+
+/* Wait queue to wait on disks coming online. */
+extern wait_queue_head_t disk_wait_h;
 
 enum {
 /* These three have identical behaviour; use the second one if DOS FDISK gets
@@ -232,6 +236,7 @@ extern struct gendisk *get_gendisk(dev_t
 
 extern void set_device_ro(struct block_device *bdev, int flag);
 extern void set_disk_ro(struct gendisk *disk, int flag);
+extern char **get_blkdevs(void);
 
 /* drivers/char/random.c */
 extern void add_disk_randomness(struct gendisk *disk);
diff -uprN -X dontdiff linux-2.6.11.8/init/do_mounts.c
linux-wakeup/init/do_mounts.c
--- linux-2.6.11.8/init/do_mounts.c	2005-04-30 03:26:32.000000000 +0200
+++ linux-wakeup/init/do_mounts.c	2005-05-02 19:22:51.000000000 +0200
@@ -12,6 +12,8 @@
 #include <linux/nfs_fs_sb.h>
 #include <linux/nfs_mount.h>
 
+#include <linux/genhd.h>
+
 #include "do_mounts.h"
 
 extern int get_filesystem_list(char * buf);
@@ -360,8 +362,35 @@ void __init change_floppy(char *fmt, ...
 }
 #endif
 
+/*
+ * match_root_name - Returns 1 if the root_device_name appears amongst
+ * the list of block devices, 0 otherwise.
+ */
+
+static int __init match_root_name(void) {
+	char **names = NULL;
+	int i = 0;
+	int match = 0;
+	
+	names = get_blkdevs();
+	while (names[i] != NULL) {
+		if (match == 0 && strncmp(names[i],
+					  root_device_name,
+					  strlen(root_device_name)) == 0) {
+			match = 1;
+			printk("Block device %s matches %s root_device_name, continuing\n",
+			       names[i], root_device_name);
+		}
+		kfree(names[i]);
+		i ++;
+	}
+	kfree(names);
+	return match;
+}
+
 void __init mount_root(void)
 {
+
 #ifdef CONFIG_ROOT_NFS
 	if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
 		if (mount_nfs_root())
@@ -383,6 +412,14 @@ void __init mount_root(void)
 			change_floppy("root floppy");
 	}
 #endif
+
+	/* Here, we wait for the root device to show up, or if it's
+	 * already there, we just go on. */
+	while (!match_root_name()) {
+		printk("Waiting for root device to wake us up\n");
+		interruptible_sleep_on(&disk_wait_h);
+	}
+ 
 	create_dev("/dev/root", ROOT_DEV, root_device_name);
 	mount_block_root("/dev/root", root_mountflags);
 }
diff -uprN -X dontdiff linux-2.6.11.8/init/main.c linux-wakeup/init/main.c
--- linux-2.6.11.8/init/main.c	2005-04-30 03:24:18.000000000 +0200
+++ linux-wakeup/init/main.c	2005-05-02 12:04:50.000000000 +0200
@@ -47,6 +47,11 @@
 #include <linux/mempolicy.h>
 #include <linux/key.h>
 
+#include <linux/genhd.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+
+
 #include <asm/io.h>
 #include <asm/bugs.h>
 #include <asm/setup.h>

[-- Attachment #2: blkdev_wakeup.patch --]
[-- Type: text/x-patch, Size: 5754 bytes --]

diff -uprN -X dontdiff linux-2.6.11.8/drivers/block/genhd.c linux-wakeup/drivers/block/genhd.c
--- linux-2.6.11.8/drivers/block/genhd.c	2005-04-30 03:27:21.000000000 +0200
+++ linux-wakeup/drivers/block/genhd.c	2005-05-02 19:22:13.000000000 +0200
@@ -14,9 +14,14 @@
 #include <linux/slab.h>
 #include <linux/kmod.h>
 #include <linux/kobj_map.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
 
 #define MAX_PROBE_HASH 255	/* random */
 
+DECLARE_WAIT_QUEUE_HEAD(disk_wait_h);
+EXPORT_SYMBOL(disk_wait_h);
+
 static struct subsystem block_subsys;
 
 static DECLARE_MUTEX(block_subsys_sem);
@@ -58,6 +63,49 @@ int get_blkdev_list(char *p)
 }
 #endif
 
+/*
+ * Returns an array of all the block device names and partitions.
+ */
+
+char **get_blkdevs(void)
+{
+	int i = 0;
+	int n = 0;
+	int len = 0;
+	struct list_head *p;
+	char **names = NULL;
+	struct gendisk *sgp;
+	char buf[BDEVNAME_SIZE];
+
+	down_read(&block_subsys.rwsem);
+	
+	list_for_each(p, &block_subsys.kset.list) {
+		len ++;
+	}
+	
+	names = kmalloc(sizeof(char *) * len + 1, GFP_KERNEL);
+
+	list_for_each(p, &block_subsys.kset.list) {
+		sgp = list_entry(p, struct gendisk, kobj.entry);
+		names[i] = kmalloc(strlen(disk_name(sgp, 0, buf)), GFP_KERNEL);
+		strcpy(names[i], disk_name(sgp, 0, buf));
+		
+		for (n = 0; n < sgp->minors - 1; n++) {
+			struct hd_struct *hd = sgp->part[n];
+			if (hd && hd->nr_sects) {
+				names[i] = kmalloc(strlen(disk_name(sgp, n+1, buf)), GFP_KERNEL);
+				strcpy(names[i], disk_name(sgp, n+1, buf));
+				i ++;
+			}
+		}
+	}
+	names[i] = NULL;
+	up_read(&block_subsys.rwsem);
+	return names;
+}
+
+EXPORT_SYMBOL(get_blkdevs);
+
 int register_blkdev(unsigned int major, const char *name)
 {
 	struct blk_major_name **n, *p;
@@ -192,6 +240,11 @@ void add_disk(struct gendisk *disk)
 			    disk->minors, NULL, exact_match, exact_lock, disk);
 	register_disk(disk);
 	blk_register_queue(disk);
+
+	/* Wake up queue in init/main.c. */
+	printk("Waking up queue on %s\n",
+	       disk->disk_name);
+	wake_up_interruptible(&disk_wait_h);
 }
 
 EXPORT_SYMBOL(add_disk);
diff -uprN -X dontdiff linux-2.6.11.8/drivers/usb/storage/usb.c linux-wakeup/drivers/usb/storage/usb.c
--- linux-2.6.11.8/drivers/usb/storage/usb.c	2005-04-30 03:25:25.000000000 +0200
+++ linux-wakeup/drivers/usb/storage/usb.c	2005-05-03 12:15:29.000000000 +0200
@@ -1009,6 +1009,7 @@ static int storage_probe(struct usb_inte
 
 	/* Start up the thread for delayed SCSI-device scanning */
 	result = kernel_thread(usb_stor_scan_thread, us, CLONE_VM);
+
 	if (result < 0) {
 		printk(KERN_WARNING USB_STORAGE 
 		       "Unable to start the device-scanning thread\n");
@@ -1016,6 +1017,8 @@ static int storage_probe(struct usb_inte
 		goto BadDevice;
 	}
 
+	wait_for_completion(&us->scsi_scan_done);
+
 	return 0;
 
 	/* We come here if there are any problems */
diff -uprN -X dontdiff linux-2.6.11.8/include/linux/genhd.h linux-wakeup/include/linux/genhd.h
--- linux-2.6.11.8/include/linux/genhd.h	2005-04-30 03:24:13.000000000 +0200
+++ linux-wakeup/include/linux/genhd.h	2005-05-02 12:04:50.000000000 +0200
@@ -16,6 +16,10 @@
 #include <linux/smp.h>
 #include <linux/string.h>
 #include <linux/fs.h>
+#include <linux/wait.h>
+
+/* Wait queue to wait on disks coming online. */
+extern wait_queue_head_t disk_wait_h;
 
 enum {
 /* These three have identical behaviour; use the second one if DOS FDISK gets
@@ -232,6 +236,7 @@ extern struct gendisk *get_gendisk(dev_t
 
 extern void set_device_ro(struct block_device *bdev, int flag);
 extern void set_disk_ro(struct gendisk *disk, int flag);
+extern char **get_blkdevs(void);
 
 /* drivers/char/random.c */
 extern void add_disk_randomness(struct gendisk *disk);
diff -uprN -X dontdiff linux-2.6.11.8/init/do_mounts.c linux-wakeup/init/do_mounts.c
--- linux-2.6.11.8/init/do_mounts.c	2005-04-30 03:26:32.000000000 +0200
+++ linux-wakeup/init/do_mounts.c	2005-05-02 19:22:51.000000000 +0200
@@ -12,6 +12,8 @@
 #include <linux/nfs_fs_sb.h>
 #include <linux/nfs_mount.h>
 
+#include <linux/genhd.h>
+
 #include "do_mounts.h"
 
 extern int get_filesystem_list(char * buf);
@@ -360,8 +362,35 @@ void __init change_floppy(char *fmt, ...
 }
 #endif
 
+/*
+ * match_root_name - Returns 1 if the root_device_name appears amongst
+ * the list of block devices, 0 otherwise.
+ */
+
+static int __init match_root_name(void) {
+	char **names = NULL;
+	int i = 0;
+	int match = 0;
+	
+	names = get_blkdevs();
+	while (names[i] != NULL) {
+		if (match == 0 && strncmp(names[i],
+					  root_device_name,
+					  strlen(root_device_name)) == 0) {
+			match = 1;
+			printk("Block device %s matches %s root_device_name, continuing\n",
+			       names[i], root_device_name);
+		}
+		kfree(names[i]);
+		i ++;
+	}
+	kfree(names);
+	return match;
+}
+
 void __init mount_root(void)
 {
+
 #ifdef CONFIG_ROOT_NFS
 	if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
 		if (mount_nfs_root())
@@ -383,6 +412,14 @@ void __init mount_root(void)
 			change_floppy("root floppy");
 	}
 #endif
+
+	/* Here, we wait for the root device to show up, or if it's
+	 * already there, we just go on. */
+	while (!match_root_name()) {
+		printk("Waiting for root device to wake us up\n");
+		interruptible_sleep_on(&disk_wait_h);
+	}
+ 
 	create_dev("/dev/root", ROOT_DEV, root_device_name);
 	mount_block_root("/dev/root", root_mountflags);
 }
diff -uprN -X dontdiff linux-2.6.11.8/init/main.c linux-wakeup/init/main.c
--- linux-2.6.11.8/init/main.c	2005-04-30 03:24:18.000000000 +0200
+++ linux-wakeup/init/main.c	2005-05-02 12:04:50.000000000 +0200
@@ -47,6 +47,11 @@
 #include <linux/mempolicy.h>
 #include <linux/key.h>
 
+#include <linux/genhd.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+
+
 #include <asm/io.h>
 #include <asm/bugs.h>
 #include <asm/setup.h>

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2005-05-03 11:14 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-03-30 18:05 rootdelay David N. Welton
2005-04-01 18:27 ` rootdelay Daniel Drake
2005-04-25  9:45   ` rootdelay David N. Welton
2005-04-25 14:42     ` rootdelay William Park
2005-04-25 21:34       ` rootdelay David N. Welton
2005-04-29 18:34         ` rootdelay William Park
2005-05-03  8:07           ` rootdelay David N. Welton
2005-05-03 11:13             ` rootdelay David Welton
2005-04-26 10:11 ` rootdelay Pekka Enberg
2005-04-26 19:54   ` rootdelay David N. Welton
2005-04-27  8:01     ` rootdelay Pekka Enberg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).