Allow PGs to be bypassed. --- diff/drivers/md/dm-mpath.c 2004-10-29 15:37:46.000000000 +0100 +++ source/drivers/md/dm-mpath.c 2004-10-29 15:37:52.000000000 +0100 @@ -40,6 +40,7 @@ struct path_selector ps; unsigned nr_paths; + unsigned bypass; struct list_head paths; }; @@ -193,6 +194,8 @@ if (m->nr_valid_paths) { /* loop through the priority groups until we find a valid path. */ list_for_each_entry (pg, &m->priority_groups, list) { + if (pg->bypass) + continue; path = pg->ps.type->select_path(&pg->ps, &m->current_count); if (path) @@ -630,6 +633,31 @@ return r; } +/* + * Set/clear bypass status of a PG. + * PG numbering goes 1, 2, 3... + */ +static int bypass_pg(struct multipath *m, const char *pgstr, int bypass) +{ + struct priority_group *pg; + unsigned pgnum; + + if (!pgstr || (sscanf(pgstr, "%u", &pgnum) != 1) || !pgnum) + goto error; + + list_for_each_entry(pg, &m->priority_groups, list) { + if (--pgnum) + continue; + + pg->bypass = bypass; + return 0; + } + +error: + DMWARN("invalid PG number supplied to bypass_pg"); + return -EINVAL; +} + static int do_end_io(struct multipath *m, struct bio *bio, int error, struct mpath_io *mpio) { @@ -746,7 +774,11 @@ if (argc != 2) goto error; - if (!strnicmp(argv[0], "reinstate", 10)) + if (!strnicmp(argv[0], "disable_group", 14)) + return bypass_pg(m, argv[1], 0); + else if (!strnicmp(argv[0], "enable_group", 13)) + return bypass_pg(m, argv[1], 1); + else if (!strnicmp(argv[0], "reinstate", 10)) action = reinstate_path; else if (!strnicmp(argv[0], "fail", 5)) action = fail_path;