diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-23 10:23:07 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-23 10:23:07 -0700 |
commit | 22484856402bfa1ff3defe47f6029ab0418240d9 (patch) | |
tree | 140c67bf59674da350a7b51765d6ff7eb101b597 | |
parent | 5ed487bc2c44ca4e9668ef9cb54c830e2a9fac47 (diff) | |
parent | 56b26add02b4bdea81d5e0ebda60db1fe3311ad4 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/viro/bdev
* git://git.kernel.org/pub/scm/linux/kernel/git/viro/bdev: (66 commits)
[PATCH] kill the rest of struct file propagation in block ioctls
[PATCH] get rid of struct file use in blkdev_ioctl() BLKBSZSET
[PATCH] get rid of blkdev_locked_ioctl()
[PATCH] get rid of blkdev_driver_ioctl()
[PATCH] sanitize blkdev_get() and friends
[PATCH] remember mode of reiserfs journal
[PATCH] propagate mode through swsusp_close()
[PATCH] propagate mode through open_bdev_excl/close_bdev_excl
[PATCH] pass fmode_t to blkdev_put()
[PATCH] kill the unused bsize on the send side of /dev/loop
[PATCH] trim file propagation in block/compat_ioctl.c
[PATCH] end of methods switch: remove the old ones
[PATCH] switch sr
[PATCH] switch sd
[PATCH] switch ide-scsi
[PATCH] switch tape_block
[PATCH] switch dcssblk
[PATCH] switch dasd
[PATCH] switch mtd_blkdevs
[PATCH] switch mmc
...
107 files changed, 868 insertions, 1002 deletions
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index b58fb8941d8d..0a868118cf06 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -98,9 +98,9 @@ static inline void ubd_set_bit(__u64 bit, unsigned char *data) static DEFINE_MUTEX(ubd_lock); -static int ubd_open(struct inode * inode, struct file * filp); -static int ubd_release(struct inode * inode, struct file * file); -static int ubd_ioctl(struct inode * inode, struct file * file, +static int ubd_open(struct block_device *bdev, fmode_t mode); +static int ubd_release(struct gendisk *disk, fmode_t mode); +static int ubd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg); static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo); @@ -1112,9 +1112,9 @@ static int __init ubd_driver_init(void){ device_initcall(ubd_driver_init); -static int ubd_open(struct inode *inode, struct file *filp) +static int ubd_open(struct block_device *bdev, fmode_t mode) { - struct gendisk *disk = inode->i_bdev->bd_disk; + struct gendisk *disk = bdev->bd_disk; struct ubd *ubd_dev = disk->private_data; int err = 0; @@ -1131,7 +1131,7 @@ static int ubd_open(struct inode *inode, struct file *filp) /* This should no more be needed. And it didn't work anyway to exclude * read-write remounting of filesystems.*/ - /*if((filp->f_mode & FMODE_WRITE) && !ubd_dev->openflags.w){ + /*if((mode & FMODE_WRITE) && !ubd_dev->openflags.w){ if(--ubd_dev->count == 0) ubd_close_dev(ubd_dev); err = -EROFS; }*/ @@ -1139,9 +1139,8 @@ static int ubd_open(struct inode *inode, struct file *filp) return err; } -static int ubd_release(struct inode * inode, struct file * file) +static int ubd_release(struct gendisk *disk, fmode_t mode) { - struct gendisk *disk = inode->i_bdev->bd_disk; struct ubd *ubd_dev = disk->private_data; if(--ubd_dev->count == 0) @@ -1306,10 +1305,10 @@ static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo) return 0; } -static int ubd_ioctl(struct inode * inode, struct file * file, +static int ubd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct ubd *ubd_dev = inode->i_bdev->bd_disk->private_data; + struct ubd *ubd_dev = bdev->bd_disk->private_data; struct hd_driveid ubd_id = { .cyls = 0, .heads = 128, diff --git a/block/bsg.c b/block/bsg.c index 034112bfe1f3..e8bd2475682a 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -173,7 +173,7 @@ unlock: static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq, struct sg_io_v4 *hdr, struct bsg_device *bd, - int has_write_perm) + fmode_t has_write_perm) { if (hdr->request_len > BLK_MAX_CDB) { rq->cmd = kzalloc(hdr->request_len, GFP_KERNEL); @@ -242,7 +242,7 @@ bsg_validate_sgv4_hdr(struct request_queue *q, struct sg_io_v4 *hdr, int *rw) * map sg_io_v4 to a request. */ static struct request * -bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, int has_write_perm) +bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm) { struct request_queue *q = bd->queue; struct request *rq, *next_rq = NULL; @@ -601,7 +601,8 @@ bsg_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) } static int __bsg_write(struct bsg_device *bd, const char __user *buf, - size_t count, ssize_t *bytes_written, int has_write_perm) + size_t count, ssize_t *bytes_written, + fmode_t has_write_perm) { struct bsg_command *bc; struct request *rq; @@ -913,7 +914,7 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case SG_EMULATED_HOST: case SCSI_IOCTL_SEND_COMMAND: { void __user *uarg = (void __user *) arg; - return scsi_cmd_ioctl(file, bd->queue, NULL, cmd, uarg); + return scsi_cmd_ioctl(bd->queue, NULL, file->f_mode, cmd, uarg); } case SG_IO: { struct request *rq; diff --git a/block/cmd-filter.c b/block/cmd-filter.c index e669aed4c6bc..504b275e1b90 100644 --- a/block/cmd-filter.c +++ b/block/cmd-filter.c @@ -27,7 +27,7 @@ #include <linux/cdrom.h> int blk_verify_command(struct blk_cmd_filter *filter, - unsigned char *cmd, int has_write_perm) + unsigned char *cmd, fmode_t has_write_perm) { /* root can do any command. */ if (capable(CAP_SYS_RAWIO)) diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c index 1e559fba7bdf..3098c92402fd 100644 --- a/block/compat_ioctl.c +++ b/block/compat_ioctl.c @@ -71,8 +71,8 @@ static int compat_hdio_getgeo(struct gendisk *disk, struct block_device *bdev, return ret; } -static int compat_hdio_ioctl(struct inode *inode, struct file *file, - struct gendisk *disk, unsigned int cmd, unsigned long arg) +static int compat_hdio_ioctl(struct block_device *bdev, fmode_t mode, + unsigned int cmd, unsigned long arg) { mm_segment_t old_fs = get_fs(); unsigned long kval; @@ -80,7 +80,7 @@ static int compat_hdio_ioctl(struct inode *inode, struct file *file, int error; set_fs(KERNEL_DS); - error = blkdev_driver_ioctl(inode, file, disk, + error = __blkdev_driver_ioctl(bdev, mode, cmd, (unsigned long)(&kval)); set_fs(old_fs); @@ -111,8 +111,8 @@ struct compat_cdrom_generic_command { compat_caddr_t reserved[1]; }; -static int compat_cdrom_read_audio(struct inode *inode, struct file *file, - struct gendisk *disk, unsigned int cmd, unsigned long arg) +static int compat_cdrom_read_audio(struct block_device *bdev, fmode_t mode, + unsigned int cmd, unsigned long arg) { struct cdrom_read_audio __user *cdread_audio; struct compat_cdrom_read_audio __user *cdread_audio32; @@ -134,12 +134,12 @@ static int compat_cdrom_read_audio(struct inode *inode, struct file *file, if (put_user(datap, &cdread_audio->buf)) return -EFAULT; - return blkdev_driver_ioctl(inode, file, disk, cmd, + return __blkdev_driver_ioctl(bdev, mode, cmd, (unsigned long)cdread_audio); } -static int compat_cdrom_generic_command(struct inode *inode, struct file *file, - struct gendisk *disk, unsigned int cmd, unsigned long arg) +static int compat_cdrom_generic_command(struct block_device *bdev, fmode_t mode, + unsigned int cmd, unsigned long arg) { struct cdrom_generic_command __user *cgc; struct compat_cdrom_generic_command __user *cgc32; @@ -167,7 +167,7 @@ static int compat_cdrom_generic_command(struct inode *inode, struct file *file, put_user(compat_ptr(data), &cgc->reserved[0])) return -EFAULT; - return blkdev_driver_ioctl(inode, file, disk, cmd, (unsigned long)cgc); + return __blkdev_driver_ioctl(bdev, mode, cmd, (unsigned long)cgc); } struct compat_blkpg_ioctl_arg { @@ -177,7 +177,7 @@ struct compat_blkpg_ioctl_arg { compat_caddr_t data; }; -static int compat_blkpg_ioctl(struct inode *inode, struct file *file, +static int compat_blkpg_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, struct compat_blkpg_ioctl_arg __user *ua32) { struct blkpg_ioctl_arg __user *a = compat_alloc_user_space(sizeof(*a)); @@ -196,7 +196,7 @@ static int compat_blkpg_ioctl(struct inode *inode, struct file *file, if (err) return err; - return blkdev_ioctl(inode, file, cmd, (unsigned long)a); + return blkdev_ioctl(bdev, mode, cmd, (unsigned long)a); } #define BLKBSZGET_32 _IOR(0x12, 112, int) @@ -308,8 +308,8 @@ static struct { #define NR_FD_IOCTL_TRANS ARRAY_SIZE(fd_ioctl_trans_table) -static int compat_fd_ioctl(struct inode *inode, struct file *file, - struct gendisk *disk, unsigned int cmd, unsigned long arg) +static int compat_fd_ioctl(struct block_device *bdev, fmode_t mode, + unsigned int cmd, unsigned long arg) { mm_segment_t old_fs = get_fs(); void *karg = NULL; @@ -413,7 +413,7 @@ static int compat_fd_ioctl(struct inode *inode, struct file *file, return -EINVAL; } set_fs(KERNEL_DS); - err = blkdev_driver_ioctl(inode, file, disk, kcmd, (unsigned long)karg); + err = __blkdev_driver_ioctl(bdev, mode, kcmd, (unsigned long)karg); set_fs(old_fs); if (err) goto out; @@ -579,8 +579,8 @@ static int compat_blk_trace_setup(struct block_device *bdev, char __user *arg) return 0; } -static int compat_blkdev_driver_ioctl(struct inode *inode, struct file *file, - struct gendisk *disk, unsigned cmd, unsigned long arg) +static int compat_blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode, + unsigned cmd, unsigned long arg) { int ret; @@ -596,7 +596,7 @@ static int compat_blkdev_driver_ioctl(struct inode *inode, struct file *file, case HDIO_GET_ACOUSTIC: case HDIO_GET_ADDRESS: case HDIO_GET_BUSSTATE: - return compat_hdio_ioctl(inode, file, disk, cmd, arg); + return compat_hdio_ioctl(bdev, mode, cmd, arg); case FDSETPRM32: case FDDEFPRM32: case FDGETPRM32: @@ -606,11 +606,11 @@ static int compat_blkdev_driver_ioctl(struct inode *inode, struct file *file, case FDPOLLDRVSTAT32: case FDGETFDCSTAT32: case FDWERRORGET32: - return compat_fd_ioctl(inode, file, disk, cmd, arg); + return compat_fd_ioctl(bdev, mode, cmd, arg); case CDROMREADAUDIO: - return compat_cdrom_read_audio(inode, file, disk, cmd, arg); + return compat_cdrom_read_audio(bdev, mode, cmd, arg); case CDROM_SEND_PACKET: - return compat_cdrom_generic_command(inode, file, disk, cmd, arg); + return compat_cdrom_generic_command(bdev, mode, cmd, arg); /* * No handler required for the ones below, we just need to @@ -679,55 +679,49 @@ static int compat_blkdev_driver_ioctl(struct inode *inode, struct file *file, case DVD_WRITE_STRUCT: case DVD_AUTH: arg = (unsigned long)compat_ptr(arg); - /* These intepret arg as an unsigned long, not as a pointer, - * so we must not do compat_ptr() conversion. */ - case HDIO_SET_MULTCOUNT: - case HDIO_SET_UNMASKINTR: - case HDIO_SET_KEEPSETTINGS: - case HDIO_SET_32BIT: - case HDIO_SET_NOWERR: - case HDIO_SET_DMA: - case HDIO_SET_PIO_MODE: - case HDIO_SET_NICE: - case HDIO_SET_WCACHE: - case HDIO_SET_ACOUSTIC: - case HDIO_SET_BUSSTATE: - case HDIO_SET_ADDRESS: - case CDROMEJECT_SW: - case CDROM_SET_OPTIONS: - case CDROM_CLEAR_OPTIONS: - case CDROM_SELECT_SPEED: - case CDROM_SELECT_DISC: - case CDROM_MEDIA_CHANGED: - case CDROM_DRIVE_STATUS: - case CDROM_LOCKDOOR: - case CDROM_DEBUG: break; default: /* unknown ioctl number */ return -ENOIOCTLCMD; } - 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); - unlock_kernel(); - return ret; - } - - return -ENOTTY; + return __blkdev_driver_ioctl(bdev, mode, cmd, arg); } -static int compat_blkdev_locked_ioctl(struct inode *inode, struct file *file, - struct block_device *bdev, - unsigned cmd, unsigned long arg) +/* Most of the generic ioctls are handled in the normal fallback path. + This assumes the blkdev's low level compat_ioctl always returns + ENOIOCTLCMD for unknown ioctls. */ +long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg) { + int ret = -ENOIOCTLCMD; + struct inode *inode = file->f_mapping->host; + struct block_device *bdev = inode->i_bdev; + struct gendisk *disk = bdev->bd_disk; + fmode_t mode = file->f_mode; struct backing_dev_info *bdi; + loff_t size; + + if (file->f_flags & O_NDELAY) + mode |= FMODE_NDELAY_NOW; switch (cmd) { + case HDIO_GETGEO: + return compat_hdio_getgeo(disk, bdev, compat_ptr(arg)); + case BLKFLSBUF: + case BLKROSET: + case BLKDISCARD: + /* + * the ones below are implemented in blkdev_locked_ioctl, + * but we call blkdev_ioctl, which gets the lock for us + */ + case BLKRRPART: + return blkdev_ioctl(bdev, mode, cmd, + (unsigned long)compat_ptr(arg)); + case BLKBSZSET_32: + return blkdev_ioctl(bdev, mode, BLKBSZSET, + (unsigned long)compat_ptr(arg)); + case BLKPG: + return compat_blkpg_ioctl(bdev, mode, cmd, compat_ptr(arg)); case BLKRAGET: case BLKFRAGET: if (!arg) @@ -753,65 +747,36 @@ static int compat_blkdev_locked_ioctl(struct inode *inode, struct file *file, bdi = blk_get_backing_dev_info(bdev); if (bdi == NULL) return -ENOTTY; + lock_kernel(); bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE; + unlock_kernel(); return 0; case BLKGETSIZE: - if ((bdev->bd_inode->i_size >> 9) > ~0UL) + size = bdev->bd_inode->i_size; + if ((size >> 9) > ~0UL) return -EFBIG; - return compat_put_ulong(arg, bdev->bd_inode->i_size >> 9); + return compat_put_ulong(arg, size >> 9); case BLKGETSIZE64_32: return compat_put_u64(arg, bdev->bd_inode->i_size); case BLKTRACESETUP32: - return compat_blk_trace_setup(bdev, compat_ptr(arg)); + lock_kernel(); + ret = compat_blk_trace_setup(bdev, compat_ptr(arg)); + unlock_kernel(); + return ret; case BLKTRACESTART: /* compatible */ case BLKTRACESTOP: /* compatible */ case BLKTRACETEARDOWN: /* compatible */ - return blk_trace_ioctl(bdev, cmd, compat_ptr(arg)); - } - return -ENOIOCTLCMD; -} - -/* Most of the generic ioctls are handled in the normal fallback path. - This assumes the blkdev's low level compat_ioctl always returns - ENOIOCTLCMD for unknown ioctls. */ -long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg) -{ - int ret = -ENOIOCTLCMD; - struct inode *inode = file->f_mapping->host; - struct block_device *bdev = inode->i_bdev; - struct gendisk *disk = bdev->bd_disk; - - switch (cmd) { - case HDIO_GETGEO: - return compat_hdio_getgeo(disk, bdev, compat_ptr(arg)); - case BLKFLSBUF: - case BLKROSET: - case BLKDISCARD: - /* - * the ones below are implemented in blkdev_locked_ioctl, - * but we call blkdev_ioctl, which gets the lock for us - */ - case BLKRRPART: - return blkdev_ioctl(inode, file, cmd, - (unsigned long)compat_ptr(arg)); - case BLKBSZSET_32: - return blkdev_ioctl(inode, file, BLKBSZSET, - (unsigned long)compat_ptr(arg)); - case BLKPG: - return compat_blkpg_ioctl(inode, file, cmd, compat_ptr(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); - unlock_kernel(); - - if (ret != -ENOIOCTLCMD) + lock_kernel(); + ret = blk_trace_ioctl(bdev, cmd, compat_ptr(arg)); + unlock_kernel(); return ret; - - return compat_blkdev_driver_ioctl(inode, file, disk, cmd, arg); + default: + if (disk->fops->compat_ioctl) + ret = disk->fops->compat_ioctl(bdev, mode, cmd, arg); + if (ret == -ENOIOCTLCMD) + ret = compat_blkdev_driver_ioctl(bdev, mode, cmd, arg); + return ret; + } } diff --git a/block/ioctl.c b/block/ioctl.c index 38bee321e1fa..c832d639b6e2 100644 --- a/block/ioctl.c +++ b/block/ioctl.c @@ -201,97 +201,41 @@ static int put_u64(unsigned long arg, u64 val) return put_user(val, (u64 __user *)arg); } -static int blkdev_locked_ioctl(struct file *file, struct block_device *bdev, - unsigned cmd, unsigned long arg) -{ - struct backing_dev_info *bdi; - int ret, n; - - switch (cmd) { - case BLKRAGET: - case BLKFRAGET: - if (!arg) - return -EINVAL; - bdi = blk_get_backing_dev_info(bdev); - if (bdi == NULL) - return -ENOTTY; - return put_long(arg, (bdi->ra_pages * PAGE_CACHE_SIZE) / 512); - case BLKROGET: - return put_int(arg, bdev_read_only(bdev) != 0); - case BLKBSZGET: /* get the logical block size (cf. BLKSSZGET) */ - return put_int(arg, block_size(bdev)); - case BLKSSZGET: /* get block device hardware sector size */ - return put_int(arg, bdev_hardsect_size(bdev)); - case BLKSECTGET: - return put_ushort(arg, bdev_get_queue(bdev)->max_sectors); - case BLKRASET: - case BLKFRASET: - if(!capable(CAP_SYS_ADMIN)) - return -EACCES; - bdi = blk_get_backing_dev_info(bdev); - if (bdi == NULL) - return -ENOTTY; - bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE; - return 0; - case BLKBSZSET: - /* set the logical block size */ - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - if (!arg) - return -EINVAL; - if (get_user(n, (int __user *) arg)) - return -EFAULT; - if (bd_claim(bdev, file) < 0) - return -EBUSY; - ret = set_blocksize(bdev, n); - bd_release(bdev); - return ret; - case BLKPG: - return blkpg_ioctl(bdev, (struct blkpg_ioctl_arg __user *) arg); - case BLKRRPART: - return blkdev_reread_part(bdev); - case BLKGETSIZE: - if ((bdev->bd_inode->i_size >> 9) > ~0UL) - return -EFBIG; - return put_ulong(arg, bdev->bd_inode->i_size >> 9); - case BLKGETSIZE64: - return put_u64(arg, bdev->bd_inode->i_size); - case BLKTRACESTART: - case BLKTRACESTOP: - case BLKTRACESETUP: - case BLKTRACETEARDOWN: - return blk_trace_ioctl(bdev, cmd, (char __user *) arg); - } - return -ENOIOCTLCMD; -} - -int blkdev_driver_ioctl(struct inode *inode, struct file *file, - struct gendisk *disk, unsigned cmd, unsigned long arg) +int __blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode, + unsigned cmd, unsigned long arg) { + struct gendisk *disk = bdev->bd_disk; int ret; - if (disk->fops->unlocked_ioctl) - return disk->fops->unlocked_ioctl(file, cmd, arg); - if (disk->fops->ioctl) { + if (disk->fops->ioctl) + return disk->fops->ioctl(bdev, mode, cmd, arg); + + if (disk->fops->locked_ioctl) { lock_kernel(); - ret = disk->fops->ioctl(inode, file, cmd, arg); + ret = disk->fops->locked_ioctl(bdev, mode, cmd, arg); unlock_kernel(); return ret; } return -ENOTTY; } -EXPORT_SYMBOL_GPL(blkdev_driver_ioctl); +/* + * For the record: _GPL here is only because somebody decided to slap it + * on the previous export. Sheer idiocy, since it wasn't copyrightable + * at all and could be open-coded without any exports by anybody who cares. + */ +EXPORT_SYMBOL_GPL(__blkdev_driver_ioctl); /* * always keep this in sync with compat_blkdev_ioctl() and * compat_blkdev_locked_ioctl() */ -int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd, +int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, unsigned long arg) { - struct block_device *bdev = inode->i_bdev; struct gendisk *disk = bdev->bd_disk; + struct backing_dev_info *bdi; + loff_t size; int ret, n; switch(cmd) { @@ -299,7 +243,7 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd, if (!capable(CAP_SYS_ADMIN)) return -EACCES; - ret = blkdev_driver_ioctl(inode, file, disk, cmd, arg); + ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg); /* -EINVAL to handle old uncorrected drivers */ if (ret != -EINVAL && ret != -ENOTTY) return ret; @@ -311,7 +255,7 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd, return 0; case BLKROSET: - ret = blkdev_driver_ioctl(inode, file, disk, cmd, arg); + ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg); /* -EINVAL to handle old uncorrected drivers */ if (ret != -EINVAL && ret != -ENOTTY) return ret; @@ -327,7 +271,7 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd, case BLKDISCARD: { uint64_t range[2]; - if (!(file->f_mode & FMODE_WRITE)) + if (!(mode & FMODE_WRITE)) return -EBADF; if (copy_from_user(range, (void __user *)arg, sizeof(range))) @@ -357,14 +301,75 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd, return -EFAULT; return 0; } - } - - lock_kernel(); - ret = blkdev_locked_ioctl(file, bdev, cmd, arg); - unlock_kernel(); - if (ret != -ENOIOCTLCMD) + case BLKRAGET: + case BLKFRAGET: + if (!arg) + return -EINVAL; + bdi = blk_get_backing_dev_info(bdev); + if (bdi == NULL) + return -ENOTTY; + return put_long(arg, (bdi->ra_pages * PAGE_CACHE_SIZE) / 512); + case BLKROGET: + return put_int(arg, bdev_read_only(bdev) != 0); + case BLKBSZGET: /* get the logical block size (cf. BLKSSZGET) */ + return put_int(arg, block_size(bdev)); + case BLKSSZGET: /* get block device hardware sector size */ + return put_int(arg, bdev_hardsect_size(bdev)); + case BLKSECTGET: + return put_ushort(arg, bdev_get_queue(bdev)->max_sectors); + case BLKRASET: + case BLKFRASET: + if(!capable(CAP_SYS_ADMIN)) + return -EACCES; + bdi = blk_get_backing_dev_info(bdev); + if (bdi == NULL) + return -ENOTTY; + lock_kernel(); + bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE; + unlock_kernel(); + return 0; + case BLKBSZSET: + /* set the logical block size */ + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + if (!arg) + return -EINVAL; + if (get_user(n, (int __user *) arg)) + return -EFAULT; + if (!(mode & FMODE_EXCL) && bd_claim(bdev, &bdev) < 0) + return -EBUSY; + ret = set_blocksize(bdev, n); + if (!(mode & FMODE_EXCL)) + bd_release(bdev); return ret; - - return blkdev_driver_ioctl(inode, file, disk, cmd, arg); + case BLKPG: + lock_kernel(); + ret = blkpg_ioctl(bdev, (struct blkpg_ioctl_arg __user *) arg); + unlock_kernel(); + break; + case BLKRRPART: + lock_kernel(); + ret = blkdev_reread_part(bdev); + unlock_kernel(); + break; + case BLKGETSIZE: + size = bdev->bd_inode->i_size; + if ((size >> 9) > ~0UL) + return -EFBIG; + return put_ulong(arg, size >> 9); + case BLKGETSIZE64: + return put_u64(arg, bdev->bd_inode->i_size); + case BLKTRACESTART: + case BLKTRACESTOP: + case BLKTRACESETUP: + case BLKTRACETEARDOWN: + lock_kernel(); + ret = blk_trace_ioctl(bdev, cmd, (char __user *) arg); + unlock_kernel(); + break; + default: + ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg); + } + return ret; } EXPORT_SYMBOL_GPL(blkdev_ioctl); diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index c34272a348fe..5963cf91a3a0 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c @@ -190,12 +190,11 @@ void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter) EXPORT_SYMBOL_GPL(blk_set_cmd_filter_defaults); static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq, - struct sg_io_hdr *hdr, struct file *file) + struct sg_io_hdr *hdr, fmode_t mode) { if (copy_from_user(rq->cmd, hdr->cmdp, hdr->cmd_len)) return -EFAULT; - if (blk_verify_command(&q->cmd_filter, rq->cmd, - file->f_mode & FMODE_WRITE)) + if (blk_verify_command(&q->cmd_filter, rq->cmd, mode & FMODE_WRITE)) return -EPERM; /* @@ -260,8 +259,8 @@ static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr, return r; } -static int sg_io(struct file *file, struct request_queue *q, - struct gendisk *bd_disk, struct sg_io_hdr *hdr) +static int sg_io(struct request_queue *q, struct gendisk *bd_disk, + struct sg_io_hdr *hdr, fmode_t mode) { unsigned long start_time; int writing = 0, ret = 0; @@ -293,7 +292,7 @@ static int sg_io(struct file *file, struct request_queue *q, if (!rq) return -ENOMEM; - if (blk_fill_sghdr_rq(q, rq, hdr, file)) { + if (blk_fill_sghdr_rq(q, rq, hdr, mode)) { blk_put_request(rq); return -EFAULT; } @@ -380,11 +379,11 @@ out: * bytes in one int) where the lowest byte is the SCSI status. */ #define OMAX_SB_LEN 16 /* For backward compatibility */ -int sg_scsi_ioctl(struct file *file, struct request_queue *q, - struct gendisk *disk, struct scsi_ioctl_command __user *sic) +int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode, + struct scsi_ioctl_command __user *sic) { struct request *rq; - int err, write_perm = 0; + int err; unsigned int in_len, out_len, bytes, opcode, cmdlen; char *buffer = NULL, sense[SCSI_SENSE_BUFFERSIZE]; @@ -426,11 +425,7 @@ int sg_scsi_ioctl(struct file *file, struct request_queue *q, if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len)) goto error; - /* scsi_ioctl passes NULL */ - if (file && (file->f_mode & FMODE_WRITE)) - write_perm = 1; - - err = blk_verify_command(&q->cmd_filter, rq->cmd, write_perm); + err = blk_verify_command(&q->cmd_filter, rq->cmd, mode & FMODE_WRITE); if (err) goto error; @@ -522,8 +517,8 @@ static inline int blk_send_start_stop(struct request_queue *q, return __blk_send_generic(q, bd_disk, GPCMD_START_STOP_UNIT, data); } -int scsi_cmd_ioctl(struct file *file, struct request_queue *q, - struct gendisk *bd_disk, unsigned int cmd, void __user *arg) +int scsi_cmd_ioctl(struct request_queue *q, struct gendisk *bd_disk, fmode_t mode, + unsigned int cmd, void __user *arg) { int err; @@ -564,7 +559,7 @@ int scsi_cmd_ioctl(struct file *file, struct request_queue *q, err = -EFAULT; if (copy_from_user(&hdr, arg, sizeof(hdr))) break; - err = sg_io(file, q, bd_disk, &hdr); + err = sg_io(q, bd_disk, &hdr, mode); if (err == -EFAULT) break; @@ -612,7 +607,7 @@ int scsi_cmd_ioctl(struct file *file, struct request_queue *q, hdr.cmdp = ((struct cdrom_generic_command __user*) arg)->cmd; hdr.cmd_len = sizeof(cgc.cmd); - err = sg_io(file, q, bd_disk, &hdr); + err = sg_io(q, bd_disk, &hdr, mode); if (err == -EFAULT) break; @@ -636,7 +631,7 @@ int scsi_cmd_ioctl(struct file *file, struct request_queue *q, if (!arg) break; - err = sg_scsi_ioctl(file, q, bd_disk, arg); + err = sg_scsi_ioctl(q, bd_disk, mode, arg); break; case CDROMCLOSETRAY: err = blk_send_start_stop(q, bd_disk, 0x03); diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index a002a381df92..f6a337c34ac4 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -72,9 +72,9 @@ static long disk_size(DAC960_Controller_T *p, int drive_nr) } } -static int DAC960_open(struct inode *inode, struct file *file) +static int DAC960_open(struct block_device *bdev, fmode_t mode) { - struct gendisk *disk = inode->i_bdev->bd_disk; + struct gendisk *disk = bdev->bd_disk; DAC960_Controller_T *p = disk->queue->queuedata; int drive_nr = (long)disk->private_data; @@ -89,7 +89,7 @@ static int DAC960_open(struct inode *inode, struct file *file) return -ENXIO; } - check_disk_change(inode->i_bdev); + check_disk_change(bdev); if (!get_capacity(p->disks[drive_nr])) return -ENXIO; diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c index 7516baff3bb9..4b1d4ac960f1 100644 --- a/drivers/block/amiflop.c +++ b/drivers/block/amiflop.c @@ -1437,10 +1437,11 @@ static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo) return 0; } -static int fd_ioctl(struct inode *inode, struct file *filp, +static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long param) { - int drive = iminor(inode) & 3; + struct amiga_floppy_struct *p = bdev->bd_disk->private_data; + int drive = p - unit; static struct floppy_struct getprm; void __user *argp = (void __user *)param; @@ -1451,7 +1452,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp, rel_fdc(); return -EBUSY; } - fsync_bdev(inode->i_bdev); + fsync_bdev(bdev); if (fd_motor_on(drive) == 0) { rel_fdc(); return -ENODEV; @@ -1464,12 +1465,12 @@ static int fd_ioctl(struct inode *inode, struct file *filp, rel_fdc(); break; case FDFMTTRK: - if (param < unit[drive].type->tracks * unit[drive].type->heads) + if (param < p->type->tracks * p->type->heads) { get_fdc(drive); if (fd_seek(drive,param) != 0){ - memset(unit[drive].trackbuf, FD_FILL_BYTE, - unit[drive].dtype->sects * unit[drive].type->sect_mult * 512); + memset(p->trackbuf, FD_FILL_BYTE, + p->dtype->sects * p->type->sect_mult * 512); non_int_flush_track(drive); } floppy_off(drive); @@ -1480,14 +1481,14 @@ static int fd_ioctl(struct inode *inode, struct file *filp, break; case FDFMTEND: floppy_off(drive); - invalidate_bdev(inode->i_bdev); + invalidate_bdev(bdev); break; case FDGETPRM: memset((void *)&getprm, 0, sizeof (getprm)); - getprm.track=unit[drive].type->tracks; - getprm.head=unit[drive].type->heads; - getprm.sect=unit[drive].dtype->sects * unit[drive].type->sect_mult; - getprm.size=unit[drive].blocks; + getprm.track=p->type->tracks; + getprm.head=p->type->heads; + getprm.sect=p->dtype->sects * p->type->sect_mult; + getprm.size=p->blocks; if (copy_to_user(argp, &getprm, sizeof(struct floppy_struct))) return -EFAULT; break; @@ -1500,10 +1501,10 @@ static int fd_ioctl(struct inode *inode, struct file *filp, break; #ifdef RAW_IOCTL case IOCTL_RAW_TRACK: - if (copy_to_user(argp, raw_buf, unit[drive].type->read_size)) + if (copy_to_user(argp, raw_buf, p->type->read_size)) return -EFAULT; else - return unit[drive].type->read_size; + return p->type->read_size; #endif default: printk(KERN_DEBUG "fd_ioctl: unknown cmd %d for drive %d.", @@ -1548,10 +1549,10 @@ static void fd_probe(int dev) * /dev/PS0 etc), and disallows simultaneous access to the same * drive with different device numbers. */ -static int floppy_open(struct inode *inode, struct file *filp) +static int floppy_open(struct block_device *bdev, fmode_t mode) { - int drive = iminor(inode) & 3; - int system = (iminor(inode) & 4) >> 2; + int drive = MINOR(bdev->bd_dev) & 3; + int system = (MINOR(bdev->bd_dev) & 4) >> 2; int old_dev; unsigned long flags; @@ -1560,9 +1561,9 @@ static int floppy_open(struct inode *inode, struct file *filp) if (fd_ref[drive] && old_dev != system) return -EBUSY; - if (filp && filp->f_mode & 3) { - check_disk_change(inode->i_bdev); - if (filp->f_mode & 2 ) { + if (mode & (FMODE_READ|FMODE_WRITE)) { + check_disk_change(bdev); + if (mode & FMODE_WRITE) { int wrprot; get_fdc(drive); @@ -1592,9 +1593,10 @@ static int floppy_open(struct inode *inode, struct file *filp) return 0; } -static int floppy_release(struct inode * inode, struct file * filp) +static int floppy_release(struct gendisk *disk, fmode_t mode) { - int drive = iminor(inode) & 3; + struct amiga_floppy_struct *p = disk->private_data; + int drive = p - unit; if (unit[drive].dirty == 1) { del_timer (flush_track_timer + drive); @@ -1650,7 +1652,7 @@ static struct block_device_operations floppy_fops = { .owner = THIS_MODULE, .open = floppy_open, .release = floppy_release, - .ioctl = fd_ioctl, + .locked_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..1747dd272cd4 100644 --- a/drivers/block/aoe/aoeblk.c +++ b/drivers/block/aoe/aoeblk.c @@ -118,13 +118,11 @@ aoedisk_rm_sysfs(struct aoedev *d) } static int -aoeblk_open(struct inode *inode, struct file *filp) +aoeblk_open(struct block_device *bdev, fmode_t mode) { - struct aoedev *d; + struct aoedev *d = bdev->bd_disk->private_data; ulong flags; - d = inode->i_bdev->bd_disk->private_data; - spin_lock_irqsave(&d->lock, flags); if (d->flags & DEVFL_UP) { d->nopen++; @@ -136,13 +134,11 @@ aoeblk_open(struct inode *inode, struct file *filp) } static int -aoeblk_release(struct inode *inode, struct file *filp) +aoeblk_release(struct gendisk *disk, fmode_t mode) { - struct aoedev *d; + struct aoedev *d = disk->private_data; ulong flags; - d = inode->i_bdev->bd_disk->private_data; - spin_lock_irqsave(&d->lock, flags); if (--d->nopen == 0) { diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c index 432cf4018291..69e1df7dfa14 100644 --- a/drivers/block/ataflop.c +++ b/drivers/block/ataflop.c @@ -361,13 +361,13 @@ static void finish_fdc( void ); static void finish_fdc_done( int dummy ); static void setup_req_params( int drive ); static void redo_fd_request( void); -static int fd_ioctl( struct inode *inode, struct file *filp, unsigned int +static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long param); static void fd_probe( int drive ); static int fd_test_drive_present( int drive ); static void config_types( void ); -static int floppy_open( struct inode *inode, struct file *filp ); -static int floppy_release( struct inode * inode, struct file * filp ); +static int floppy_open(struct block_device *bdev, fmode_t mode); +static int floppy_release(struct gendisk *disk, fmode_t mode); /************************* End of Prototypes **************************/ @@ -1483,10 +1483,10 @@ void do_fd_request(struct request_queue * q) atari_enable_irq( IRQ_MFP_FDC ); } -static int fd_ioctl(struct inode *inode, struct file *filp, +static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long param) { - struct gendisk *disk = inode->i_bdev->bd_disk; + struct gendisk *disk = bdev->bd_disk; struct atari_floppy_struct *floppy = disk->private_data; int drive = floppy - unit; int type = floppy->type; @@ -1661,7 +1661,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp, /* invalidate the buffer track to force a reread */ BufferDrive = -1; set_bit(drive, &fake_change); - check_disk_change(inode->i_bdev); + check_disk_change(bdev); return 0; default: return -EINVAL; @@ -1804,37 +1804,36 @@ static void __init config_types( void ) * drive with different device numbers. */ -static int floppy_open( struct inode *inode, struct file *filp ) +static int floppy_open(struct block_device *bdev, fmode_t mode) { - struct atari_floppy_struct *p = inode->i_bdev->bd_disk->private_data; - int type = iminor(inode) >> 2; + struct atari_floppy_struct *p = bdev->bd_disk->private_data; + int type = MINOR(bdev->bd_dev) >> 2; DPRINT(("fd_open: type=%d\n",type)); if (p->ref && p->type != type) return -EBUSY; - if (p->ref == -1 || (p->ref && filp->f_flags & O_EXCL)) + if (p->ref == -1 || (p->ref && mode & FMODE_EXCL)) return -EBUSY; - if (filp->f_flags & O_EXCL) + if (mode & FMODE_EXCL) p->ref = -1; else p->ref++; p->type = type; - if (filp->f_flags & O_NDELAY) + if (mode & FMODE_NDELAY) return 0; - if (filp->f_mode & 3) { - check_disk_change(inode->i_bdev); - if (filp->f_mode & 2) { + if (mode & (FMODE_READ|FMODE_WRITE)) { + check_disk_change(bdev); + if (mode & FMODE_WRITE) { if (p->wpstat) { if (p->ref < 0) p->ref = 0; else p->ref--; - floppy_release(inode, filp); return -EROFS; } } @@ -1843,9 +1842,9 @@ static int floppy_open( struct inode *inode, struct file *filp ) } -static int floppy_release( struct inode * inode, struct file * filp ) +static int floppy_release(struct gendisk *disk, fmode_t mode) { - struct atari_floppy_struct *p = inode->i_bdev->bd_disk->private_data; + struct atari_floppy_struct *p = disk->private_data; if (p->ref < 0) p->ref = 0; else if (!p->ref--) { @@ -1859,7 +1858,7 @@ static struct block_device_operations floppy_fops = { .owner = THIS_MODULE, .open = floppy_open, .release = floppy_release, - .ioctl = fd_ioctl, + .locked_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..bdd4f5f45575 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c @@ -340,11 +340,10 @@ static int brd_direct_access (struct block_device *bdev, sector_t sector, } #endif -static int brd_ioctl(struct inode *inode, struct file *file, +static int brd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { int error; - struct block_device *bdev = inode->i_bdev; struct brd_device *brd = bdev->bd_disk->private_data; if (cmd != BLKFLSBUF) @@ -376,7 +375,7 @@ static int brd_ioctl(struct inode *inode, struct file *file, static struct block_device_operations brd_fops = { .owner = THIS_MODULE, - .ioctl = brd_ioctl, + .locked_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 1e1f9153000c..4023885353e0 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -152,9 +152,9 @@ static ctlr_info_t *hba[MAX_CTLR]; static void do_cciss_request(struct request_queue *q); static irqreturn_t do_cciss_intr(int irq, void *dev_id); -static int cciss_open(struct inode *inode, struct file *filep); -static int cciss_release(struct inode *inode, struct file *filep); -static int cciss_ioctl(struct inode *inode, struct file *filep, +static int cciss_open(struct block_device *bdev, fmode_t mode); +static int cciss_release(struct gendisk *disk, fmode_t mode); +static int cciss_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg); static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo); @@ -192,14 +192,15 @@ static void cciss_procinit(int i) #endif /* CONFIG_PROC_FS */ #ifdef CONFIG_COMPAT -static long cciss_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg); +static int cciss_compat_ioctl(struct block_device *, fmode_t, + unsigned, unsigned long); #endif static struct block_device_operations cciss_fops = { .owner = THIS_MODULE, .open = cciss_open, .release = cciss_release, - .ioctl = cciss_ioctl, + .locked_ioctl = cciss_ioctl, .getgeo = cciss_getgeo, #ifdef CONFIG_COMPAT .compat_ioctl = cciss_compat_ioctl, @@ -547,13 +548,13 @@ static inline drive_info_struct *get_drv(struct gendisk *disk) /* * Open. Make sure the device is really there. */ -static int cciss_open(struct inode *inode, struct file *filep) +static int cciss_open(struct block_device *bdev, fmode_t mode) { - ctlr_info_t *host = get_host(inode->i_bdev->bd_disk); - drive_info_struct *drv = get_drv(inode->i_bdev->bd_disk); + ctlr_info_t *host = get_host(bdev->bd_disk); + drive_info_struct *drv = get_drv(bdev->bd_disk); #ifdef CCISS_DEBUG - printk(KERN_DEBUG "cciss_open %s\n", inode->i_bdev->bd_disk->disk_name); + printk(KERN_DEBUG "cciss_open %s\n", bdev->bd_disk->disk_name); #endif /* CCISS_DEBUG */ if (host->busy_initializing || drv->busy_configuring) @@ -567,9 +568,9 @@ static int cciss_open(struct inode *inode, struct file *filep) * for "raw controller". */ if (drv->heads == 0) { - if (iminor(inode) != 0) { /* not node 0? */ + if (MINOR(bdev->bd_dev) != 0) { /* not node 0? */ /* if not node 0 make sure it is a partition = 0 */ - if (iminor(inode) & 0x0f) { + if (MINOR(bdev->bd_dev) & 0x0f) { return -ENXIO; /* if it is, make sure we have a LUN ID */ } else if (drv->LunID == 0) { @@ -587,14 +588,13 @@ static int cciss_open(struct inode *inode, struct file *filep) /* * Close. Sync first. */ -static int cciss_release(struct inode *inode, struct file *filep) +static int cciss_release(struct gendisk *disk, fmode_t mode) { - ctlr_info_t *host = get_host(inode->i_bdev->bd_disk); - drive_info_struct *drv = get_drv(inode->i_bdev->bd_disk); + ctlr_info_t *host = get_host(disk); + drive_info_struct *drv = get_drv(disk); #ifdef CCISS_DEBUG - printk(KERN_DEBUG "cciss_release %s\n", - inode->i_bdev->bd_disk->disk_name); + printk(KERN_DEBUG "cciss_release %s\n", disk->disk_name); #endif /* CCISS_DEBUG */ drv->usage_count--; @@ -604,21 +604,23 @@ static int cciss_release(struct inode *inode, struct file *filep) #ifdef CONFIG_COMPAT -static int do_ioctl(struct file *f, unsigned cmd, unsigned long arg) +static int do_ioctl(struct block_device *bdev, fmode_t mode, + unsigned cmd, unsigned long arg) { int ret; lock_kernel(); - ret = cciss_ioctl(f->f_path.dentry->d_inode, f, cmd, arg); + ret = cciss_ioctl(bdev, mode, cmd, arg); unlock_kernel(); return ret; } -static int cciss_ioctl32_passthru(struct file *f, unsigned cmd, - unsigned long arg); -static int cciss_ioctl32_big_passthru(struct file *f, unsigned cmd, - unsigned long arg); +static int cciss_ioctl32_passthru(struct block_device *bdev, fmode_t mode, + unsigned cmd, unsigned long arg); +static int cciss_ioctl32_big_passthru(struct block_device *bdev, fmode_t mode, + unsigned cmd, unsigned long arg); -static long cciss_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg) +static int cciss_compat_ioctl(struct block_device *bdev, fmode_t mode, + unsigned cmd, unsigned long arg) { switch (cmd) { case CCISS_GETPCIINFO: @@ -636,20 +638,20 @@ static long cciss_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg) case CCISS_REGNEWD: case CCISS_RESCANDISK: case CCISS_GETLUNINFO: - return do_ioctl(f, cmd, arg); + return do_ioctl(bdev, mode, cmd, arg); case CCISS_PASSTHRU32: - return cciss_ioctl32_passthru(f, cmd, arg); + return cciss_ioctl32_passthru(bdev, mode, cmd, arg); case CCISS_BIG_PASSTHRU32: - return cciss_ioctl32_big_passthru(f, cmd, arg); + return cciss_ioctl32_big_passthru(bdev, mode, cmd, arg); default: return -ENOIOCTLCMD; } } -static int cciss_ioctl32_passthru(struct file *f, unsigned cmd, - unsigned long arg) +static int cciss_ioctl32_passthru(struct block_device *bdev, fmode_t mode, + unsigned cmd, unsigned long arg) { IOCTL32_Command_struct __user *arg32 = (IOCTL32_Command_struct __user *) arg; @@ -676,7 +678,7 @@ static int cciss_ioctl32_passthru(struct file *f, unsigned cmd, if (err) return -EFAULT; - err = do_ioctl(f, CCISS_PASSTHRU, (unsigned long)p); + err = do_ioctl(bdev, mode, CCISS_PASSTHRU, (unsigned long)p); if (err) return err; err |= @@ -687,8 +689,8 @@ static int cciss_ioctl32_passthru(struct file *f, unsigned cmd, return err; } -static int cciss_ioctl32_big_passthru(struct file *file, unsigned cmd, - unsigned long arg) +static int cciss_ioctl32_big_passthru(struct block_device *bdev, fmode_t mode, + unsigned cmd, unsigned long arg) { BIG_IOCTL32_Command_struct __user *arg32 = (BIG_IOCTL32_Command_struct __user *) arg; @@ -717,7 +719,7 @@ static int cciss_ioctl32_big_passthru(struct file *file, unsigned cmd, if (err) return -EFAULT; - err = do_ioctl(file, CCISS_BIG_PASSTHRU, (unsigned long)p); + err = do_ioctl(bdev, mode, CCISS_BIG_PASSTHRU, (unsigned long)p); if (err) return err; err |= @@ -745,10 +747,9 @@ static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo) /* * ioctl */ -static int cciss_ioctl(struct inode *inode, struct file *filep, +static int cciss_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct block_device *bdev = inode->i_bdev; struct gendisk *disk = bdev->bd_disk; ctlr_info_t *host = get_host(disk); drive_info_struct *drv = get_drv(disk); @@ -1232,7 +1233,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, case SG_EMULATED_HOST: case SG_IO: case SCSI_IOCTL_SEND_COMMAND: - return scsi_cmd_ioctl(filep, disk->queue, disk, cmd, argp); + return scsi_cmd_ioctl(disk->queue, disk, mode, cmd, argp); /* scsi_cmd_ioctl would normally handle these, below, but */ /* they aren't a good fit for cciss, as CD-ROMs are */ diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index 3d967525e9a9..47d233c6d0b3 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c @@ -156,9 +156,9 @@ static int sendcmd( unsigned int blkcnt, unsigned int log_unit ); -static int ida_open(struct inode *inode, struct file *filep); -static int ida_release(struct inode *inode, struct file *filep); -static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg); +static int ida_open(struct block_device *bdev, fmode_t mode); +static int ida_release(struct gendisk *disk, fmode_t mode); +static int ida_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg); static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo); static int ida_ctlr_ioctl(ctlr_info_t *h, int dsk, ida_ioctl_t *io); @@ -197,7 +197,7 @@ static struct block_device_operations ida_fops = { .owner = THIS_MODULE, .open = ida_open, .release = ida_release, - .ioctl = ida_ioctl, + .locked_ioctl = ida_ioctl, .getgeo = ida_getgeo, .revalidate_disk= ida_revalidate, }; @@ -818,12 +818,12 @@ DBGINFO( /* * Open. Make sure the device is really there. */ -static int ida_open(struct inode *inode, struct file *filep) +static int ida_open(struct block_device *bdev, fmode_t mode) { - drv_info_t *drv = get_drv(inode->i_bdev->bd_disk); - ctlr_info_t *host = get_host(inode->i_bdev->bd_disk); + drv_info_t *drv = get_drv(bdev->bd_disk); + ctlr_info_t *host = get_host(bdev->bd_disk); - DBGINFO(printk("ida_open %s\n", inode->i_bdev->bd_disk->disk_name)); + DBGINFO(printk("ida_open %s\n", bdev->bd_disk->disk_name)); /* * Root is allowed to open raw volume zero even if it's not configured * so array config can still work. I don't think I really like this, @@ -843,9 +843,9 @@ static int ida_open(struct inode *inode, struct file *filep) /* * Close. Sync first. */ -static int ida_release(struct inode *inode, struct file *filep) +static int ida_release(struct gendisk *disk, fmode_t mode) { - ctlr_info_t *host = get_host(inode->i_bdev->bd_disk); + ctlr_info_t *host = get_host(disk); host->usage_count--; return 0; } @@ -1128,10 +1128,10 @@ static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo) * ida_ioctl does some miscellaneous stuff like reporting drive geometry, * setting readahead and submitting commands from userspace to the controller. */ -static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg) +static int ida_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - drv_info_t *drv = get_drv(inode->i_bdev->bd_disk); - ctlr_info_t *host = get_host(inode->i_bdev->bd_disk); + drv_info_t *drv = get_drv(bdev->bd_disk); + ctlr_info_t *host = get_host(bdev->bd_disk); int error; ida_ioctl_t __user *io = (ida_ioctl_t __user *)arg; ida_ioctl_t *my_io; @@ -1165,7 +1165,7 @@ out_passthru: put_user(host->ctlr_sig, (int __user *)arg); return 0; case IDAREVALIDATEVOLS: - if (iminor(inode) != 0) + if (MINOR(bdev->bd_dev) != 0) return -ENXIO; return revalidate_allvol(host); case IDADRIVERVERSION: diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 2cea27aba9a0..14db747a636e 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -3450,14 +3450,14 @@ static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo) return 0; } -static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, +static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long param) { -#define FD_IOCTL_ALLOWED ((filp) && (filp)->private_data) +#define FD_IOCTL_ALLOWED (mode & (FMODE_WRITE|FMODE_WRITE_IOCTL)) #define OUT(c,x) case c: outparam = (const char *) (x); break #define IN(c,x,tag) case c: *(x) = inparam. tag ; return 0 - int drive = (long)inode->i_bdev->bd_disk->private_data; + int drive = (long)bdev->bd_disk->private_data; int type = ITYPE(UDRS->fd_device); int i; int ret; @@ -3516,11 +3516,11 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, current_type[drive] = NULL; floppy_sizes[drive] = MAX_DISK_SIZE << 1; UDRS->keep_data = 0; - return invalidate_drive(inode->i_bdev); + return invalidate_drive(bdev); case FDSETPRM: case FDDEFPRM: return set_geometry(cmd, &inparam.g, - drive, type, inode->i_bdev); + drive, type, bdev); case FDGETPRM: ECALL(get_floppy_geometry(drive, type, (struct floppy_struct **) @@ -3551,7 +3551,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, case FDFMTEND: case FDFLUSH: LOCK_FDC(drive, 1); - return invalidate_drive(inode->i_bdev); + return invalidate_drive(bdev); case FDSETEMSGTRESH: UDP->max_errors.reporting = @@ -3659,9 +3659,9 @@ static void __init config_types(void) printk("\n"); } -static int floppy_release(struct inode *inode, struct file *filp) +static int floppy_release(struct gendisk *disk, fmode_t mode) { - int drive = (long)inode->i_bdev->bd_disk->private_data; + int drive = (long)disk->private_data; mutex_lock(&open_lock); if (UDRS->fd_ref < 0) @@ -3682,18 +3682,17 @@ static int floppy_release(struct inode *inode, struct file *filp) * /dev/PS0 etc), and disallows simultaneous access to the same * drive with different device numbers. */ -static int floppy_open(struct inode *inode, struct file *filp) +static int floppy_open(struct block_device *bdev, fmode_t mode) { - int drive = (long)inode->i_bdev->bd_disk->private_data; - int old_dev; + int drive = (long)bdev->bd_disk->private_data; + int old_dev, new_dev; int try; int res = -EBUSY; char *tmp; - filp->private_data = (void *)0; mutex_lock(&open_lock); old_dev = UDRS->fd_device; - if (opened_bdev[drive] && opened_bdev[drive] != inode->i_bdev) + if (opened_bdev[drive] && opened_bdev[drive] != bdev) goto out2; if (!UDRS->fd_ref && (UDP->flags & FD_BROKEN_DCL)) { @@ -3701,15 +3700,15 @@ static int floppy_open(struct inode *inode, struct file *filp) USETF(FD_VERIFY); } - if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (filp->f_flags & O_EXCL))) + if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (mode & FMODE_EXCL))) goto out2; - if (filp->f_flags & O_EXCL) + if (mode & FMODE_EXCL) UDRS->fd_ref = -1; else UDRS->fd_ref++; - opened_bdev[drive] = inode->i_bdev; + opened_bdev[drive] = bdev; res = -ENXIO; @@ -3744,31 +3743,26 @@ static int floppy_open(struct inode *inode, struct file *filp) } } - UDRS->fd_device = iminor(inode); - set_capacity(disks[drive], floppy_sizes[iminor(inode)]); - if (old_dev != -1 && old_dev != iminor(inode)) { + new_dev = MINOR(bdev->bd_dev); + UDRS->fd_device = new_dev; + set_capacity(disks[drive], floppy_sizes[new_dev]); + if (old_dev != -1 && old_dev != new_dev) { if (buffer_drive == drive) buffer_track = -1; } - /* Allow ioctls if we have write-permissions even if read-only open. - * Needed so that programs such as fdrawcmd still can work on write - * protected disks */ - if ((filp->f_mode & FMODE_WRITE) || !file_permission(filp, MAY_WRITE)) - filp->private_data = (void *)8; - if (UFDCS->rawcmd == 1) UFDCS->rawcmd = 2; - if (!(filp->f_flags & O_NDELAY)) { - if (filp->f_mode & 3) { + if (!(mode & FMODE_NDELAY)) { + if (mode & (FMODE_READ|FMODE_WRITE)) { UDRS->last_checked = 0; - check_disk_change(inode->i_bdev); + check_disk_change(bdev); if (UTESTF(FD_DISK_CHANGED)) goto out; } res = -EROFS; - if ((filp->f_mode & 2) && !(UTESTF(FD_DISK_WRITABLE))) + if ((mode & FMODE_WRITE) && !(UTESTF(FD_DISK_WRITABLE))) goto out; } mutex_unlock(&open_lock); @@ -3911,7 +3905,7 @@ static struct block_device_operations floppy_fops = { .owner = THIS_MODULE, .open = floppy_open, .release = floppy_release, - .ioctl = fd_ioctl, + .locked_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..3f09cd8bcc38 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -210,7 +210,7 @@ lo_do_transfer(struct loop_device *lo, int cmd, * space operations write_begin and write_end. */ static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec, - int bsize, loff_t pos, struct page *unused) + loff_t pos, struct page *unused) { struct file *file = lo->lo_backing_file; /* kudos to NFsckingS */ struct address_space *mapping = file->f_mapping; @@ -302,7 +302,7 @@ static int __do_lo_send_write(struct file *file, * filesystems. */ static int do_lo_send_direct_write(struct loop_device *lo, - struct bio_vec *bvec, int bsize, loff_t pos, struct page *page) + struct bio_vec *bvec, loff_t pos, struct page *page) { ssize_t bw = __do_lo_send_write(lo->lo_backing_file, kmap(bvec->bv_page) + bvec->bv_offset, @@ -326,7 +326,7 @@ static int do_lo_send_direct_write(struct loop_device *lo, * destination pages of the backing file. */ static int do_lo_send_write(struct loop_device *lo, struct bio_vec *bvec, - int bsize, loff_t pos, struct page *page) + loff_t pos, struct page *page) { int ret = lo_do_transfer(lo, WRITE, page, 0, bvec->bv_page, bvec->bv_offset, bvec->bv_len, pos >> 9); @@ -341,10 +341,9 @@ static int do_lo_send_write(struct loop_device *lo, struct bio_vec *bvec, return ret; } -static int lo_send(struct loop_device *lo, struct bio *bio, int bsize, - loff_t pos) +static int lo_send(struct loop_device *lo, struct bio *bio, loff_t pos) { - int (*do_lo_send)(struct loop_device *, struct bio_vec *, int, loff_t, + int (*do_lo_send)(struct loop_device *, struct bio_vec *, loff_t, struct page *page); struct bio_vec *bvec; struct page *page = NULL; @@ -362,7 +361,7 @@ static int lo_send(struct loop_device *lo, struct bio *bio, int bsize, } } bio_for_each_segment(bvec, bio, i) { - ret = do_lo_send(lo, bvec, bsize, pos, page); + ret = do_lo_send(lo, bvec, pos, page); if (ret < 0) break; pos += bvec->bv_len; @@ -478,7 +477,7 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio) pos = ((loff_t) bio->bi_sector << 9) + lo->lo_offset; if (bio_rw(bio) == WRITE) - ret = lo_send(lo, bio, lo->lo_blocksize, pos); + ret = lo_send(lo, bio, pos); else ret = lo_receive(lo, bio, lo->lo_blocksize, pos); return ret; @@ -652,8 +651,8 @@ static void do_loop_switch(struct loop_device *lo, struct switch_request *p) * This can only work if the loop device is used read-only, and if the * new backing store is the same size and type as the old backing store. */ -static int loop_change_fd(struct loop_device *lo, struct file *lo_file, - struct block_device *bdev, unsigned int arg) +static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, + unsigned int arg) { struct file *file, *old_file; struct inode *inode; @@ -712,7 +711,7 @@ static inline int is_loop_device(struct file *file) return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR; } -static int loop_set_fd(struct loop_device *lo, struct file *lo_file, +static int loop_set_fd(struct loop_device *lo, fmode_t mode, struct block_device *bdev, unsigned int arg) { struct file *file, *f; @@ -740,7 +739,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, while (is_loop_device(f)) { struct loop_device *l; - if (f->f_mapping->host->i_rdev == lo_file->f_mapping->host->i_rdev) + if (f->f_mapping->host->i_bdev == bdev) goto out_putf; l = f->f_mapping->host->i_bdev->bd_disk->private_data; @@ -786,7 +785,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, goto out_putf; } - if (!(lo_file->f_mode & FMODE_WRITE)) + if (!(mode & FMODE_WRITE)) lo_flags |= LO_FLAGS_READ_ONLY; set_device_ro(bdev, (lo_flags & LO_FLAGS_READ_ONLY) != 0); @@ -918,9 +917,11 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE); memset(lo->lo_crypt_name, 0, LO_NAME_SIZE); memset(lo->lo_file_name, 0, LO_NAME_SIZE); - invalidate_bdev(bdev); + if (bdev) + invalidate_bdev(bdev); set_capacity(lo->lo_disk, 0); - bd_set_size(bdev, 0); + if (bdev) + bd_set_size(bdev, 0); mapping_set_gfp_mask(filp->f_mapping, gfp); lo->lo_state = Lo_unbound; fput(filp); @@ -1137,22 +1138,22 @@ loop_get_status64(struct loop_device *lo, struct loop_info64 __user *arg) { return err; } -static int lo_ioctl(struct inode * inode, struct file * file, +static int lo_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct loop_device *lo = inode->i_bdev->bd_disk->private_data; + struct loop_device *lo = bdev->bd_disk->private_data; int err; mutex_lock(&lo->lo_ctl_mutex); switch (cmd) { case LOOP_SET_FD: - err = loop_set_fd(lo, file, inode->i_bdev, arg); + err = loop_set_fd(lo, mode, bdev, arg); break; case LOOP_CHANGE_FD: - err = loop_change_fd(lo, file, inode->i_bdev, arg); + err = loop_change_fd(lo, bdev, arg); break; case LOOP_CLR_FD: - err = loop_clr_fd(lo, inode->i_bdev); + err = loop_clr_fd(lo, bdev); break; case LOOP_SET_STATUS: err = loop_set_status_old(lo, (struct loop_info __user *) arg); @@ -1292,10 +1293,10 @@ loop_get_status_compat(struct loop_device *lo, return err; } -static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +static int lo_compat_ioctl(struct block_device *bdev, fmode_t mode, + unsigned int cmd, unsigned long arg) { - struct inode *inode = file->f_path.dentry->d_inode; - struct loop_device *lo = inode->i_bdev->bd_disk->private_data; + struct loop_device *lo = bdev->bd_disk->private_data; int err; switch(cmd) { @@ -1317,7 +1318,7 @@ static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long a arg = (unsigned long) compat_ptr(arg); case LOOP_SET_FD: case LOOP_CHANGE_FD: - err = lo_ioctl(inode, file, cmd, arg); + err = lo_ioctl(bdev, mode, cmd, arg); break; default: err = -ENOIOCTLCMD; @@ -1327,9 +1328,9 @@ static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long a } #endif -static int lo_open(struct inode *inode, struct file *file) +static int lo_open(struct block_device *bdev, fmode_t mode) { - struct loop_device *lo = inode->i_bdev->bd_disk->private_data; + struct loop_device *lo = bdev->bd_disk->private_data; mutex_lock(&lo->lo_ctl_mutex); lo->lo_refcnt++; @@ -1338,15 +1339,15 @@ static int lo_open(struct inode *inode, struct file *file) return 0; } -static int lo_release(struct inode *inode, struct file *file) +static int lo_release(struct gendisk *disk, fmode_t mode) { - struct loop_device *lo = inode->i_bdev->bd_disk->private_data; + struct loop_device *lo = disk->private_data; mutex_lock(&lo->lo_ctl_mutex); --lo->lo_refcnt; if ((lo->lo_flags & LO_FLAGS_AUTOCLEAR) && !lo->lo_refcnt) - loop_clr_fd(lo, inode->i_bdev); + loop_clr_fd(lo, NULL); mutex_unlock(&lo->lo_ctl_mutex); diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 9034ca585afd..d3a91cacee8c 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -557,10 +557,11 @@ static void do_nbd_request(struct request_queue * q) } } -static int nbd_ioctl(struct inode *inode, struct file *file, +static int nbd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct nbd_device *lo = inode->i_bdev->bd_disk->private_data; + struct nbd_device *lo = bdev->bd_disk->private_data; + struct file *file; int error; struct request sreq ; struct task_struct *thread; @@ -612,8 +613,7 @@ static int nbd_ioctl(struct inode *inode, struct file *file, error = -EINVAL; file = fget(arg); if (file) { - struct block_device *bdev = inode->i_bdev; - inode = file->f_path.dentry->d_inode; + struct inode *inode = file->f_path.dentry->d_inode; if (S_ISSOCK(inode->i_mode)) { lo->file = file; lo->sock = SOCKET_I(inode); @@ -628,14 +628,14 @@ static int nbd_ioctl(struct inode *inode, struct file *file, case NBD_SET_BLKSIZE: lo->blksize = arg; lo->bytesize &= ~(lo->blksize-1); - inode->i_bdev->bd_inode->i_size = lo->bytesize; - set_blocksize(inode->i_bdev, lo->blksize); + bdev->bd_inode->i_size = lo->bytesize; + set_blocksize(bdev, lo->blksize); set_capacity(lo->disk, lo->bytesize >> 9); return 0; case NBD_SET_SIZE: lo->bytesize = arg & ~(lo->blksize-1); - inode->i_bdev->bd_inode->i_size = lo->bytesize; - set_blocksize(inode->i_bdev, lo->blksize); + bdev->bd_inode->i_size = lo->bytesize; + set_blocksize(bdev, lo->blksize); set_capacity(lo->disk, lo->bytesize >> 9); return 0; case NBD_SET_TIMEOUT: @@ -643,8 +643,8 @@ static int nbd_ioctl(struct inode *inode, struct file *file, return 0; case NBD_SET_SIZE_BLOCKS: lo->bytesize = ((u64) arg) * lo->blksize; - inode->i_bdev->bd_inode->i_size = lo->bytesize; - set_blocksize(inode->i_bdev, lo->blksize); + bdev->bd_inode->i_size = lo->bytesize; + set_blocksize(bdev, lo->blksize); set_capacity(lo->disk, lo->bytesize >> 9); return 0; case NBD_DO_IT: @@ -666,10 +666,10 @@ static int nbd_ioctl(struct inode *inode, struct file *file, if (file) fput(file); lo->bytesize = 0; - inode->i_bdev->bd_inode->i_size = 0; + bdev->bd_inode->i_size = 0; set_capacity(lo->disk, 0); if (max_part > 0) - ioctl_by_bdev(inode->i_bdev, BLKRRPART, 0); + ioctl_by_bdev(bdev, BLKRRPART, 0); return lo->harderror; case NBD_CLEAR_QUE: /* @@ -680,7 +680,7 @@ static int nbd_ioctl(struct inode *inode, struct file *file, return 0; case NBD_PRINT_DEBUG: printk(KERN_INFO "%s: next = %p, prev = %p, head = %p\n", - inode->i_bdev->bd_disk->disk_name, + bdev->bd_disk->disk_name, lo->queue_head.next, lo->queue_head.prev, &lo->queue_head); return 0; @@ -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, + .locked_ioctl = nbd_ioctl, }; /* diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c index b8a994a2b013..e91d4b4b014f 100644 --- a/drivers/block/paride/pcd.c +++ b/drivers/block/paride/pcd.c @@ -223,23 +223,24 @@ static int pcd_warned; /* Have we logged a phase warning ? */ /* kernel glue structures */ -static int pcd_block_open(struct inode *inode, struct file *file) +static int pcd_block_open(struct block_device *bdev, fmode_t mode) { - struct pcd_unit *cd = inode->i_bdev->bd_disk->private_data; - return cdrom_open(&cd->info, inode, file); + struct pcd_unit *cd = bdev->bd_disk->private_data; + return cdrom_open(&cd->info, bdev, mode); } -static int pcd_block_release(struct inode *inode, struct file *file) +static int pcd_block_release(struct gendisk *disk, fmode_t mode) { - struct pcd_unit *cd = inode->i_bdev->bd_disk->private_data; - return cdrom_release(&cd->info, file); + struct pcd_unit *cd = disk->private_data; + cdrom_release(&cd->info, mode); + return 0; } -static int pcd_block_ioctl(struct inode *inode, struct file *file, +static int pcd_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, unsigned long arg) { - struct pcd_unit *cd = inode->i_bdev->bd_disk->private_data; - return cdrom_ioctl(file, &cd->info, inode, cmd, arg); + struct pcd_unit *cd = bdev->bd_disk->private_data; + return cdrom_ioctl(&cd->info, bdev, mode, cmd, arg); } static int pcd_block_media_changed(struct gendisk *disk) @@ -252,7 +253,7 @@ static struct block_device_operations pcd_bdops = { .owner = THIS_MODULE, .open = pcd_block_open, .release = pcd_block_release, - .ioctl = pcd_block_ioctl, + .locked_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..9299455b0af6 100644 --- a/drivers/block/paride/pd.c +++ b/drivers/block/paride/pd.c @@ -728,9 +728,9 @@ static int pd_special_command(struct pd_unit *disk, /* kernel glue structures */ -static int pd_open(struct inode *inode, struct file *file) +static int pd_open(struct block_device *bdev, fmode_t mode) { - struct pd_unit *disk = inode->i_bdev->bd_disk->private_data; + struct pd_unit *disk = bdev->bd_disk->private_data; disk->access++; @@ -758,10 +758,10 @@ static int pd_getgeo(struct block_device *bdev, struct hd_geometry *geo) return 0; } -static int pd_ioctl(struct inode *inode, struct file *file, +static int pd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct pd_unit *disk = inode->i_bdev->bd_disk->private_data; + struct pd_unit *disk = bdev->bd_disk->private_data; switch (cmd) { case CDROMEJECT: @@ -773,9 +773,9 @@ static int pd_ioctl(struct inode *inode, struct file *file, } } -static int pd_release(struct inode *inode, struct file *file) +static int pd_release(struct gendisk *p, fmode_t mode) { - struct pd_unit *disk = inode->i_bdev->bd_disk->private_data; + struct pd_unit *disk = p->private_data; if (!--disk->access && disk->removable) pd_special_command(disk, pd_door_unlock); @@ -809,7 +809,7 @@ static struct block_device_operations pd_fops = { .owner = THIS_MODULE, .open = pd_open, .release = pd_release, - .ioctl = pd_ioctl, + .locked_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 e7fe6ca97dd8..bef3b997ba3e 100644 --- a/drivers/block/paride/pf.c +++ b/drivers/block/paride/pf.c @@ -201,13 +201,13 @@ module_param_array(drive3, int, NULL, 0); #define ATAPI_READ_10 0x28 #define ATAPI_WRITE_10 0x2a -static int pf_open(struct inode *inode, struct file *file); +static int pf_open(struct block_device *bdev, fmode_t mode); static void do_pf_request(struct request_queue * q); -static int pf_ioctl(struct inode *inode, struct file *file, +static int pf_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg); static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo); -static int pf_release(struct inode *inode, struct file *file); +static int pf_release(struct gendisk *disk, fmode_t mode); static int pf_detect(void); static void do_pf_read(void); @@ -266,7 +266,7 @@ static struct block_device_operations pf_fops = { .owner = THIS_MODULE, .open = pf_open, .release = pf_release, - .ioctl = pf_ioctl, + .locked_ioctl = pf_ioctl, .getgeo = pf_getgeo, .media_changed = pf_check_media, }; @@ -296,16 +296,16 @@ static void __init pf_init_units(void) } } -static int pf_open(struct inode *inode, struct file *file) +static int pf_open(struct block_device *bdev, fmode_t mode) { - struct pf_unit *pf = inode->i_bdev->bd_disk->private_data; + struct pf_unit *pf = bdev->bd_disk->private_data; pf_identify(pf); if (pf->media_status == PF_NM) return -ENODEV; - if ((pf->media_status == PF_RO) && (file->f_mode & 2)) + if ((pf->media_status == PF_RO) && (mode & FMODE_WRITE)) return -EROFS; pf->access++; @@ -333,9 +333,9 @@ static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo) return 0; } -static int pf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +static int pf_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct pf_unit *pf = inode->i_bdev->bd_disk->private_data; + struct pf_unit *pf = bdev->bd_disk->private_data; if (cmd != CDROMEJECT) return -EINVAL; @@ -346,9 +346,9 @@ static int pf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un return 0; } -static int pf_release(struct inode *inode, struct file *file) +static int pf_release(struct gendisk *disk, fmode_t mode) { - struct pf_unit *pf = inode->i_bdev->bd_disk->private_data; + struct pf_unit *pf = disk->private_data; if (pf->access <= 0) return -EINVAL; diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c index 5ae229656eaa..1e4006e18f03 100644 --- a/drivers/block/paride/pt.c +++ b/drivers/block/paride/pt.c @@ -667,7 +667,7 @@ static int pt_open(struct inode *inode, struct file *file) goto out; err = -EROFS; - if ((!(tape->flags & PT_WRITE_OK)) && (file->f_mode & 2)) + if ((!(tape->flags & PT_WRITE_OK)) && (file->f_mode & FMODE_WRITE)) goto out; if (!(iminor(inode) & 128)) diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 195ca7c720f5..f20bf359b84f 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -2320,7 +2320,7 @@ static int pkt_open_write(struct pktcdvd_device *pd) /* * called at open time. */ -static int pkt_open_dev(struct pktcdvd_device *pd, int write) +static int pkt_open_dev(struct pktcdvd_device *pd, fmode_t write) { int ret; long lba; @@ -2332,7 +2332,7 @@ static int pkt_open_dev(struct pktcdvd_device *pd, int write) * so bdget() can't fail. */ bdget(pd->bdev->bd_dev); - if ((ret = blkdev_get(pd->bdev, FMODE_READ, O_RDONLY))) + if ((ret = blkdev_get(pd->bdev, FMODE_READ))) goto out; if ((ret = bd_claim(pd->bdev, pd))) @@ -2381,7 +2381,7 @@ static int pkt_open_dev(struct pktcdvd_device *pd, int write) out_unclaim: bd_release(pd->bdev); out_putdev: - blkdev_put(pd->bdev); + blkdev_put(pd->bdev, FMODE_READ); out: return ret; } @@ -2399,7 +2399,7 @@ static void pkt_release_dev(struct pktcdvd_device *pd, int flush) pkt_set_speed(pd, MAX_SPEED, MAX_SPEED); bd_release(pd->bdev); - blkdev_put(pd->bdev); + blkdev_put(pd->bdev, FMODE_READ); pkt_shrink_pktlist(pd); } @@ -2411,7 +2411,7 @@ static struct pktcdvd_device *pkt_find_dev_from_minor(int dev_minor) return pkt_devs[dev_minor]; } -static int pkt_open(struct inode *inode, struct file *file) +static int pkt_open(struct block_device *bdev, fmode_t mode) { struct pktcdvd_device *pd = NULL; int ret; @@ -2419,7 +2419,7 @@ static int pkt_open(struct inode *inode, struct file *file) VPRINTK(DRIVER_NAME": entering open\n"); mutex_lock(&ctl_mutex); - pd = pkt_find_dev_from_minor(iminor(inode)); + pd = pkt_find_dev_from_minor(MINOR(bdev->bd_dev)); if (!pd) { ret = -ENODEV; goto out; @@ -2428,20 +2428,20 @@ static int pkt_open(struct inode *inode, struct file *file) pd->refcnt++; if (pd->refcnt > 1) { - if ((file->f_mode & FMODE_WRITE) && + if ((mode & FMODE_WRITE) && !test_bit(PACKET_WRITABLE, &pd->flags)) { ret = -EBUSY; goto out_dec; } } else { - ret = pkt_open_dev(pd, file->f_mode & FMODE_WRITE); + ret = pkt_open_dev(pd, mode & FMODE_WRITE); if (ret) goto out_dec; /* * needed here as well, since ext2 (among others) may change * the blocksize at mount time */ - set_blocksize(inode->i_bdev, CD_FRAMESIZE); + set_blocksize(bdev, CD_FRAMESIZE); } mutex_unlock(&ctl_mutex); @@ -2455,9 +2455,9 @@ out: return ret; } -static int pkt_close(struct inode *inode, struct file *file) +static int pkt_close(struct gendisk *disk, fmode_t mode) { - struct pktcdvd_device *pd = inode->i_bdev->bd_disk->private_data; + struct pktcdvd_device *pd = disk->private_data; int ret = 0; mutex_lock(&ctl_mutex); @@ -2765,7 +2765,7 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev) bdev = bdget(dev); if (!bdev) return -ENOMEM; - ret = blkdev_get(bdev, FMODE_READ, O_RDONLY | O_NONBLOCK); + ret = blkdev_get(bdev, FMODE_READ | FMODE_NDELAY); if (ret) return ret; @@ -2790,19 +2790,28 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev) return 0; out_mem: - blkdev_put(bdev); + blkdev_put(bdev, FMODE_READ|FMODE_WRITE); /* This is safe: open() is still holding a reference. */ module_put(THIS_MODULE); return ret; } -static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +static int pkt_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct pktcdvd_device *pd = inode->i_bdev->bd_disk->private_data; + struct pktcdvd_device *pd = bdev->bd_disk->private_data; - VPRINTK("pkt_ioctl: cmd %x, dev %d:%d\n", cmd, imajor(inode), iminor(inode)); + VPRINTK("pkt_ioctl: cmd %x, dev %d:%d\n", cmd, + MAJOR(bdev->bd_dev), MINOR(bdev->bd_dev)); switch (cmd) { + case CDROMEJECT: + /* + * The door gets locked when the device is opened, so we + * have to unlock it or else the eject command fails. + */ + if (pd->refcnt == 1) + pkt_lock_door(pd, 0); + /* fallthru */ /* * forward selected CDROM ioctls to CD-ROM, for UDF */ @@ -2811,16 +2820,7 @@ static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u case CDROM_LAST_WRITTEN: case CDROM_SEND_PACKET: case SCSI_IOCTL_SEND_COMMAND: - return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg); - - case CDROMEJECT: - /* - * The door gets locked when the device is opened, so we - * have to unlock it or else the eject command fails. - */ - if (pd->refcnt == 1) - pkt_lock_door(pd, 0); - return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg); + return __blkdev_driver_ioctl(pd->bdev, mode, cmd, arg); default: VPRINTK(DRIVER_NAME": Unknown ioctl for %s (%x)\n", pd->name, cmd); @@ -2849,7 +2849,7 @@ static struct block_device_operations pktcdvd_ops = { .owner = THIS_MODULE, .open = pkt_open, .release = pkt_close, - .ioctl = pkt_ioctl, + .locked_ioctl = pkt_ioctl, .media_changed = pkt_media_changed, }; @@ -2975,7 +2975,7 @@ static int pkt_remove_dev(dev_t pkt_dev) pkt_debugfs_dev_remove(pd); pkt_sysfs_dev_remove(pd); - blkdev_put(pd->bdev); + blkdev_put(pd->bdev, FMODE_READ|FMODE_WRITE); remove_proc_entry(pd->name, pkt_proc); DPRINTK(DRIVER_NAME": writer %s unmapped\n", pd->name); diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c index 730ccea78e45..612965307ba0 100644 --- a/drivers/block/swim3.c +++ b/drivers/block/swim3.c @@ -244,10 +244,10 @@ static int grab_drive(struct floppy_state *fs, enum swim_state state, int interruptible); static void release_drive(struct floppy_state *fs); static int fd_eject(struct floppy_state *fs); -static int floppy_ioctl(struct inode *inode, struct file *filp, +static int floppy_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long param); -static int floppy_open(struct inode *inode, struct file *filp); -static int floppy_release(struct inode *inode, struct file *filp); +static int floppy_open(struct block_device *bdev, fmode_t mode); +static int floppy_release(struct gendisk *disk, fmode_t mode); static int floppy_check_change(struct gendisk *disk); static int floppy_revalidate(struct gendisk *disk); @@ -839,10 +839,10 @@ static int fd_eject(struct floppy_state *fs) static struct floppy_struct floppy_type = { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,NULL }; /* 7 1.44MB 3.5" */ -static int floppy_ioctl(struct inode *inode, struct file *filp, +static int floppy_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long param) { - struct floppy_state *fs = inode->i_bdev->bd_disk->private_data; + struct floppy_state *fs = bdev->bd_disk->private_data; int err; if ((cmd & 0x80) && !capable(CAP_SYS_ADMIN)) @@ -868,9 +868,9 @@ static int floppy_ioctl(struct inode *inode, struct file *filp, return -ENOTTY; } -static int floppy_open(struct inode *inode, struct file *filp) +static int floppy_open(struct block_device *bdev, fmode_t mode) { - struct floppy_state *fs = inode->i_bdev->bd_disk->private_data; + struct floppy_state *fs = bdev->bd_disk->private_data; struct swim3 __iomem *sw = fs->swim3; int n, err = 0; @@ -904,17 +904,17 @@ static int floppy_open(struct inode *inode, struct file *filp) swim3_action(fs, SETMFM); swim3_select(fs, RELAX); - } else if (fs->ref_count == -1 || filp->f_flags & O_EXCL) + } else if (fs->ref_count == -1 || mode & FMODE_EXCL) return -EBUSY; - if (err == 0 && (filp->f_flags & O_NDELAY) == 0 - && (filp->f_mode & 3)) { - check_disk_change(inode->i_bdev); + if (err == 0 && (mode & FMODE_NDELAY) == 0 + && (mode & (FMODE_READ|FMODE_WRITE))) { + check_disk_change(bdev); if (fs->ejected) err = -ENXIO; } - if (err == 0 && (filp->f_mode & 2)) { + if (err == 0 && (mode & FMODE_WRITE)) { if (fs->write_prot < 0) fs->write_prot = swim3_readbit(fs, WRITE_PROT); if (fs->write_prot) @@ -930,7 +930,7 @@ static int floppy_open(struct inode *inode, struct file *filp) return err; } - if (filp->f_flags & O_EXCL) + if (mode & FMODE_EXCL) fs->ref_count = -1; else ++fs->ref_count; @@ -938,9 +938,9 @@ static int floppy_open(struct inode *inode, struct file *filp) return 0; } -static int floppy_release(struct inode *inode, struct file *filp) +static int floppy_release(struct gendisk *disk, fmode_t mode) { - struct floppy_state *fs = inode->i_bdev->bd_disk->private_data; + struct floppy_state *fs = disk->private_data; struct swim3 __iomem *sw = fs->swim3; if (fs->ref_count > 0 && --fs->ref_count == 0) { swim3_action(fs, MOTOR_OFF); @@ -1000,7 +1000,7 @@ static int floppy_revalidate(struct gendisk *disk) static struct block_device_operations floppy_fops = { .open = floppy_open, .release = floppy_release, - .ioctl = floppy_ioctl, + .locked_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 f60e41833f69..fccac18d3111 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c @@ -1667,10 +1667,9 @@ static void ub_revalidate(struct ub_dev *sc, struct ub_lun *lun) * This is mostly needed to keep refcounting, but also to support * media checks on removable media drives. */ -static int ub_bd_open(struct inode *inode, struct file *filp) +static int ub_bd_open(struct block_device *bdev, fmode_t mode) { - struct gendisk *disk = inode->i_bdev->bd_disk; - struct ub_lun *lun = disk->private_data; + struct ub_lun *lun = bdev->bd_disk->private_data; struct ub_dev *sc = lun->udev; unsigned long flags; int rc; @@ -1684,19 +1683,19 @@ static int ub_bd_open(struct inode *inode, struct file *filp) spin_unlock_irqrestore(&ub_lock, flags); if (lun->removable || lun->readonly) - check_disk_change(inode->i_bdev); + check_disk_change(bdev); /* * The sd.c considers ->media_present and ->changed not equivalent, * under some pretty murky conditions (a failure of READ CAPACITY). * We may need it one day. */ - if (lun->removable && lun->changed && !(filp->f_flags & O_NDELAY)) { + if (lun->removable && lun->changed && !(mode & FMODE_NDELAY)) { rc = -ENOMEDIUM; goto err_open; } - if (lun->readonly && (filp->f_mode & FMODE_WRITE)) { + if (lun->readonly && (mode & FMODE_WRITE)) { rc = -EROFS; goto err_open; } @@ -1710,9 +1709,8 @@ err_open: /* */ -static int ub_bd_release(struct inode *inode, struct file *filp) +static int ub_bd_release(struct gendisk *disk, fmode_t mode) { - struct gendisk *disk = inode->i_bdev->bd_disk; struct ub_lun *lun = disk->private_data; struct ub_dev *sc = lun->udev; @@ -1723,13 +1721,13 @@ static int ub_bd_release(struct inode *inode, struct file *filp) /* * The ioctl interface. */ -static int ub_bd_ioctl(struct inode *inode, struct file *filp, +static int ub_bd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct gendisk *disk = inode->i_bdev->bd_disk; + struct gendisk *disk = bdev->bd_disk; void __user *usermem = (void __user *) arg; - return scsi_cmd_ioctl(filp, disk->queue, disk, cmd, usermem); + return scsi_cmd_ioctl(disk->queue, disk, mode, cmd, usermem); } /* @@ -1793,7 +1791,7 @@ static struct block_device_operations ub_bd_fops = { .owner = THIS_MODULE, .open = ub_bd_open, .release = ub_bd_release, - .ioctl = ub_bd_ioctl, + .locked_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..ecccf65dce2f 100644 --- a/drivers/block/viodasd.c +++ b/drivers/block/viodasd.c @@ -130,15 +130,15 @@ struct viodasd_device { /* * External open entry point. */ -static int viodasd_open(struct inode *ino, struct file *fil) +static int viodasd_open(struct block_device *bdev, fmode_t mode) { - struct viodasd_device *d = ino->i_bdev->bd_disk->private_data; + struct viodasd_device *d = bdev->bd_disk->private_data; HvLpEvent_Rc hvrc; struct viodasd_waitevent we; u16 flags = 0; if (d->read_only) { - if ((fil != NULL) && (fil->f_mode & FMODE_WRITE)) + if (mode & FMODE_WRITE) return -EROFS; flags = vioblockflags_ro; } @@ -179,9 +179,9 @@ static int viodasd_open(struct inode *ino, struct file *fil) /* * External release entry point. */ -static int viodasd_release(struct inode *ino, struct file *fil) +static int viodasd_release(struct gendisk *disk, fmode_t mode) { - struct viodasd_device *d = ino->i_bdev->bd_disk->private_data; + struct viodasd_device *d = disk->private_data; HvLpEvent_Rc hvrc; /* Send the event to OS/400. We DON'T expect a response */ diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 6ec5fc052786..85d79a02d487 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -146,11 +146,11 @@ static void do_virtblk_request(struct request_queue *q) vblk->vq->vq_ops->kick(vblk->vq); } -static int virtblk_ioctl(struct inode *inode, struct file *filp, +static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, unsigned long data) { - return scsi_cmd_ioctl(filp, inode->i_bdev->bd_disk->queue, - inode->i_bdev->bd_disk, cmd, + return scsi_cmd_ioctl(bdev->bd_disk->queue, + bdev->bd_disk, mode, cmd, (void __user *)data); } @@ -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, + .locked_ioctl = virtblk_ioctl, .owner = THIS_MODULE, .getgeo = virtblk_getgeo, }; diff --git a/drivers/block/xd.c b/drivers/block/xd.c index 624d30f7da3f..64b496fce98b 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, + .locked_ioctl = xd_ioctl, .getgeo = xd_getgeo, }; static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int); @@ -343,7 +343,7 @@ static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo) } /* xd_ioctl: handle device ioctl's */ -static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg) +static int xd_ioctl(struct block_device *bdev, fmode_t mode, u_int cmd, u_long arg) { switch (cmd) { case HDIO_SET_DMA: diff --git a/drivers/block/xd.h b/drivers/block/xd.h index cffd44a20383..37cacef16e93 100644 --- a/drivers/block/xd.h +++ b/drivers/block/xd.h @@ -105,7 +105,7 @@ static u_char xd_detect (u_char *controller, unsigned int *address); static u_char xd_initdrives (void (*init_drive)(u_char drive)); static void do_xd_request (struct request_queue * q); -static int xd_ioctl (struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg); +static int xd_ioctl (struct block_device *bdev,fmode_t mode,unsigned int cmd,unsigned long arg); static int xd_readwrite (u_char operation,XD_INFO *disk,char *buffer,u_int block,u_int count); static void xd_recalibrate (u_char drive); diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 1a50ae70f716..b220c686089d 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -156,11 +156,10 @@ static int blkif_getgeo(struct block_device *bd, struct hd_geometry *hg) return 0; } -static int blkif_ioctl(struct inode *inode, struct file *filep, +static int blkif_ioctl(struct block_device *bdev, fmode_t mode, unsigned command, unsigned long argument) { - struct blkfront_info *info = - inode->i_bdev->bd_disk->private_data; + struct blkfront_info *info = bdev->bd_disk->private_data; int i; dev_dbg(&info->xbdev->dev, "command: 0x%x, argument: 0x%lx\n", @@ -1014,16 +1013,16 @@ static int blkfront_is_ready(struct xenbus_device *dev) return info->is_ready; } -static int blkif_open(struct inode *inode, struct file *filep) +static int blkif_open(struct block_device *bdev, fmode_t mode) { - struct blkfront_info *info = inode->i_bdev->bd_disk->private_data; + struct blkfront_info *info = bdev->bd_disk->private_data; info->users++; return 0; } -static int blkif_release(struct inode *inode, struct file *filep) +static int blkif_release(struct gendisk *disk, fmode_t mode) { - struct blkfront_info *info = inode->i_bdev->bd_disk->private_data; + struct blkfront_info *info = disk->private_data; info->users--; if (info->users == 0) { /* Check whether we have been instructed to close. We will @@ -1044,7 +1043,7 @@ static struct block_device_operations xlvbd_block_fops = .open = blkif_open, .release = blkif_release, .getgeo = blkif_getgeo, - .ioctl = blkif_ioctl, + .locked_ioctl = blkif_ioctl, }; diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index 4a7a059ebaf7..ecab9e67d47a 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c @@ -870,25 +870,24 @@ static int ace_revalidate_disk(struct gendisk *gd) return ace->id_result; } -static int ace_open(struct inode *inode, struct file *filp) +static int ace_open(struct block_device *bdev, fmode_t mode) { - struct ace_device *ace = inode->i_bdev->bd_disk->private_data; + struct ace_device *ace = bdev->bd_disk->private_data; unsigned long flags; dev_dbg(ace->dev, "ace_open() users=%i\n", ace->users + 1); - filp->private_data = ace; spin_lock_irqsave(&ace->lock, flags); ace->users++; spin_unlock_irqrestore(&ace->lock, flags); - check_disk_change(inode->i_bdev); + check_disk_change(bdev); return 0; } -static int ace_release(struct inode *inode, struct file *filp) +static int ace_release(struct gendisk *disk, fmode_t mode) { - struct ace_device *ace = inode->i_bdev->bd_disk->private_data; + struct ace_device *ace = disk->private_data; unsigned long flags; u16 val; diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c index be20a67f1fa8..80754cdd3119 100644 --- a/drivers/block/z2ram.c +++ b/drivers/block/z2ram.c @@ -137,8 +137,7 @@ get_chipram( void ) return; } -static int -z2_open( struct inode *inode, struct file *filp ) +static int z2_open(struct block_device *bdev, fmode_t mode) { int device; int max_z2_map = ( Z2RAM_SIZE / Z2RAM_CHUNKSIZE ) * @@ -147,7 +146,7 @@ z2_open( struct inode *inode, struct file *filp ) sizeof( z2ram_map[0] ); int rc = -ENOMEM; - device = iminor(inode); + device = MINOR(bdev->bd_dev); if ( current_device != -1 && current_device != device ) { @@ -299,7 +298,7 @@ err_out: } static int -z2_release( struct inode *inode, struct file *filp ) +z2_release(struct gendisk *disk, fmode_t mode) { if ( current_device == -1 ) return 0; diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index d47f2f80accd..d16b02423d61 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -973,7 +973,7 @@ static int cdrom_close_write(struct cdrom_device_info *cdi) * is in their own interest: device control becomes a lot easier * this way. */ -int cdrom_open(struct cdrom_device_info *cdi, struct inode *ip, struct file *fp) +int cdrom_open(struct cdrom_device_info *cdi, struct block_device *bdev, fmode_t mode) { int ret; @@ -982,14 +982,14 @@ int cdrom_open(struct cdrom_device_info *cdi, struct inode *ip, struct file *fp) /* if this was a O_NONBLOCK open and we should honor the flags, * do a quick open without drive/disc integrity checks. */ cdi->use_count++; - if ((fp->f_flags & O_NONBLOCK) && (cdi->options & CDO_USE_FFLAGS)) { + if ((mode & FMODE_NDELAY) && (cdi->options & CDO_USE_FFLAGS)) { ret = cdi->ops->open(cdi, 1); } else { ret = open_for_data(cdi); if (ret) goto err; cdrom_mmc3_profile(cdi); - if (fp->f_mode & FMODE_WRITE) { + if (mode & FMODE_WRITE) { ret = -EROFS; if (cdrom_open_write(cdi)) goto err_release; @@ -1007,7 +1007,7 @@ int cdrom_open(struct cdrom_device_info *cdi, struct inode *ip, struct file *fp) cdi->name, cdi->use_count); /* Do this on open. Don't wait for mount, because they might not be mounting, but opening with O_NONBLOCK */ - check_disk_change(ip->i_bdev); + check_disk_change(bdev); return 0; err_release: if (CDROM_CAN(CDC_LOCK) && cdi->options & CDO_LOCK) { @@ -1184,7 +1184,7 @@ static int check_for_audio_disc(struct cdrom_device_info * cdi, return 0; } -int cdrom_release(struct cdrom_device_info *cdi, struct file *fp) +void cdrom_release(struct cdrom_device_info *cdi, fmode_t mode) { struct cdrom_device_ops *cdo = cdi->ops; int opened_for_data; @@ -1205,7 +1205,7 @@ int cdrom_release(struct cdrom_device_info *cdi, struct file *fp) } opened_for_data = !(cdi->options & CDO_USE_FFLAGS) || - !(fp && fp->f_flags & O_NONBLOCK); + !(mode & FMODE_NDELAY); /* * flush cache on last write release @@ -1219,7 +1219,6 @@ int cdrom_release(struct cdrom_device_info *cdi, struct file *fp) cdi->options & CDO_AUTO_EJECT && CDROM_CAN(CDC_OPEN_TRAY)) cdo->tray_move(cdi, 1); } - return 0; } static int cdrom_read_mech_status(struct cdrom_device_info *cdi, @@ -2662,17 +2661,17 @@ static int cdrom_ioctl_audioctl(struct cdrom_device_info *cdi, * these days. * ATAPI / SCSI specific code now mainly resides in mmc_ioctl(). */ -int cdrom_ioctl(struct file * file, struct cdrom_device_info *cdi, - struct inode *ip, unsigned int cmd, unsigned long arg) +int cdrom_ioctl(struct cdrom_device_info *cdi, struct block_device *bdev, + fmode_t mode, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; int ret; - struct gendisk *disk = ip->i_bdev->bd_disk; + struct gendisk *disk = bdev->bd_disk; /* * Try the generic SCSI command ioctl's first. */ - ret = scsi_cmd_ioctl(file, disk->queue, disk, cmd, argp); + ret = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, argp); if (ret != -ENOTTY) return ret; @@ -2696,7 +2695,7 @@ int cdrom_ioctl(struct file * file, struct cdrom_device_info *cdi, case CDROM_SELECT_DISC: return cdrom_ioctl_select_disc(cdi, arg); case CDROMRESET: - return cdrom_ioctl_reset(cdi, ip->i_bdev); + return cdrom_ioctl_reset(cdi, bdev); case CDROM_LOCKDOOR: return cdrom_ioctl_lock_door(cdi, arg); case CDROM_DEBUG: diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c index d6ba77a2dd7b..9aaa86b232b1 100644 --- a/drivers/cdrom/gdrom.c +++ b/drivers/cdrom/gdrom.c @@ -490,14 +490,14 @@ static struct cdrom_device_ops gdrom_ops = { .n_minors = 1, }; -static int gdrom_bdops_open(struct inode *inode, struct file *file) +static int gdrom_bdops_open(struct block_device *bdev, fmode_t mode) { - return cdrom_open(gd.cd_info, inode, file); + return cdrom_open(gd.cd_info, bdev, mode); } -static int gdrom_bdops_release(struct inode *inode, struct file *file) +static int gdrom_bdops_release(struct block_device *bdev, fmode_t mode) { - return cdrom_release(gd.cd_info, file); + return cdrom_release(gd.cd_info, mode); } static int gdrom_bdops_mediachanged(struct gendisk *disk) @@ -505,10 +505,10 @@ static int gdrom_bdops_mediachanged(struct gendisk *disk) return cdrom_media_changed(gd.cd_info); } -static int gdrom_bdops_ioctl(struct inode *inode, struct file *file, +static int gdrom_bdops_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, unsigned long arg) { - return cdrom_ioctl(file, gd.cd_info, inode, cmd, arg); + return cdrom_ioctl(gd.cd_info, bdev, mode, cmd, arg); } static struct block_device_operations gdrom_bdops = { @@ -516,7 +516,7 @@ static struct block_device_operations gdrom_bdops = { .open = gdrom_bdops_open, .release = gdrom_bdops_release, .media_changed = gdrom_bdops_mediachanged, - .ioctl = gdrom_bdops_ioctl, + .locked_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 031e0e1a1a3b..13929356135c 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c @@ -151,23 +151,24 @@ static const struct file_operations proc_viocd_operations = { .release = single_release, }; -static int viocd_blk_open(struct inode *inode, struct file *file) +static int viocd_blk_open(struct block_device *bdev, fmode_t mode) { - struct disk_info *di = inode->i_bdev->bd_disk->private_data; - return cdrom_open(&di->viocd_info, inode, file); + struct disk_info *di = bdev->bd_disk->private_data; + return cdrom_open(&di->viocd_info, bdev, mode); } -static int viocd_blk_release(struct inode *inode, struct file *file) +static int viocd_blk_release(struct gendisk *disk, fmode_t mode) { - struct disk_info *di = inode->i_bdev->bd_disk->private_data; - return cdrom_release(&di->viocd_info, file); + struct disk_info *di = disk->private_data; + cdrom_release(&di->viocd_info, mode); + return 0; } -static int viocd_blk_ioctl(struct inode *inode, struct file *file, +static int viocd_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, unsigned long arg) { - struct disk_info *di = inode->i_bdev->bd_disk->private_data; - return cdrom_ioctl(file, &di->viocd_info, inode, cmd, arg); + struct disk_info *di = bdev->bd_disk->private_data; + return cdrom_ioctl(&di->viocd_info, bdev, mode, cmd, arg); } static int viocd_blk_media_changed(struct gendisk *disk) @@ -180,7 +181,7 @@ struct block_device_operations viocd_fops = { .owner = THIS_MODULE, .open = viocd_blk_open, .release = viocd_blk_release, - .ioctl = viocd_blk_ioctl, + .locked_ioctl = viocd_blk_ioctl, .media_changed = viocd_blk_media_changed, }; diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c index 39f6357e3b5d..8054ee839b3c 100644 --- a/drivers/char/nvram.c +++ b/drivers/char/nvram.c @@ -338,7 +338,7 @@ nvram_open(struct inode *inode, struct file *file) if ((nvram_open_cnt && (file->f_flags & O_EXCL)) || (nvram_open_mode & NVRAM_EXCL) || - ((file->f_mode & 2) && (nvram_open_mode & NVRAM_WRITE))) { + ((file->f_mode & FMODE_WRITE) && (nvram_open_mode & NVRAM_WRITE))) { spin_unlock(&nvram_state_lock); unlock_kernel(); return -EBUSY; @@ -346,7 +346,7 @@ nvram_open(struct inode *inode, struct file *file) if (file->f_flags & O_EXCL) nvram_open_mode |= NVRAM_EXCL; - if (file->f_mode & 2) + if (file->f_mode & FMODE_WRITE) nvram_open_mode |= NVRAM_WRITE; nvram_open_cnt++; @@ -366,7 +366,7 @@ nvram_release(struct inode *inode, struct file *file) /* if only one instance is open, clear the EXCL bit */ if (nvram_open_mode & NVRAM_EXCL) nvram_open_mode &= ~NVRAM_EXCL; - if (file->f_mode & 2) + if (file->f_mode & FMODE_WRITE) nvram_open_mode &= ~NVRAM_WRITE; spin_unlock(&nvram_state_lock); diff --git a/drivers/char/raw.c b/drivers/char/raw.c index e139372d0e69..96adf28a17e4 100644 --- a/drivers/char/raw.c +++ b/drivers/char/raw.c @@ -65,7 +65,7 @@ static int raw_open(struct inode *inode, struct file *filp) if (!bdev) goto out; igrab(bdev->bd_inode); - err = blkdev_get(bdev, filp->f_mode, 0); + err = blkdev_get(bdev, filp->f_mode); if (err) goto out; err = bd_claim(bdev, raw_open); @@ -87,7 +87,7 @@ static int raw_open(struct inode *inode, struct file *filp) out2: bd_release(bdev); out1: - blkdev_put(bdev); + blkdev_put(bdev, filp->f_mode); out: mutex_unlock(&raw_mutex); return err; @@ -112,7 +112,7 @@ static int raw_release(struct inode *inode, struct file *filp) mutex_unlock(&raw_mutex); bd_release(bdev); - blkdev_put(bdev); + blkdev_put(bdev, filp->f_mode); return 0; } @@ -125,7 +125,7 @@ raw_ioctl(struct inode *inode, struct file *filp, { struct block_device *bdev = filp->private_data; - return blkdev_ioctl(bdev->bd_inode, NULL, command, arg); + return blkdev_ioctl(bdev, 0, command, arg); } static void bind_device(struct raw_config_request *rq) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 13265a8827da..133afd09843c 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -2089,17 +2089,15 @@ static ide_driver_t ide_cdrom_driver = { #endif }; -static int idecd_open(struct inode *inode, struct file *file) +static int idecd_open(struct block_device *bdev, fmode_t mode) { - struct gendisk *disk = inode->i_bdev->bd_disk; - struct cdrom_info *info; + struct cdrom_info *info = ide_cd_get(bdev->bd_disk); int rc = -ENOMEM; - info = ide_cd_get(disk); if (!info) return -ENXIO; - rc = cdrom_open(&info->devinfo, inode, file); + rc = cdrom_open(&info->devinfo, bdev, mode); if (rc < 0) ide_cd_put(info); @@ -2107,12 +2105,11 @@ static int idecd_open(struct inode *inode, struct file *file) return rc; } -static int idecd_release(struct inode *inode, struct file *file) +static int idecd_release(struct gendisk *disk, fmode_t mode) { - struct gendisk *disk = inode->i_bdev->bd_disk; struct cdrom_info *info = ide_drv_g(disk, cdrom_info); - cdrom_release(&info->devinfo, file); + cdrom_release(&info->devinfo, mode); ide_cd_put(info); @@ -2158,10 +2155,9 @@ static int idecd_get_spindown(struct cdrom_device_info *cdi, unsigned long arg) return 0; } -static int idecd_ioctl(struct inode *inode, struct file *file, +static int idecd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct block_device *bdev = inode->i_bdev; struct cdrom_info *info = ide_drv_g(bdev->bd_disk, cdrom_info); int err; @@ -2174,9 +2170,9 @@ static int idecd_ioctl(struct inode *inode, struct file *file, break; } - err = generic_ide_ioctl(info->drive, file, bdev, cmd, arg); + err = generic_ide_ioctl(info->drive, bdev, cmd, arg); if (err == -EINVAL) - err = cdrom_ioctl(file, &info->devinfo, inode, cmd, arg); + err = cdrom_ioctl(&info->devinfo, bdev, mode, cmd, arg); return err; } @@ -2201,7 +2197,7 @@ static struct block_device_operations idecd_ops = { .owner = THIS_MODULE, .open = idecd_open, .release = idecd_release, - .ioctl = idecd_ioctl, + .locked_ioctl = idecd_ioctl, .media_changed = idecd_media_changed, .revalidate_disk = idecd_revalidate_disk }; diff --git a/drivers/ide/ide-disk.h b/drivers/ide/ide-disk.h index b234b0feaf7b..d511dab7c4aa 100644 --- a/drivers/ide/ide-disk.h +++ b/drivers/ide/ide-disk.h @@ -13,7 +13,7 @@ ide_decl_devset(wcache); ide_decl_devset(acoustic); /* ide-disk_ioctl.c */ -int ide_disk_ioctl(ide_drive_t *, struct inode *, struct file *, unsigned int, +int ide_disk_ioctl(ide_drive_t *, struct block_device *, fmode_t, unsigned int, unsigned long); #ifdef CONFIG_IDE_PROC_FS diff --git a/drivers/ide/ide-disk_ioctl.c b/drivers/ide/ide-disk_ioctl.c index a49698bcf966..7b783dd7c0be 100644 --- a/drivers/ide/ide-disk_ioctl.c +++ b/drivers/ide/ide-disk_ioctl.c @@ -13,15 +13,14 @@ static const struct ide_ioctl_devset ide_disk_ioctl_settings[] = { { 0 } }; -int ide_disk_ioctl(ide_drive_t *drive, struct inode *inode, struct file *file, +int ide_disk_ioctl(ide_drive_t *drive, struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct block_device *bdev = inode->i_bdev; int err; err = ide_setting_ioctl(drive, bdev, cmd, arg, ide_disk_ioctl_settings); if (err != -EOPNOTSUPP) return err; - return generic_ide_ioctl(drive, file, bdev, cmd, arg); + return generic_ide_ioctl(drive, bdev, cmd, arg); } diff --git a/drivers/ide/ide-floppy.h b/drivers/ide/ide-floppy.h index c17124dd6079..6dd2beb48434 100644 --- a/drivers/ide/ide-floppy.h +++ b/drivers/ide/ide-floppy.h @@ -23,8 +23,8 @@ void ide_floppy_create_mode_sense_cmd(struct ide_atapi_pc *, u8); void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *); /* ide-floppy_ioctl.c */ -int ide_floppy_ioctl(ide_drive_t *, struct inode *, struct file *, unsigned int, - unsigned long); +int ide_floppy_ioctl(ide_drive_t *, struct block_device *, fmode_t, + unsigned int, unsigned long); #ifdef CONFIG_IDE_PROC_FS /* ide-floppy_proc.c */ diff --git a/drivers/ide/ide-floppy_ioctl.c b/drivers/ide/ide-floppy_ioctl.c index 409e4c15f9b7..2bc51ff73fee 100644 --- a/drivers/ide/ide-floppy_ioctl.c +++ b/drivers/ide/ide-floppy_ioctl.c @@ -241,7 +241,7 @@ static int ide_floppy_lockdoor(ide_drive_t *drive, struct ide_atapi_pc *pc, return 0; } -static int ide_floppy_format_ioctl(ide_drive_t *drive, struct file *file, +static int ide_floppy_format_ioctl(ide_drive_t *drive, fmode_t mode, unsigned int cmd, void __user *argp) { switch (cmd) { @@ -250,7 +250,7 @@ static int ide_floppy_format_ioctl(ide_drive_t *drive, struct file *file, case IDEFLOPPY_IOCTL_FORMAT_GET_CAPACITY: return ide_floppy_get_format_capacities(drive, argp); case IDEFLOPPY_IOCTL_FORMAT_START: - if (!(file->f_mode & 2)) + if (!(mode & FMODE_WRITE)) return -EPERM; return ide_floppy_format_unit(drive, (int __user *)argp); case IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS: @@ -260,10 +260,9 @@ static int ide_floppy_format_ioctl(ide_drive_t *drive, struct file *file, } } -int ide_floppy_ioctl(ide_drive_t *drive, struct inode *inode, - struct file *file, unsigned int cmd, unsigned long arg) +int ide_floppy_ioctl(ide_drive_t *drive, struct block_device *bdev, + fmode_t mode, unsigned int cmd, unsigned long arg) { - struct block_device *bdev = inode->i_bdev; struct ide_atapi_pc pc; void __user *argp = (void __user *)arg; int err; @@ -271,7 +270,7 @@ int ide_floppy_ioctl(ide_drive_t *drive, struct inode *inode, if (cmd == CDROMEJECT || cmd == CDROM_LOCKDOOR) return ide_floppy_lockdoor(drive, &pc, arg, cmd); - err = ide_floppy_format_ioctl(drive, file, cmd, argp); + err = ide_floppy_format_ioctl(drive, mode, cmd, argp); if (err != -ENOTTY) return err; @@ -280,11 +279,11 @@ int ide_floppy_ioctl(ide_drive_t *drive, struct inode *inode, * and CDROM_SEND_PACKET (legacy) ioctls */ if (cmd != CDROM_SEND_PACKET && cmd != SCSI_IOCTL_SEND_COMMAND) - err = scsi_cmd_ioctl(file, bdev->bd_disk->queue, - bdev->bd_disk, cmd, argp); + err = scsi_cmd_ioctl(bdev->bd_disk->queue, bdev->bd_disk, + mode, cmd, argp); if (err == -ENOTTY) - err = generic_ide_ioctl(drive, file, bdev, cmd, arg); + err = generic_ide_ioctl(drive, bdev, cmd, arg); return err; } diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c index d44898f46c33..7b6662854374 100644 --- a/drivers/ide/ide-gd.c +++ b/drivers/ide/ide-gd.c @@ -169,9 +169,9 @@ static ide_driver_t ide_gd_driver = { #endif }; -static int ide_gd_open(struct inode *inode, struct file *filp) +static int ide_gd_open(struct block_device *bdev, fmode_t mode) { - struct gendisk *disk = inode->i_bdev->bd_disk; + struct gendisk *disk = bdev->bd_disk; struct ide_disk_obj *idkp; ide_drive_t *drive; int ret = 0; @@ -197,12 +197,12 @@ static int ide_gd_open(struct inode *inode, struct file *filp) * unreadable disk, so that we can get the format capacity * of the drive or begin the format - Sam */ - if (ret && (filp->f_flags & O_NDELAY) == 0) { + if (ret && (mode & FMODE_NDELAY) == 0) { ret = -EIO; goto out_put_idkp; } - if ((drive->dev_flags & IDE_DFLAG_WP) && (filp->f_mode & 2)) { + if ((drive->dev_flags & IDE_DFLAG_WP) && (mode & FMODE_WRITE)) { ret = -EROFS; goto out_put_idkp; } @@ -214,7 +214,7 @@ static int ide_gd_open(struct inode *inode, struct file *filp) */ drive->disk_ops->set_doorlock(drive, disk, 1); drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED; - check_disk_change(inode->i_bdev); + check_disk_change(bdev); } else if (drive->dev_flags & IDE_DFLAG_FORMAT_IN_PROGRESS) { ret = -EBUSY; goto out_put_idkp; @@ -227,9 +227,8 @@ out_put_idkp: return ret; } -static int ide_gd_release(struct inode *inode, struct file *filp) +static int ide_gd_release(struct gendisk *disk, fmode_t mode) { - struct gendisk *disk = inode->i_bdev->bd_disk; struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); ide_drive_t *drive = idkp->drive; @@ -286,21 +285,20 @@ static int ide_gd_revalidate_disk(struct gendisk *disk) return 0; } -static int ide_gd_ioctl(struct inode *inode, struct file *file, +static int ide_gd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct block_device *bdev = inode->i_bdev; struct ide_disk_obj *idkp = ide_drv_g(bdev->bd_disk, ide_disk_obj); ide_drive_t *drive = idkp->drive; - return drive->disk_ops->ioctl(drive, inode, file, cmd, arg); + return drive->disk_ops->ioctl(drive, bdev, mode, cmd, arg); } static struct block_device_operations ide_gd_ops = { .owner = THIS_MODULE, .open = ide_gd_open, .release = ide_gd_release, - .ioctl = ide_gd_ioctl, + .locked_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-ioctls.c b/drivers/ide/ide-ioctls.c index a90945f49792..fcde16bb53a7 100644 --- a/drivers/ide/ide-ioctls.c +++ b/drivers/ide/ide-ioctls.c @@ -240,8 +240,7 @@ static int generic_drive_reset(ide_drive_t *drive) return ret; } -int generic_ide_ioctl(ide_drive_t *drive, struct file *file, - struct block_device *bdev, +int generic_ide_ioctl(ide_drive_t *drive, struct block_device *bdev, unsigned int cmd, unsigned long arg) { int err; diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index b2b2e5e8d38e..a2d470eb2b55 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -2340,35 +2340,30 @@ static const struct file_operations idetape_fops = { .release = idetape_chrdev_release, }; -static int idetape_open(struct inode *inode, struct file *filp) +static int idetape_open(struct block_device *bdev, fmode_t mode) { - struct gendisk *disk = inode->i_bdev->bd_disk; - struct ide_tape_obj *tape; + struct ide_tape_obj *tape = ide_tape_get(bdev->bd_disk); - tape = ide_tape_get(disk); if (!tape) return -ENXIO; return 0; } -static int idetape_release(struct inode *inode, struct file *filp) +static int idetape_release(struct gendisk *disk, fmode_t mode) { - struct gendisk *disk = inode->i_bdev->bd_disk; struct ide_tape_obj *tape = ide_drv_g(disk, ide_tape_obj); ide_tape_put(tape); - return 0; } -static int idetape_ioctl(struct inode *inode, struct file *file, +static int idetape_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct block_device *bdev = inode->i_bdev; struct ide_tape_obj *tape = ide_drv_g(bdev->bd_disk, ide_tape_obj); ide_drive_t *drive = tape->drive; - int err = generic_ide_ioctl(drive, file, bdev, cmd, arg); + int err = generic_ide_ioctl(drive, bdev, cmd, arg); if (err == -EINVAL) err = idetape_blkdev_ioctl(drive, cmd, arg); return err; @@ -2378,7 +2373,7 @@ static struct block_device_operations idetape_block_ops = { .owner = THIS_MODULE, .open = idetape_open, .release = idetape_release, - .ioctl = idetape_ioctl, + .locked_ioctl = idetape_ioctl, }; static int ide_tape_probe(ide_drive_t *drive) diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index dca401dc70a0..777c948180f9 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -988,9 +988,9 @@ static int dev_wait(struct dm_ioctl *param, size_t param_size) return r; } -static inline int get_mode(struct dm_ioctl *param) +static inline fmode_t get_mode(struct dm_ioctl *param) { - int mode = FMODE_READ | FMODE_WRITE; + fmode_t mode = FMODE_READ | FMODE_WRITE; if (param->flags & DM_READONLY_FLAG) mode = FMODE_READ; diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c index 1b29e9136758..44042becad8a 100644 --- a/drivers/md/dm-linear.c +++ b/drivers/md/dm-linear.c @@ -110,20 +110,11 @@ static int linear_status(struct dm_target *ti, status_type_t type, return 0; } -static int linear_ioctl(struct dm_target *ti, struct inode *inode, - struct file *filp, unsigned int cmd, +static int linear_ioctl(struct dm_target *ti, unsigned int cmd, unsigned long arg) { struct linear_c *lc = (struct linear_c *) ti->private; - struct block_device *bdev = lc->dev->bdev; - struct file fake_file = {}; - struct dentry fake_dentry = {}; - - fake_file.f_mode = lc->dev->mode; - fake_file.f_path.dentry = &fake_dentry; - fake_dentry.d_inode = bdev->bd_inode; - - return blkdev_driver_ioctl(bdev->bd_inode, &fake_file, bdev->bd_disk, cmd, arg); + return __blkdev_driver_ioctl(lc->dev->bdev, lc->dev->mode, cmd, arg); } 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 abf6e8cfaedb..4840733cd903 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c @@ -1396,19 +1396,15 @@ error: return -EINVAL; } -static int multipath_ioctl(struct dm_target *ti, struct inode *inode, - struct file *filp, unsigned int cmd, +static int multipath_ioctl(struct dm_target *ti, unsigned int cmd, unsigned long arg) { struct multipath *m = (struct multipath *) ti->private; struct block_device *bdev = NULL; + fmode_t mode = 0; unsigned long flags; - struct file fake_file = {}; - struct dentry fake_dentry = {}; int r = 0; - fake_file.f_path.dentry = &fake_dentry; - spin_lock_irqsave(&m->lock, flags); if (!m->current_pgpath) @@ -1416,8 +1412,7 @@ static int multipath_ioctl(struct dm_target *ti, struct inode *inode, if (m->current_pgpath) { bdev = m->current_pgpath->path.dev->bdev; - fake_dentry.d_inode = bdev->bd_inode; - fake_file.f_mode = m->current_pgpath->path.dev->mode; + mode = m->current_pgpath->path.dev->mode; } if (m->queue_io) @@ -1427,8 +1422,7 @@ static int multipath_ioctl(struct dm_target *ti, struct inode *inode, spin_unlock_irqrestore(&m->lock, flags); - return r ? : blkdev_driver_ioctl(bdev->bd_inode, &fake_file, - bdev->bd_disk, cmd, arg); + return r ? : __blkdev_driver_ioctl(bdev, mode, cmd, arg); } /*----------------------------------------------------------------- diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 1407eb96f1a4..a63161aec487 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -43,7 +43,7 @@ struct dm_table { * device. This should be a combination of FMODE_READ * and FMODE_WRITE. */ - int mode; + fmode_t mode; /* a list of devices used by this table */ struct list_head devices; @@ -217,7 +217,7 @@ static int alloc_targets(struct dm_table *t, unsigned int num) return 0; } -int dm_table_create(struct dm_table **result, int mode, +int dm_table_create(struct dm_table **result, fmode_t mode, unsigned num_targets, struct mapped_device *md) { struct dm_table *t = kzalloc(sizeof(*t), GFP_KERNEL); @@ -344,7 +344,7 @@ static int open_dev(struct dm_dev_internal *d, dev_t dev, return PTR_ERR(bdev); r = bd_claim_by_disk(bdev, _claim_ptr, dm_disk(md)); if (r) - blkdev_put(bdev); + blkdev_put(bdev, d->dm_dev.mode); else d->dm_dev.bdev = bdev; return r; @@ -359,7 +359,7 @@ static void close_dev(struct dm_dev_internal *d, struct mapped_device *md) return; bd_release_from_disk(d->dm_dev.bdev, dm_disk(md)); - blkdev_put(d->dm_dev.bdev); + blkdev_put(d->dm_dev.bdev, d->dm_dev.mode); d->dm_dev.bdev = NULL; } @@ -382,7 +382,7 @@ static int check_device_area(struct dm_dev_internal *dd, sector_t start, * careful to leave things as they were if we fail to reopen the * device. */ -static int upgrade_mode(struct dm_dev_internal *dd, int new_mode, +static int upgrade_mode(struct dm_dev_internal *dd, fmode_t new_mode, struct mapped_device *md) { int r; @@ -408,7 +408,7 @@ static int upgrade_mode(struct dm_dev_internal *dd, int new_mode, */ static int __table_get_device(struct dm_table *t, struct dm_target *ti, const char *path, sector_t start, sector_t len, - int mode, struct dm_dev **result) + fmode_t mode, struct dm_dev **result) { int r; dev_t uninitialized_var(dev); @@ -528,7 +528,7 @@ void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev) EXPORT_SYMBOL_GPL(dm_set_device_limits); int dm_get_device(struct dm_target *ti, const char *path, sector_t start, - sector_t len, int mode, struct dm_dev **result) + sector_t len, fmode_t mode, struct dm_dev **result) { int r = __table_get_device(ti->table, ti, path, start, len, mode, result); @@ -878,7 +878,7 @@ struct list_head *dm_table_get_devices(struct dm_table *t) return &t->devices; } -int dm_table_get_mode(struct dm_table *t) +fmode_t dm_table_get_mode(struct dm_table *t) { return t->mode; } diff --git a/drivers/md/dm.c b/drivers/md/dm.c index d1d0cd0f5750..6963ad148408 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -21,7 +21,6 @@ #include <linux/idr.h> #include <linux/hdreg.h> #include <linux/blktrace_api.h> -#include <linux/smp_lock.h> #define DM_MSG_PREFIX "core" @@ -248,13 +247,13 @@ static void __exit dm_exit(void) /* * Block device functions */ -static int dm_blk_open(struct inode *inode, struct file *file) +static int dm_blk_open(struct block_device *bdev, fmode_t mode) { struct mapped_device *md; spin_lock(&_minor_lock); - md = inode->i_bdev->bd_disk->private_data; + md = bdev->bd_disk->private_data; if (!md) goto out; @@ -273,11 +272,9 @@ out: return md ? 0 : -ENXIO; } -static int dm_blk_close(struct inode *inode, struct file *file) +static int dm_blk_close(struct gendisk *disk, fmode_t mode) { - struct mapped_device *md; - - md = inode->i_bdev->bd_disk->private_data; + struct mapped_device *md = disk->private_data; atomic_dec(&md->open_count); dm_put(md); return 0; @@ -314,21 +311,14 @@ static int dm_blk_getgeo(struct block_device *bdev, struct hd_geometry *geo) return dm_get_geometry(md, geo); } -static int dm_blk_ioctl(struct inode *inode, struct file *file, +static int dm_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct mapped_device *md; - struct dm_table *map; + struct mapped_device *md = bdev->bd_disk->private_data; + struct dm_table *map = dm_get_table(md); struct dm_target *tgt; int r = -ENOTTY; - /* We don't really need this lock, but we do need 'inode'. */ - unlock_kernel(); - - md = inode->i_bdev->bd_disk->private_data; - - map = dm_get_table(md); - if (!map || !dm_table_get_size(map)) goto out; @@ -344,12 +334,11 @@ static int dm_blk_ioctl(struct inode *inode, struct file *file, } if (tgt->type->ioctl) - r = tgt->type->ioctl(tgt, inode, file, cmd, arg); + r = tgt->type->ioctl(tgt, cmd, arg); out: dm_table_put(map); - lock_kernel(); return r; } diff --git a/drivers/md/md.c b/drivers/md/md.c index aaa3d465de4e..c1a837ca193c 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -1520,7 +1520,7 @@ static int lock_rdev(mdk_rdev_t *rdev, dev_t dev, int shared) if (err) { printk(KERN_ERR "md: could not bd_claim %s.\n", bdevname(bdev, b)); - blkdev_put(bdev); + blkdev_put(bdev, FMODE_READ|FMODE_WRITE); return err; } if (!shared) @@ -1536,7 +1536,7 @@ static void unlock_rdev(mdk_rdev_t *rdev) if (!bdev) MD_BUG(); bd_release(bdev); - blkdev_put(bdev); + blkdev_put(bdev, FMODE_READ|FMODE_WRITE); } void md_autodetect_dev(dev_t dev); @@ -4785,7 +4785,7 @@ static int md_getgeo(struct block_device *bdev, struct hd_geometry *geo) return 0; } -static int md_ioctl(struct inode *inode, struct file *file, +static int md_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { int err = 0; @@ -4823,7 +4823,7 @@ static int md_ioctl(struct inode *inode, struct file *file, * Commands creating/starting a new array: */ - mddev = inode->i_bdev->bd_disk->private_data; + mddev = bdev->bd_disk->private_data; if (!mddev) { BUG(); @@ -4996,13 +4996,13 @@ abort: return err; } -static int md_open(struct inode *inode, struct file *file) +static int md_open(struct block_device *bdev, fmode_t mode) { /* * Succeed if we can lock the mddev, which confirms that * it isn't being stopped right now. */ - mddev_t *mddev = inode->i_bdev->bd_disk->private_data; + mddev_t *mddev = bdev->bd_disk->private_data; int err; if ((err = mutex_lock_interruptible_nested(&mddev->reconfig_mutex, 1))) @@ -5013,14 +5013,14 @@ static int md_open(struct inode *inode, struct file *file) atomic_inc(&mddev->openers); mddev_unlock(mddev); - check_disk_change(inode->i_bdev); + check_disk_change(bdev); out: return err; } -static int md_release(struct inode *inode, struct file * file) +static int md_release(struct gendisk *disk, fmode_t mode) { - mddev_t *mddev = inode->i_bdev->bd_disk->private_data; + mddev_t *mddev = disk->private_data; BUG_ON(!mddev); atomic_dec(&mddev->openers); @@ -5048,7 +5048,7 @@ static struct block_device_operations md_fops = .owner = THIS_MODULE, .open = md_open, .release = md_release, - .ioctl = md_ioctl, + .locked_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..7911151e56a3 100644 --- a/drivers/memstick/core/mspro_block.c +++ b/drivers/memstick/core/mspro_block.c @@ -172,9 +172,9 @@ static int mspro_block_complete_req(struct memstick_dev *card, int error); /*** Block device ***/ -static int mspro_block_bd_open(struct inode *inode, struct file *filp) +static int mspro_block_bd_open(struct block_device *bdev, fmode_t mode) { - struct gendisk *disk = inode->i_bdev->bd_disk; + struct gendisk *disk = bdev->bd_disk; struct mspro_block_data *msb = disk->private_data; int rc = -ENXIO; @@ -182,7 +182,7 @@ static int mspro_block_bd_open(struct inode *inode, struct file *filp) if (msb && msb->card) { msb->usage_count++; - if ((filp->f_mode & FMODE_WRITE) && msb->read_only) + if ((mode & FMODE_WRITE) && msb->read_only) rc = -EROFS; else rc = 0; @@ -218,9 +218,8 @@ static int mspro_block_disk_release(struct gendisk *disk) return 0; } -static int mspro_block_bd_release(struct inode *inode, struct file *filp) +static int mspro_block_bd_release(struct gendisk *disk, fmode_t mode) { - struct gendisk *disk = inode->i_bdev->bd_disk; return mspro_block_disk_release(disk); } diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c index 81483de8c0fd..11a617ab4243 100644 --- a/drivers/message/i2o/i2o_block.c +++ b/drivers/message/i2o/i2o_block.c @@ -575,9 +575,9 @@ static void i2o_block_biosparam(unsigned long capacity, unsigned short *cyls, * * Returns 0 on success or negative error code on failure. */ -static int i2o_block_open(struct inode *inode, struct file *file) +static int i2o_block_open(struct block_device *bdev, fmode_t mode) { - struct i2o_block_device *dev = inode->i_bdev->bd_disk->private_data; + struct i2o_block_device *dev = bdev->bd_disk->private_data; if (!dev->i2o_dev) return -ENODEV; @@ -604,9 +604,8 @@ static int i2o_block_open(struct inode *inode, struct file *file) * * Returns 0 on success or negative error code on failure. */ -static int i2o_block_release(struct inode *inode, struct file *file) +static int i2o_block_release(struct gendisk *disk, fmode_t mode) { - struct gendisk *disk = inode->i_bdev->bd_disk; struct i2o_block_device *dev = disk->private_data; u8 operation; @@ -653,10 +652,10 @@ static int i2o_block_getgeo(struct block_device *bdev, struct hd_geometry *geo) * * Return 0 on success or negative error on failure. */ -static int i2o_block_ioctl(struct inode *inode, struct file *file, +static int i2o_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct gendisk *disk = inode->i_bdev->bd_disk; + struct gendisk *disk = bdev->bd_disk; struct i2o_block_device *dev = disk->private_data; /* Anyone capable of this syscall can do *real bad* things */ @@ -933,7 +932,7 @@ static struct block_device_operations i2o_block_fops = { .owner = THIS_MODULE, .open = i2o_block_open, .release = i2o_block_release, - .ioctl = i2o_block_ioctl, + .locked_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..3d067c35185d 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -92,18 +92,17 @@ static void mmc_blk_put(struct mmc_blk_data *md) mutex_unlock(&open_lock); } -static int mmc_blk_open(struct inode *inode, struct file *filp) +static int mmc_blk_open(struct block_device *bdev, fmode_t mode) { - struct mmc_blk_data *md; + struct mmc_blk_data *md = mmc_blk_get(bdev->bd_disk); int ret = -ENXIO; - md = mmc_blk_get(inode->i_bdev->bd_disk); if (md) { if (md->usage == 2) - check_disk_change(inode->i_bdev); + check_disk_change(bdev); ret = 0; - if ((filp->f_mode & FMODE_WRITE) && md->read_only) { + if ((mode & FMODE_WRITE) && md->read_only) { mmc_blk_put(md); ret = -EROFS; } @@ -112,9 +111,9 @@ static int mmc_blk_open(struct inode *inode, struct file *filp) return ret; } -static int mmc_blk_release(struct inode *inode, struct file *filp) +static int mmc_blk_release(struct gendisk *disk, fmode_t mode) { - struct mmc_blk_data *md = inode->i_bdev->bd_disk->private_data; + struct mmc_blk_data *md = disk->private_data; mmc_blk_put(md); return 0; diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index 91fbba767635..8c295f40d2ac 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c @@ -224,7 +224,7 @@ static void block2mtd_free_device(struct block2mtd_dev *dev) if (dev->blkdev) { invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping, 0, -1); - close_bdev_excl(dev->blkdev); + close_bdev_exclusive(dev->blkdev, FMODE_READ|FMODE_WRITE); } kfree(dev); @@ -246,7 +246,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size) return NULL; /* Get a handle on the device */ - bdev = open_bdev_excl(devname, O_RDWR, NULL); + bdev = open_bdev_exclusive(devname, FMODE_READ|FMODE_WRITE, NULL); #ifndef MODULE if (IS_ERR(bdev)) { diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c index 681d5aca2af4..1409f01406f6 100644 --- a/drivers/mtd/mtd_blkdevs.c +++ b/drivers/mtd/mtd_blkdevs.c @@ -133,15 +133,12 @@ static void mtd_blktrans_request(struct request_queue *rq) } -static int blktrans_open(struct inode *i, struct file *f) +static int blktrans_open(struct block_device *bdev, fmode_t mode) { - struct mtd_blktrans_dev *dev; - struct mtd_blktrans_ops *tr; + struct mtd_blktrans_dev *dev = bdev->bd_disk->private_data; + struct mtd_blktrans_ops *tr = dev->tr; int ret = -ENODEV; - dev = i->i_bdev->bd_disk->private_data; - tr = dev->tr; - if (!try_module_get(dev->mtd->owner)) goto out; @@ -164,15 +161,12 @@ static int blktrans_open(struct inode *i, struct file *f) return ret; } -static int blktrans_release(struct inode *i, struct file *f) +static int blktrans_release(struct gendisk *disk, fmode_t mode) { - struct mtd_blktrans_dev *dev; - struct mtd_blktrans_ops *tr; + struct mtd_blktrans_dev *dev = disk->private_data; + struct mtd_blktrans_ops *tr = dev->tr; int ret = 0; - dev = i->i_bdev->bd_disk->private_data; - tr = dev->tr; - if (tr->release) ret = tr->release(dev); @@ -194,10 +188,10 @@ static int blktrans_getgeo(struct block_device *bdev, struct hd_geometry *geo) return -ENOTTY; } -static int blktrans_ioctl(struct inode *inode, struct file *file, +static int blktrans_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct mtd_blktrans_dev *dev = inode->i_bdev->bd_disk->private_data; + struct mtd_blktrans_dev *dev = bdev->bd_disk->private_data; struct mtd_blktrans_ops *tr = dev->tr; switch (cmd) { @@ -215,7 +209,7 @@ static struct block_device_operations mtd_blktrans_ops = { .owner = THIS_MODULE, .open = blktrans_open, .release = blktrans_release, - .ioctl = blktrans_ioctl, + .locked_ioctl = blktrans_ioctl, .getgeo = blktrans_getgeo, }; diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 963840e9b5bf..bcffeda2df3d 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -96,7 +96,7 @@ static int mtd_open(struct inode *inode, struct file *file) return -ENODEV; /* You can't open the RO devices RW */ - if ((file->f_mode & 2) && (minor & 1)) + if ((file->f_mode & FMODE_WRITE) && (minor & 1)) return -EACCES; lock_kernel(); @@ -114,7 +114,7 @@ static int mtd_open(struct inode *inode, struct file *file) } /* You can't open it RW if it's not a writeable device */ - if ((file->f_mode & 2) && !(mtd->flags & MTD_WRITEABLE)) { + if ((file->f_mode & FMODE_WRITE) && !(mtd->flags & MTD_WRITEABLE)) { put_mtd_device(mtd); ret = -EACCES; goto out; @@ -144,7 +144,7 @@ static int mtd_close(struct inode *inode, struct file *file) DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n"); /* Only sync if opened RW */ - if ((file->f_mode & 2) && mtd->sync) + if ((file->f_mode & FMODE_WRITE) && mtd->sync) mtd->sync(mtd); put_mtd_device(mtd); @@ -443,7 +443,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file, { struct erase_info *erase; - if(!(file->f_mode & 2)) + if(!(file->f_mode & FMODE_WRITE)) return -EPERM; erase=kzalloc(sizeof(struct erase_info),GFP_KERNEL); @@ -497,7 +497,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file, struct mtd_oob_buf __user *user_buf = argp; uint32_t retlen; - if(!(file->f_mode & 2)) + if(!(file->f_mode & FMODE_WRITE)) return -EPERM; if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf))) diff --git a/drivers/parisc/eisa_eeprom.c b/drivers/parisc/eisa_eeprom.c index 5ac207932fd7..685d94e69d44 100644 --- a/drivers/parisc/eisa_eeprom.c +++ b/drivers/parisc/eisa_eeprom.c @@ -86,7 +86,7 @@ static int eisa_eeprom_open(struct inode *inode, struct file *file) { cycle_kernel_lock(); - if (file->f_mode & 2) + if (file->f_mode & FMODE_WRITE) return -EINVAL; return 0; diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 0a225ccda026..4b76fca64a6f 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -2011,10 +2011,9 @@ static void dasd_flush_request_queue(struct dasd_block *block) spin_unlock_irq(&block->request_queue_lock); } -static int dasd_open(struct inode *inp, struct file *filp) +static int dasd_open(struct block_device *bdev, fmode_t mode) { - struct gendisk *disk = inp->i_bdev->bd_disk; - struct dasd_block *block = disk->private_data; + struct dasd_block *block = bdev->bd_disk->private_data; struct dasd_device *base = block->base; int rc; @@ -2052,9 +2051,8 @@ unlock: return rc; } -static int dasd_release(struct inode *inp, struct file *filp) +static int dasd_release(struct gendisk *disk, fmode_t mode) { - struct gendisk *disk = inp->i_bdev->bd_disk; struct dasd_block *block = disk->private_data; atomic_dec(&block->open_count); @@ -2089,8 +2087,7 @@ dasd_device_operations = { .owner = THIS_MODULE, .open = dasd_open, .release = dasd_release, - .ioctl = dasd_ioctl, - .compat_ioctl = dasd_compat_ioctl, + .locked_ioctl = dasd_ioctl, .getgeo = dasd_getgeo, }; diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c index aee6565aaf98..e99d566b69cc 100644 --- a/drivers/s390/block/dasd_genhd.c +++ b/drivers/s390/block/dasd_genhd.c @@ -99,7 +99,7 @@ int dasd_scan_partitions(struct dasd_block *block) struct block_device *bdev; bdev = bdget_disk(block->gdp, 0); - if (!bdev || blkdev_get(bdev, FMODE_READ, 1) < 0) + if (!bdev || blkdev_get(bdev, FMODE_READ) < 0) return -ENODEV; /* * See fs/partition/check.c:register_disk,rescan_partitions @@ -152,7 +152,7 @@ void dasd_destroy_partitions(struct dasd_block *block) invalidate_partition(block->gdp, 0); /* Matching blkdev_put to the blkdev_get in dasd_scan_partitions. */ - blkdev_put(bdev); + blkdev_put(bdev, FMODE_READ); set_capacity(block->gdp, 0); } diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index 489d5fe488fb..05a14536c369 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h @@ -610,8 +610,7 @@ int dasd_scan_partitions(struct dasd_block *); void dasd_destroy_partitions(struct dasd_block *); /* externals in dasd_ioctl.c */ -int dasd_ioctl(struct inode *, struct file *, unsigned int, unsigned long); -long dasd_compat_ioctl(struct file *, unsigned int, unsigned long); +int dasd_ioctl(struct block_device *, fmode_t, unsigned int, unsigned long); /* externals in dasd_proc.c */ int dasd_proc_init(void); diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index 91a64630cb0f..b82d816d9ef7 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c @@ -366,10 +366,9 @@ static int dasd_ioctl_readall_cmb(struct dasd_block *block, unsigned int cmd, } int -dasd_ioctl(struct inode *inode, struct file *file, +dasd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct block_device *bdev = inode->i_bdev; struct dasd_block *block = bdev->bd_disk->private_data; void __user *argp = (void __user *)arg; @@ -421,15 +420,3 @@ dasd_ioctl(struct inode *inode, struct file *file, return -EINVAL; } } - -long -dasd_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - int rval; - - lock_kernel(); - rval = dasd_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg); - unlock_kernel(); - - return (rval == -EINVAL) ? -ENOIOCTLCMD : rval; -} diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index a7ff167d5b81..63f26a135fe5 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c @@ -31,8 +31,8 @@ #define PRINT_WARN(x...) printk(KERN_WARNING DCSSBLK_NAME " warning: " x) #define PRINT_ERR(x...) printk(KERN_ERR DCSSBLK_NAME " error: " x) -static int dcssblk_open(struct inode *inode, struct file *filp); -static int dcssblk_release(struct inode *inode, struct file *filp); +static int dcssblk_open(struct block_device *bdev, fmode_t mode); +static int dcssblk_release(struct gendisk *disk, fmode_t mode); static int dcssblk_make_request(struct request_queue *q, struct bio *bio); static int dcssblk_direct_access(struct block_device *bdev, sector_t secnum, void **kaddr, unsigned long *pfn); @@ -776,32 +776,31 @@ out_buf: } static int -dcssblk_open(struct inode *inode, struct file *filp) +dcssblk_open(struct block_device *bdev, fmode_t mode) { struct dcssblk_dev_info *dev_info; int rc; - dev_info = inode->i_bdev->bd_disk->private_data; + dev_info = bdev->bd_disk->private_data; if (NULL == dev_info) { rc = -ENODEV; goto out; } atomic_inc(&dev_info->use_count); - inode->i_bdev->bd_block_size = 4096; + bdev->bd_block_size = 4096; rc = 0; out: return rc; } static int -dcssblk_release(struct inode *inode, struct file *filp) +dcssblk_release(struct gendisk *disk, fmode_t mode) { - struct dcssblk_dev_info *dev_info; + struct dcssblk_dev_info *dev_info = disk->private_data; struct segment_info *entry; int rc; - dev_info = inode->i_bdev->bd_disk->private_data; - if (NULL == dev_info) { + if (!dev_info) { rc = -ENODEV; goto out; } diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c index a25b8bf54f41..023803dbb0c7 100644 --- a/drivers/s390/char/tape_block.c +++ b/drivers/s390/char/tape_block.c @@ -43,9 +43,9 @@ /* * file operation structure for tape block frontend */ -static int tapeblock_open(struct inode *, struct file *); -static int tapeblock_release(struct inode *, struct file *); -static int tapeblock_ioctl(struct inode *, struct file *, unsigned int, +static int tapeblock_open(struct block_device *, fmode_t); +static int tapeblock_release(struct gendisk *, fmode_t); +static int tapeblock_ioctl(struct block_device *, fmode_t, unsigned int, unsigned long); static int tapeblock_medium_changed(struct gendisk *); static int tapeblock_revalidate_disk(struct gendisk *); @@ -54,7 +54,7 @@ static struct block_device_operations tapeblock_fops = { .owner = THIS_MODULE, .open = tapeblock_open, .release = tapeblock_release, - .ioctl = tapeblock_ioctl, + .locked_ioctl = tapeblock_ioctl, .media_changed = tapeblock_medium_changed, .revalidate_disk = tapeblock_revalidate_disk, }; @@ -364,13 +364,12 @@ tapeblock_medium_changed(struct gendisk *disk) * Block frontend tape device open function. */ static int -tapeblock_open(struct inode *inode, struct file *filp) +tapeblock_open(struct block_device *bdev, fmode_t mode) { - struct gendisk * disk; + struct gendisk * disk = bdev->bd_disk; struct tape_device * device; int rc; - disk = inode->i_bdev->bd_disk; device = tape_get_device_reference(disk->private_data); if (device->required_tapemarks) { @@ -410,9 +409,8 @@ release: * we just get the pointer here and release the reference. */ static int -tapeblock_release(struct inode *inode, struct file *filp) +tapeblock_release(struct gendisk *disk, fmode_t mode) { - struct gendisk *disk = inode->i_bdev->bd_disk; struct tape_device *device = disk->private_data; tape_state_set(device, TS_IN_USE); @@ -427,22 +425,21 @@ tapeblock_release(struct inode *inode, struct file *filp) */ static int tapeblock_ioctl( - struct inode * inode, - struct file * file, + struct block_device * bdev, + fmode_t mode, unsigned int command, unsigned long arg ) { int rc; int minor; - struct gendisk *disk; + struct gendisk *disk = bdev->bd_disk; struct tape_device *device; rc = 0; - disk = inode->i_bdev->bd_disk; BUG_ON(!disk); device = disk->private_data; BUG_ON(!device); - minor = iminor(inode); + minor = MINOR(bdev->bd_dev); DBF_LH(6, "tapeblock_ioctl(0x%0x)\n", command); DBF_LH(6, "device = %d:%d\n", tapeblock_major, minor); diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index afc96e844a25..2370fd82ebfe 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -452,40 +452,34 @@ static ide_driver_t idescsi_driver = { #endif }; -static int idescsi_ide_open(struct inode *inode, struct file *filp) +static int idescsi_ide_open(struct block_device *bdev, fmode_t mode) { - struct gendisk *disk = inode->i_bdev->bd_disk; - struct ide_scsi_obj *scsi; + struct ide_scsi_obj *scsi = ide_scsi_get(bdev->bd_disk); - if (!(scsi = ide_scsi_get(disk))) + if (!scsi) return -ENXIO; return 0; } -static int idescsi_ide_release(struct inode *inode, struct file *filp) +static int idescsi_ide_release(struct gendisk *disk, fmode_t mode) { - struct gendisk *disk = inode->i_bdev->bd_disk; - struct ide_scsi_obj *scsi = ide_scsi_g(disk); - - ide_scsi_put(scsi); - + ide_scsi_put(ide_scsi_g(disk)); return 0; } -static int idescsi_ide_ioctl(struct inode *inode, struct file *file, +static int idescsi_ide_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct block_device *bdev = inode->i_bdev; struct ide_scsi_obj *scsi = ide_scsi_g(bdev->bd_disk); - return generic_ide_ioctl(scsi->drive, file, bdev, cmd, arg); + return generic_ide_ioctl(scsi->drive, bdev, cmd, arg); } static struct block_device_operations idescsi_ops = { .owner = THIS_MODULE, .open = idescsi_ide_open, .release = idescsi_ide_release, - .ioctl = idescsi_ide_ioctl, + .locked_ioctl = idescsi_ide_ioctl, }; static int idescsi_slave_configure(struct scsi_device * sdp) diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c index 28b19ef26309..dc1cfb2fd76b 100644 --- a/drivers/scsi/scsi_ioctl.c +++ b/drivers/scsi/scsi_ioctl.c @@ -237,7 +237,7 @@ int scsi_ioctl(struct scsi_device *sdev, int cmd, void __user *arg) case SCSI_IOCTL_SEND_COMMAND: if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) return -EACCES; - return sg_scsi_ioctl(NULL, sdev->request_queue, NULL, arg); + return sg_scsi_ioctl(sdev->request_queue, NULL, 0, arg); case SCSI_IOCTL_DOORLOCK: return scsi_set_medium_removal(sdev, SCSI_REMOVAL_PREVENT); case SCSI_IOCTL_DOORUNLOCK: @@ -277,14 +277,14 @@ EXPORT_SYMBOL(scsi_ioctl); * @filp: either NULL or a &struct file which must have the O_NONBLOCK flag. */ int scsi_nonblockable_ioctl(struct scsi_device *sdev, int cmd, - void __user *arg, struct file *filp) + void __user *arg, int ndelay) { int val, result; /* The first set of iocts may be executed even if we're doing * error processing, as long as the device was opened * non-blocking */ - if (filp && (filp->f_flags & O_NONBLOCK)) { + if (ndelay) { if (scsi_host_in_recovery(sdev->host)) return -ENODEV; } else if (!scsi_block_when_processing_errors(sdev)) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 7c4d2e68df1c..43f34c73df12 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -609,17 +609,15 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) * In the latter case @inode and @filp carry an abridged amount * of information as noted above. **/ -static int sd_open(struct inode *inode, struct file *filp) +static int sd_open(struct block_device *bdev, fmode_t mode) { - struct gendisk *disk = inode->i_bdev->bd_disk; - struct scsi_disk *sdkp; + struct scsi_disk *sdkp = scsi_disk_get(bdev->bd_disk); struct scsi_device *sdev; int retval; - if (!(sdkp = scsi_disk_get(disk))) + if (!sdkp) return -ENXIO; - SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_open\n")); sdev = sdkp->device; @@ -633,14 +631,13 @@ static int sd_open(struct inode *inode, struct file *filp) goto error_out; if (sdev->removable || sdkp->write_prot) - check_disk_change(inode->i_bdev); + check_disk_change(bdev); /* * If the drive is empty, just let the open fail. */ retval = -ENOMEDIUM; - if (sdev->removable && !sdkp->media_present && - !(filp->f_flags & O_NDELAY)) + if (sdev->removable && !sdkp->media_present && !(mode & FMODE_NDELAY)) goto error_out; /* @@ -648,7 +645,7 @@ static int sd_open(struct inode *inode, struct file *filp) * if the user expects to be able to write to the thing. */ retval = -EROFS; - if (sdkp->write_prot && (filp->f_mode & FMODE_WRITE)) + if (sdkp->write_prot && (mode & FMODE_WRITE)) goto error_out; /* @@ -684,9 +681,8 @@ error_out: * Note: may block (uninterruptible) if error recovery is underway * on this disk. **/ -static int sd_release(struct inode *inode, struct file *filp) +static int sd_release(struct gendisk *disk, fmode_t mode) { - struct gendisk *disk = inode->i_bdev->bd_disk; struct scsi_disk *sdkp = scsi_disk(disk); struct scsi_device *sdev = sdkp->device; @@ -743,10 +739,9 @@ static int sd_getgeo(struct block_device *bdev, struct hd_geometry *geo) * Note: most ioctls are forward onto the block subsystem or further * down in the scsi subsystem. **/ -static int sd_ioctl(struct inode * inode, struct file * filp, +static int sd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct block_device *bdev = inode->i_bdev; struct gendisk *disk = bdev->bd_disk; struct scsi_device *sdp = scsi_disk(disk)->device; void __user *p = (void __user *)arg; @@ -761,7 +756,8 @@ static int sd_ioctl(struct inode * inode, struct file * filp, * may try and take the device offline, in which case all further * access to the device is prohibited. */ - error = scsi_nonblockable_ioctl(sdp, cmd, p, filp); + error = scsi_nonblockable_ioctl(sdp, cmd, p, + (mode & FMODE_NDELAY_NOW) != 0); if (!scsi_block_when_processing_errors(sdp) || !error) return error; @@ -775,7 +771,7 @@ static int sd_ioctl(struct inode * inode, struct file * filp, case SCSI_IOCTL_GET_BUS_NUMBER: return scsi_ioctl(sdp, cmd, p); default: - error = scsi_cmd_ioctl(filp, disk->queue, disk, cmd, p); + error = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, p); if (error != -ENOTTY) return error; } @@ -928,11 +924,10 @@ static void sd_rescan(struct device *dev) * This gets directly called from VFS. When the ioctl * is not recognized we go back to the other translation paths. */ -static long sd_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +static int sd_compat_ioctl(struct block_device *bdev, fmode_t mode, + unsigned int cmd, unsigned long arg) { - struct block_device *bdev = file->f_path.dentry->d_inode->i_bdev; - struct gendisk *disk = bdev->bd_disk; - struct scsi_device *sdev = scsi_disk(disk)->device; + struct scsi_device *sdev = scsi_disk(bdev->bd_disk)->device; /* * If we are in the middle of error recovery, don't let anyone @@ -962,7 +957,7 @@ static struct block_device_operations sd_fops = { .owner = THIS_MODULE, .open = sd_open, .release = sd_release, - .ioctl = sd_ioctl, + .locked_ioctl = sd_ioctl, .getgeo = sd_getgeo, #ifdef CONFIG_COMPAT .compat_ioctl = sd_compat_ioctl, diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 93bd59a1ed79..9adf35bd8b56 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -1059,7 +1059,7 @@ sg_ioctl(struct inode *inode, struct file *filp, if (sg_allow_access(filp, &opcode)) return -EPERM; } - return sg_scsi_ioctl(filp, sdp->device->request_queue, NULL, p); + return sg_scsi_ioctl(sdp->device->request_queue, NULL, filp->f_mode, p); case SG_SET_DEBUG: result = get_user(val, ip); if (result) diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 0f17009c99d2..62b6633e3a97 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -471,38 +471,31 @@ static int sr_prep_fn(struct request_queue *q, struct request *rq) return scsi_prep_return(q, rq, ret); } -static int sr_block_open(struct inode *inode, struct file *file) +static int sr_block_open(struct block_device *bdev, fmode_t mode) { - struct gendisk *disk = inode->i_bdev->bd_disk; - struct scsi_cd *cd; - int ret = 0; - - if(!(cd = scsi_cd_get(disk))) - return -ENXIO; - - if((ret = cdrom_open(&cd->cdi, inode, file)) != 0) - scsi_cd_put(cd); + struct scsi_cd *cd = scsi_cd_get(bdev->bd_disk); + int ret = -ENXIO; + if (cd) { + ret = cdrom_open(&cd->cdi, bdev, mode); + if (ret) + scsi_cd_put(cd); + } return ret; } -static int sr_block_release(struct inode *inode, struct file *file) +static int sr_block_release(struct gendisk *disk, fmode_t mode) { - int ret; - struct scsi_cd *cd = scsi_cd(inode->i_bdev->bd_disk); - ret = cdrom_release(&cd->cdi, file); - if(ret) - return ret; - + struct scsi_cd *cd = scsi_cd(disk); + cdrom_release(&cd->cdi, mode); scsi_cd_put(cd); - return 0; } -static int sr_block_ioctl(struct inode *inode, struct file *file, unsigned cmd, +static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, unsigned long arg) { - struct scsi_cd *cd = scsi_cd(inode->i_bdev->bd_disk); + struct scsi_cd *cd = scsi_cd(bdev->bd_disk); struct scsi_device *sdev = cd->device; void __user *argp = (void __user *)arg; int ret; @@ -517,7 +510,7 @@ static int sr_block_ioctl(struct inode *inode, struct file *file, unsigned cmd, return scsi_ioctl(sdev, cmd, argp); } - ret = cdrom_ioctl(file, &cd->cdi, inode, cmd, arg); + ret = cdrom_ioctl(&cd->cdi, bdev, mode, cmd, arg); if (ret != -ENOSYS) return ret; @@ -527,7 +520,8 @@ static int sr_block_ioctl(struct inode *inode, struct file *file, unsigned cmd, * case fall through to scsi_ioctl, which will return ENDOEV again * if it doesn't recognise the ioctl */ - ret = scsi_nonblockable_ioctl(sdev, cmd, argp, NULL); + ret = scsi_nonblockable_ioctl(sdev, cmd, argp, + (mode & FMODE_NDELAY_NOW) != 0); if (ret != -ENODEV) return ret; return scsi_ioctl(sdev, cmd, argp); @@ -544,7 +538,7 @@ static struct block_device_operations sr_bdops = .owner = THIS_MODULE, .open = sr_block_open, .release = sr_block_release, - .ioctl = sr_block_ioctl, + .locked_ioctl = sr_block_ioctl, .media_changed = sr_block_media_changed, /* * No compat_ioctl for now because sr_block_ioctl never diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 5c28d08f18f4..c959bdc55f4f 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -3263,7 +3263,8 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg) * may try and take the device offline, in which case all further * access to the device is prohibited. */ - retval = scsi_nonblockable_ioctl(STp->device, cmd_in, p, file); + retval = scsi_nonblockable_ioctl(STp->device, cmd_in, p, + file->f_flags & O_NDELAY); if (!scsi_block_when_processing_errors(STp->device) || retval != -ENODEV) goto out; retval = 0; @@ -3567,8 +3568,8 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg) !capable(CAP_SYS_RAWIO)) i = -EPERM; else - i = scsi_cmd_ioctl(file, STp->disk->queue, - STp->disk, cmd_in, p); + i = scsi_cmd_ioctl(STp->disk->queue, STp->disk, + file->f_mode, cmd_in, p); if (i != -ENOTTY) return i; break; diff --git a/fs/block_dev.c b/fs/block_dev.c index d06fe3c3dd3f..88a776fa0ef6 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -840,13 +840,12 @@ EXPORT_SYMBOL_GPL(bd_release_from_disk); * to be used for internal purposes. If you ever need it - reconsider * your API. */ -struct block_device *open_by_devnum(dev_t dev, unsigned mode) +struct block_device *open_by_devnum(dev_t dev, fmode_t mode) { struct block_device *bdev = bdget(dev); int err = -ENOMEM; - int flags = mode & FMODE_WRITE ? O_RDWR : O_RDONLY; if (bdev) - err = blkdev_get(bdev, mode, flags); + err = blkdev_get(bdev, mode); return err ? ERR_PTR(err) : bdev; } @@ -975,9 +974,7 @@ void bd_set_size(struct block_device *bdev, loff_t size) } EXPORT_SYMBOL(bd_set_size); -static int __blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags, - int for_part); -static int __blkdev_put(struct block_device *bdev, int for_part); +static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part); /* * bd_mutex locking: @@ -986,7 +983,7 @@ static int __blkdev_put(struct block_device *bdev, int for_part); * mutex_lock_nested(whole->bd_mutex, 1) */ -static int do_open(struct block_device *bdev, struct file *file, int for_part) +static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) { struct gendisk *disk; struct hd_struct *part = NULL; @@ -994,9 +991,9 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part) int partno; int perm = 0; - if (file->f_mode & FMODE_READ) + if (mode & FMODE_READ) perm |= MAY_READ; - if (file->f_mode & FMODE_WRITE) + if (mode & FMODE_WRITE) perm |= MAY_WRITE; /* * hooks: /n/, see "layering violations". @@ -1008,7 +1005,6 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part) } ret = -ENXIO; - file->f_mapping = bdev->bd_inode->i_mapping; lock_kernel(); @@ -1027,7 +1023,7 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part) if (!partno) { struct backing_dev_info *bdi; if (disk->fops->open) { - ret = disk->fops->open(bdev->bd_inode, file); + ret = disk->fops->open(bdev, mode); if (ret) goto out_clear; } @@ -1047,7 +1043,7 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part) if (!whole) goto out_clear; BUG_ON(for_part); - ret = __blkdev_get(whole, file->f_mode, file->f_flags, 1); + ret = __blkdev_get(whole, mode, 1); if (ret) goto out_clear; bdev->bd_contains = whole; @@ -1068,7 +1064,7 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part) disk = NULL; if (bdev->bd_contains == bdev) { if (bdev->bd_disk->fops->open) { - ret = bdev->bd_disk->fops->open(bdev->bd_inode, file); + ret = bdev->bd_disk->fops->open(bdev, mode); if (ret) goto out_unlock_bdev; } @@ -1088,7 +1084,7 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part) bdev->bd_part = NULL; bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info; if (bdev != bdev->bd_contains) - __blkdev_put(bdev->bd_contains, 1); + __blkdev_put(bdev->bd_contains, mode, 1); bdev->bd_contains = NULL; out_unlock_bdev: mutex_unlock(&bdev->bd_mutex); @@ -1104,28 +1100,9 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part) return ret; } -static int __blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags, - int for_part) +int blkdev_get(struct block_device *bdev, fmode_t mode) { - /* - * This crockload is due to bad choice of ->open() type. - * It will go away. - * For now, block device ->open() routine must _not_ - * examine anything in 'inode' argument except ->i_rdev. - */ - struct file fake_file = {}; - struct dentry fake_dentry = {}; - fake_file.f_mode = mode; - fake_file.f_flags = flags; - fake_file.f_path.dentry = &fake_dentry; - fake_dentry.d_inode = bdev->bd_inode; - - return do_open(bdev, &fake_file, for_part); -} - -int blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags) -{ - return __blkdev_get(bdev, mode, flags, 0); + return __blkdev_get(bdev, mode, 0); } EXPORT_SYMBOL(blkdev_get); @@ -1142,28 +1119,36 @@ static int blkdev_open(struct inode * inode, struct file * filp) */ filp->f_flags |= O_LARGEFILE; + if (filp->f_flags & O_NDELAY) + filp->f_mode |= FMODE_NDELAY; + if (filp->f_flags & O_EXCL) + filp->f_mode |= FMODE_EXCL; + if ((filp->f_flags & O_ACCMODE) == 3) + filp->f_mode |= FMODE_WRITE_IOCTL; + bdev = bd_acquire(inode); if (bdev == NULL) return -ENOMEM; - res = do_open(bdev, filp, 0); + filp->f_mapping = bdev->bd_inode->i_mapping; + + res = blkdev_get(bdev, filp->f_mode); if (res) return res; - if (!(filp->f_flags & O_EXCL) ) + if (!(filp->f_mode & FMODE_EXCL)) return 0; if (!(res = bd_claim(bdev, filp))) return 0; - blkdev_put(bdev); + blkdev_put(bdev, filp->f_mode); return res; } -static int __blkdev_put(struct block_device *bdev, int for_part) +static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part) { int ret = 0; - struct inode *bd_inode = bdev->bd_inode; struct gendisk *disk = bdev->bd_disk; struct block_device *victim = NULL; @@ -1178,7 +1163,7 @@ static int __blkdev_put(struct block_device *bdev, int for_part) } if (bdev->bd_contains == bdev) { if (disk->fops->release) - ret = disk->fops->release(bd_inode, NULL); + ret = disk->fops->release(disk, mode); } if (!bdev->bd_openers) { struct module *owner = disk->fops->owner; @@ -1197,13 +1182,13 @@ static int __blkdev_put(struct block_device *bdev, int for_part) mutex_unlock(&bdev->bd_mutex); bdput(bdev); if (victim) - __blkdev_put(victim, 1); + __blkdev_put(victim, mode, 1); return ret; } -int blkdev_put(struct block_device *bdev) +int blkdev_put(struct block_device *bdev, fmode_t mode) { - return __blkdev_put(bdev, 0); + return __blkdev_put(bdev, mode, 0); } EXPORT_SYMBOL(blkdev_put); @@ -1212,12 +1197,16 @@ static int blkdev_close(struct inode * inode, struct file * filp) struct block_device *bdev = I_BDEV(filp->f_mapping->host); if (bdev->bd_holder == filp) bd_release(bdev); - return blkdev_put(bdev); + return blkdev_put(bdev, filp->f_mode); } static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg) { - return blkdev_ioctl(file->f_mapping->host, file, cmd, arg); + struct block_device *bdev = I_BDEV(file->f_mapping->host); + fmode_t mode = file->f_mode; + if (file->f_flags & O_NDELAY) + mode |= FMODE_NDELAY_NOW; + return blkdev_ioctl(bdev, mode, cmd, arg); } static const struct address_space_operations def_blk_aops = { @@ -1253,7 +1242,7 @@ int ioctl_by_bdev(struct block_device *bdev, unsigned cmd, unsigned long arg) int res; mm_segment_t old_fs = get_fs(); set_fs(KERNEL_DS); - res = blkdev_ioctl(bdev->bd_inode, NULL, cmd, arg); + res = blkdev_ioctl(bdev, 0, cmd, arg); set_fs(old_fs); return res; } @@ -1303,32 +1292,29 @@ fail: EXPORT_SYMBOL(lookup_bdev); /** - * open_bdev_excl - open a block device by name and set it up for use + * open_bdev_exclusive - open a block device by name and set it up for use * * @path: special file representing the block device - * @flags: %MS_RDONLY for opening read-only + * @mode: FMODE_... combination to pass be used * @holder: owner for exclusion * * Open the blockdevice described by the special file at @path, claim it * for the @holder. */ -struct block_device *open_bdev_excl(const char *path, int flags, void *holder) +struct block_device *open_bdev_exclusive(const char *path, fmode_t mode, void *holder) { struct block_device *bdev; - mode_t mode = FMODE_READ; int error = 0; bdev = lookup_bdev(path); if (IS_ERR(bdev)) return bdev; - if (!(flags & MS_RDONLY)) - mode |= FMODE_WRITE; - error = blkdev_get(bdev, mode, 0); + error = blkdev_get(bdev, mode); if (error) return ERR_PTR(error); error = -EACCES; - if (!(flags & MS_RDONLY) && bdev_read_only(bdev)) + if ((mode & FMODE_WRITE) && bdev_read_only(bdev)) goto blkdev_put; error = bd_claim(bdev, holder); if (error) @@ -1337,26 +1323,27 @@ struct block_device *open_bdev_excl(const char *path, int flags, void *holder) return bdev; blkdev_put: - blkdev_put(bdev); + blkdev_put(bdev, mode); return ERR_PTR(error); } -EXPORT_SYMBOL(open_bdev_excl); +EXPORT_SYMBOL(open_bdev_exclusive); /** - * close_bdev_excl - release a blockdevice openen by open_bdev_excl() + * close_bdev_exclusive - close a blockdevice opened by open_bdev_exclusive() * * @bdev: blockdevice to close + * @mode: mode, must match that used to open. * - * This is the counterpart to open_bdev_excl(). + * This is the counterpart to open_bdev_exclusive(). */ -void close_bdev_excl(struct block_device *bdev) +void close_bdev_exclusive(struct block_device *bdev, fmode_t mode) { bd_release(bdev); - blkdev_put(bdev); + blkdev_put(bdev, mode); } -EXPORT_SYMBOL(close_bdev_excl); +EXPORT_SYMBOL(close_bdev_exclusive); int __invalidate_device(struct block_device *bdev) { diff --git a/fs/ext2/xip.c b/fs/ext2/xip.c index 4fb94c20041b..b72b85884223 100644 --- a/fs/ext2/xip.c +++ b/fs/ext2/xip.c @@ -11,6 +11,7 @@ #include <linux/buffer_head.h> #include <linux/ext2_fs_sb.h> #include <linux/ext2_fs.h> +#include <linux/blkdev.h> #include "ext2.h" #include "xip.h" diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 34b6fca765d7..8147dd44cede 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -347,7 +347,7 @@ fail: static int ext3_blkdev_put(struct block_device *bdev) { bd_release(bdev); - return blkdev_put(bdev); + return blkdev_put(bdev, FMODE_READ|FMODE_WRITE); } static int ext3_blkdev_remove(struct ext3_sb_info *sbi) @@ -2067,7 +2067,7 @@ static journal_t *ext3_get_dev_journal(struct super_block *sb, if (bd_claim(bdev, sb)) { printk(KERN_ERR "EXT3: failed to claim external journal device.\n"); - blkdev_put(bdev); + blkdev_put(bdev, FMODE_READ|FMODE_WRITE); return NULL; } diff --git a/fs/ext4/super.c b/fs/ext4/super.c index ae35f176b697..bdddea14e782 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -399,7 +399,7 @@ fail: static int ext4_blkdev_put(struct block_device *bdev) { bd_release(bdev); - return blkdev_put(bdev); + return blkdev_put(bdev, FMODE_READ|FMODE_WRITE); } static int ext4_blkdev_remove(struct ext4_sb_info *sbi) @@ -2553,7 +2553,7 @@ static journal_t *ext4_get_dev_journal(struct super_block *sb, if (bd_claim(bdev, sb)) { printk(KERN_ERR "EXT4: failed to claim external journal device.\n"); - blkdev_put(bdev); + blkdev_put(bdev, FMODE_READ|FMODE_WRITE); return NULL; } diff --git a/fs/fifo.c b/fs/fifo.c index 987bf9411495..f8f97b8b6d44 100644 --- a/fs/fifo.c +++ b/fs/fifo.c @@ -51,7 +51,7 @@ static int fifo_open(struct inode *inode, struct file *filp) filp->f_mode &= (FMODE_READ | FMODE_WRITE); switch (filp->f_mode) { - case 1: + case FMODE_READ: /* * O_RDONLY * POSIX.1 says that O_NONBLOCK means return with the FIFO @@ -76,7 +76,7 @@ static int fifo_open(struct inode *inode, struct file *filp) } break; - case 2: + case FMODE_WRITE: /* * O_WRONLY * POSIX.1 says that O_NONBLOCK means return -1 with @@ -98,7 +98,7 @@ static int fifo_open(struct inode *inode, struct file *filp) } break; - case 3: + case FMODE_READ | FMODE_WRITE: /* * O_RDWR * POSIX.1 leaves this case "undefined" when O_NONBLOCK is set. diff --git a/fs/file_table.c b/fs/file_table.c index f45a4493f9e7..efc06faede6c 100644 --- a/fs/file_table.c +++ b/fs/file_table.c @@ -161,7 +161,7 @@ EXPORT_SYMBOL(get_empty_filp); * code should be moved into this function. */ struct file *alloc_file(struct vfsmount *mnt, struct dentry *dentry, - mode_t mode, const struct file_operations *fop) + fmode_t mode, const struct file_operations *fop) { struct file *file; struct path; @@ -193,7 +193,7 @@ EXPORT_SYMBOL(alloc_file); * of this should be moving to alloc_file(). */ int init_file(struct file *file, struct vfsmount *mnt, struct dentry *dentry, - mode_t mode, const struct file_operations *fop) + fmode_t mode, const struct file_operations *fop) { int error = 0; file->f_path.dentry = dentry; diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index d6ecabf4d231..7f34f4385de0 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c @@ -20,7 +20,7 @@ struct hostfs_inode_info { char *host_filename; int fd; - int mode; + fmode_t mode; struct inode vfs_inode; }; @@ -373,7 +373,8 @@ int hostfs_readdir(struct file *file, void *ent, filldir_t filldir) int hostfs_file_open(struct inode *ino, struct file *file) { char *name; - int mode = 0, r = 0, w = 0, fd; + fmode_t mode = 0; + int r = 0, w = 0, fd; mode = file->f_mode & (FMODE_READ | FMODE_WRITE); if ((mode & HOSTFS_I(ino)->mode) == mode) diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c index cd2ec2988b59..335c4de6552d 100644 --- a/fs/jfs/jfs_logmgr.c +++ b/fs/jfs/jfs_logmgr.c @@ -1168,7 +1168,7 @@ journal_found: bd_release(bdev); close: /* close external log device */ - blkdev_put(bdev); + blkdev_put(bdev, FMODE_READ|FMODE_WRITE); free: /* free log descriptor */ mutex_unlock(&jfs_log_mutex); @@ -1514,7 +1514,7 @@ int lmLogClose(struct super_block *sb) rc = lmLogShutdown(log); bd_release(bdev); - blkdev_put(bdev); + blkdev_put(bdev, FMODE_READ|FMODE_WRITE); kfree(log); diff --git a/fs/locks.c b/fs/locks.c index 5eb259e3cd38..20457486d6b2 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1580,7 +1580,8 @@ asmlinkage long sys_flock(unsigned int fd, unsigned int cmd) cmd &= ~LOCK_NB; unlock = (cmd == LOCK_UN); - if (!unlock && !(cmd & LOCK_MAND) && !(filp->f_mode & 3)) + if (!unlock && !(cmd & LOCK_MAND) && + !(filp->f_mode & (FMODE_READ|FMODE_WRITE))) goto out_putf; error = flock_make_lock(filp, &lock, cmd); diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index 7dce1612553e..6ebaa58e2c03 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c @@ -976,7 +976,7 @@ static void o2hb_region_release(struct config_item *item) } if (reg->hr_bdev) - blkdev_put(reg->hr_bdev); + blkdev_put(reg->hr_bdev, FMODE_READ|FMODE_WRITE); if (reg->hr_slots) kfree(reg->hr_slots); @@ -1268,7 +1268,7 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, goto out; reg->hr_bdev = I_BDEV(filp->f_mapping->host); - ret = blkdev_get(reg->hr_bdev, FMODE_WRITE | FMODE_READ, 0); + ret = blkdev_get(reg->hr_bdev, FMODE_WRITE | FMODE_READ); if (ret) { reg->hr_bdev = NULL; goto out; @@ -1358,7 +1358,7 @@ out: iput(inode); if (ret < 0) { if (reg->hr_bdev) { - blkdev_put(reg->hr_bdev); + blkdev_put(reg->hr_bdev, FMODE_READ|FMODE_WRITE); reg->hr_bdev = NULL; } } diff --git a/fs/open.c b/fs/open.c index 5596049863bf..83cdb9dee0c1 100644 --- a/fs/open.c +++ b/fs/open.c @@ -798,7 +798,7 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, int error; f->f_flags = flags; - f->f_mode = ((flags+1) & O_ACCMODE) | FMODE_LSEEK | + f->f_mode = (__force fmode_t)((flags+1) & O_ACCMODE) | FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE; inode = dentry->d_inode; if (f->f_mode & FMODE_WRITE) { diff --git a/fs/partitions/check.c b/fs/partitions/check.c index cfb0c80690aa..633f7a0ebb2c 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c @@ -485,10 +485,10 @@ void register_disk(struct gendisk *disk) goto exit; bdev->bd_invalidated = 1; - err = blkdev_get(bdev, FMODE_READ, 0); + err = blkdev_get(bdev, FMODE_READ); if (err < 0) goto exit; - blkdev_put(bdev); + blkdev_put(bdev, FMODE_READ); exit: /* announce disk after possible partitions are created */ diff --git a/fs/proc/base.c b/fs/proc/base.c index b5918ae8ca79..486cf3fe7139 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -1712,9 +1712,9 @@ static struct dentry *proc_fd_instantiate(struct inode *dir, file = fcheck_files(files, fd); if (!file) goto out_unlock; - if (file->f_mode & 1) + if (file->f_mode & FMODE_READ) inode->i_mode |= S_IRUSR | S_IXUSR; - if (file->f_mode & 2) + if (file->f_mode & FMODE_WRITE) inode->i_mode |= S_IWUSR | S_IXUSR; spin_unlock(&files->file_lock); put_files_struct(files); diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index c21df71943a6..9643c3bbeb3b 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c @@ -2575,7 +2575,7 @@ static int release_journal_dev(struct super_block *super, if (journal->j_dev_bd != NULL) { if (journal->j_dev_bd->bd_dev != super->s_dev) bd_release(journal->j_dev_bd); - result = blkdev_put(journal->j_dev_bd); + result = blkdev_put(journal->j_dev_bd, journal->j_dev_mode); journal->j_dev_bd = NULL; } @@ -2593,7 +2593,7 @@ static int journal_init_dev(struct super_block *super, { int result; dev_t jdev; - int blkdev_mode = FMODE_READ | FMODE_WRITE; + fmode_t blkdev_mode = FMODE_READ | FMODE_WRITE; char b[BDEVNAME_SIZE]; result = 0; @@ -2608,6 +2608,7 @@ static int journal_init_dev(struct super_block *super, /* there is no "jdev" option and journal is on separate device */ if ((!jdev_name || !jdev_name[0])) { journal->j_dev_bd = open_by_devnum(jdev, blkdev_mode); + journal->j_dev_mode = blkdev_mode; if (IS_ERR(journal->j_dev_bd)) { result = PTR_ERR(journal->j_dev_bd); journal->j_dev_bd = NULL; @@ -2618,7 +2619,7 @@ static int journal_init_dev(struct super_block *super, } else if (jdev != super->s_dev) { result = bd_claim(journal->j_dev_bd, journal); if (result) { - blkdev_put(journal->j_dev_bd); + blkdev_put(journal->j_dev_bd, blkdev_mode); return result; } @@ -2628,7 +2629,9 @@ static int journal_init_dev(struct super_block *super, return 0; } - journal->j_dev_bd = open_bdev_excl(jdev_name, 0, journal); + journal->j_dev_mode = blkdev_mode; + journal->j_dev_bd = open_bdev_exclusive(jdev_name, + blkdev_mode, journal); if (IS_ERR(journal->j_dev_bd)) { result = PTR_ERR(journal->j_dev_bd); journal->j_dev_bd = NULL; diff --git a/fs/super.c b/fs/super.c index f31ef824d069..400a7608f15e 100644 --- a/fs/super.c +++ b/fs/super.c @@ -755,9 +755,13 @@ int get_sb_bdev(struct file_system_type *fs_type, { struct block_device *bdev; struct super_block *s; + fmode_t mode = FMODE_READ; int error = 0; - bdev = open_bdev_excl(dev_name, flags, fs_type); + if (!(flags & MS_RDONLY)) + mode |= FMODE_WRITE; + + bdev = open_bdev_exclusive(dev_name, mode, fs_type); if (IS_ERR(bdev)) return PTR_ERR(bdev); @@ -780,11 +784,12 @@ int get_sb_bdev(struct file_system_type *fs_type, goto error_bdev; } - close_bdev_excl(bdev); + close_bdev_exclusive(bdev, mode); } else { char b[BDEVNAME_SIZE]; s->s_flags = flags; + s->s_mode = mode; strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id)); sb_set_blocksize(s, block_size(bdev)); error = fill_super(s, data, flags & MS_SILENT ? 1 : 0); @@ -802,7 +807,7 @@ int get_sb_bdev(struct file_system_type *fs_type, error_s: error = PTR_ERR(s); error_bdev: - close_bdev_excl(bdev); + close_bdev_exclusive(bdev, mode); error: return error; } @@ -812,10 +817,11 @@ EXPORT_SYMBOL(get_sb_bdev); void kill_block_super(struct super_block *sb) { struct block_device *bdev = sb->s_bdev; + fmode_t mode = sb->s_mode; generic_shutdown_super(sb); sync_blockdev(bdev); - close_bdev_excl(bdev); + close_bdev_exclusive(bdev, mode); } EXPORT_SYMBOL(kill_block_super); diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index e39013619b26..37ebe36056eb 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -589,7 +589,7 @@ xfs_blkdev_get( { int error = 0; - *bdevp = open_bdev_excl(name, 0, mp); + *bdevp = open_bdev_exclusive(name, FMODE_READ|FMODE_WRITE, mp); if (IS_ERR(*bdevp)) { error = PTR_ERR(*bdevp); printk("XFS: Invalid device [%s], error=%d\n", name, error); @@ -603,7 +603,7 @@ xfs_blkdev_put( struct block_device *bdev) { if (bdev) - close_bdev_excl(bdev); + close_bdev_exclusive(bdev, FMODE_READ|FMODE_WRITE); } /* diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index b4fe68fe3a57..a135256b272c 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -717,10 +717,10 @@ extern void blk_plug_device(struct request_queue *); extern void blk_plug_device_unlocked(struct request_queue *); extern int blk_remove_plug(struct request_queue *); extern void blk_recount_segments(struct request_queue *, struct bio *); -extern int scsi_cmd_ioctl(struct file *, struct request_queue *, - struct gendisk *, unsigned int, void __user *); -extern int sg_scsi_ioctl(struct file *, struct request_queue *, - struct gendisk *, struct scsi_ioctl_command __user *); +extern int scsi_cmd_ioctl(struct request_queue *, struct gendisk *, fmode_t, + unsigned int, void __user *); +extern int sg_scsi_ioctl(struct request_queue *, struct gendisk *, fmode_t, + struct scsi_ioctl_command __user *); /* * Temporary export, until SCSI gets fixed up. @@ -910,7 +910,8 @@ static inline int sb_issue_discard(struct super_block *sb, * command filter functions */ extern int blk_verify_command(struct blk_cmd_filter *filter, - unsigned char *cmd, int has_write_perm); + unsigned char *cmd, fmode_t has_write_perm); +extern void blk_unregister_filter(struct gendisk *disk); extern void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter); #define MAX_PHYS_SEGMENTS 128 @@ -1056,6 +1057,22 @@ static inline int blk_integrity_rq(struct request *rq) #endif /* CONFIG_BLK_DEV_INTEGRITY */ +struct block_device_operations { + 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 *); + int (*revalidate_disk) (struct gendisk *); + int (*getgeo)(struct block_device *, struct hd_geometry *); + struct module *owner; +}; + +extern int __blkdev_driver_ioctl(struct block_device *, fmode_t, unsigned int, + unsigned long); #else /* CONFIG_BLOCK */ /* * stubs for when the block layer is configured out diff --git a/include/linux/cdrom.h b/include/linux/cdrom.h index 5db265ea60f6..0b49e08d3cb0 100644 --- a/include/linux/cdrom.h +++ b/include/linux/cdrom.h @@ -987,11 +987,11 @@ struct cdrom_device_ops { }; /* the general block_device operations structure: */ -extern int cdrom_open(struct cdrom_device_info *cdi, struct inode *ip, - struct file *fp); -extern int cdrom_release(struct cdrom_device_info *cdi, struct file *fp); -extern int cdrom_ioctl(struct file *file, struct cdrom_device_info *cdi, - struct inode *ip, unsigned int cmd, unsigned long arg); +extern int cdrom_open(struct cdrom_device_info *cdi, struct block_device *bdev, + fmode_t mode); +extern void cdrom_release(struct cdrom_device_info *cdi, fmode_t mode); +extern int cdrom_ioctl(struct cdrom_device_info *cdi, struct block_device *bdev, + fmode_t mode, unsigned int cmd, unsigned long arg); extern int cdrom_media_changed(struct cdrom_device_info *); extern int register_cdrom(struct cdrom_device_info *cdi); diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index dfb30db475ed..c17fd334e574 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -69,8 +69,7 @@ typedef int (*dm_status_fn) (struct dm_target *ti, status_type_t status_type, typedef int (*dm_message_fn) (struct dm_target *ti, unsigned argc, char **argv); -typedef int (*dm_ioctl_fn) (struct dm_target *ti, struct inode *inode, - struct file *filp, unsigned int cmd, +typedef int (*dm_ioctl_fn) (struct dm_target *ti, unsigned int cmd, unsigned long arg); typedef int (*dm_merge_fn) (struct dm_target *ti, struct bvec_merge_data *bvm, @@ -85,7 +84,7 @@ void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev); struct dm_dev { struct block_device *bdev; - int mode; + fmode_t mode; char name[16]; }; @@ -95,7 +94,7 @@ struct dm_dev { * FIXME: too many arguments. */ int dm_get_device(struct dm_target *ti, const char *path, sector_t start, - sector_t len, int mode, struct dm_dev **result); + sector_t len, fmode_t mode, struct dm_dev **result); void dm_put_device(struct dm_target *ti, struct dm_dev *d); /* @@ -223,7 +222,7 @@ int dm_set_geometry(struct mapped_device *md, struct hd_geometry *geo); /* * First create an empty table. */ -int dm_table_create(struct dm_table **result, int mode, +int dm_table_create(struct dm_table **result, fmode_t mode, unsigned num_targets, struct mapped_device *md); /* @@ -254,7 +253,7 @@ void dm_table_put(struct dm_table *t); */ sector_t dm_table_get_size(struct dm_table *t); unsigned int dm_table_get_num_targets(struct dm_table *t); -int dm_table_get_mode(struct dm_table *t); +fmode_t dm_table_get_mode(struct dm_table *t); struct mapped_device *dm_table_get_md(struct dm_table *t); /* diff --git a/include/linux/file.h b/include/linux/file.h index a20259e248a5..335a0a5c316e 100644 --- a/include/linux/file.h +++ b/include/linux/file.h @@ -19,10 +19,10 @@ struct file_operations; struct vfsmount; struct dentry; extern int init_file(struct file *, struct vfsmount *mnt, - struct dentry *dentry, mode_t mode, + struct dentry *dentry, fmode_t mode, const struct file_operations *fop); extern struct file *alloc_file(struct vfsmount *, struct dentry *dentry, - mode_t mode, const struct file_operations *fop); + fmode_t mode, const struct file_operations *fop); static inline void fput_light(struct file *file, int fput_needed) { diff --git a/include/linux/fs.h b/include/linux/fs.h index 7d719c1a18e3..43659ae52e4d 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -63,18 +63,23 @@ extern int dir_notify_enable; #define MAY_ACCESS 16 #define MAY_OPEN 32 -#define FMODE_READ 1 -#define FMODE_WRITE 2 +#define FMODE_READ ((__force fmode_t)1) +#define FMODE_WRITE ((__force fmode_t)2) /* Internal kernel extensions */ -#define FMODE_LSEEK 4 -#define FMODE_PREAD 8 +#define FMODE_LSEEK ((__force fmode_t)4) +#define FMODE_PREAD ((__force fmode_t)8) #define FMODE_PWRITE FMODE_PREAD /* These go hand in hand */ /* File is being opened for execution. Primary users of this flag are distributed filesystems that can use it to achieve correct ETXTBUSY behavior for cross-node execution/opening_for_writing of files */ -#define FMODE_EXEC 16 +#define FMODE_EXEC ((__force fmode_t)16) + +#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 @@ -825,7 +830,7 @@ struct file { const struct file_operations *f_op; atomic_long_t f_count; unsigned int f_flags; - mode_t f_mode; + fmode_t f_mode; loff_t f_pos; struct fown_struct f_owner; unsigned int f_uid, f_gid; @@ -1152,6 +1157,7 @@ struct super_block { char s_id[32]; /* Informational name */ void *s_fs_info; /* Filesystem private info */ + fmode_t s_mode; /* * The next field is for VFS *only*. No filesystems have any business @@ -1266,20 +1272,7 @@ int generic_osync_inode(struct inode *, struct address_space *, int); * to have different dirent layouts depending on the binary type. */ typedef int (*filldir_t)(void *, const char *, int, loff_t, u64, unsigned); - -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 (*direct_access) (struct block_device *, sector_t, - void **, unsigned long *); - int (*media_changed) (struct gendisk *); - int (*revalidate_disk) (struct gendisk *); - int (*getgeo)(struct block_device *, struct hd_geometry *); - struct module *owner; -}; +struct block_device_operations; /* These macros are for out of kernel modules to test that * the kernel supports the unlocked_ioctl and compat_ioctl @@ -1713,7 +1706,7 @@ extern struct block_device *bdget(dev_t); extern void bd_set_size(struct block_device *, loff_t size); extern void bd_forget(struct inode *inode); extern void bdput(struct block_device *); -extern struct block_device *open_by_devnum(dev_t, unsigned); +extern struct block_device *open_by_devnum(dev_t, fmode_t); #else static inline void bd_forget(struct inode *inode) {} #endif @@ -1723,13 +1716,10 @@ extern const struct file_operations bad_sock_fops; extern const struct file_operations def_fifo_fops; #ifdef CONFIG_BLOCK extern int ioctl_by_bdev(struct block_device *, unsigned, unsigned long); -extern int blkdev_ioctl(struct inode *, struct file *, unsigned, unsigned long); -extern int blkdev_driver_ioctl(struct inode *inode, struct file *file, - struct gendisk *disk, unsigned cmd, - unsigned long arg); +extern int blkdev_ioctl(struct block_device *, fmode_t, unsigned, unsigned long); extern long compat_blkdev_ioctl(struct file *, unsigned, unsigned long); -extern int blkdev_get(struct block_device *, mode_t, unsigned); -extern int blkdev_put(struct block_device *); +extern int blkdev_get(struct block_device *, fmode_t); +extern int blkdev_put(struct block_device *, fmode_t); extern int bd_claim(struct block_device *, void *); extern void bd_release(struct block_device *); #ifdef CONFIG_SYSFS @@ -1760,9 +1750,10 @@ extern void chrdev_show(struct seq_file *,off_t); extern const char *__bdevname(dev_t, char *buffer); extern const char *bdevname(struct block_device *bdev, char *buffer); extern struct block_device *lookup_bdev(const char *); -extern struct block_device *open_bdev_excl(const char *, int, void *); -extern void close_bdev_excl(struct block_device *); +extern struct block_device *open_bdev_exclusive(const char *, fmode_t, void *); +extern void close_bdev_exclusive(struct block_device *, fmode_t); extern void blkdev_show(struct seq_file *,off_t); + #else #define BLKDEV_MAJOR_HASH_SIZE 0 #endif diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index a89513188ce7..00fbd5b245c9 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -188,7 +188,7 @@ static inline void fsnotify_close(struct file *file) struct dentry *dentry = file->f_path.dentry; struct inode *inode = dentry->d_inode; const char *name = dentry->d_name.name; - mode_t mode = file->f_mode; + fmode_t mode = file->f_mode; u32 mask = (mode & FMODE_WRITE) ? IN_CLOSE_WRITE : IN_CLOSE_NOWRITE; if (S_ISDIR(inode->i_mode)) diff --git a/include/linux/ide.h b/include/linux/ide.h index 89e53cfbc787..54525be4b5f8 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -474,8 +474,8 @@ struct ide_disk_ops { ide_startstop_t (*do_request)(struct ide_drive_s *, struct request *, sector_t); int (*end_request)(struct ide_drive_s *, int, int); - int (*ioctl)(struct ide_drive_s *, struct inode *, - struct file *, unsigned int, unsigned long); + int (*ioctl)(struct ide_drive_s *, struct block_device *, + fmode_t, unsigned int, unsigned long); }; /* ATAPI device flags */ @@ -1158,8 +1158,7 @@ struct ide_ioctl_devset { int ide_setting_ioctl(ide_drive_t *, struct block_device *, unsigned int, unsigned long, const struct ide_ioctl_devset *); -int generic_ide_ioctl(ide_drive_t *, struct file *, struct block_device *, - unsigned, unsigned long); +int generic_ide_ioctl(ide_drive_t *, struct block_device *, unsigned, unsigned long); extern int ide_vlb_clk; extern int ide_pci_clk; diff --git a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h index 315517e8bfa1..bda6b562a1e0 100644 --- a/include/linux/reiserfs_fs_sb.h +++ b/include/linux/reiserfs_fs_sb.h @@ -178,6 +178,7 @@ struct reiserfs_journal { struct reiserfs_journal_cnode *j_first; /* oldest journal block. start here for traverse */ struct block_device *j_dev_bd; + fmode_t j_dev_mode; int j_1st_reserved_block; /* first block on s_dev of reserved area journal */ unsigned long j_state; diff --git a/include/linux/types.h b/include/linux/types.h index f24f7beb47df..1d98330b1f2c 100644 --- a/include/linux/types.h +++ b/include/linux/types.h @@ -190,6 +190,7 @@ typedef __u32 __bitwise __wsum; #ifdef __KERNEL__ typedef unsigned __bitwise__ gfp_t; +typedef unsigned __bitwise__ fmode_t; #ifdef CONFIG_PHYS_ADDR_T_64BIT typedef u64 phys_addr_t; diff --git a/include/scsi/scsi_ioctl.h b/include/scsi/scsi_ioctl.h index edb9525386da..b9006848b813 100644 --- a/include/scsi/scsi_ioctl.h +++ b/include/scsi/scsi_ioctl.h @@ -42,7 +42,7 @@ typedef struct scsi_fctargaddress { extern int scsi_ioctl(struct scsi_device *, int, void __user *); extern int scsi_nonblockable_ioctl(struct scsi_device *sdev, int cmd, - void __user *arg, struct file *filp); + void __user *arg, int ndelay); #endif /* __KERNEL__ */ #endif /* _SCSI_IOCTL_H */ diff --git a/ipc/shm.c b/ipc/shm.c index 0add3fa5f547..867e5d6a55c2 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -817,7 +817,7 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr) struct ipc_namespace *ns; struct shm_file_data *sfd; struct path path; - mode_t f_mode; + fmode_t f_mode; err = -EINVAL; if (shmid < 0) diff --git a/kernel/power/disk.c b/kernel/power/disk.c index 331f9836383f..c9d74083746f 100644 --- a/kernel/power/disk.c +++ b/kernel/power/disk.c @@ -651,7 +651,7 @@ static int software_resume(void) pr_debug("PM: Preparing processes for restore.\n"); error = prepare_processes(); if (error) { - swsusp_close(); + swsusp_close(FMODE_READ); goto Done; } diff --git a/kernel/power/power.h b/kernel/power/power.h index acc0c101dbd5..46b5ec7a3afb 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h @@ -153,7 +153,7 @@ extern int swsusp_shrink_memory(void); extern void swsusp_free(void); extern int swsusp_read(unsigned int *flags_p); extern int swsusp_write(unsigned int flags); -extern void swsusp_close(void); +extern void swsusp_close(fmode_t); struct timeval; /* kernel/power/swsusp.c */ diff --git a/kernel/power/swap.c b/kernel/power/swap.c index 80ccac849e46..b7713b53d07a 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c @@ -172,13 +172,13 @@ static int swsusp_swap_check(void) /* This is called before saving image */ return res; root_swap = res; - res = blkdev_get(resume_bdev, FMODE_WRITE, O_RDWR); + res = blkdev_get(resume_bdev, FMODE_WRITE); if (res) return res; res = set_blocksize(resume_bdev, PAGE_SIZE); if (res < 0) - blkdev_put(resume_bdev); + blkdev_put(resume_bdev, FMODE_WRITE); return res; } @@ -426,7 +426,7 @@ int swsusp_write(unsigned int flags) release_swap_writer(&handle); out: - swsusp_close(); + swsusp_close(FMODE_WRITE); return error; } @@ -574,7 +574,7 @@ int swsusp_read(unsigned int *flags_p) error = load_image(&handle, &snapshot, header->pages - 1); release_swap_reader(&handle); - blkdev_put(resume_bdev); + blkdev_put(resume_bdev, FMODE_READ); if (!error) pr_debug("PM: Image successfully loaded\n"); @@ -609,7 +609,7 @@ int swsusp_check(void) return -EINVAL; } if (error) - blkdev_put(resume_bdev); + blkdev_put(resume_bdev, FMODE_READ); else pr_debug("PM: Signature found, resuming\n"); } else { @@ -626,14 +626,14 @@ int swsusp_check(void) * swsusp_close - close swap device. */ -void swsusp_close(void) +void swsusp_close(fmode_t mode) { if (IS_ERR(resume_bdev)) { pr_debug("PM: Image device not initialised\n"); return; } - blkdev_put(resume_bdev); + blkdev_put(resume_bdev, mode); /* move up */ } static int swsusp_header_init(void) diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 1af62b8b86c6..e17836680f49 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -2283,7 +2283,7 @@ static int snd_pcm_oss_open_file(struct file *file, int idx, err; struct snd_pcm_oss_file *pcm_oss_file; struct snd_pcm_substream *substream; - unsigned int f_mode = file->f_mode; + fmode_t f_mode = file->f_mode; if (rpcm_oss_file) *rpcm_oss_file = NULL; diff --git a/sound/oss/au1550_ac97.c b/sound/oss/au1550_ac97.c index 23018a7c063a..81e1f443d094 100644 --- a/sound/oss/au1550_ac97.c +++ b/sound/oss/au1550_ac97.c @@ -93,7 +93,7 @@ static struct au1550_state { spinlock_t lock; struct mutex open_mutex; struct mutex sem; - mode_t open_mode; + fmode_t open_mode; wait_queue_head_t open_wait; struct dmabuf { diff --git a/sound/oss/dmasound/dmasound.h b/sound/oss/dmasound/dmasound.h index d978b0096564..1cb13fe56ec4 100644 --- a/sound/oss/dmasound/dmasound.h +++ b/sound/oss/dmasound/dmasound.h @@ -129,7 +129,7 @@ typedef struct { int (*mixer_ioctl)(u_int, u_long); /* optional */ int (*write_sq_setup)(void); /* optional */ int (*read_sq_setup)(void); /* optional */ - int (*sq_open)(mode_t); /* optional */ + int (*sq_open)(fmode_t); /* optional */ int (*state_info)(char *, size_t); /* optional */ void (*abort_read)(void); /* optional */ int min_dsp_speed; @@ -235,7 +235,7 @@ struct sound_queue { */ int active; wait_queue_head_t action_queue, open_queue, sync_queue; - int open_mode; + fmode_t open_mode; int busy, syncing, xruns, died; }; diff --git a/sound/oss/dmasound/dmasound_atari.c b/sound/oss/dmasound/dmasound_atari.c index 285239d64b82..4d45bd63718b 100644 --- a/sound/oss/dmasound/dmasound_atari.c +++ b/sound/oss/dmasound/dmasound_atari.c @@ -143,7 +143,7 @@ static int AtaMixerIoctl(u_int cmd, u_long arg); static int TTMixerIoctl(u_int cmd, u_long arg); static int FalconMixerIoctl(u_int cmd, u_long arg); static int AtaWriteSqSetup(void); -static int AtaSqOpen(mode_t mode); +static int AtaSqOpen(fmode_t mode); static int TTStateInfo(char *buffer, size_t space); static int FalconStateInfo(char *buffer, size_t space); @@ -1461,7 +1461,7 @@ static int AtaWriteSqSetup(void) return 0 ; } -static int AtaSqOpen(mode_t mode) +static int AtaSqOpen(fmode_t mode) { write_sq_ignore_int = 1; return 0 ; diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c index 95fc5c681755..b8239f3168fb 100644 --- a/sound/oss/dmasound/dmasound_core.c +++ b/sound/oss/dmasound/dmasound_core.c @@ -212,7 +212,7 @@ static int irq_installed; #endif /* MODULE */ /* control over who can modify resources shared between play/record */ -static mode_t shared_resource_owner; +static fmode_t shared_resource_owner; static int shared_resources_initialised; /* @@ -668,7 +668,7 @@ static inline void sq_init_waitqueue(struct sound_queue *sq) #if 0 /* blocking open() */ static inline void sq_wake_up(struct sound_queue *sq, struct file *file, - mode_t mode) + fmode_t mode) { if (file->f_mode & mode) { sq->busy = 0; /* CHECK: IS THIS OK??? */ @@ -677,7 +677,7 @@ static inline void sq_wake_up(struct sound_queue *sq, struct file *file, } #endif -static int sq_open2(struct sound_queue *sq, struct file *file, mode_t mode, +static int sq_open2(struct sound_queue *sq, struct file *file, fmode_t mode, int numbufs, int bufsize) { int rc = 0; @@ -891,10 +891,10 @@ static int sq_release(struct inode *inode, struct file *file) is the owner - if we have problems. */ -static int shared_resources_are_mine(mode_t md) +static int shared_resources_are_mine(fmode_t md) { if (shared_resource_owner) - return (shared_resource_owner & md ) ; + return (shared_resource_owner & md) != 0; else { shared_resource_owner = md ; return 1 ; diff --git a/sound/oss/msnd.h b/sound/oss/msnd.h index 61b3955481c5..c8be47ec2b7e 100644 --- a/sound/oss/msnd.h +++ b/sound/oss/msnd.h @@ -211,7 +211,7 @@ typedef struct multisound_dev { /* State variables */ enum { msndClassic, msndPinnacle } type; - mode_t mode; + fmode_t mode; unsigned long flags; #define F_RESETTING 0 #define F_HAVEDIGITAL 1 diff --git a/sound/oss/sound_config.h b/sound/oss/sound_config.h index 1a00a3210616..55271fbe7f49 100644 --- a/sound/oss/sound_config.h +++ b/sound/oss/sound_config.h @@ -110,24 +110,16 @@ struct channel_info { #define OPEN_WRITE PCM_ENABLE_OUTPUT #define OPEN_READWRITE (OPEN_READ|OPEN_WRITE) -#if OPEN_READ == FMODE_READ && OPEN_WRITE == FMODE_WRITE - -static inline int translate_mode(struct file *file) -{ - return file->f_mode; -} - -#else - static inline int translate_mode(struct file *file) { - return ((file->f_mode & FMODE_READ) ? OPEN_READ : 0) | - ((file->f_mode & FMODE_WRITE) ? OPEN_WRITE : 0); + if (OPEN_READ == (__force int)FMODE_READ && + OPEN_WRITE == (__force int)FMODE_WRITE) + return (__force int)(file->f_mode & (FMODE_READ | FMODE_WRITE)); + else + return ((file->f_mode & FMODE_READ) ? OPEN_READ : 0) | + ((file->f_mode & FMODE_WRITE) ? OPEN_WRITE : 0); } -#endif - - #include "sound_calls.h" #include "dev_table.h" diff --git a/sound/oss/swarm_cs4297a.c b/sound/oss/swarm_cs4297a.c index 044453a4ee5b..41562ecde5bb 100644 --- a/sound/oss/swarm_cs4297a.c +++ b/sound/oss/swarm_cs4297a.c @@ -295,7 +295,7 @@ struct cs4297a_state { struct mutex open_mutex; struct mutex open_sem_adc; struct mutex open_sem_dac; - mode_t open_mode; + fmode_t open_mode; wait_queue_head_t open_wait; wait_queue_head_t open_wait_adc; wait_queue_head_t open_wait_dac; diff --git a/sound/oss/vwsnd.c b/sound/oss/vwsnd.c index dcbb3f739e61..78b8acc7c3b9 100644 --- a/sound/oss/vwsnd.c +++ b/sound/oss/vwsnd.c @@ -1509,7 +1509,7 @@ typedef struct vwsnd_dev { struct mutex open_mutex; struct mutex io_mutex; struct mutex mix_mutex; - mode_t open_mode; + fmode_t open_mode; wait_queue_head_t open_wait; lithium_t lith; |