Don't change PG until it runs out of paths. --- diff/drivers/md/dm-mpath.c 2005-01-12 19:14:21.000000000 +0000 +++ source/drivers/md/dm-mpath.c 2005-01-12 19:14:33.000000000 +0000 @@ -211,16 +211,41 @@ } } +static struct pgpath *__choose_path_in_pg(struct multipath *m, + struct priority_group *pg) +{ + struct path *path; + struct pgpath *pgpath; + + path = pg->ps.type->select_path(&pg->ps, &m->current_count); + if (!path) { + return NULL; + } + + pgpath = path_to_pgpath(path); + + if (m->current_pg != pg) + __switch_pg(m, pgpath); + + return pgpath; +} + static void __choose_pgpath(struct multipath *m) { struct priority_group *pg; struct pgpath *pgpath = NULL; - struct path *path; unsigned bypassed = 1; if (!m->nr_valid_paths) goto out; + /* Don't change PG until it has no remaining paths */ + if (m->current_pg) { + pgpath = __choose_path_in_pg(m, m->current_pg); + if (pgpath) + goto out; + } + /* * Loop through priority groups until we find a valid path. * First time we skip PGs marked 'bypassed'. @@ -230,17 +255,9 @@ list_for_each_entry (pg, &m->priority_groups, list) { if (pg->bypassed == bypassed) continue; - path = pg->ps.type->select_path(&pg->ps, - &m->current_count); - if (!path) - continue; - - pgpath = path_to_pgpath(path); - - if (m->current_pg != pg) - __switch_pg(m, pgpath); - - goto out; + pgpath = __choose_path_in_pg(m, pg); + if (pgpath) + goto out; } } while (bypassed--);