diff options
author | Mike Anderson <andmike@linux.vnet.ibm.com> | 2009-12-10 18:52:21 -0500 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2009-12-10 18:52:21 -0500 |
commit | 67a46dad25ccc8910995d8671f7ec17a6bc823cb (patch) | |
tree | 6e5221b6fdd5ad8de5e88e2c45737f788288c6cf | |
parent | 6380f26f0424034345461cabaab9a7030d905b59 (diff) |
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>
-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 { | |||
95 | mempool_t *mpio_pool; | 95 | mempool_t *mpio_pool; |
96 | 96 | ||
97 | struct mutex work_mutex; | 97 | struct mutex work_mutex; |
98 | |||
99 | unsigned suspended; /* Don't create new I/O internally when set. */ | ||
98 | }; | 100 | }; |
99 | 101 | ||
100 | /* | 102 | /* |
@@ -1274,6 +1276,7 @@ static void multipath_postsuspend(struct dm_target *ti) | |||
1274 | struct multipath *m = ti->private; | 1276 | struct multipath *m = ti->private; |
1275 | 1277 | ||
1276 | mutex_lock(&m->work_mutex); | 1278 | mutex_lock(&m->work_mutex); |
1279 | m->suspended = 1; | ||
1277 | flush_multipath_work(); | 1280 | flush_multipath_work(); |
1278 | mutex_unlock(&m->work_mutex); | 1281 | mutex_unlock(&m->work_mutex); |
1279 | } | 1282 | } |
@@ -1286,6 +1289,10 @@ static void multipath_resume(struct dm_target *ti) | |||
1286 | struct multipath *m = (struct multipath *) ti->private; | 1289 | struct multipath *m = (struct multipath *) ti->private; |
1287 | unsigned long flags; | 1290 | unsigned long flags; |
1288 | 1291 | ||
1292 | mutex_lock(&m->work_mutex); | ||
1293 | m->suspended = 0; | ||
1294 | mutex_unlock(&m->work_mutex); | ||
1295 | |||
1289 | spin_lock_irqsave(&m->lock, flags); | 1296 | spin_lock_irqsave(&m->lock, flags); |
1290 | m->queue_if_no_path = m->saved_queue_if_no_path; | 1297 | m->queue_if_no_path = m->saved_queue_if_no_path; |
1291 | spin_unlock_irqrestore(&m->lock, flags); | 1298 | spin_unlock_irqrestore(&m->lock, flags); |
@@ -1421,6 +1428,11 @@ static int multipath_message(struct dm_target *ti, unsigned argc, char **argv) | |||
1421 | 1428 | ||
1422 | mutex_lock(&m->work_mutex); | 1429 | mutex_lock(&m->work_mutex); |
1423 | 1430 | ||
1431 | if (m->suspended) { | ||
1432 | r = -EBUSY; | ||
1433 | goto out; | ||
1434 | } | ||
1435 | |||
1424 | if (argc == 1) { | 1436 | if (argc == 1) { |
1425 | if (!strnicmp(argv[0], MESG_STR("queue_if_no_path"))) { | 1437 | if (!strnicmp(argv[0], MESG_STR("queue_if_no_path"))) { |
1426 | r = queue_if_no_path(m, 1, 0); | 1438 | r = queue_if_no_path(m, 1, 0); |