diff options
author | Mike Anderson <andmike@linux.vnet.ibm.com> | 2009-12-11 00:52:21 +0100 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2009-12-11 00:52:21 +0100 |
commit | 67a46dad25ccc8910995d8671f7ec17a6bc823cb (patch) | |
tree | 6e5221b6fdd5ad8de5e88e2c45737f788288c6cf /drivers/md | |
parent | dm mpath: add mutex to synchronize adding and flushing work (diff) | |
download | linux-67a46dad25ccc8910995d8671f7ec17a6bc823cb.tar.xz linux-67a46dad25ccc8910995d8671f7ec17a6bc823cb.zip |
dm mpath: prevent io from work queue while suspended
Reject messages that can generate I/O while the device itself
is suspended.
Signed-off-by: Mike Anderson <andmike@linux.vnet.ibm.com>
Acked-by: Kiyoshi Ueda <k-ueda@ct.jp.nec.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/dm-mpath.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 700154e21483..45d9bf14cc48 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c @@ -95,6 +95,8 @@ struct multipath { mempool_t *mpio_pool; struct mutex work_mutex; + + unsigned suspended; /* Don't create new I/O internally when set. */ }; /* @@ -1274,6 +1276,7 @@ static void multipath_postsuspend(struct dm_target *ti) struct multipath *m = ti->private; mutex_lock(&m->work_mutex); + m->suspended = 1; flush_multipath_work(); mutex_unlock(&m->work_mutex); } @@ -1286,6 +1289,10 @@ static void multipath_resume(struct dm_target *ti) struct multipath *m = (struct multipath *) ti->private; unsigned long flags; + mutex_lock(&m->work_mutex); + m->suspended = 0; + mutex_unlock(&m->work_mutex); + spin_lock_irqsave(&m->lock, flags); m->queue_if_no_path = m->saved_queue_if_no_path; spin_unlock_irqrestore(&m->lock, flags); @@ -1421,6 +1428,11 @@ static int multipath_message(struct dm_target *ti, unsigned argc, char **argv) mutex_lock(&m->work_mutex); + if (m->suspended) { + r = -EBUSY; + goto out; + } + if (argc == 1) { if (!strnicmp(argv[0], MESG_STR("queue_if_no_path"))) { r = queue_if_no_path(m, 1, 0); |