Skip to content

Commit

Permalink
Merge tag 'for-5.15/dm-fixes' of git://git.kernel.org/pub/scm/linux/k…
Browse files Browse the repository at this point in the history
…ernel/git/device-mapper/linux-dm

Pull device mapper fixes from Mike Snitzer:

 - Fix DM verity target to skip redundant processing on I/O errors.

 - Fix request-based DM so that it doesn't queue request to blk-mq when
   DM device is suspended.

 - Fix DM core mempool NULL pointer race when completing IO.

 - Make DM clone target's 'descs' array static.

* tag 'for-5.15/dm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm:
  dm: fix mempool NULL pointer race when completing IO
  dm rq: don't queue request to blk-mq during DM suspend
  dm clone: make array 'descs' static
  dm verity: skip redundant verity_handle_err() on I/O errors
  • Loading branch information
Linus Torvalds committed Oct 16, 2021
2 parents 304040f + d208b89 commit dcd6198
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 11 deletions.
2 changes: 1 addition & 1 deletion drivers/md/dm-clone-target.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ static const char *clone_device_name(struct clone *clone)

static void __set_clone_mode(struct clone *clone, enum clone_metadata_mode new_mode)
{
const char *descs[] = {
static const char * const descs[] = {
"read-write",
"read-only",
"fail"
Expand Down
8 changes: 8 additions & 0 deletions drivers/md/dm-rq.c
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,14 @@ static blk_status_t dm_mq_queue_rq(struct blk_mq_hw_ctx *hctx,
struct mapped_device *md = tio->md;
struct dm_target *ti = md->immutable_target;

/*
* blk-mq's unquiesce may come from outside events, such as
* elevator switch, updating nr_requests or others, and request may
* come during suspend, so simply ask for blk-mq to requeue it.
*/
if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)))
return BLK_STS_RESOURCE;

if (unlikely(!ti)) {
int srcu_idx;
struct dm_table *map = dm_get_live_table(md, &srcu_idx);
Expand Down
15 changes: 12 additions & 3 deletions drivers/md/dm-verity-target.c
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,7 @@ static int verity_verify_io(struct dm_verity_io *io)
struct bvec_iter start;
unsigned b;
struct crypto_wait wait;
struct bio *bio = dm_bio_from_per_bio_data(io, v->ti->per_io_data_size);

for (b = 0; b < io->n_blocks; b++) {
int r;
Expand Down Expand Up @@ -529,9 +530,17 @@ static int verity_verify_io(struct dm_verity_io *io)
else if (verity_fec_decode(v, io, DM_VERITY_BLOCK_TYPE_DATA,
cur_block, NULL, &start) == 0)
continue;
else if (verity_handle_err(v, DM_VERITY_BLOCK_TYPE_DATA,
cur_block))
return -EIO;
else {
if (bio->bi_status) {
/*
* Error correction failed; Just return error
*/
return -EIO;
}
if (verity_handle_err(v, DM_VERITY_BLOCK_TYPE_DATA,
cur_block))
return -EIO;
}
}

return 0;
Expand Down
17 changes: 10 additions & 7 deletions drivers/md/dm.c
Original file line number Diff line number Diff line change
Expand Up @@ -496,18 +496,17 @@ static void start_io_acct(struct dm_io *io)
false, 0, &io->stats_aux);
}

static void end_io_acct(struct dm_io *io)
static void end_io_acct(struct mapped_device *md, struct bio *bio,
unsigned long start_time, struct dm_stats_aux *stats_aux)
{
struct mapped_device *md = io->md;
struct bio *bio = io->orig_bio;
unsigned long duration = jiffies - io->start_time;
unsigned long duration = jiffies - start_time;

bio_end_io_acct(bio, io->start_time);
bio_end_io_acct(bio, start_time);

if (unlikely(dm_stats_used(&md->stats)))
dm_stats_account_io(&md->stats, bio_data_dir(bio),
bio->bi_iter.bi_sector, bio_sectors(bio),
true, duration, &io->stats_aux);
true, duration, stats_aux);

/* nudge anyone waiting on suspend queue */
if (unlikely(wq_has_sleeper(&md->wait)))
Expand Down Expand Up @@ -790,6 +789,8 @@ void dm_io_dec_pending(struct dm_io *io, blk_status_t error)
blk_status_t io_error;
struct bio *bio;
struct mapped_device *md = io->md;
unsigned long start_time = 0;
struct dm_stats_aux stats_aux;

/* Push-back supersedes any I/O errors */
if (unlikely(error)) {
Expand Down Expand Up @@ -821,8 +822,10 @@ void dm_io_dec_pending(struct dm_io *io, blk_status_t error)
}

io_error = io->status;
end_io_acct(io);
start_time = io->start_time;
stats_aux = io->stats_aux;
free_io(md, io);
end_io_acct(md, bio, start_time, &stats_aux);

if (io_error == BLK_STS_DM_REQUEUE)
return;
Expand Down

0 comments on commit dcd6198

Please sign in to comment.