The early_lookup_bdev() function returns successfully when the disk
device is present but not necessarily its partitions. In this situation,
dm_early_create() fails as the partition block device does not exist
yet.

In my case, this phenomenon occurs quite often because the device is
an SD card with slow reading times, on which kernel takes time to
enumerate available partitions.

Fortunately, the underlying device is back to "probing" state while
enumerating partitions. Waiting for all probing to end is enough to fix
this issue.

That's also the reason why this problem never occurs with rootwait=
parameter: the while loop inside wait_for_root() explicitly waits for
probing to be done and then the function calls async_synchronize_full().
These lines were omitted in 035641b, even though the commit says it's
based on the rootwait logic...

Anyway, calling wait_for_device_probe() after our while loop does the
job (it both waits for probing and calls async_synchronize_full).

Fixes: 035641b01e72 ("dm init: add dm-mod.waitfor to wait for asynchronously 
probed block devices")
Signed-off-by: Guillaume Gonnet <[email protected]>
---

Hello,

This patch is my attempt to fix the dm-mod.waitfor= issue. I had this
fix for quite a while now, but I've never made the effort to contribute
until recently.

Some have tried to fix it this issue in the past but without finding
its real root cause (ie. not waiting for device probe to end).

Here are the links to those patches, for reference:
https://lore.kernel.org/all/[email protected]/
https://lore.kernel.org/all/[email protected]/
https://lore.kernel.org/dm-devel/[email protected]/

 drivers/md/dm-init.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/md/dm-init.c b/drivers/md/dm-init.c
index 7403823384c5..c1bacba92c65 100644
--- a/drivers/md/dm-init.c
+++ b/drivers/md/dm-init.c
@@ -303,8 +303,10 @@ static int __init dm_init_init(void)
                }
        }
 
-       if (waitfor[0])
+       if (waitfor[0]) {
+               wait_for_device_probe();
                DMINFO("all devices available");
+       }
 
        list_for_each_entry(dev, &devices, list) {
                if (dm_early_create(&dev->dmi, dev->table,
-- 
2.43.0


Reply via email to