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

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

Merge tag 'for-5.18/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 integrity shrink crash due to journal entry not being marked
   unused.

 - Fix DM bio polling to handle possibility that underlying device(s)
   return BLK_STS_AGAIN during submission.

 - Fix dm_io and dm_target_io flags race condition on Alpha.

 - Add some pr_err debugging to help debug cases when DM ioctl structure
   is corrupted.

* tag 'for-5.18/dm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm:
  dm: fix bio polling to handle possibile BLK_STS_AGAIN
  dm: fix dm_io and dm_target_io flags race condition on Alpha
  dm integrity: set journal entry unused when shrinking device
  dm ioctl: log an error if the ioctl structure is corrupted
parents 7a3ecddc 52919840
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -210,7 +210,7 @@ struct dm_table {
#define DM_TIO_MAGIC 28714
struct dm_target_io {
	unsigned short magic;
	unsigned short flags;
	blk_short_t flags;
	unsigned int target_bio_nr;
	struct dm_io *io;
	struct dm_target *ti;
@@ -244,7 +244,7 @@ static inline void dm_tio_set_flag(struct dm_target_io *tio, unsigned int bit)
#define DM_IO_MAGIC 19577
struct dm_io {
	unsigned short magic;
	unsigned short flags;
	blk_short_t flags;
	atomic_t io_count;
	struct mapped_device *md;
	struct bio *orig_bio;
+4 −2
Original line number Diff line number Diff line
@@ -2472,9 +2472,11 @@ static void do_journal_write(struct dm_integrity_c *ic, unsigned write_start,
					dm_integrity_io_error(ic, "invalid sector in journal", -EIO);
					sec &= ~(sector_t)(ic->sectors_per_block - 1);
				}
			}
			if (unlikely(sec >= ic->provided_data_sectors))
				if (unlikely(sec >= ic->provided_data_sectors)) {
					journal_entry_set_unused(je);
					continue;
				}
			}
			get_area_and_offset(ic, sec, &area, &offset);
			restore_last_bytes(ic, access_journal_data(ic, i, j), je);
			for (k = j + 1; k < ic->journal_section_entries; k++) {
+12 −3
Original line number Diff line number Diff line
@@ -891,15 +891,21 @@ static struct hash_cell *__find_device_hash_cell(struct dm_ioctl *param)
	struct hash_cell *hc = NULL;

	if (*param->uuid) {
		if (*param->name || param->dev)
		if (*param->name || param->dev) {
			DMERR("Invalid ioctl structure: uuid %s, name %s, dev %llx",
			      param->uuid, param->name, (unsigned long long)param->dev);
			return NULL;
		}

		hc = __get_uuid_cell(param->uuid);
		if (!hc)
			return NULL;
	} else if (*param->name) {
		if (param->dev)
		if (param->dev) {
			DMERR("Invalid ioctl structure: name %s, dev %llx",
			      param->name, (unsigned long long)param->dev);
			return NULL;
		}

		hc = __get_name_cell(param->name);
		if (!hc)
@@ -1851,8 +1857,11 @@ static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl *param_kern
	if (copy_from_user(param_kernel, user, minimum_data_size))
		return -EFAULT;

	if (param_kernel->data_size < minimum_data_size)
	if (param_kernel->data_size < minimum_data_size) {
		DMERR("Invalid data size in the ioctl structure: %u",
		      param_kernel->data_size);
		return -EINVAL;
	}

	secure_data = param_kernel->flags & DM_SECURE_DATA_FLAG;

+13 −7
Original line number Diff line number Diff line
@@ -892,13 +892,19 @@ static void dm_io_complete(struct dm_io *io)
	if (unlikely(wq_has_sleeper(&md->wait)))
		wake_up(&md->wait);

	if (io_error == BLK_STS_DM_REQUEUE) {
	if (io_error == BLK_STS_DM_REQUEUE || io_error == BLK_STS_AGAIN) {
		if (bio->bi_opf & REQ_POLLED) {
			/*
		 * Upper layer won't help us poll split bio, io->orig_bio
		 * may only reflect a subset of the pre-split original,
		 * so clear REQ_POLLED in case of requeue
			 * Upper layer won't help us poll split bio (io->orig_bio
			 * may only reflect a subset of the pre-split original)
			 * so clear REQ_POLLED in case of requeue.
			 */
			bio->bi_opf &= ~REQ_POLLED;
			if (io_error == BLK_STS_AGAIN) {
				/* io_uring doesn't handle BLK_STS_AGAIN (yet) */
				queue_io(md, bio);
			}
		}
		return;
	}

+2 −0
Original line number Diff line number Diff line
@@ -85,8 +85,10 @@ struct block_device {
 */
#if defined(CONFIG_ALPHA) && !defined(__alpha_bwx__)
typedef u32 __bitwise blk_status_t;
typedef u32 blk_short_t;
#else
typedef u8 __bitwise blk_status_t;
typedef u16 blk_short_t;
#endif
#define	BLK_STS_OK 0
#define BLK_STS_NOTSUPP		((__force blk_status_t)1)