diff options
author | Junichi Nomura <j-nomura@ce.jp.nec.com> | 2015-05-29 04:51:03 -0400 |
---|---|---|
committer | Mike Snitzer <snitzer@redhat.com> | 2015-05-29 13:41:16 -0400 |
commit | 15b94a690470038aa08247eedbebbe7e2218d5ee (patch) | |
tree | e3a715140ed69f9566e5fff834ef2daad742ade7 | |
parent | e5d8de32cc02a259e1a237ab57cba00f2930fa6a (diff) |
dm: fix reload failure of 0 path multipath mapping on blk-mq devices
dm-multipath accepts 0 path mapping.
# echo '0 2097152 multipath 0 0 0 0' | dmsetup create newdev
Such a mapping can be used to release underlying devices while still
holding requests in its queue until working paths come back.
However, once the multipath device is created over blk-mq devices,
it rejects reloading of 0 path mapping:
# echo '0 2097152 multipath 0 0 1 1 queue-length 0 1 1 /dev/sda 1' \
| dmsetup create mpath1
# echo '0 2097152 multipath 0 0 0 0' | dmsetup load mpath1
device-mapper: reload ioctl on mpath1 failed: Invalid argument
Command failed
With following kernel message:
device-mapper: ioctl: can't change device type after initial table load.
DM tries to inherit the current table type using dm_table_set_type()
but it doesn't work as expected because of unnecessary check about
whether the target type is hybrid or not.
Hybrid type is for targets that work as either request-based or bio-based
and not required for blk-mq or non blk-mq checking.
Fixes: 65803c205983 ("dm table: train hybrid target type detection to select blk-mq if appropriate")
Signed-off-by: Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
-rw-r--r-- | drivers/md/dm-table.c | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index d9b00b8565c6..16ba55ad7089 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c | |||
@@ -820,6 +820,12 @@ void dm_consume_args(struct dm_arg_set *as, unsigned num_args) | |||
820 | } | 820 | } |
821 | EXPORT_SYMBOL(dm_consume_args); | 821 | EXPORT_SYMBOL(dm_consume_args); |
822 | 822 | ||
823 | static bool __table_type_request_based(unsigned table_type) | ||
824 | { | ||
825 | return (table_type == DM_TYPE_REQUEST_BASED || | ||
826 | table_type == DM_TYPE_MQ_REQUEST_BASED); | ||
827 | } | ||
828 | |||
823 | static int dm_table_set_type(struct dm_table *t) | 829 | static int dm_table_set_type(struct dm_table *t) |
824 | { | 830 | { |
825 | unsigned i; | 831 | unsigned i; |
@@ -852,8 +858,7 @@ static int dm_table_set_type(struct dm_table *t) | |||
852 | * Determine the type from the live device. | 858 | * Determine the type from the live device. |
853 | * Default to bio-based if device is new. | 859 | * Default to bio-based if device is new. |
854 | */ | 860 | */ |
855 | if (live_md_type == DM_TYPE_REQUEST_BASED || | 861 | if (__table_type_request_based(live_md_type)) |
856 | live_md_type == DM_TYPE_MQ_REQUEST_BASED) | ||
857 | request_based = 1; | 862 | request_based = 1; |
858 | else | 863 | else |
859 | bio_based = 1; | 864 | bio_based = 1; |
@@ -903,7 +908,7 @@ static int dm_table_set_type(struct dm_table *t) | |||
903 | } | 908 | } |
904 | t->type = DM_TYPE_MQ_REQUEST_BASED; | 909 | t->type = DM_TYPE_MQ_REQUEST_BASED; |
905 | 910 | ||
906 | } else if (hybrid && list_empty(devices) && live_md_type != DM_TYPE_NONE) { | 911 | } else if (list_empty(devices) && __table_type_request_based(live_md_type)) { |
907 | /* inherit live MD type */ | 912 | /* inherit live MD type */ |
908 | t->type = live_md_type; | 913 | t->type = live_md_type; |
909 | 914 | ||
@@ -925,10 +930,7 @@ struct target_type *dm_table_get_immutable_target_type(struct dm_table *t) | |||
925 | 930 | ||
926 | bool dm_table_request_based(struct dm_table *t) | 931 | bool dm_table_request_based(struct dm_table *t) |
927 | { | 932 | { |
928 | unsigned table_type = dm_table_get_type(t); | 933 | return __table_type_request_based(dm_table_get_type(t)); |
929 | |||
930 | return (table_type == DM_TYPE_REQUEST_BASED || | ||
931 | table_type == DM_TYPE_MQ_REQUEST_BASED); | ||
932 | } | 934 | } |
933 | 935 | ||
934 | bool dm_table_mq_request_based(struct dm_table *t) | 936 | bool dm_table_mq_request_based(struct dm_table *t) |