|
@@ -87,6 +87,7 @@ struct multipath {
|
|
|
unsigned queue_if_no_path:1; /* Queue I/O if last path fails? */
|
|
|
unsigned saved_queue_if_no_path:1; /* Saved state during suspension */
|
|
|
unsigned retain_attached_hw_handler:1; /* If there's already a hw_handler present, don't change it. */
|
|
|
+ unsigned pg_init_disabled:1; /* pg_init is not currently allowed */
|
|
|
|
|
|
unsigned pg_init_retries; /* Number of times to retry pg_init */
|
|
|
unsigned pg_init_count; /* Number of times pg_init called */
|
|
@@ -497,7 +498,8 @@ static void process_queued_ios(struct work_struct *work)
|
|
|
(!pgpath && !m->queue_if_no_path))
|
|
|
must_queue = 0;
|
|
|
|
|
|
- if (m->pg_init_required && !m->pg_init_in_progress && pgpath)
|
|
|
+ if (m->pg_init_required && !m->pg_init_in_progress && pgpath &&
|
|
|
+ !m->pg_init_disabled)
|
|
|
__pg_init_all_paths(m);
|
|
|
|
|
|
spin_unlock_irqrestore(&m->lock, flags);
|
|
@@ -942,10 +944,20 @@ static void multipath_wait_for_pg_init_completion(struct multipath *m)
|
|
|
|
|
|
static void flush_multipath_work(struct multipath *m)
|
|
|
{
|
|
|
+ unsigned long flags;
|
|
|
+
|
|
|
+ spin_lock_irqsave(&m->lock, flags);
|
|
|
+ m->pg_init_disabled = 1;
|
|
|
+ spin_unlock_irqrestore(&m->lock, flags);
|
|
|
+
|
|
|
flush_workqueue(kmpath_handlerd);
|
|
|
multipath_wait_for_pg_init_completion(m);
|
|
|
flush_workqueue(kmultipathd);
|
|
|
flush_work(&m->trigger_event);
|
|
|
+
|
|
|
+ spin_lock_irqsave(&m->lock, flags);
|
|
|
+ m->pg_init_disabled = 0;
|
|
|
+ spin_unlock_irqrestore(&m->lock, flags);
|
|
|
}
|
|
|
|
|
|
static void multipath_dtr(struct dm_target *ti)
|
|
@@ -1164,7 +1176,7 @@ static int pg_init_limit_reached(struct multipath *m, struct pgpath *pgpath)
|
|
|
|
|
|
spin_lock_irqsave(&m->lock, flags);
|
|
|
|
|
|
- if (m->pg_init_count <= m->pg_init_retries)
|
|
|
+ if (m->pg_init_count <= m->pg_init_retries && !m->pg_init_disabled)
|
|
|
m->pg_init_required = 1;
|
|
|
else
|
|
|
limit_reached = 1;
|
|
@@ -1714,7 +1726,7 @@ out:
|
|
|
*---------------------------------------------------------------*/
|
|
|
static struct target_type multipath_target = {
|
|
|
.name = "multipath",
|
|
|
- .version = {1, 5, 1},
|
|
|
+ .version = {1, 6, 0},
|
|
|
.module = THIS_MODULE,
|
|
|
.ctr = multipath_ctr,
|
|
|
.dtr = multipath_dtr,
|