On Fri, 8 Jan 2021 11:15:56 -0500 (EST)
Mikulas Patocka <[email protected]> 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 <[email protected]>
> Reported-by: Lukas Straub <[email protected]>
> Cc: [email protected]

Looks good to me.
Reviewed-by: Lukas Straub <[email protected]>

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: pgpvyIzIYh6B4.pgp
Description: OpenPGP digital signature

--
dm-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/dm-devel

Reply via email to