aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Snitzer <snitzer@redhat.com>2014-12-18 16:26:47 -0500
committerMike Snitzer <snitzer@redhat.com>2015-02-09 13:06:47 -0500
commit65803c2059832fb99b992728157f7924c2e42d4b (patch)
tree02ba090a7ff05070a3bb999708ceee67dadd0a10
parente5863d9ad754926e7d3f38b43ac8bd48ef73b097 (diff)
dm table: train hybrid target type detection to select blk-mq if appropriate
Otherwise replacing the multipath target with the error target fails: device-mapper: ioctl: can't change device type after initial table load. The error target was mistakenly considered to be target type DM_TYPE_REQUEST_BASED rather than DM_TYPE_MQ_REQUEST_BASED even if the target it was to replace was of type DM_TYPE_MQ_REQUEST_BASED. Signed-off-by: Mike Snitzer <snitzer@redhat.com>
-rw-r--r--drivers/md/dm-table.c35
-rw-r--r--drivers/md/dm.h3
2 files changed, 22 insertions, 16 deletions
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 2d7e373955f3..14954d844668 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -831,7 +831,7 @@ static int dm_table_set_type(struct dm_table *t)
831 struct dm_target *tgt; 831 struct dm_target *tgt;
832 struct dm_dev_internal *dd; 832 struct dm_dev_internal *dd;
833 struct list_head *devices; 833 struct list_head *devices;
834 unsigned live_md_type; 834 unsigned live_md_type = dm_get_md_type(t->md);
835 835
836 for (i = 0; i < t->num_targets; i++) { 836 for (i = 0; i < t->num_targets; i++) {
837 tgt = t->targets + i; 837 tgt = t->targets + i;
@@ -855,8 +855,8 @@ static int dm_table_set_type(struct dm_table *t)
855 * Determine the type from the live device. 855 * Determine the type from the live device.
856 * Default to bio-based if device is new. 856 * Default to bio-based if device is new.
857 */ 857 */
858 live_md_type = dm_get_md_type(t->md); 858 if (live_md_type == DM_TYPE_REQUEST_BASED ||
859 if (live_md_type == DM_TYPE_REQUEST_BASED) 859 live_md_type == DM_TYPE_MQ_REQUEST_BASED)
860 request_based = 1; 860 request_based = 1;
861 else 861 else
862 bio_based = 1; 862 bio_based = 1;
@@ -870,6 +870,17 @@ static int dm_table_set_type(struct dm_table *t)
870 870
871 BUG_ON(!request_based); /* No targets in this table */ 871 BUG_ON(!request_based); /* No targets in this table */
872 872
873 /*
874 * Request-based dm supports only tables that have a single target now.
875 * To support multiple targets, request splitting support is needed,
876 * and that needs lots of changes in the block-layer.
877 * (e.g. request completion process for partial completion.)
878 */
879 if (t->num_targets > 1) {
880 DMWARN("Request-based dm doesn't support multiple targets yet");
881 return -EINVAL;
882 }
883
873 /* Non-request-stackable devices can't be used for request-based dm */ 884 /* Non-request-stackable devices can't be used for request-based dm */
874 devices = dm_table_get_devices(t); 885 devices = dm_table_get_devices(t);
875 list_for_each_entry(dd, devices, list) { 886 list_for_each_entry(dd, devices, list) {
@@ -893,20 +904,14 @@ static int dm_table_set_type(struct dm_table *t)
893 " are blk-mq request-stackable"); 904 " are blk-mq request-stackable");
894 return -EINVAL; 905 return -EINVAL;
895 } 906 }
896 } 907 t->type = DM_TYPE_MQ_REQUEST_BASED;
897 908
898 /* 909 } else if (hybrid && list_empty(devices) && live_md_type != DM_TYPE_NONE) {
899 * Request-based dm supports only tables that have a single target now. 910 /* inherit live MD type */
900 * To support multiple targets, request splitting support is needed, 911 t->type = live_md_type;
901 * and that needs lots of changes in the block-layer.
902 * (e.g. request completion process for partial completion.)
903 */
904 if (t->num_targets > 1) {
905 DMWARN("Request-based dm doesn't support multiple targets yet");
906 return -EINVAL;
907 }
908 912
909 t->type = !use_blk_mq ? DM_TYPE_REQUEST_BASED : DM_TYPE_MQ_REQUEST_BASED; 913 } else
914 t->type = DM_TYPE_REQUEST_BASED;
910 915
911 return 0; 916 return 0;
912} 917}
diff --git a/drivers/md/dm.h b/drivers/md/dm.h
index 84d79784b866..59f53e79db82 100644
--- a/drivers/md/dm.h
+++ b/drivers/md/dm.h
@@ -101,7 +101,8 @@ int dm_setup_md_queue(struct mapped_device *md);
101/* 101/*
102 * To check whether the target type is request-based or not (bio-based). 102 * To check whether the target type is request-based or not (bio-based).
103 */ 103 */
104#define dm_target_request_based(t) ((t)->type->map_rq != NULL) 104#define dm_target_request_based(t) (((t)->type->map_rq != NULL) || \
105 ((t)->type->clone_and_map_rq != NULL))
105 106
106/* 107/*
107 * To check whether the target type is a hybrid (capable of being 108 * To check whether the target type is a hybrid (capable of being