On Fri, 8 Jan 2021 11:15:56 -0500 (EST) Mikulas Patocka <mpatocka@xxxxxxxxxx> wrote: > 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. > > Signed-off-by: Mikulas Patocka <mpatocka@xxxxxxxxxx> > Reported-by: Lukas Straub <lukasstraub2@xxxxxx> > Cc: stable@xxxxxxxxxxxxxxx Looks good to me. Reviewed-by: Lukas Straub <lukasstraub2@xxxxxx> Regards, Lukas Straub > --- > drivers/md/dm-bufio.c | 6 ++++ > drivers/md/dm-integrity.c | 60 +++++++++++++++++++++++++++++++++++++--------- > include/linux/dm-bufio.h | 1 > 3 files changed, 56 insertions(+), 11 deletions(-) > > Index: linux-2.6/drivers/md/dm-integrity.c > =================================================================== > --- linux-2.6.orig/drivers/md/dm-integrity.c 2021-01-07 17:22:39.000000000 +0100 > +++ linux-2.6/drivers/md/dm-integrity.c 2021-01-08 15:51:19.000000000 +0100 > @@ -1379,12 +1379,52 @@ thorough_test: > #undef MAY_BE_HASH > } > > -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) > @@ -2110,7 +2150,7 @@ offload_to_thread: > > if (unlikely(dio->op == REQ_OP_DISCARD) && likely(ic->mode != 'D')) { > integrity_metadata(&dio->work); > - dm_integrity_flush_buffers(ic); > + dm_integrity_flush_buffers(ic, false); > > dio->in_flight = (atomic_t)ATOMIC_INIT(1); > dio->completion = NULL; > @@ -2195,7 +2235,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; > } > > @@ -2409,7 +2449,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) > @@ -2451,7 +2491,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; > > @@ -2654,7 +2694,7 @@ static void bitmap_flush_work(struct wor > unsigned long limit; > struct bio *bio; > > - dm_integrity_flush_buffers(ic); > + dm_integrity_flush_buffers(ic, false); > > range.logical_sector = 0; > range.n_sectors = ic->provided_data_sectors; > @@ -2663,9 +2703,7 @@ static void bitmap_flush_work(struct wor > add_new_range_and_wait(ic, &range); > spin_unlock_irq(&ic->endio_wait.lock); > > - dm_integrity_flush_buffers(ic); > - if (ic->meta_dev) > - blkdev_issue_flush(ic->dev->bdev, GFP_NOIO); > + dm_integrity_flush_buffers(ic, true); > > limit = ic->provided_data_sectors; > if (ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING)) { > @@ -2934,11 +2972,11 @@ 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); > } > > if (ic->mode == 'B') { > - dm_integrity_flush_buffers(ic); > + dm_integrity_flush_buffers(ic, true); > #if 1 > /* set to 0 to test bitmap replay code */ > init_journal(ic, 0, ic->journal_sections, 0); > Index: linux-2.6/include/linux/dm-bufio.h > =================================================================== > --- linux-2.6.orig/include/linux/dm-bufio.h 2020-09-05 10:01:42.000000000 +0200 > +++ linux-2.6/include/linux/dm-bufio.h 2021-01-08 15:12:31.000000000 +0100 > @@ -150,6 +150,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); > Index: linux-2.6/drivers/md/dm-bufio.c > =================================================================== > --- linux-2.6.orig/drivers/md/dm-bufio.c 2021-01-08 15:11:20.000000000 +0100 > +++ linux-2.6/drivers/md/dm-bufio.c 2021-01-08 15:12:25.000000000 +0100 > @@ -1534,6 +1534,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; > --
Attachment:
pgppN7lHhJtpN.pgp
Description: OpenPGP digital signature
-- dm-devel mailing list dm-devel@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/dm-devel