Commit dcd61984 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'for-5.15/dm-fixes' of...

Merge tag 'for-5.15/dm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/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
parents 304040fb d208b894
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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"
+8 −0
Original line number Diff line number Diff line
@@ -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);
+12 −3
Original line number Diff line number Diff line
@@ -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;
@@ -529,10 +530,18 @@ 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,
		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;
}
+10 −7
Original line number Diff line number Diff line
@@ -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)))
@@ -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)) {
@@ -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;