]>
Commit | Line | Data |
---|---|---|
d33cec38 GKH |
1 | From eb40c0acdc342b815d4d03ae6abb09e80c0f2988 Mon Sep 17 00:00:00 2001 |
2 | From: Ilya Dryomov <idryomov@gmail.com> | |
3 | Date: Tue, 26 Mar 2019 20:20:58 +0100 | |
4 | Subject: dm table: propagate BDI_CAP_STABLE_WRITES to fix sporadic checksum errors | |
5 | ||
6 | From: Ilya Dryomov <idryomov@gmail.com> | |
7 | ||
8 | commit eb40c0acdc342b815d4d03ae6abb09e80c0f2988 upstream. | |
9 | ||
10 | Some devices don't use blk_integrity but still want stable pages | |
11 | because they do their own checksumming. Examples include rbd and iSCSI | |
12 | when data digests are negotiated. Stacking DM (and thus LVM) on top of | |
13 | these devices results in sporadic checksum errors. | |
14 | ||
15 | Set BDI_CAP_STABLE_WRITES if any underlying device has it set. | |
16 | ||
17 | Cc: stable@vger.kernel.org | |
18 | Signed-off-by: Ilya Dryomov <idryomov@gmail.com> | |
19 | Signed-off-by: Mike Snitzer <snitzer@redhat.com> | |
20 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
21 | ||
22 | --- | |
23 | drivers/md/dm-table.c | 39 +++++++++++++++++++++++++++++++++++++++ | |
24 | 1 file changed, 39 insertions(+) | |
25 | ||
26 | --- a/drivers/md/dm-table.c | |
27 | +++ b/drivers/md/dm-table.c | |
28 | @@ -1872,6 +1872,36 @@ static bool dm_table_supports_secure_era | |
29 | return true; | |
30 | } | |
31 | ||
32 | +static int device_requires_stable_pages(struct dm_target *ti, | |
33 | + struct dm_dev *dev, sector_t start, | |
34 | + sector_t len, void *data) | |
35 | +{ | |
36 | + struct request_queue *q = bdev_get_queue(dev->bdev); | |
37 | + | |
38 | + return q && bdi_cap_stable_pages_required(q->backing_dev_info); | |
39 | +} | |
40 | + | |
41 | +/* | |
42 | + * If any underlying device requires stable pages, a table must require | |
43 | + * them as well. Only targets that support iterate_devices are considered: | |
44 | + * don't want error, zero, etc to require stable pages. | |
45 | + */ | |
46 | +static bool dm_table_requires_stable_pages(struct dm_table *t) | |
47 | +{ | |
48 | + struct dm_target *ti; | |
49 | + unsigned i; | |
50 | + | |
51 | + for (i = 0; i < dm_table_get_num_targets(t); i++) { | |
52 | + ti = dm_table_get_target(t, i); | |
53 | + | |
54 | + if (ti->type->iterate_devices && | |
55 | + ti->type->iterate_devices(ti, device_requires_stable_pages, NULL)) | |
56 | + return true; | |
57 | + } | |
58 | + | |
59 | + return false; | |
60 | +} | |
61 | + | |
62 | void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, | |
63 | struct queue_limits *limits) | |
64 | { | |
65 | @@ -1930,6 +1960,15 @@ void dm_table_set_restrictions(struct dm | |
66 | dm_table_verify_integrity(t); | |
67 | ||
68 | /* | |
69 | + * Some devices don't use blk_integrity but still want stable pages | |
70 | + * because they do their own checksumming. | |
71 | + */ | |
72 | + if (dm_table_requires_stable_pages(t)) | |
73 | + q->backing_dev_info->capabilities |= BDI_CAP_STABLE_WRITES; | |
74 | + else | |
75 | + q->backing_dev_info->capabilities &= ~BDI_CAP_STABLE_WRITES; | |
76 | + | |
77 | + /* | |
78 | * Determine whether or not this queue's I/O timings contribute | |
79 | * to the entropy pool, Only request-based targets use this. | |
80 | * Clear QUEUE_FLAG_ADD_RANDOM if any underlying device does not |