From: Kiyoshi Ueda Currently process_queued_ios() triggers pg_init (which needs a kthread context). But recently we introduced activate_path() on a work queue and can use this instead. This patch is a preparation of the next patch, which fixes the issue that ioctl isn't processed until any I/O is issued. (And also it is a preparation of another patch-set to remove multipath internal queue.) No functional change. Signed-off-by: Kiyoshi Ueda Signed-off-by: Jun'ichi Nomura --- drivers/md/dm-mpath.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) Index: linux-2.6.33-rc6/drivers/md/dm-mpath.c =================================================================== --- linux-2.6.33-rc6.orig/drivers/md/dm-mpath.c +++ linux-2.6.33-rc6/drivers/md/dm-mpath.c @@ -365,8 +365,9 @@ static int map_io(struct multipath *m, s /* Queue for the daemon to resubmit */ list_add_tail(&clone->queuelist, &m->queued_ios); m->queue_size++; - if ((m->pg_init_required && !m->pg_init_in_progress) || - !m->queue_io) + if (m->pg_init_required && !m->pg_init_in_progress && pgpath) + __pg_init_all_paths(m); + else if (!m->queue_io) queue_work(kmultipathd, &m->process_queued_ios); pgpath = NULL; r = DM_MAPIO_SUBMITTED; @@ -1222,9 +1223,24 @@ static void pg_init_done(void *data, int /* Activations of other paths are still on going */ goto out; - if (!m->pg_init_required) - m->queue_io = 0; + if (m->pg_init_required) { + /* Requested retry or a new pg_init */ + if (likely(m->current_pgpath)) { + __pg_init_all_paths(m); + goto out; + } + + /* + * The condition requiring pg_init has been changed by someone + * after the pg_init had been requested. + * Cancel m->pg_init_required here explicitly, and start over + * from path selection. + */ + m->pg_init_required = 0; + m->current_pg = NULL; + } + m->queue_io = 0; queue_work(kmultipathd, &m->process_queued_ios); /*