diff options
-rw-r--r-- | block/ioctl.c | 31 | ||||
-rw-r--r-- | drivers/block/pktcdvd.c | 4 | ||||
-rw-r--r-- | drivers/md/dm-linear.c | 10 | ||||
-rw-r--r-- | drivers/md/dm-mpath.c | 11 | ||||
-rw-r--r-- | include/linux/blkdev.h | 2 |
5 files changed, 39 insertions, 19 deletions
diff --git a/block/ioctl.c b/block/ioctl.c index 38bee321e1f..9a26ace6d04 100644 --- a/block/ioctl.c +++ b/block/ioctl.c | |||
@@ -283,6 +283,37 @@ int blkdev_driver_ioctl(struct inode *inode, struct file *file, | |||
283 | } | 283 | } |
284 | EXPORT_SYMBOL_GPL(blkdev_driver_ioctl); | 284 | EXPORT_SYMBOL_GPL(blkdev_driver_ioctl); |
285 | 285 | ||
286 | int __blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode, | ||
287 | unsigned cmd, unsigned long arg) | ||
288 | { | ||
289 | struct gendisk *disk = bdev->bd_disk; | ||
290 | int ret; | ||
291 | /* you bet it'll go away by the end of patch series */ | ||
292 | struct file fake_file = {}; | ||
293 | struct dentry fake_dentry = {}; | ||
294 | fake_file.f_mode = mode; | ||
295 | fake_file.f_path.dentry = &fake_dentry; | ||
296 | fake_dentry.d_inode = bdev->bd_inode; | ||
297 | |||
298 | if (disk->fops->unlocked_ioctl) | ||
299 | return disk->fops->unlocked_ioctl(&fake_file, cmd, arg); | ||
300 | |||
301 | if (disk->fops->ioctl) { | ||
302 | lock_kernel(); | ||
303 | ret = disk->fops->ioctl(bdev->bd_inode, &fake_file, cmd, arg); | ||
304 | unlock_kernel(); | ||
305 | return ret; | ||
306 | } | ||
307 | |||
308 | return -ENOTTY; | ||
309 | } | ||
310 | /* | ||
311 | * For the record: _GPL here is only because somebody decided to slap it | ||
312 | * on the previous export. Sheer idiocy, since it wasn't copyrightable | ||
313 | * at all and could be open-coded without any exports by anybody who cares. | ||
314 | */ | ||
315 | EXPORT_SYMBOL_GPL(__blkdev_driver_ioctl); | ||
316 | |||
286 | /* | 317 | /* |
287 | * always keep this in sync with compat_blkdev_ioctl() and | 318 | * always keep this in sync with compat_blkdev_ioctl() and |
288 | * compat_blkdev_locked_ioctl() | 319 | * compat_blkdev_locked_ioctl() |
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index bdd49abcb54..a0ba4023953 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c | |||
@@ -2819,8 +2819,8 @@ static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u | |||
2819 | case CDROM_LAST_WRITTEN: | 2819 | case CDROM_LAST_WRITTEN: |
2820 | case CDROM_SEND_PACKET: | 2820 | case CDROM_SEND_PACKET: |
2821 | case SCSI_IOCTL_SEND_COMMAND: | 2821 | case SCSI_IOCTL_SEND_COMMAND: |
2822 | return blkdev_driver_ioctl(pd->bdev->bd_inode, pd->bdev->bd_disk, | 2822 | return __blkdev_driver_ioctl(pd->bdev, file ? file->f_mode : 0, |
2823 | file, cmd, arg); | 2823 | cmd, arg); |
2824 | 2824 | ||
2825 | default: | 2825 | default: |
2826 | VPRINTK(DRIVER_NAME": Unknown ioctl for %s (%x)\n", pd->name, cmd); | 2826 | VPRINTK(DRIVER_NAME": Unknown ioctl for %s (%x)\n", pd->name, cmd); |
diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c index fa358385eed..373442b1e98 100644 --- a/drivers/md/dm-linear.c +++ b/drivers/md/dm-linear.c | |||
@@ -114,15 +114,7 @@ static int linear_ioctl(struct dm_target *ti, unsigned int cmd, | |||
114 | unsigned long arg) | 114 | unsigned long arg) |
115 | { | 115 | { |
116 | struct linear_c *lc = (struct linear_c *) ti->private; | 116 | struct linear_c *lc = (struct linear_c *) ti->private; |
117 | struct block_device *bdev = lc->dev->bdev; | 117 | return __blkdev_driver_ioctl(lc->dev->bdev, lc->dev->mode, cmd, arg); |
118 | struct file fake_file = {}; | ||
119 | struct dentry fake_dentry = {}; | ||
120 | |||
121 | fake_file.f_mode = lc->dev->mode; | ||
122 | fake_file.f_path.dentry = &fake_dentry; | ||
123 | fake_dentry.d_inode = bdev->bd_inode; | ||
124 | |||
125 | return blkdev_driver_ioctl(bdev->bd_inode, &fake_file, bdev->bd_disk, cmd, arg); | ||
126 | } | 118 | } |
127 | 119 | ||
128 | static int linear_merge(struct dm_target *ti, struct bvec_merge_data *bvm, | 120 | static int linear_merge(struct dm_target *ti, struct bvec_merge_data *bvm, |
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index c681d5e5f45..d85c65a4643 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c | |||
@@ -1400,13 +1400,10 @@ static int multipath_ioctl(struct dm_target *ti, unsigned int cmd, | |||
1400 | { | 1400 | { |
1401 | struct multipath *m = (struct multipath *) ti->private; | 1401 | struct multipath *m = (struct multipath *) ti->private; |
1402 | struct block_device *bdev = NULL; | 1402 | struct block_device *bdev = NULL; |
1403 | fmode_t mode = 0; | ||
1403 | unsigned long flags; | 1404 | unsigned long flags; |
1404 | struct file fake_file = {}; | ||
1405 | struct dentry fake_dentry = {}; | ||
1406 | int r = 0; | 1405 | int r = 0; |
1407 | 1406 | ||
1408 | fake_file.f_path.dentry = &fake_dentry; | ||
1409 | |||
1410 | spin_lock_irqsave(&m->lock, flags); | 1407 | spin_lock_irqsave(&m->lock, flags); |
1411 | 1408 | ||
1412 | if (!m->current_pgpath) | 1409 | if (!m->current_pgpath) |
@@ -1414,8 +1411,7 @@ static int multipath_ioctl(struct dm_target *ti, unsigned int cmd, | |||
1414 | 1411 | ||
1415 | if (m->current_pgpath) { | 1412 | if (m->current_pgpath) { |
1416 | bdev = m->current_pgpath->path.dev->bdev; | 1413 | bdev = m->current_pgpath->path.dev->bdev; |
1417 | fake_dentry.d_inode = bdev->bd_inode; | 1414 | mode = m->current_pgpath->path.dev->mode; |
1418 | fake_file.f_mode = m->current_pgpath->path.dev->mode; | ||
1419 | } | 1415 | } |
1420 | 1416 | ||
1421 | if (m->queue_io) | 1417 | if (m->queue_io) |
@@ -1425,8 +1421,7 @@ static int multipath_ioctl(struct dm_target *ti, unsigned int cmd, | |||
1425 | 1421 | ||
1426 | spin_unlock_irqrestore(&m->lock, flags); | 1422 | spin_unlock_irqrestore(&m->lock, flags); |
1427 | 1423 | ||
1428 | return r ? : blkdev_driver_ioctl(bdev->bd_inode, &fake_file, | 1424 | return r ? : __blkdev_driver_ioctl(bdev, mode, cmd, arg); |
1429 | bdev->bd_disk, cmd, arg); | ||
1430 | } | 1425 | } |
1431 | 1426 | ||
1432 | /*----------------------------------------------------------------- | 1427 | /*----------------------------------------------------------------- |
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 48ec8862a11..2bad616b994 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -1074,6 +1074,8 @@ struct block_device_operations { | |||
1074 | struct module *owner; | 1074 | struct module *owner; |
1075 | }; | 1075 | }; |
1076 | 1076 | ||
1077 | extern int __blkdev_driver_ioctl(struct block_device *, fmode_t, unsigned int, | ||
1078 | unsigned long); | ||
1077 | #else /* CONFIG_BLOCK */ | 1079 | #else /* CONFIG_BLOCK */ |
1078 | /* | 1080 | /* |
1079 | * stubs for when the block layer is configured out | 1081 | * stubs for when the block layer is configured out |