diff options
| -rw-r--r-- | drivers/md/dm-mpath.c | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 030bc2a053ec..c1335487cc72 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c | |||
| @@ -235,6 +235,21 @@ static void free_multipath(struct multipath *m) | |||
| 235 | * Path selection | 235 | * Path selection |
| 236 | *-----------------------------------------------*/ | 236 | *-----------------------------------------------*/ |
| 237 | 237 | ||
| 238 | static void __pg_init_all_paths(struct multipath *m) | ||
| 239 | { | ||
| 240 | struct pgpath *pgpath; | ||
| 241 | |||
| 242 | m->pg_init_count++; | ||
| 243 | m->pg_init_required = 0; | ||
| 244 | list_for_each_entry(pgpath, &m->current_pg->pgpaths, list) { | ||
| 245 | /* Skip failed paths */ | ||
| 246 | if (!pgpath->is_active) | ||
| 247 | continue; | ||
| 248 | if (queue_work(kmpath_handlerd, &pgpath->activate_path)) | ||
| 249 | m->pg_init_in_progress++; | ||
| 250 | } | ||
| 251 | } | ||
| 252 | |||
| 238 | static void __switch_pg(struct multipath *m, struct pgpath *pgpath) | 253 | static void __switch_pg(struct multipath *m, struct pgpath *pgpath) |
| 239 | { | 254 | { |
| 240 | m->current_pg = pgpath->pg; | 255 | m->current_pg = pgpath->pg; |
| @@ -439,7 +454,7 @@ static void process_queued_ios(struct work_struct *work) | |||
| 439 | { | 454 | { |
| 440 | struct multipath *m = | 455 | struct multipath *m = |
| 441 | container_of(work, struct multipath, process_queued_ios); | 456 | container_of(work, struct multipath, process_queued_ios); |
| 442 | struct pgpath *pgpath = NULL, *tmp; | 457 | struct pgpath *pgpath = NULL; |
| 443 | unsigned must_queue = 1; | 458 | unsigned must_queue = 1; |
| 444 | unsigned long flags; | 459 | unsigned long flags; |
| 445 | 460 | ||
| @@ -457,17 +472,9 @@ static void process_queued_ios(struct work_struct *work) | |||
| 457 | (!pgpath && !m->queue_if_no_path)) | 472 | (!pgpath && !m->queue_if_no_path)) |
| 458 | must_queue = 0; | 473 | must_queue = 0; |
| 459 | 474 | ||
| 460 | if (m->pg_init_required && !m->pg_init_in_progress && pgpath) { | 475 | if (m->pg_init_required && !m->pg_init_in_progress && pgpath) |
| 461 | m->pg_init_count++; | 476 | __pg_init_all_paths(m); |
| 462 | m->pg_init_required = 0; | 477 | |
| 463 | list_for_each_entry(tmp, &pgpath->pg->pgpaths, list) { | ||
| 464 | /* Skip failed paths */ | ||
| 465 | if (!tmp->is_active) | ||
| 466 | continue; | ||
| 467 | if (queue_work(kmpath_handlerd, &tmp->activate_path)) | ||
| 468 | m->pg_init_in_progress++; | ||
| 469 | } | ||
| 470 | } | ||
| 471 | out: | 478 | out: |
| 472 | spin_unlock_irqrestore(&m->lock, flags); | 479 | spin_unlock_irqrestore(&m->lock, flags); |
| 473 | if (!must_queue) | 480 | if (!must_queue) |
