]>
Commit | Line | Data |
---|---|---|
1050601f GKH |
1 | From 6936c12cf809850180b24947271b8f068fdb15e9 Mon Sep 17 00:00:00 2001 |
2 | From: Mike Snitzer <snitzer@redhat.com> | |
3 | Date: Wed, 23 Nov 2016 13:51:09 -0500 | |
4 | Subject: dm table: fix 'all_blk_mq' inconsistency when an empty table is loaded | |
5 | ||
6 | From: Mike Snitzer <snitzer@redhat.com> | |
7 | ||
8 | commit 6936c12cf809850180b24947271b8f068fdb15e9 upstream. | |
9 | ||
10 | An earlier DM multipath table could have been build ontop of underlying | |
11 | devices that were all using blk-mq. In that case, if that active | |
12 | multipath table is replaced with an empty DM multipath table (that | |
13 | reflects all paths have failed) then it is important that the | |
14 | 'all_blk_mq' state of the active table is transfered to the new empty DM | |
15 | table. Otherwise dm-rq.c:dm_old_prep_tio() will incorrectly clone a | |
16 | request that isn't needed by the DM multipath target when it is to issue | |
17 | IO to an underlying blk-mq device. | |
18 | ||
19 | Fixes: e83068a5 ("dm mpath: add optional "queue_mode" feature") | |
20 | Reported-by: Bart Van Assche <bart.vanassche@sandisk.com> | |
21 | Tested-by: Bart Van Assche <bart.vanassche@sandisk.com> | |
22 | Signed-off-by: Mike Snitzer <snitzer@redhat.com> | |
23 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
24 | ||
25 | --- | |
26 | drivers/md/dm-table.c | 19 +++++++++++++------ | |
27 | 1 file changed, 13 insertions(+), 6 deletions(-) | |
28 | ||
29 | --- a/drivers/md/dm-table.c | |
30 | +++ b/drivers/md/dm-table.c | |
31 | @@ -924,12 +924,6 @@ static int dm_table_determine_type(struc | |
32 | ||
33 | BUG_ON(!request_based); /* No targets in this table */ | |
34 | ||
35 | - if (list_empty(devices) && __table_type_request_based(live_md_type)) { | |
36 | - /* inherit live MD type */ | |
37 | - t->type = live_md_type; | |
38 | - return 0; | |
39 | - } | |
40 | - | |
41 | /* | |
42 | * The only way to establish DM_TYPE_MQ_REQUEST_BASED is by | |
43 | * having a compatible target use dm_table_set_type. | |
44 | @@ -948,6 +942,19 @@ verify_rq_based: | |
45 | return -EINVAL; | |
46 | } | |
47 | ||
48 | + if (list_empty(devices)) { | |
49 | + int srcu_idx; | |
50 | + struct dm_table *live_table = dm_get_live_table(t->md, &srcu_idx); | |
51 | + | |
52 | + /* inherit live table's type and all_blk_mq */ | |
53 | + if (live_table) { | |
54 | + t->type = live_table->type; | |
55 | + t->all_blk_mq = live_table->all_blk_mq; | |
56 | + } | |
57 | + dm_put_live_table(t->md, srcu_idx); | |
58 | + return 0; | |
59 | + } | |
60 | + | |
61 | /* Non-request-stackable devices can't be used for request-based dm */ | |
62 | list_for_each_entry(dd, devices, list) { | |
63 | struct request_queue *q = bdev_get_queue(dd->dm_dev->bdev); |