| From eb40c0acdc342b815d4d03ae6abb09e80c0f2988 Mon Sep 17 00:00:00 2001 |
| From: Ilya Dryomov <idryomov@gmail.com> |
| Date: Tue, 26 Mar 2019 20:20:58 +0100 |
| Subject: dm table: propagate BDI_CAP_STABLE_WRITES to fix sporadic checksum errors |
| |
| From: Ilya Dryomov <idryomov@gmail.com> |
| |
| commit eb40c0acdc342b815d4d03ae6abb09e80c0f2988 upstream. |
| |
| Some devices don't use blk_integrity but still want stable pages |
| because they do their own checksumming. Examples include rbd and iSCSI |
| when data digests are negotiated. Stacking DM (and thus LVM) on top of |
| these devices results in sporadic checksum errors. |
| |
| Set BDI_CAP_STABLE_WRITES if any underlying device has it set. |
| |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Ilya Dryomov <idryomov@gmail.com> |
| Signed-off-by: Mike Snitzer <snitzer@redhat.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/md/dm-table.c | 39 +++++++++++++++++++++++++++++++++++++++ |
| 1 file changed, 39 insertions(+) |
| |
| --- a/drivers/md/dm-table.c |
| +++ b/drivers/md/dm-table.c |
| @@ -1852,6 +1852,36 @@ static bool dm_table_supports_secure_era |
| return true; |
| } |
| |
| +static int device_requires_stable_pages(struct dm_target *ti, |
| + struct dm_dev *dev, sector_t start, |
| + sector_t len, void *data) |
| +{ |
| + struct request_queue *q = bdev_get_queue(dev->bdev); |
| + |
| + return q && bdi_cap_stable_pages_required(q->backing_dev_info); |
| +} |
| + |
| +/* |
| + * If any underlying device requires stable pages, a table must require |
| + * them as well. Only targets that support iterate_devices are considered: |
| + * don't want error, zero, etc to require stable pages. |
| + */ |
| +static bool dm_table_requires_stable_pages(struct dm_table *t) |
| +{ |
| + struct dm_target *ti; |
| + unsigned i; |
| + |
| + for (i = 0; i < dm_table_get_num_targets(t); i++) { |
| + ti = dm_table_get_target(t, i); |
| + |
| + if (ti->type->iterate_devices && |
| + ti->type->iterate_devices(ti, device_requires_stable_pages, NULL)) |
| + return true; |
| + } |
| + |
| + return false; |
| +} |
| + |
| void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, |
| struct queue_limits *limits) |
| { |
| @@ -1910,6 +1940,15 @@ void dm_table_set_restrictions(struct dm |
| dm_table_verify_integrity(t); |
| |
| /* |
| + * Some devices don't use blk_integrity but still want stable pages |
| + * because they do their own checksumming. |
| + */ |
| + if (dm_table_requires_stable_pages(t)) |
| + q->backing_dev_info->capabilities |= BDI_CAP_STABLE_WRITES; |
| + else |
| + q->backing_dev_info->capabilities &= ~BDI_CAP_STABLE_WRITES; |
| + |
| + /* |
| * Determine whether or not this queue's I/O timings contribute |
| * to the entropy pool, Only request-based targets use this. |
| * Clear QUEUE_FLAG_ADD_RANDOM if any underlying device does not |