From: Greg Kroah-Hartman Date: Wed, 20 Jan 2021 11:00:15 +0000 (+0100) Subject: 4.19-stable patches X-Git-Tag: v4.4.253~28 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fc5fe1687037996e10b11e64772b84422a742671;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches added patches: dm-integrity-fix-flush-with-external-metadata-device.patch --- diff --git a/queue-4.19/dm-integrity-fix-flush-with-external-metadata-device.patch b/queue-4.19/dm-integrity-fix-flush-with-external-metadata-device.patch new file mode 100644 index 00000000000..78213257809 --- /dev/null +++ b/queue-4.19/dm-integrity-fix-flush-with-external-metadata-device.patch @@ -0,0 +1,146 @@ +From 9b5948267adc9e689da609eb61cf7ed49cae5fa8 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Fri, 8 Jan 2021 11:15:56 -0500 +Subject: dm integrity: fix flush with external metadata device + +From: Mikulas Patocka + +commit 9b5948267adc9e689da609eb61cf7ed49cae5fa8 upstream. + +With external metadata device, flush requests are not passed down to the +data device. + +Fix this by submitting the flush request in dm_integrity_flush_buffers. In +order to not degrade performance, we overlap the data device flush with +the metadata device flush. + +Reported-by: Lukas Straub +Signed-off-by: Mikulas Patocka +Cc: stable@vger.kernel.org +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + + +--- + drivers/md/dm-bufio.c | 6 +++++ + drivers/md/dm-integrity.c | 50 +++++++++++++++++++++++++++++++++++++++++----- + include/linux/dm-bufio.h | 1 + 3 files changed, 52 insertions(+), 5 deletions(-) + +--- a/drivers/md/dm-bufio.c ++++ b/drivers/md/dm-bufio.c +@@ -1471,6 +1471,12 @@ sector_t dm_bufio_get_device_size(struct + } + EXPORT_SYMBOL_GPL(dm_bufio_get_device_size); + ++struct dm_io_client *dm_bufio_get_dm_io_client(struct dm_bufio_client *c) ++{ ++ return c->dm_io; ++} ++EXPORT_SYMBOL_GPL(dm_bufio_get_dm_io_client); ++ + sector_t dm_bufio_get_block_number(struct dm_buffer *b) + { + return b->block; +--- a/drivers/md/dm-integrity.c ++++ b/drivers/md/dm-integrity.c +@@ -1153,12 +1153,52 @@ static int dm_integrity_rw_tag(struct dm + return 0; + } + +-static void dm_integrity_flush_buffers(struct dm_integrity_c *ic) ++struct flush_request { ++ struct dm_io_request io_req; ++ struct dm_io_region io_reg; ++ struct dm_integrity_c *ic; ++ struct completion comp; ++}; ++ ++static void flush_notify(unsigned long error, void *fr_) ++{ ++ struct flush_request *fr = fr_; ++ if (unlikely(error != 0)) ++ dm_integrity_io_error(fr->ic, "flusing disk cache", -EIO); ++ complete(&fr->comp); ++} ++ ++static void dm_integrity_flush_buffers(struct dm_integrity_c *ic, bool flush_data) + { + int r; ++ ++ struct flush_request fr; ++ ++ if (!ic->meta_dev) ++ flush_data = false; ++ if (flush_data) { ++ fr.io_req.bi_op = REQ_OP_WRITE, ++ fr.io_req.bi_op_flags = REQ_PREFLUSH | REQ_SYNC, ++ fr.io_req.mem.type = DM_IO_KMEM, ++ fr.io_req.mem.ptr.addr = NULL, ++ fr.io_req.notify.fn = flush_notify, ++ fr.io_req.notify.context = &fr; ++ fr.io_req.client = dm_bufio_get_dm_io_client(ic->bufio), ++ fr.io_reg.bdev = ic->dev->bdev, ++ fr.io_reg.sector = 0, ++ fr.io_reg.count = 0, ++ fr.ic = ic; ++ init_completion(&fr.comp); ++ r = dm_io(&fr.io_req, 1, &fr.io_reg, NULL); ++ BUG_ON(r); ++ } ++ + r = dm_bufio_write_dirty_buffers(ic->bufio); + if (unlikely(r)) + dm_integrity_io_error(ic, "writing tags", r); ++ ++ if (flush_data) ++ wait_for_completion(&fr.comp); + } + + static void sleep_on_endio_wait(struct dm_integrity_c *ic) +@@ -1846,7 +1886,7 @@ static void integrity_commit(struct work + flushes = bio_list_get(&ic->flush_bio_list); + if (unlikely(ic->mode != 'J')) { + spin_unlock_irq(&ic->endio_wait.lock); +- dm_integrity_flush_buffers(ic); ++ dm_integrity_flush_buffers(ic, true); + goto release_flush_bios; + } + +@@ -2057,7 +2097,7 @@ skip_io: + complete_journal_op(&comp); + wait_for_completion_io(&comp.comp); + +- dm_integrity_flush_buffers(ic); ++ dm_integrity_flush_buffers(ic, true); + } + + static void integrity_writer(struct work_struct *w) +@@ -2099,7 +2139,7 @@ static void recalc_write_super(struct dm + { + int r; + +- dm_integrity_flush_buffers(ic); ++ dm_integrity_flush_buffers(ic, false); + if (dm_integrity_failed(ic)) + return; + +@@ -2409,7 +2449,7 @@ static void dm_integrity_postsuspend(str + if (ic->meta_dev) + queue_work(ic->writer_wq, &ic->writer_work); + drain_workqueue(ic->writer_wq); +- dm_integrity_flush_buffers(ic); ++ dm_integrity_flush_buffers(ic, true); + } + + BUG_ON(!RB_EMPTY_ROOT(&ic->in_progress)); +--- a/include/linux/dm-bufio.h ++++ b/include/linux/dm-bufio.h +@@ -138,6 +138,7 @@ void dm_bufio_set_minimum_buffers(struct + + unsigned dm_bufio_get_block_size(struct dm_bufio_client *c); + sector_t dm_bufio_get_device_size(struct dm_bufio_client *c); ++struct dm_io_client *dm_bufio_get_dm_io_client(struct dm_bufio_client *c); + sector_t dm_bufio_get_block_number(struct dm_buffer *b); + void *dm_bufio_get_block_data(struct dm_buffer *b); + void *dm_bufio_get_aux_data(struct dm_buffer *b); diff --git a/queue-4.19/series b/queue-4.19/series index ab3c52acd07..4307ae6dcb3 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -1,2 +1,3 @@ usb-ohci-make-distrust_firmware-param-default-to-false.patch compiler.h-raise-minimum-version-of-gcc-to-5.1-for-arm64.patch +dm-integrity-fix-flush-with-external-metadata-device.patch