summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/um/drivers/ubd_kern.c6
-rw-r--r--block/compat_ioctl.c17
-rw-r--r--block/ioctl.c35
-rw-r--r--drivers/block/DAC960.c2
-rw-r--r--drivers/block/amiflop.c6
-rw-r--r--drivers/block/aoe/aoeblk.c4
-rw-r--r--drivers/block/ataflop.c6
-rw-r--r--drivers/block/brd.c2
-rw-r--r--drivers/block/cciss.c8
-rw-r--r--drivers/block/cpqarray.c6
-rw-r--r--drivers/block/floppy.c6
-rw-r--r--drivers/block/loop.c8
-rw-r--r--drivers/block/nbd.c2
-rw-r--r--drivers/block/paride/pcd.c6
-rw-r--r--drivers/block/paride/pd.c6
-rw-r--r--drivers/block/paride/pf.c6
-rw-r--r--drivers/block/pktcdvd.c6
-rw-r--r--drivers/block/swim3.c6
-rw-r--r--drivers/block/ub.c6
-rw-r--r--drivers/block/viodasd.c4
-rw-r--r--drivers/block/virtio_blk.c2
-rw-r--r--drivers/block/xd.c2
-rw-r--r--drivers/block/xen-blkfront.c4
-rw-r--r--drivers/block/xsysace.c4
-rw-r--r--drivers/block/z2ram.c4
-rw-r--r--drivers/cdrom/gdrom.c6
-rw-r--r--drivers/cdrom/viocd.c6
-rw-r--r--drivers/ide/ide-cd.c6
-rw-r--r--drivers/ide/ide-gd.c6
-rw-r--r--drivers/ide/ide-tape.c6
-rw-r--r--drivers/md/dm.c6
-rw-r--r--drivers/md/md.c6
-rw-r--r--drivers/memstick/core/mspro_block.c4
-rw-r--r--drivers/message/i2o/i2o_block.c6
-rw-r--r--drivers/mmc/card/block.c4
-rw-r--r--drivers/mtd/mtd_blkdevs.c6
-rw-r--r--drivers/s390/block/dasd.c8
-rw-r--r--drivers/s390/block/dcssblk.c4
-rw-r--r--drivers/s390/char/tape_block.c6
-rw-r--r--drivers/scsi/ide-scsi.c6
-rw-r--r--drivers/scsi/sd.c8
-rw-r--r--drivers/scsi/sr.c6
-rw-r--r--fs/block_dev.c18
-rw-r--r--include/linux/blkdev.h15
-rw-r--r--include/linux/fs.h1
45 files changed, 167 insertions, 131 deletions
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index b58fb8941d8..72569cc3cbb 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -108,9 +108,9 @@ static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo);
static struct block_device_operations ubd_blops = {
.owner = THIS_MODULE,
- .open = ubd_open,
- .release = ubd_release,
- .ioctl = ubd_ioctl,
+ .__open = ubd_open,
+ .__release = ubd_release,
+ .__ioctl = ubd_ioctl,
.getgeo = ubd_getgeo,
};
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
index 1e559fba7bd..576c4fd1546 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 9a26ace6d04..01ff463bc80 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;
}
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index a002a381df9..4b90ebfa667 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -153,7 +153,7 @@ static int DAC960_revalidate_disk(struct gendisk *disk)
static struct block_device_operations DAC960_BlockDeviceOperations = {
.owner = THIS_MODULE,
- .open = DAC960_open,
+ .__open = DAC960_open,
.getgeo = DAC960_getgeo,
.media_changed = DAC960_media_changed,
.revalidate_disk = DAC960_revalidate_disk,
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index d19c5a939fe..d5da4e3cb2a 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -1648,9 +1648,9 @@ static int amiga_floppy_change(struct gendisk *disk)
static struct block_device_operations floppy_fops = {
.owner = THIS_MODULE,
- .open = floppy_open,
- .release = floppy_release,
- .ioctl = fd_ioctl,
+ .__open = floppy_open,
+ .__release = floppy_release,
+ .__ioctl = fd_ioctl,
.getgeo = fd_getgeo,
.media_changed = amiga_floppy_change,
};
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
index d876ad86123..d4d9796d5dd 100644
--- a/drivers/block/aoe/aoeblk.c
+++ b/drivers/block/aoe/aoeblk.c
@@ -239,8 +239,8 @@ aoeblk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
}
static struct block_device_operations aoe_bdops = {
- .open = aoeblk_open,
- .release = aoeblk_release,
+ .__open = aoeblk_open,
+ .__release = aoeblk_release,
.getgeo = aoeblk_getgeo,
.owner = THIS_MODULE,
};
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
index 85d56a26f7c..30166774327 100644
--- a/drivers/block/ataflop.c
+++ b/drivers/block/ataflop.c
@@ -1857,9 +1857,9 @@ static int floppy_release( struct inode * inode, struct file * filp )
static struct block_device_operations floppy_fops = {
.owner = THIS_MODULE,
- .open = floppy_open,
- .release = floppy_release,
- .ioctl = fd_ioctl,
+ .__open = floppy_open,
+ .__release = floppy_release,
+ .__ioctl = fd_ioctl,
.media_changed = check_floppy_change,
.revalidate_disk= floppy_revalidate,
};
diff --git a/drivers/block/brd.c b/drivers/block/brd.c
index d070d492e38..2ea99f94766 100644
--- a/drivers/block/brd.c
+++ b/drivers/block/brd.c
@@ -376,7 +376,7 @@ static int brd_ioctl(struct inode *inode, struct file *file,
static struct block_device_operations brd_fops = {
.owner = THIS_MODULE,
- .ioctl = brd_ioctl,
+ .__ioctl = brd_ioctl,
#ifdef CONFIG_BLK_DEV_XIP
.direct_access = brd_direct_access,
#endif
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index d9b1c15b811..781b745181d 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -197,12 +197,12 @@ static long cciss_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg);
static struct block_device_operations cciss_fops = {
.owner = THIS_MODULE,
- .open = cciss_open,
- .release = cciss_release,
- .ioctl = cciss_ioctl,
+ .__open = cciss_open,
+ .__release = cciss_release,
+ .__ioctl = cciss_ioctl,
.getgeo = cciss_getgeo,
#ifdef CONFIG_COMPAT
- .compat_ioctl = cciss_compat_ioctl,
+ .__compat_ioctl = cciss_compat_ioctl,
#endif
.revalidate_disk = cciss_revalidate,
};
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index 3d967525e9a..b71334b968b 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -195,9 +195,9 @@ static inline ctlr_info_t *get_host(struct gendisk *disk)
static struct block_device_operations ida_fops = {
.owner = THIS_MODULE,
- .open = ida_open,
- .release = ida_release,
- .ioctl = ida_ioctl,
+ .__open = ida_open,
+ .__release = ida_release,
+ .__ioctl = ida_ioctl,
.getgeo = ida_getgeo,
.revalidate_disk= ida_revalidate,
};
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 5d60c05a736..72363df5895 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -3902,9 +3902,9 @@ static int floppy_revalidate(struct gendisk *disk)
static struct block_device_operations floppy_fops = {
.owner = THIS_MODULE,
- .open = floppy_open,
- .release = floppy_release,
- .ioctl = fd_ioctl,
+ .__open = floppy_open,
+ .__release = floppy_release,
+ .__ioctl = fd_ioctl,
.getgeo = fd_getgeo,
.media_changed = check_floppy_change,
.revalidate_disk = floppy_revalidate,
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index d3a25b027ff..6faca2b7ae3 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1355,11 +1355,11 @@ static int lo_release(struct inode *inode, struct file *file)
static struct block_device_operations lo_fops = {
.owner = THIS_MODULE,
- .open = lo_open,
- .release = lo_release,
- .ioctl = lo_ioctl,
+ .__open = lo_open,
+ .__release = lo_release,
+ .__ioctl = lo_ioctl,
#ifdef CONFIG_COMPAT
- .compat_ioctl = lo_compat_ioctl,
+ .__compat_ioctl = lo_compat_ioctl,
#endif
};
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 9034ca585af..36015e0945b 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -691,7 +691,7 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
static struct block_device_operations nbd_fops =
{
.owner = THIS_MODULE,
- .ioctl = nbd_ioctl,
+ .__ioctl = nbd_ioctl,
};
/*
diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c
index 8bd557e2a65..6e6dcc1d432 100644
--- a/drivers/block/paride/pcd.c
+++ b/drivers/block/paride/pcd.c
@@ -252,9 +252,9 @@ static int pcd_block_media_changed(struct gendisk *disk)
static struct block_device_operations pcd_bdops = {
.owner = THIS_MODULE,
- .open = pcd_block_open,
- .release = pcd_block_release,
- .ioctl = pcd_block_ioctl,
+ .__open = pcd_block_open,
+ .__release = pcd_block_release,
+ .__ioctl = pcd_block_ioctl,
.media_changed = pcd_block_media_changed,
};
diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
index 5fdfa7c888c..b3023844947 100644
--- a/drivers/block/paride/pd.c
+++ b/drivers/block/paride/pd.c
@@ -807,9 +807,9 @@ static int pd_revalidate(struct gendisk *p)
static struct block_device_operations pd_fops = {
.owner = THIS_MODULE,
- .open = pd_open,
- .release = pd_release,
- .ioctl = pd_ioctl,
+ .__open = pd_open,
+ .__release = pd_release,
+ .__ioctl = pd_ioctl,
.getgeo = pd_getgeo,
.media_changed = pd_check_media,
.revalidate_disk= pd_revalidate
diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c
index a902d84fd33..e08ca5161ad 100644
--- a/drivers/block/paride/pf.c
+++ b/drivers/block/paride/pf.c
@@ -264,9 +264,9 @@ static char *pf_buf; /* buffer for request in progress */
static struct block_device_operations pf_fops = {
.owner = THIS_MODULE,
- .open = pf_open,
- .release = pf_release,
- .ioctl = pf_ioctl,
+ .__open = pf_open,
+ .__release = pf_release,
+ .__ioctl = pf_ioctl,
.getgeo = pf_getgeo,
.media_changed = pf_check_media,
};
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index a0ba4023953..33ac8ddf491 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -2847,9 +2847,9 @@ static int pkt_media_changed(struct gendisk *disk)
static struct block_device_operations pktcdvd_ops = {
.owner = THIS_MODULE,
- .open = pkt_open,
- .release = pkt_close,
- .ioctl = pkt_ioctl,
+ .__open = pkt_open,
+ .__release = pkt_close,
+ .__ioctl = pkt_ioctl,
.media_changed = pkt_media_changed,
};
diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c
index 5c45d5556ae..9398af86a7a 100644
--- a/drivers/block/swim3.c
+++ b/drivers/block/swim3.c
@@ -998,9 +998,9 @@ static int floppy_revalidate(struct gendisk *disk)
}
static struct block_device_operations floppy_fops = {
- .open = floppy_open,
- .release = floppy_release,
- .ioctl = floppy_ioctl,
+ .__open = floppy_open,
+ .__release = floppy_release,
+ .__ioctl = floppy_ioctl,
.media_changed = floppy_check_change,
.revalidate_disk= floppy_revalidate,
};
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index bc04330f368..5261773407d 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -1791,9 +1791,9 @@ static int ub_bd_media_changed(struct gendisk *disk)
static struct block_device_operations ub_bd_fops = {
.owner = THIS_MODULE,
- .open = ub_bd_open,
- .release = ub_bd_release,
- .ioctl = ub_bd_ioctl,
+ .__open = ub_bd_open,
+ .__release = ub_bd_release,
+ .__ioctl = ub_bd_ioctl,
.media_changed = ub_bd_media_changed,
.revalidate_disk = ub_bd_revalidate,
};
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
index 1730d29e604..7f7beec29eb 100644
--- a/drivers/block/viodasd.c
+++ b/drivers/block/viodasd.c
@@ -221,8 +221,8 @@ static int viodasd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
*/
static struct block_device_operations viodasd_fops = {
.owner = THIS_MODULE,
- .open = viodasd_open,
- .release = viodasd_release,
+ .__open = viodasd_open,
+ .__release = viodasd_release,
.getgeo = viodasd_getgeo,
};
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 7643cd16fd6..10f157ea7b0 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -180,7 +180,7 @@ static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo)
}
static struct block_device_operations virtblk_fops = {
- .ioctl = virtblk_ioctl,
+ .__ioctl = virtblk_ioctl,
.owner = THIS_MODULE,
.getgeo = virtblk_getgeo,
};
diff --git a/drivers/block/xd.c b/drivers/block/xd.c
index 624d30f7da3..316fa1da4b9 100644
--- a/drivers/block/xd.c
+++ b/drivers/block/xd.c
@@ -132,7 +132,7 @@ static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo);
static struct block_device_operations xd_fops = {
.owner = THIS_MODULE,
- .ioctl = xd_ioctl,
+ .__ioctl = xd_ioctl,
.getgeo = xd_getgeo,
};
static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int);
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 1a50ae70f71..7efac80c8dd 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -1041,8 +1041,8 @@ static int blkif_release(struct inode *inode, struct file *filep)
static struct block_device_operations xlvbd_block_fops =
{
.owner = THIS_MODULE,
- .open = blkif_open,
- .release = blkif_release,
+ .__open = blkif_open,
+ .__release = blkif_release,
.getgeo = blkif_getgeo,
.ioctl = blkif_ioctl,
};
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c
index 4a7a059ebaf..e4efe5b7ec2 100644
--- a/drivers/block/xsysace.c
+++ b/drivers/block/xsysace.c
@@ -919,8 +919,8 @@ static int ace_getgeo(struct block_device *bdev, struct hd_geometry *geo)
static struct block_device_operations ace_fops = {
.owner = THIS_MODULE,
- .open = ace_open,
- .release = ace_release,
+ .__open = ace_open,
+ .__release = ace_release,
.media_changed = ace_media_changed,
.revalidate_disk = ace_revalidate_disk,
.getgeo = ace_getgeo,
diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c
index be20a67f1fa..4860d0f3687 100644
--- a/drivers/block/z2ram.c
+++ b/drivers/block/z2ram.c
@@ -314,8 +314,8 @@ z2_release( struct inode *inode, struct file *filp )
static struct block_device_operations z2_fops =
{
.owner = THIS_MODULE,
- .open = z2_open,
- .release = z2_release,
+ .__open = z2_open,
+ .__release = z2_release,
};
static struct kobject *z2_find(dev_t dev, int *part, void *data)
diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c
index 0959edf2afd..ab0c637f58b 100644
--- a/drivers/cdrom/gdrom.c
+++ b/drivers/cdrom/gdrom.c
@@ -514,10 +514,10 @@ static int gdrom_bdops_ioctl(struct inode *inode, struct file *file,
static struct block_device_operations gdrom_bdops = {
.owner = THIS_MODULE,
- .open = gdrom_bdops_open,
- .release = gdrom_bdops_release,
+ .__open = gdrom_bdops_open,
+ .__release = gdrom_bdops_release,
.media_changed = gdrom_bdops_mediachanged,
- .ioctl = gdrom_bdops_ioctl,
+ .__ioctl = gdrom_bdops_ioctl,
};
static irqreturn_t gdrom_command_interrupt(int irq, void *dev_id)
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index abc4079c3f4..57c2dced3e9 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -180,9 +180,9 @@ static int viocd_blk_media_changed(struct gendisk *disk)
struct block_device_operations viocd_fops = {
.owner = THIS_MODULE,
- .open = viocd_blk_open,
- .release = viocd_blk_release,
- .ioctl = viocd_blk_ioctl,
+ .__open = viocd_blk_open,
+ .__release = viocd_blk_release,
+ .__ioctl = viocd_blk_ioctl,
.media_changed = viocd_blk_media_changed,
};
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 87d90200b16..3533984355a 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -2200,9 +2200,9 @@ static int idecd_revalidate_disk(struct gendisk *disk)
static struct block_device_operations idecd_ops = {
.owner = THIS_MODULE,
- .open = idecd_open,
- .release = idecd_release,
- .ioctl = idecd_ioctl,
+ .__open = idecd_open,
+ .__release = idecd_release,
+ .__ioctl = idecd_ioctl,
.media_changed = idecd_media_changed,
.revalidate_disk = idecd_revalidate_disk
};
diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c
index 948af08abe2..d118bbed7cd 100644
--- a/drivers/ide/ide-gd.c
+++ b/drivers/ide/ide-gd.c
@@ -298,9 +298,9 @@ static int ide_gd_ioctl(struct inode *inode, struct file *file,
static struct block_device_operations ide_gd_ops = {
.owner = THIS_MODULE,
- .open = ide_gd_open,
- .release = ide_gd_release,
- .ioctl = ide_gd_ioctl,
+ .__open = ide_gd_open,
+ .__release = ide_gd_release,
+ .__ioctl = ide_gd_ioctl,
.getgeo = ide_gd_getgeo,
.media_changed = ide_gd_media_changed,
.revalidate_disk = ide_gd_revalidate_disk
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 2b263281ffe..c5df53c4838 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -2376,9 +2376,9 @@ static int idetape_ioctl(struct inode *inode, struct file *file,
static struct block_device_operations idetape_block_ops = {
.owner = THIS_MODULE,
- .open = idetape_open,
- .release = idetape_release,
- .ioctl = idetape_ioctl,
+ .__open = idetape_open,
+ .__release = idetape_release,
+ .__ioctl = idetape_ioctl,
};
static int ide_tape_probe(ide_drive_t *drive)
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 5f0f4c8bcd3..8b4c92b1b6d 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -1698,9 +1698,9 @@ int dm_noflush_suspending(struct dm_target *ti)
EXPORT_SYMBOL_GPL(dm_noflush_suspending);
static struct block_device_operations dm_blk_dops = {
- .open = dm_blk_open,
- .release = dm_blk_close,
- .ioctl = dm_blk_ioctl,
+ .__open = dm_blk_open,
+ .__release = dm_blk_close,
+ .__ioctl = dm_blk_ioctl,
.getgeo = dm_blk_getgeo,
.owner = THIS_MODULE
};
diff --git a/drivers/md/md.c b/drivers/md/md.c
index aaa3d465de4..21b04d39ba3 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -5046,9 +5046,9 @@ static int md_revalidate(struct gendisk *disk)
static struct block_device_operations md_fops =
{
.owner = THIS_MODULE,
- .open = md_open,
- .release = md_release,
- .ioctl = md_ioctl,
+ .__open = md_open,
+ .__release = md_release,
+ .__ioctl = md_ioctl,
.getgeo = md_getgeo,
.media_changed = md_media_changed,
.revalidate_disk= md_revalidate,
diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c
index 5263913e0c6..fbe5919789d 100644
--- a/drivers/memstick/core/mspro_block.c
+++ b/drivers/memstick/core/mspro_block.c
@@ -237,8 +237,8 @@ static int mspro_block_bd_getgeo(struct block_device *bdev,
}
static struct block_device_operations ms_block_bdops = {
- .open = mspro_block_bd_open,
- .release = mspro_block_bd_release,
+ .__open = mspro_block_bd_open,
+ .__release = mspro_block_bd_release,
.getgeo = mspro_block_bd_getgeo,
.owner = THIS_MODULE
};
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index 81483de8c0f..71500dda8eb 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -931,9 +931,9 @@ static void i2o_block_request_fn(struct request_queue *q)
/* I2O Block device operations definition */
static struct block_device_operations i2o_block_fops = {
.owner = THIS_MODULE,
- .open = i2o_block_open,
- .release = i2o_block_release,
- .ioctl = i2o_block_ioctl,
+ .__open = i2o_block_open,
+ .__release = i2o_block_release,
+ .__ioctl = i2o_block_ioctl,
.getgeo = i2o_block_getgeo,
.media_changed = i2o_block_media_changed
};
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 24c97d3d16b..8cba06f5e11 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -130,8 +130,8 @@ mmc_blk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
}
static struct block_device_operations mmc_bdops = {
- .open = mmc_blk_open,
- .release = mmc_blk_release,
+ .__open = mmc_blk_open,
+ .__release = mmc_blk_release,
.getgeo = mmc_blk_getgeo,
.owner = THIS_MODULE,
};
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 681d5aca2af..b00d07c5375 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -213,9 +213,9 @@ static int blktrans_ioctl(struct inode *inode, struct file *file,
static struct block_device_operations mtd_blktrans_ops = {
.owner = THIS_MODULE,
- .open = blktrans_open,
- .release = blktrans_release,
- .ioctl = blktrans_ioctl,
+ .__open = blktrans_open,
+ .__release = blktrans_release,
+ .__ioctl = blktrans_ioctl,
.getgeo = blktrans_getgeo,
};
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 0a225ccda02..6bf68e5fe89 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -2087,10 +2087,10 @@ static int dasd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
struct block_device_operations
dasd_device_operations = {
.owner = THIS_MODULE,
- .open = dasd_open,
- .release = dasd_release,
- .ioctl = dasd_ioctl,
- .compat_ioctl = dasd_compat_ioctl,
+ .__open = dasd_open,
+ .__release = dasd_release,
+ .__ioctl = dasd_ioctl,
+ .__compat_ioctl = dasd_compat_ioctl,
.getgeo = dasd_getgeo,
};
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index a7ff167d5b8..413460cc3dd 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -42,8 +42,8 @@ static char dcssblk_segments[DCSSBLK_PARM_LEN] = "\0";
static int dcssblk_major;
static struct block_device_operations dcssblk_devops = {
.owner = THIS_MODULE,
- .open = dcssblk_open,
- .release = dcssblk_release,
+ .__open = dcssblk_open,
+ .__release = dcssblk_release,
.direct_access = dcssblk_direct_access,
};
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c
index a25b8bf54f4..f1a741c9a6f 100644
--- a/drivers/s390/char/tape_block.c
+++ b/drivers/s390/char/tape_block.c
@@ -52,9 +52,9 @@ static int tapeblock_revalidate_disk(struct gendisk *);
static struct block_device_operations tapeblock_fops = {
.owner = THIS_MODULE,
- .open = tapeblock_open,
- .release = tapeblock_release,
- .ioctl = tapeblock_ioctl,
+ .__open = tapeblock_open,
+ .__release = tapeblock_release,
+ .__ioctl = tapeblock_ioctl,
.media_changed = tapeblock_medium_changed,
.revalidate_disk = tapeblock_revalidate_disk,
};
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 5bcc04e82c2..9069afbad9d 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -483,9 +483,9 @@ static int idescsi_ide_ioctl(struct inode *inode, struct file *file,
static struct block_device_operations idescsi_ops = {
.owner = THIS_MODULE,
- .open = idescsi_ide_open,
- .release = idescsi_ide_release,
- .ioctl = idescsi_ide_ioctl,
+ .__open = idescsi_ide_open,
+ .__release = idescsi_ide_release,
+ .__ioctl = idescsi_ide_ioctl,
};
static int idescsi_slave_configure(struct scsi_device * sdp)
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 5a18528a69d..c8b95e8d285 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -962,12 +962,12 @@ static long sd_compat_ioctl(struct file *file, unsigned int cmd, unsigned long a
static struct block_device_operations sd_fops = {
.owner = THIS_MODULE,
- .open = sd_open,
- .release = sd_release,
- .ioctl = sd_ioctl,
+ .__open = sd_open,
+ .__release = sd_release,
+ .__ioctl = sd_ioctl,
.getgeo = sd_getgeo,
#ifdef CONFIG_COMPAT
- .compat_ioctl = sd_compat_ioctl,
+ .__compat_ioctl = sd_compat_ioctl,
#endif
.media_changed = sd_media_changed,
.revalidate_disk = sd_revalidate_disk,
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 2fb8d4d2d6f..9446cbf4de8 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -540,9 +540,9 @@ static int sr_block_media_changed(struct gendisk *disk)
static struct block_device_operations sr_bdops =
{
.owner = THIS_MODULE,
- .open = sr_block_open,
- .release = sr_block_release,
- .ioctl = sr_block_ioctl,
+ .__open = sr_block_open,
+ .__release = sr_block_release,
+ .__ioctl = sr_block_ioctl,
.media_changed = sr_block_media_changed,
/*
* No compat_ioctl for now because sr_block_ioctl never
diff --git a/fs/block_dev.c b/fs/block_dev.c
index b9022694e9f..73b6ce47c86 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1033,8 +1033,13 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part)
bdev->bd_contains = bdev;
if (!partno) {
struct backing_dev_info *bdi;
+ if (disk->fops->__open) {
+ ret = disk->fops->__open(bdev->bd_inode, file);
+ if (ret)
+ goto out_first;
+ }
if (disk->fops->open) {
- ret = disk->fops->open(bdev->bd_inode, file);
+ ret = disk->fops->open(bdev, file->f_mode);
if (ret)
goto out_clear;
}
@@ -1074,8 +1079,13 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part)
part = NULL;
disk = NULL;
if (bdev->bd_contains == bdev) {
+ if (bdev->bd_disk->fops->__open) {
+ ret = bdev->bd_disk->fops->__open(bdev->bd_inode, file);
+ if (ret)
+ goto out;
+ }
if (bdev->bd_disk->fops->open) {
- ret = bdev->bd_disk->fops->open(bdev->bd_inode, file);
+ ret = bdev->bd_disk->fops->open(bdev, file->f_mode);
if (ret)
goto out_unlock_bdev;
}
@@ -1184,8 +1194,10 @@ static int __blkdev_put(struct block_device *bdev, int for_part)
kill_bdev(bdev);
}
if (bdev->bd_contains == bdev) {
+ if (disk->fops->__release)
+ ret = disk->fops->__release(bd_inode, NULL);
if (disk->fops->release)
- ret = disk->fops->release(bd_inode, NULL);
+ ret = disk->fops->release(disk, 0);
}
if (!bdev->bd_openers) {
struct module *owner = disk->fops->owner;
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 2bad616b994..b573186ff1a 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1061,11 +1061,16 @@ struct file;
struct inode;
struct block_device_operations {
- int (*open) (struct inode *, struct file *);
- int (*release) (struct inode *, struct file *);
- int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long);
- long (*unlocked_ioctl) (struct file *, unsigned, unsigned long);
- long (*compat_ioctl) (struct file *, unsigned, unsigned long);
+ int (*__open) (struct inode *, struct file *);
+ int (*__release) (struct inode *, struct file *);
+ int (*__ioctl) (struct inode *, struct file *, unsigned, unsigned long);
+ long (*__unlocked_ioctl) (struct file *, unsigned, unsigned long);
+ long (*__compat_ioctl) (struct file *, unsigned, unsigned long);
+ int (*open) (struct block_device *, fmode_t);
+ int (*release) (struct gendisk *, fmode_t);
+ int (*locked_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
+ int (*ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
+ int (*compat_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
int (*direct_access) (struct block_device *, sector_t,
void **, unsigned long *);
int (*media_changed) (struct gendisk *);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 58bbf689fef..b5894604ba5 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -79,6 +79,7 @@ extern int dir_notify_enable;
#define FMODE_NDELAY ((__force fmode_t)32)
#define FMODE_EXCL ((__force fmode_t)64)
#define FMODE_WRITE_IOCTL ((__force fmode_t)128)
+#define FMODE_NDELAY_NOW ((__force fmode_t)256)
#define RW_MASK 1
#define RWA_MASK 2