Commit 485ef69e authored by Alasdair G Kergon's avatar Alasdair G Kergon Committed by Linus Torvalds

[PATCH] device-mapper: Fix queue_if_no_path initialisation

When creating a multipath device, if the queue_if_no_path parameter is
specified it gets ignored.

While the queue_if_no_path variable is correctly set to 1, the
saved_queue_if_no_path gets set to 0.  When the device is subsequently made
live (resumed), the saved value (0) always overwrites the live value (1) so
the option *always* gets turned off.

The fix adds a parameter to the queue_if_no_path() function to indicate
whether the previous value should be preserved or not - if not, as when the
device is being set up, the saved value is set to the new value (1).
Signed-Off-By: default avatarAlasdair G Kergon <agk@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 269fd2a6
...@@ -329,13 +329,17 @@ static int map_io(struct multipath *m, struct bio *bio, struct mpath_io *mpio, ...@@ -329,13 +329,17 @@ static int map_io(struct multipath *m, struct bio *bio, struct mpath_io *mpio,
/* /*
* If we run out of usable paths, should we queue I/O or error it? * If we run out of usable paths, should we queue I/O or error it?
*/ */
static int queue_if_no_path(struct multipath *m, unsigned queue_if_no_path) static int queue_if_no_path(struct multipath *m, unsigned queue_if_no_path,
unsigned save_old_value)
{ {
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&m->lock, flags); spin_lock_irqsave(&m->lock, flags);
m->saved_queue_if_no_path = m->queue_if_no_path; if (save_old_value)
m->saved_queue_if_no_path = m->queue_if_no_path;
else
m->saved_queue_if_no_path = queue_if_no_path;
m->queue_if_no_path = queue_if_no_path; m->queue_if_no_path = queue_if_no_path;
if (!m->queue_if_no_path && m->queue_size) if (!m->queue_if_no_path && m->queue_size)
queue_work(kmultipathd, &m->process_queued_ios); queue_work(kmultipathd, &m->process_queued_ios);
...@@ -677,7 +681,7 @@ static int parse_features(struct arg_set *as, struct multipath *m, ...@@ -677,7 +681,7 @@ static int parse_features(struct arg_set *as, struct multipath *m,
return 0; return 0;
if (!strnicmp(shift(as), MESG_STR("queue_if_no_path"))) if (!strnicmp(shift(as), MESG_STR("queue_if_no_path")))
return queue_if_no_path(m, 1); return queue_if_no_path(m, 1, 0);
else { else {
ti->error = "Unrecognised multipath feature request"; ti->error = "Unrecognised multipath feature request";
return -EINVAL; return -EINVAL;
...@@ -1077,7 +1081,7 @@ static void multipath_presuspend(struct dm_target *ti) ...@@ -1077,7 +1081,7 @@ static void multipath_presuspend(struct dm_target *ti)
{ {
struct multipath *m = (struct multipath *) ti->private; struct multipath *m = (struct multipath *) ti->private;
queue_if_no_path(m, 0); queue_if_no_path(m, 0, 1);
} }
/* /*
...@@ -1222,9 +1226,9 @@ static int multipath_message(struct dm_target *ti, unsigned argc, char **argv) ...@@ -1222,9 +1226,9 @@ static int multipath_message(struct dm_target *ti, unsigned argc, char **argv)
if (argc == 1) { if (argc == 1) {
if (!strnicmp(argv[0], MESG_STR("queue_if_no_path"))) if (!strnicmp(argv[0], MESG_STR("queue_if_no_path")))
return queue_if_no_path(m, 1); return queue_if_no_path(m, 1, 0);
else if (!strnicmp(argv[0], MESG_STR("fail_if_no_path"))) else if (!strnicmp(argv[0], MESG_STR("fail_if_no_path")))
return queue_if_no_path(m, 0); return queue_if_no_path(m, 0, 0);
} }
if (argc != 2) if (argc != 2)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment