Skip to content

Commit 04bb7cc

Browse files
committed
dm: Allow .prepare_ioctl to handle ioctls directly
jira LE-3497 Rebuild_History Non-Buildable kernel-5.14.0-570.24.1.el9_6 commit-author Kevin Wolf <[email protected]> commit 4862c88 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 <[email protected]> Reviewed-by: Benjamin Marzinski <[email protected]> Signed-off-by: Mikulas Patocka <[email protected]> (cherry picked from commit 4862c88) Signed-off-by: Jonathan Maple <[email protected]>
1 parent db880e1 commit 04bb7cc

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
@@ -409,7 +409,8 @@ static void ebs_status(struct dm_target *ti, status_type_t type,
409409
}
410410
}
411411

412-
static int ebs_prepare_ioctl(struct dm_target *ti, struct block_device **bdev)
412+
static int ebs_prepare_ioctl(struct dm_target *ti, struct block_device **bdev,
413+
unsigned int cmd, unsigned long arg, bool *forward)
413414
{
414415
struct ebs_c *ec = ti->private;
415416
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
@@ -638,7 +638,9 @@ static void flakey_status(struct dm_target *ti, status_type_t type,
638638
}
639639
}
640640

641-
static int flakey_prepare_ioctl(struct dm_target *ti, struct block_device **bdev)
641+
static int flakey_prepare_ioctl(struct dm_target *ti, struct block_device **bdev,
642+
unsigned int cmd, unsigned long arg,
643+
bool *forward)
642644
{
643645
struct flakey_c *fc = ti->private;
644646

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
@@ -945,7 +945,9 @@ static void verity_status(struct dm_target *ti, status_type_t type,
945945
}
946946
}
947947

948-
static int verity_prepare_ioctl(struct dm_target *ti, struct block_device **bdev)
948+
static int verity_prepare_ioctl(struct dm_target *ti, struct block_device **bdev,
949+
unsigned int cmd, unsigned long arg,
950+
bool *forward)
949951
{
950952
struct dm_verity *v = ti->private;
951953

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) {
@@ -3576,10 +3578,13 @@ static int dm_pr_clear(struct block_device *bdev, u64 key)
35763578
struct mapped_device *md = bdev->bd_disk->private_data;
35773579
const struct pr_ops *ops;
35783580
int r, srcu_idx;
3581+
bool forward = true;
35793582

3580-
r = dm_prepare_ioctl(md, &srcu_idx, &bdev);
3583+
/* Not a real ioctl, but targets must not interpret non-DM ioctls */
3584+
r = dm_prepare_ioctl(md, &srcu_idx, &bdev, 0, 0, &forward);
35813585
if (r < 0)
35823586
goto out;
3587+
WARN_ON_ONCE(!forward);
35833588

35843589
ops = bdev->bd_disk->fops->pr_ops;
35853590
if (ops && ops->pr_clear)

0 commit comments

Comments
 (0)