dm integrity: use dm_bio_record and dm_bio_restore
[ Upstream commit 248aa2645aa7fc9175d1107c2593cc90d4af5a4e ]
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: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
da23154ff0
commit
1ea3bdf9e9
@@ -6,6 +6,8 @@
|
|||||||
* This file is released under the GPL.
|
* This file is released under the GPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "dm-bio-record.h"
|
||||||
|
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/device-mapper.h>
|
#include <linux/device-mapper.h>
|
||||||
@@ -276,11 +278,7 @@ struct dm_integrity_io {
|
|||||||
|
|
||||||
struct completion *completion;
|
struct completion *completion;
|
||||||
|
|
||||||
struct gendisk *orig_bi_disk;
|
struct dm_bio_details bio_details;
|
||||||
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 journal_completion {
|
struct journal_completion {
|
||||||
@@ -1249,14 +1247,9 @@ static void integrity_end_io(struct bio *bio)
|
|||||||
{
|
{
|
||||||
struct dm_integrity_io *dio = dm_per_bio_data(bio, sizeof(struct dm_integrity_io));
|
struct dm_integrity_io *dio = dm_per_bio_data(bio, sizeof(struct dm_integrity_io));
|
||||||
|
|
||||||
bio->bi_iter = dio->orig_bi_iter;
|
dm_bio_restore(&dio->bio_details, bio);
|
||||||
bio->bi_disk = dio->orig_bi_disk;
|
if (bio->bi_integrity)
|
||||||
bio->bi_partno = dio->orig_bi_partno;
|
|
||||||
if (dio->orig_bi_integrity) {
|
|
||||||
bio->bi_integrity = dio->orig_bi_integrity;
|
|
||||||
bio->bi_opf |= REQ_INTEGRITY;
|
bio->bi_opf |= REQ_INTEGRITY;
|
||||||
}
|
|
||||||
bio->bi_end_io = dio->orig_bi_end_io;
|
|
||||||
|
|
||||||
if (dio->completion)
|
if (dio->completion)
|
||||||
complete(dio->completion);
|
complete(dio->completion);
|
||||||
@@ -1336,7 +1329,7 @@ static void integrity_metadata(struct work_struct *w)
|
|||||||
if (!checksums)
|
if (!checksums)
|
||||||
checksums = checksums_onstack;
|
checksums = checksums_onstack;
|
||||||
|
|
||||||
__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;
|
unsigned pos;
|
||||||
char *mem, *checksums_ptr;
|
char *mem, *checksums_ptr;
|
||||||
|
|
||||||
@@ -1380,7 +1373,7 @@ static void integrity_metadata(struct work_struct *w)
|
|||||||
if (likely(checksums != checksums_onstack))
|
if (likely(checksums != checksums_onstack))
|
||||||
kfree(checksums);
|
kfree(checksums);
|
||||||
} else {
|
} else {
|
||||||
struct bio_integrity_payload *bip = dio->orig_bi_integrity;
|
struct bio_integrity_payload *bip = dio->bio_details.bi_integrity;
|
||||||
|
|
||||||
if (bip) {
|
if (bip) {
|
||||||
struct bio_vec biv;
|
struct bio_vec biv;
|
||||||
@@ -1784,20 +1777,13 @@ static void dm_integrity_map_continue(struct dm_integrity_io *dio, bool from_map
|
|||||||
} else
|
} else
|
||||||
dio->completion = NULL;
|
dio->completion = NULL;
|
||||||
|
|
||||||
dio->orig_bi_iter = bio->bi_iter;
|
dm_bio_record(&dio->bio_details, bio);
|
||||||
|
|
||||||
dio->orig_bi_disk = bio->bi_disk;
|
|
||||||
dio->orig_bi_partno = bio->bi_partno;
|
|
||||||
bio_set_dev(bio, ic->dev->bdev);
|
bio_set_dev(bio, ic->dev->bdev);
|
||||||
|
|
||||||
dio->orig_bi_integrity = bio_integrity(bio);
|
|
||||||
bio->bi_integrity = NULL;
|
bio->bi_integrity = NULL;
|
||||||
bio->bi_opf &= ~REQ_INTEGRITY;
|
bio->bi_opf &= ~REQ_INTEGRITY;
|
||||||
|
|
||||||
dio->orig_bi_end_io = bio->bi_end_io;
|
|
||||||
bio->bi_end_io = integrity_end_io;
|
bio->bi_end_io = integrity_end_io;
|
||||||
|
|
||||||
bio->bi_iter.bi_size = dio->range.n_sectors << SECTOR_SHIFT;
|
bio->bi_iter.bi_size = dio->range.n_sectors << SECTOR_SHIFT;
|
||||||
|
|
||||||
generic_make_request(bio);
|
generic_make_request(bio);
|
||||||
|
|
||||||
if (need_sync_io) {
|
if (need_sync_io) {
|
||||||
|
|||||||
Reference in New Issue
Block a user