| From 8938a7282a6ad19fcd5f4ffd844ebcfe2e2ce92c Mon Sep 17 00:00:00 2001 |
| From: Mike Snitzer <snitzer@redhat.com> |
| Date: Fri, 28 Feb 2020 18:11:53 -0500 |
| Subject: [PATCH] dm integrity: use dm_bio_record and dm_bio_restore |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| commit 248aa2645aa7fc9175d1107c2593cc90d4af5a4e upstream. |
| |
| In cases where dec_in_flight() has to requeue the integrity_bio_wait |
| work to transfer the rest of the data, the bio's __bi_remaining might |
| already have been decremented to 0, e.g.: if bio passed to underlying |
| data device was split via blk_queue_split(). |
| |
| Use dm_bio_{record,restore} rather than effectively open-coding them in |
| dm-integrity -- these methods now manage __bi_remaining too. |
| |
| Depends-on: f7f0b057a9c1 ("dm bio record: save/restore bi_end_io and bi_integrity") |
| Reported-by: Daniel Glöckner <dg@emlix.com> |
| Suggested-by: Mikulas Patocka <mpatocka@redhat.com> |
| Signed-off-by: Mike Snitzer <snitzer@redhat.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c |
| index 41d1c70b5b81..bdefb9548886 100644 |
| --- a/drivers/md/dm-integrity.c |
| +++ b/drivers/md/dm-integrity.c |
| @@ -6,6 +6,8 @@ |
| * This file is released under the GPL. |
| */ |
| |
| +#include "dm-bio-record.h" |
| + |
| #include <linux/compiler.h> |
| #include <linux/module.h> |
| #include <linux/device-mapper.h> |
| @@ -292,11 +294,7 @@ struct dm_integrity_io { |
| |
| struct completion *completion; |
| |
| - struct gendisk *orig_bi_disk; |
| - u8 orig_bi_partno; |
| - bio_end_io_t *orig_bi_end_io; |
| - struct bio_integrity_payload *orig_bi_integrity; |
| - struct bvec_iter orig_bi_iter; |
| + struct dm_bio_details bio_details; |
| }; |
| |
| struct journal_completion { |
| @@ -1434,14 +1432,9 @@ static void integrity_end_io(struct bio *bio) |
| { |
| struct dm_integrity_io *dio = dm_per_bio_data(bio, sizeof(struct dm_integrity_io)); |
| |
| - bio->bi_iter = dio->orig_bi_iter; |
| - bio->bi_disk = dio->orig_bi_disk; |
| - bio->bi_partno = dio->orig_bi_partno; |
| - if (dio->orig_bi_integrity) { |
| - bio->bi_integrity = dio->orig_bi_integrity; |
| + dm_bio_restore(&dio->bio_details, bio); |
| + if (bio->bi_integrity) |
| bio->bi_opf |= REQ_INTEGRITY; |
| - } |
| - bio->bi_end_io = dio->orig_bi_end_io; |
| |
| if (dio->completion) |
| complete(dio->completion); |
| @@ -1526,7 +1519,7 @@ static void integrity_metadata(struct work_struct *w) |
| } |
| } |
| |
| - __bio_for_each_segment(bv, bio, iter, dio->orig_bi_iter) { |
| + __bio_for_each_segment(bv, bio, iter, dio->bio_details.bi_iter) { |
| unsigned pos; |
| char *mem, *checksums_ptr; |
| |
| @@ -1570,7 +1563,7 @@ static void integrity_metadata(struct work_struct *w) |
| if (likely(checksums != checksums_onstack)) |
| kfree(checksums); |
| } else { |
| - struct bio_integrity_payload *bip = dio->orig_bi_integrity; |
| + struct bio_integrity_payload *bip = dio->bio_details.bi_integrity; |
| |
| if (bip) { |
| struct bio_vec biv; |
| @@ -1989,20 +1982,13 @@ static void dm_integrity_map_continue(struct dm_integrity_io *dio, bool from_map |
| } else |
| dio->completion = NULL; |
| |
| - dio->orig_bi_iter = bio->bi_iter; |
| - |
| - dio->orig_bi_disk = bio->bi_disk; |
| - dio->orig_bi_partno = bio->bi_partno; |
| + dm_bio_record(&dio->bio_details, bio); |
| bio_set_dev(bio, ic->dev->bdev); |
| - |
| - dio->orig_bi_integrity = bio_integrity(bio); |
| bio->bi_integrity = NULL; |
| bio->bi_opf &= ~REQ_INTEGRITY; |
| - |
| - dio->orig_bi_end_io = bio->bi_end_io; |
| bio->bi_end_io = integrity_end_io; |
| - |
| bio->bi_iter.bi_size = dio->range.n_sectors << SECTOR_SHIFT; |
| + |
| generic_make_request(bio); |
| |
| if (need_sync_io) { |
| -- |
| 2.7.4 |
| |