aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Anderson <andmike@linux.vnet.ibm.com>2009-12-10 18:52:21 -0500
committerAlasdair G Kergon <agk@redhat.com>2009-12-10 18:52:21 -0500
commit6380f26f0424034345461cabaab9a7030d905b59 (patch)
treecc9fbd6e8d990bf3ee2f577ae7f842a4df1d5ef6
parentc50abeb38026ea721a812cf8a9b2fac5d3b7684b (diff)
dm mpath: add mutex to synchronize adding and flushing work
Add a mutex to allow possible creators of new work to synchronize with flushing work queues. 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.c59
1 files changed, 38 insertions, 21 deletions
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 5b23f2df9bde..700154e21483 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -93,6 +93,8 @@ struct multipath {
93 * can resubmit bios on error. 93 * can resubmit bios on error.
94 */ 94 */
95 mempool_t *mpio_pool; 95 mempool_t *mpio_pool;
96
97 struct mutex work_mutex;
96}; 98};
97 99
98/* 100/*
@@ -198,6 +200,7 @@ static struct multipath *alloc_multipath(struct dm_target *ti)
198 m->queue_io = 1; 200 m->queue_io = 1;
199 INIT_WORK(&m->process_queued_ios, process_queued_ios); 201 INIT_WORK(&m->process_queued_ios, process_queued_ios);
200 INIT_WORK(&m->trigger_event, trigger_event); 202 INIT_WORK(&m->trigger_event, trigger_event);
203 mutex_init(&m->work_mutex);
201 m->mpio_pool = mempool_create_slab_pool(MIN_IOS, _mpio_cache); 204 m->mpio_pool = mempool_create_slab_pool(MIN_IOS, _mpio_cache);
202 if (!m->mpio_pool) { 205 if (!m->mpio_pool) {
203 kfree(m); 206 kfree(m);
@@ -1268,7 +1271,11 @@ static void multipath_presuspend(struct dm_target *ti)
1268 1271
1269static void multipath_postsuspend(struct dm_target *ti) 1272static void multipath_postsuspend(struct dm_target *ti)
1270{ 1273{
1274 struct multipath *m = ti->private;
1275
1276 mutex_lock(&m->work_mutex);
1271 flush_multipath_work(); 1277 flush_multipath_work();
1278 mutex_unlock(&m->work_mutex);
1272} 1279}
1273 1280
1274/* 1281/*
@@ -1407,51 +1414,61 @@ static int multipath_status(struct dm_target *ti, status_type_t type,
1407 1414
1408static int multipath_message(struct dm_target *ti, unsigned argc, char **argv) 1415static int multipath_message(struct dm_target *ti, unsigned argc, char **argv)
1409{ 1416{
1410 int r; 1417 int r = -EINVAL;
1411 struct dm_dev *dev; 1418 struct dm_dev *dev;
1412 struct multipath *m = (struct multipath *) ti->private; 1419 struct multipath *m = (struct multipath *) ti->private;
1413 action_fn action; 1420 action_fn action;
1414 1421
1422 mutex_lock(&m->work_mutex);
1423
1415 if (argc == 1) { 1424 if (argc == 1) {
1416 if (!strnicmp(argv[0], MESG_STR("queue_if_no_path"))) 1425 if (!strnicmp(argv[0], MESG_STR("queue_if_no_path"))) {
1417 return queue_if_no_path(m, 1, 0); 1426 r = queue_if_no_path(m, 1, 0);
1418 else if (!strnicmp(argv[0], MESG_STR("fail_if_no_path"))) 1427 goto out;
1419 return queue_if_no_path(m, 0, 0); 1428 } else if (!strnicmp(argv[0], MESG_STR("fail_if_no_path"))) {
1429 r = queue_if_no_path(m, 0, 0);
1430 goto out;
1431 }
1420 } 1432 }
1421 1433
1422 if (argc != 2) 1434 if (argc != 2) {
1423 goto error; 1435 DMWARN("Unrecognised multipath message received.");
1436 goto out;
1437 }
1424 1438
1425 if (!strnicmp(argv[0], MESG_STR("disable_group"))) 1439 if (!strnicmp(argv[0], MESG_STR("disable_group"))) {
1426 return bypass_pg_num(m, argv[1], 1); 1440 r = bypass_pg_num(m, argv[1], 1);
1427 else if (!strnicmp(argv[0], MESG_STR("enable_group"))) 1441 goto out;
1428 return bypass_pg_num(m, argv[1], 0); 1442 } else if (!strnicmp(argv[0], MESG_STR("enable_group"))) {
1429 else if (!strnicmp(argv[0], MESG_STR("switch_group"))) 1443 r = bypass_pg_num(m, argv[1], 0);
1430 return switch_pg_num(m, argv[1]); 1444 goto out;
1431 else if (!strnicmp(argv[0], MESG_STR("reinstate_path"))) 1445 } else if (!strnicmp(argv[0], MESG_STR("switch_group"))) {
1446 r = switch_pg_num(m, argv[1]);
1447 goto out;
1448 } else if (!strnicmp(argv[0], MESG_STR("reinstate_path")))
1432 action = reinstate_path; 1449 action = reinstate_path;
1433 else if (!strnicmp(argv[0], MESG_STR("fail_path"))) 1450 else if (!strnicmp(argv[0], MESG_STR("fail_path")))
1434 action = fail_path; 1451 action = fail_path;
1435 else 1452 else {
1436 goto error; 1453 DMWARN("Unrecognised multipath message received.");
1454 goto out;
1455 }
1437 1456
1438 r = dm_get_device(ti, argv[1], ti->begin, ti->len, 1457 r = dm_get_device(ti, argv[1], ti->begin, ti->len,
1439 dm_table_get_mode(ti->table), &dev); 1458 dm_table_get_mode(ti->table), &dev);
1440 if (r) { 1459 if (r) {
1441 DMWARN("message: error getting device %s", 1460 DMWARN("message: error getting device %s",
1442 argv[1]); 1461 argv[1]);
1443 return -EINVAL; 1462 goto out;
1444 } 1463 }
1445 1464
1446 r = action_dev(m, dev, action); 1465 r = action_dev(m, dev, action);
1447 1466
1448 dm_put_device(ti, dev); 1467 dm_put_device(ti, dev);
1449 1468
1469out:
1470 mutex_unlock(&m->work_mutex);
1450 return r; 1471 return r;
1451
1452error:
1453 DMWARN("Unrecognised multipath message received.");
1454 return -EINVAL;
1455} 1472}
1456 1473
1457static int multipath_ioctl(struct dm_target *ti, unsigned int cmd, 1474static int multipath_ioctl(struct dm_target *ti, unsigned int cmd,