Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

dm: do not forward ioctls from logical volumes to the underlying device

A logical volume can map to just part of underlying physical volume.
In this case, it must be treated like a partition.

Based on a patch from Alasdair G Kergon.

Cc: Alasdair G Kergon <agk@redhat.com>
Cc: dm-devel@redhat.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Paolo Bonzini and committed by
Linus Torvalds
ec8013be 0bfc96cb

+27 -2
+10 -1
drivers/md/dm-flakey.c
··· 368 368 static int flakey_ioctl(struct dm_target *ti, unsigned int cmd, unsigned long arg) 369 369 { 370 370 struct flakey_c *fc = ti->private; 371 + struct dm_dev *dev = fc->dev; 372 + int r = 0; 371 373 372 - return __blkdev_driver_ioctl(fc->dev->bdev, fc->dev->mode, cmd, arg); 374 + /* 375 + * Only pass ioctls through if the device sizes match exactly. 376 + */ 377 + if (fc->start || 378 + ti->len != i_size_read(dev->bdev->bd_inode) >> SECTOR_SHIFT) 379 + r = scsi_verify_blk_ioctl(NULL, cmd); 380 + 381 + return r ? : __blkdev_driver_ioctl(dev->bdev, dev->mode, cmd, arg); 373 382 } 374 383 375 384 static int flakey_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
+11 -1
drivers/md/dm-linear.c
··· 116 116 unsigned long arg) 117 117 { 118 118 struct linear_c *lc = (struct linear_c *) ti->private; 119 - return __blkdev_driver_ioctl(lc->dev->bdev, lc->dev->mode, cmd, arg); 119 + struct dm_dev *dev = lc->dev; 120 + int r = 0; 121 + 122 + /* 123 + * Only pass ioctls through if the device sizes match exactly. 124 + */ 125 + if (lc->start || 126 + ti->len != i_size_read(dev->bdev->bd_inode) >> SECTOR_SHIFT) 127 + r = scsi_verify_blk_ioctl(NULL, cmd); 128 + 129 + return r ? : __blkdev_driver_ioctl(dev->bdev, dev->mode, cmd, arg); 120 130 } 121 131 122 132 static int linear_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
+6
drivers/md/dm-mpath.c
··· 1520 1520 1521 1521 spin_unlock_irqrestore(&m->lock, flags); 1522 1522 1523 + /* 1524 + * Only pass ioctls through if the device sizes match exactly. 1525 + */ 1526 + if (!r && ti->len != i_size_read(bdev->bd_inode) >> SECTOR_SHIFT) 1527 + r = scsi_verify_blk_ioctl(NULL, cmd); 1528 + 1523 1529 return r ? : __blkdev_driver_ioctl(bdev, mode, cmd, arg); 1524 1530 } 1525 1531