If pg_init_retries is set and a request is queued against a
multipath device with all underlying block devices in the "dying"
state then an infinite loop is triggered because activate_path()
never succeeds and hence never calls pg_init_done(). Fix this by
making ql_select_path() skip dying paths.

Signed-off-by: Bart Van Assche <[email protected]>
---
 drivers/md/dm-queue-length.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/md/dm-queue-length.c b/drivers/md/dm-queue-length.c
index 23f1786..a283c66 100644
--- a/drivers/md/dm-queue-length.c
+++ b/drivers/md/dm-queue-length.c
@@ -199,11 +199,12 @@ static struct dm_path *ql_select_path(struct 
path_selector *ps, size_t nr_bytes)
        list_move_tail(s->valid_paths.next, &s->valid_paths);
 
        list_for_each_entry(pi, &s->valid_paths, list) {
-               if (!best ||
-                   (atomic_read(&pi->qlen) < atomic_read(&best->qlen)))
+               if ((!best ||
+                    atomic_read(&pi->qlen) < atomic_read(&best->qlen)) &&
+                   !blk_queue_dying(pi->path->dev->bdev->bd_queue))
                        best = pi;
 
-               if (!atomic_read(&best->qlen))
+               if (best && atomic_read(&best->qlen) == 0)
                        break;
        }
 
-- 
2.9.3

--
dm-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/dm-devel

Reply via email to