Skip to content

Commit 4862c88

Browse files
kevmwMikulas Patocka
authored andcommitted
dm: Allow .prepare_ioctl to handle ioctls directly
This adds a 'bool *forward' parameter to .prepare_ioctl, which allows device mapper targets to accept ioctls to themselves instead of the underlying device. If the target already fully handled the ioctl, it sets *forward to false and device mapper won't forward it to the underlying device any more. In order for targets to actually know what the ioctl is about and how to handle it, pass also cmd and arg. As long as targets restrict themselves to interpreting ioctls of type DM_IOCTL, this is a backwards compatible change because previously, any such ioctl would have been passed down through all device mapper layers until it reached a device that can't understand the ioctl and would return an error. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
1 parent 13e7907 commit 4862c88

File tree

11 files changed

+44
-16
lines changed

11 files changed

+44
-16
lines changed

drivers/md/dm-dust.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,9 @@ static void dust_status(struct dm_target *ti, status_type_t type,
534534
}
535535
}
536536

537-
static int dust_prepare_ioctl(struct dm_target *ti, struct block_device **bdev)
537+
static int dust_prepare_ioctl(struct dm_target *ti, struct block_device **bdev,
538+
unsigned int cmd, unsigned long arg,
539+
bool *forward)
538540
{
539541
struct dust_device *dd = ti->private;
540542
struct dm_dev *dev = dd->dev;

drivers/md/dm-ebs-target.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,8 @@ static void ebs_status(struct dm_target *ti, status_type_t type,
415415
}
416416
}
417417

418-
static int ebs_prepare_ioctl(struct dm_target *ti, struct block_device **bdev)
418+
static int ebs_prepare_ioctl(struct dm_target *ti, struct block_device **bdev,
419+
unsigned int cmd, unsigned long arg, bool *forward)
419420
{
420421
struct ebs_c *ec = ti->private;
421422
struct dm_dev *dev = ec->dev;

drivers/md/dm-flakey.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,9 @@ static void flakey_status(struct dm_target *ti, status_type_t type,
648648
}
649649
}
650650

651-
static int flakey_prepare_ioctl(struct dm_target *ti, struct block_device **bdev)
651+
static int flakey_prepare_ioctl(struct dm_target *ti, struct block_device **bdev,
652+
unsigned int cmd, unsigned long arg,
653+
bool *forward)
652654
{
653655
struct flakey_c *fc = ti->private;
654656

drivers/md/dm-linear.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,9 @@ static void linear_status(struct dm_target *ti, status_type_t type,
119119
}
120120
}
121121

122-
static int linear_prepare_ioctl(struct dm_target *ti, struct block_device **bdev)
122+
static int linear_prepare_ioctl(struct dm_target *ti, struct block_device **bdev,
123+
unsigned int cmd, unsigned long arg,
124+
bool *forward)
123125
{
124126
struct linear_c *lc = ti->private;
125127
struct dm_dev *dev = lc->dev;

drivers/md/dm-log-writes.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,9 @@ static void log_writes_status(struct dm_target *ti, status_type_t type,
818818
}
819819

820820
static int log_writes_prepare_ioctl(struct dm_target *ti,
821-
struct block_device **bdev)
821+
struct block_device **bdev,
822+
unsigned int cmd, unsigned long arg,
823+
bool *forward)
822824
{
823825
struct log_writes_c *lc = ti->private;
824826
struct dm_dev *dev = lc->dev;

drivers/md/dm-mpath.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2022,7 +2022,9 @@ static int multipath_message(struct dm_target *ti, unsigned int argc, char **arg
20222022
}
20232023

20242024
static int multipath_prepare_ioctl(struct dm_target *ti,
2025-
struct block_device **bdev)
2025+
struct block_device **bdev,
2026+
unsigned int cmd, unsigned long arg,
2027+
bool *forward)
20262028
{
20272029
struct multipath *m = ti->private;
20282030
struct pgpath *pgpath;

drivers/md/dm-switch.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,9 @@ static void switch_status(struct dm_target *ti, status_type_t type,
517517
*
518518
* Passthrough all ioctls to the path for sector 0
519519
*/
520-
static int switch_prepare_ioctl(struct dm_target *ti, struct block_device **bdev)
520+
static int switch_prepare_ioctl(struct dm_target *ti, struct block_device **bdev,
521+
unsigned int cmd, unsigned long arg,
522+
bool *forward)
521523
{
522524
struct switch_ctx *sctx = ti->private;
523525
unsigned int path_nr;

drivers/md/dm-verity-target.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -994,7 +994,9 @@ static void verity_status(struct dm_target *ti, status_type_t type,
994994
}
995995
}
996996

997-
static int verity_prepare_ioctl(struct dm_target *ti, struct block_device **bdev)
997+
static int verity_prepare_ioctl(struct dm_target *ti, struct block_device **bdev,
998+
unsigned int cmd, unsigned long arg,
999+
bool *forward)
9981000
{
9991001
struct dm_verity *v = ti->private;
10001002

drivers/md/dm-zoned-target.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1015,7 +1015,8 @@ static void dmz_io_hints(struct dm_target *ti, struct queue_limits *limits)
10151015
/*
10161016
* Pass on ioctl to the backend device.
10171017
*/
1018-
static int dmz_prepare_ioctl(struct dm_target *ti, struct block_device **bdev)
1018+
static int dmz_prepare_ioctl(struct dm_target *ti, struct block_device **bdev,
1019+
unsigned int cmd, unsigned long arg, bool *forward)
10191020
{
10201021
struct dmz_target *dmz = ti->private;
10211022
struct dmz_dev *dev = &dmz->dev[0];

drivers/md/dm.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,8 @@ static int dm_blk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
411411
}
412412

413413
static int dm_prepare_ioctl(struct mapped_device *md, int *srcu_idx,
414-
struct block_device **bdev)
414+
struct block_device **bdev, unsigned int cmd,
415+
unsigned long arg, bool *forward)
415416
{
416417
struct dm_target *ti;
417418
struct dm_table *map;
@@ -434,8 +435,8 @@ static int dm_prepare_ioctl(struct mapped_device *md, int *srcu_idx,
434435
if (dm_suspended_md(md))
435436
return -EAGAIN;
436437

437-
r = ti->type->prepare_ioctl(ti, bdev);
438-
if (r == -ENOTCONN && !fatal_signal_pending(current)) {
438+
r = ti->type->prepare_ioctl(ti, bdev, cmd, arg, forward);
439+
if (r == -ENOTCONN && *forward && !fatal_signal_pending(current)) {
439440
dm_put_live_table(md, *srcu_idx);
440441
fsleep(10000);
441442
goto retry;
@@ -454,9 +455,10 @@ static int dm_blk_ioctl(struct block_device *bdev, blk_mode_t mode,
454455
{
455456
struct mapped_device *md = bdev->bd_disk->private_data;
456457
int r, srcu_idx;
458+
bool forward = true;
457459

458-
r = dm_prepare_ioctl(md, &srcu_idx, &bdev);
459-
if (r < 0)
460+
r = dm_prepare_ioctl(md, &srcu_idx, &bdev, cmd, arg, &forward);
461+
if (!forward || r < 0)
460462
goto out;
461463

462464
if (r > 0) {
@@ -3630,10 +3632,13 @@ static int dm_pr_clear(struct block_device *bdev, u64 key)
36303632
struct mapped_device *md = bdev->bd_disk->private_data;
36313633
const struct pr_ops *ops;
36323634
int r, srcu_idx;
3635+
bool forward = true;
36333636

3634-
r = dm_prepare_ioctl(md, &srcu_idx, &bdev);
3637+
/* Not a real ioctl, but targets must not interpret non-DM ioctls */
3638+
r = dm_prepare_ioctl(md, &srcu_idx, &bdev, 0, 0, &forward);
36353639
if (r < 0)
36363640
goto out;
3641+
WARN_ON_ONCE(!forward);
36373642

36383643
ops = bdev->bd_disk->fops->pr_ops;
36393644
if (ops && ops->pr_clear)

0 commit comments

Comments
 (0)