Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e56f81e0 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Mike Snitzer
Browse files

dm: refactor ioctl handling



This moves the call to blkdev_ioctl and the argument checking to DM core
code, and only leaves a callout to find the block device to operate on
in the targets.  This simplifies the code and allows us to pass through
ioctl-like command using other methods in the next patch.

Also split out a helper around calling the prepare_ioctl method that
will be reused for persistent reservation handling.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
parent 47796938
Loading
Loading
Loading
Loading
+8 −8
Original line number Diff line number Diff line
@@ -373,20 +373,20 @@ static void flakey_status(struct dm_target *ti, status_type_t type,
	}
}

static int flakey_ioctl(struct dm_target *ti, unsigned int cmd, unsigned long arg)
static int flakey_prepare_ioctl(struct dm_target *ti,
		struct block_device **bdev, fmode_t *mode)
{
	struct flakey_c *fc = ti->private;
	struct dm_dev *dev = fc->dev;
	int r = 0;

	*bdev = fc->dev->bdev;

	/*
	 * Only pass ioctls through if the device sizes match exactly.
	 */
	if (fc->start ||
	    ti->len != i_size_read(dev->bdev->bd_inode) >> SECTOR_SHIFT)
		r = scsi_verify_blk_ioctl(NULL, cmd);

	return r ? : __blkdev_driver_ioctl(dev->bdev, dev->mode, cmd, arg);
	    ti->len != i_size_read((*bdev)->bd_inode) >> SECTOR_SHIFT)
		return 1;
	return 0;
}

static int flakey_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn fn, void *data)
@@ -405,7 +405,7 @@ static struct target_type flakey_target = {
	.map    = flakey_map,
	.end_io = flakey_end_io,
	.status = flakey_status,
	.ioctl	= flakey_ioctl,
	.prepare_ioctl = flakey_prepare_ioctl,
	.iterate_devices = flakey_iterate_devices,
};

+7 −7
Original line number Diff line number Diff line
@@ -116,21 +116,21 @@ static void linear_status(struct dm_target *ti, status_type_t type,
	}
}

static int linear_ioctl(struct dm_target *ti, unsigned int cmd,
			unsigned long arg)
static int linear_prepare_ioctl(struct dm_target *ti,
		struct block_device **bdev, fmode_t *mode)
{
	struct linear_c *lc = (struct linear_c *) ti->private;
	struct dm_dev *dev = lc->dev;
	int r = 0;

	*bdev = dev->bdev;

	/*
	 * Only pass ioctls through if the device sizes match exactly.
	 */
	if (lc->start ||
	    ti->len != i_size_read(dev->bdev->bd_inode) >> SECTOR_SHIFT)
		r = scsi_verify_blk_ioctl(NULL, cmd);

	return r ? : __blkdev_driver_ioctl(dev->bdev, dev->mode, cmd, arg);
		return 1;
	return 0;
}

static int linear_iterate_devices(struct dm_target *ti,
@@ -149,7 +149,7 @@ static struct target_type linear_target = {
	.dtr    = linear_dtr,
	.map    = linear_map,
	.status = linear_status,
	.ioctl  = linear_ioctl,
	.prepare_ioctl = linear_prepare_ioctl,
	.iterate_devices = linear_iterate_devices,
};

+6 −7
Original line number Diff line number Diff line
@@ -714,20 +714,19 @@ static void log_writes_status(struct dm_target *ti, status_type_t type,
	}
}

static int log_writes_ioctl(struct dm_target *ti, unsigned int cmd,
			    unsigned long arg)
static int log_writes_prepare_ioctl(struct dm_target *ti,
		struct block_device **bdev, fmode_t *mode)
{
	struct log_writes_c *lc = ti->private;
	struct dm_dev *dev = lc->dev;
	int r = 0;

	*bdev = dev->bdev;
	/*
	 * Only pass ioctls through if the device sizes match exactly.
	 */
	if (ti->len != i_size_read(dev->bdev->bd_inode) >> SECTOR_SHIFT)
		r = scsi_verify_blk_ioctl(NULL, cmd);

	return r ? : __blkdev_driver_ioctl(dev->bdev, dev->mode, cmd, arg);
		return 1;
	return 0;
}

static int log_writes_iterate_devices(struct dm_target *ti,
@@ -782,7 +781,7 @@ static struct target_type log_writes_target = {
	.map    = log_writes_map,
	.end_io = normal_end_io,
	.status = log_writes_status,
	.ioctl	= log_writes_ioctl,
	.prepare_ioctl = log_writes_prepare_ioctl,
	.message = log_writes_message,
	.iterate_devices = log_writes_iterate_devices,
	.io_hints = log_writes_io_hints,
+12 −17
Original line number Diff line number Diff line
@@ -1533,18 +1533,14 @@ static int multipath_message(struct dm_target *ti, unsigned argc, char **argv)
	return r;
}

static int multipath_ioctl(struct dm_target *ti, unsigned int cmd,
			   unsigned long arg)
static int multipath_prepare_ioctl(struct dm_target *ti,
		struct block_device **bdev, fmode_t *mode)
{
	struct multipath *m = ti->private;
	struct pgpath *pgpath;
	struct block_device *bdev;
	fmode_t mode;
	unsigned long flags;
	int r;

	bdev = NULL;
	mode = 0;
	r = 0;

	spin_lock_irqsave(&m->lock, flags);
@@ -1555,23 +1551,17 @@ static int multipath_ioctl(struct dm_target *ti, unsigned int cmd,
	pgpath = m->current_pgpath;

	if (pgpath) {
		bdev = pgpath->path.dev->bdev;
		mode = pgpath->path.dev->mode;
		*bdev = pgpath->path.dev->bdev;
		*mode = pgpath->path.dev->mode;
	}

	if ((pgpath && m->queue_io) || (!pgpath && m->queue_if_no_path))
		r = -ENOTCONN;
	else if (!bdev)
	else if (!*bdev)
		r = -EIO;

	spin_unlock_irqrestore(&m->lock, flags);

	/*
	 * Only pass ioctls through if the device sizes match exactly.
	 */
	if (!r && ti->len != i_size_read(bdev->bd_inode) >> SECTOR_SHIFT)
		r = scsi_verify_blk_ioctl(NULL, cmd);

	if (r == -ENOTCONN && !fatal_signal_pending(current)) {
		spin_lock_irqsave(&m->lock, flags);
		if (!m->current_pg) {
@@ -1584,7 +1574,12 @@ static int multipath_ioctl(struct dm_target *ti, unsigned int cmd,
		dm_table_run_md_queue_async(m->ti->table);
	}

	return r ? : __blkdev_driver_ioctl(bdev, mode, cmd, arg);
	/*
	 * Only pass ioctls through if the device sizes match exactly.
	 */
	if (!r && ti->len != i_size_read((*bdev)->bd_inode) >> SECTOR_SHIFT)
		return 1;
	return r;
}

static int multipath_iterate_devices(struct dm_target *ti,
@@ -1700,7 +1695,7 @@ static struct target_type multipath_target = {
	.resume = multipath_resume,
	.status = multipath_status,
	.message = multipath_message,
	.ioctl  = multipath_ioctl,
	.prepare_ioctl = multipath_prepare_ioctl,
	.iterate_devices = multipath_iterate_devices,
	.busy = multipath_busy,
};
+9 −12
Original line number Diff line number Diff line
@@ -511,27 +511,24 @@ static void switch_status(struct dm_target *ti, status_type_t type,
 *
 * Passthrough all ioctls to the path for sector 0
 */
static int switch_ioctl(struct dm_target *ti, unsigned cmd,
			unsigned long arg)
static int switch_prepare_ioctl(struct dm_target *ti,
		struct block_device **bdev, fmode_t *mode)
{
	struct switch_ctx *sctx = ti->private;
	struct block_device *bdev;
	fmode_t mode;
	unsigned path_nr;
	int r = 0;

	path_nr = switch_get_path_nr(sctx, 0);

	bdev = sctx->path_list[path_nr].dmdev->bdev;
	mode = sctx->path_list[path_nr].dmdev->mode;
	*bdev = sctx->path_list[path_nr].dmdev->bdev;
	*mode = sctx->path_list[path_nr].dmdev->mode;

	/*
	 * Only pass ioctls through if the device sizes match exactly.
	 */
	if (ti->len + sctx->path_list[path_nr].start != i_size_read(bdev->bd_inode) >> SECTOR_SHIFT)
		r = scsi_verify_blk_ioctl(NULL, cmd);

	return r ? : __blkdev_driver_ioctl(bdev, mode, cmd, arg);
	if (ti->len + sctx->path_list[path_nr].start !=
	    i_size_read((*bdev)->bd_inode) >> SECTOR_SHIFT)
		return 1;
	return 0;
}

static int switch_iterate_devices(struct dm_target *ti,
@@ -560,7 +557,7 @@ static struct target_type switch_target = {
	.map = switch_map,
	.message = switch_message,
	.status = switch_status,
	.ioctl = switch_ioctl,
	.prepare_ioctl = switch_prepare_ioctl,
	.iterate_devices = switch_iterate_devices,
};

Loading