diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index b58fb8941d8d..72569cc3cbb7 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 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->ioctl) { + if (disk->fops->__unlocked_ioctl) + return disk->fops->__unlocked_ioctl(file, cmd, arg); + + 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) { + if (disk->fops->__ioctl) { lock_kernel(); - ret = disk->fops->ioctl(bdev->bd_inode, &fake_file, cmd, arg); + 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->locked_ioctl) { + lock_kernel(); + 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 a002a381df92..4b90ebfa6676 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 d19c5a939fe8..d5da4e3cb2ad 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 d876ad861237..d4d9796d5ddd 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 85d56a26f7c6..30166774327d 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 d070d492e385..2ea99f947667 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 d9b1c15b8113..781b745181d2 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 3d967525e9a9..b71334b968b6 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 5d60c05a736a..72363df58953 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 d3a25b027ff9..6faca2b7ae37 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 9034ca585afd..36015e0945b1 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 8bd557e2a659..6e6dcc1d4328 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 5fdfa7c888ce..b3023844947c 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 a902d84fd330..e08ca5161ad8 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 a0ba4023953b..33ac8ddf4912 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 5c45d5556ae8..9398af86a7aa 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 bc04330f3683..5261773407da 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 1730d29e6044..7f7beec29ebb 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 7643cd16fd67..10f157ea7b0b 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 624d30f7da3f..316fa1da4b9c 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 1a50ae70f716..7efac80c8dde 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 4a7a059ebaf7..e4efe5b7ec22 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 be20a67f1fa8..4860d0f36870 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 0959edf2afdb..ab0c637f58be 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 abc4079c3f41..57c2dced3e9d 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 87d90200b169..3533984355a6 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 948af08abe23..d118bbed7cd3 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 2b263281ffea..c5df53c4838c 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 5f0f4c8bcd3e..8b4c92b1b6db 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 aaa3d465de4e..21b04d39ba3b 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 5263913e0c69..fbe5919789d0 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 81483de8c0fd..71500dda8eb3 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 24c97d3d16bb..8cba06f5e11d 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 681d5aca2af4..b00d07c53753 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 0a225ccda026..6bf68e5fe89f 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 a7ff167d5b81..413460cc3dd8 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 a25b8bf54f41..f1a741c9a6f0 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 5bcc04e82c28..9069afbad9d3 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 5a18528a69d0..c8b95e8d2859 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 2fb8d4d2d6f6..9446cbf4de84 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 b9022694e9f7..73b6ce47c861 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 2bad616b9949..b573186ff1a1 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 58bbf689fef7..b5894604ba5e 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