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,
};
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,
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;
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);
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;
}
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,
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,
};
}
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,
};
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,
};
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
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,
};
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,
};
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,
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
};
static struct block_device_operations nbd_fops =
{
.owner = THIS_MODULE,
- .ioctl = nbd_ioctl,
+ .__ioctl = nbd_ioctl,
};
/*
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,
};
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
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,
};
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,
};
}
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,
};
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,
};
*/
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,
};
}
static struct block_device_operations virtblk_fops = {
- .ioctl = virtblk_ioctl,
+ .__ioctl = virtblk_ioctl,
.owner = THIS_MODULE,
.getgeo = virtblk_getgeo,
};
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);
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,
};
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,
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)
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)
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,
};
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
};
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
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)
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
};
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,
}
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
};
/* 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
};
}
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,
};
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,
};
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,
};
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,
};
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,
};
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)
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,
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
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;
}
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;
}
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;
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 *);
#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