summaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
Diffstat (limited to 'block')
-rw-r--r--block/compat_ioctl.c17
-rw-r--r--block/ioctl.c35
2 files changed, 35 insertions, 17 deletions
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
index 1e559fba7bdf..576c4fd15463 100644
--- a/block/compat_ioctl.c
+++ b/block/compat_ioctl.c
@@ -708,17 +708,17 @@ static int compat_blkdev_driver_ioctl(struct inode *inode, struct file *file,
return -ENOIOCTLCMD;
}
- if (disk->fops->unlocked_ioctl)
- return disk->fops->unlocked_ioctl(file, cmd, arg);
+ if (disk->fops->__unlocked_ioctl)
+ return disk->fops->__unlocked_ioctl(file, cmd, arg);
- if (disk->fops->ioctl) {
+ if (disk->fops->__ioctl) {
lock_kernel();
- ret = disk->fops->ioctl(inode, file, cmd, arg);
+ ret = disk->fops->__ioctl(inode, file, cmd, arg);
unlock_kernel();
return ret;
}
- return -ENOTTY;
+ return __blkdev_driver_ioctl(inode->i_bdev, file->f_mode, cmd, arg);
}
static int compat_blkdev_locked_ioctl(struct inode *inode, struct file *file,
@@ -805,10 +805,11 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
lock_kernel();
ret = compat_blkdev_locked_ioctl(inode, file, bdev, cmd, arg);
- /* FIXME: why do we assume -> compat_ioctl needs the BKL? */
- if (ret == -ENOIOCTLCMD && disk->fops->compat_ioctl)
- ret = disk->fops->compat_ioctl(file, cmd, arg);
+ if (ret == -ENOIOCTLCMD && disk->fops->__compat_ioctl)
+ ret = disk->fops->__compat_ioctl(file, cmd, arg);
unlock_kernel();
+ if (ret == -ENOIOCTLCMD && disk->fops->compat_ioctl)
+ ret = disk->fops->compat_ioctl(bdev, file->f_mode, cmd, arg);
if (ret != -ENOIOCTLCMD)
return ret;
diff --git a/block/ioctl.c b/block/ioctl.c
index 9a26ace6d042..01ff463bc801 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -269,17 +269,24 @@ int blkdev_driver_ioctl(struct inode *inode, struct file *file,
struct gendisk *disk, unsigned cmd, unsigned long arg)
{
int ret;
- if (disk->fops->unlocked_ioctl)
- return disk->fops->unlocked_ioctl(file, cmd, arg);
+ fmode_t mode = 0;
+ if (file) {
+ mode = file->f_mode;
+ if (file->f_flags & O_NDELAY)
+ mode |= FMODE_NDELAY_NOW;
+ }
+
+ if (disk->fops->__unlocked_ioctl)
+ return disk->fops->__unlocked_ioctl(file, cmd, arg);
- if (disk->fops->ioctl) {
+ if (disk->fops->__ioctl) {
lock_kernel();
- ret = disk->fops->ioctl(inode, file, cmd, arg);
+ ret = disk->fops->__ioctl(inode, file, cmd, arg);
unlock_kernel();
return ret;
}
- return -ENOTTY;
+ return __blkdev_driver_ioctl(inode->i_bdev, mode, cmd, arg);
}
EXPORT_SYMBOL_GPL(blkdev_driver_ioctl);
@@ -295,12 +302,22 @@ int __blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode,
fake_file.f_path.dentry = &fake_dentry;
fake_dentry.d_inode = bdev->bd_inode;
- if (disk->fops->unlocked_ioctl)
- return disk->fops->unlocked_ioctl(&fake_file, cmd, arg);
+ if (disk->fops->__unlocked_ioctl)
+ return disk->fops->__unlocked_ioctl(&fake_file, cmd, arg);
+
+ if (disk->fops->__ioctl) {
+ lock_kernel();
+ ret = disk->fops->__ioctl(bdev->bd_inode, &fake_file, cmd, arg);
+ unlock_kernel();
+ return ret;
+ }
+
+ if (disk->fops->ioctl)
+ return disk->fops->ioctl(bdev, mode, cmd, arg);
- if (disk->fops->ioctl) {
+ if (disk->fops->locked_ioctl) {
lock_kernel();
- ret = disk->fops->ioctl(bdev->bd_inode, &fake_file, cmd, arg);
+ ret = disk->fops->locked_ioctl(bdev, mode, cmd, arg);
unlock_kernel();
return ret;
}