aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
Diffstat (limited to 'block')
-rw-r--r--block/bsg.c9
-rw-r--r--block/cmd-filter.c2
-rw-r--r--block/compat_ioctl.c177
-rw-r--r--block/ioctl.c173
-rw-r--r--block/scsi_ioctl.c33
5 files changed, 179 insertions, 215 deletions
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:
173 173
174static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq, 174static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq,
175 struct sg_io_v4 *hdr, struct bsg_device *bd, 175 struct sg_io_v4 *hdr, struct bsg_device *bd,
176 int has_write_perm) 176 fmode_t has_write_perm)
177{ 177{
178 if (hdr->request_len > BLK_MAX_CDB) { 178 if (hdr->request_len > BLK_MAX_CDB) {
179 rq->cmd = kzalloc(hdr->request_len, GFP_KERNEL); 179 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)
242 * map sg_io_v4 to a request. 242 * map sg_io_v4 to a request.
243 */ 243 */
244static struct request * 244static struct request *
245bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, int has_write_perm) 245bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm)
246{ 246{
247 struct request_queue *q = bd->queue; 247 struct request_queue *q = bd->queue;
248 struct request *rq, *next_rq = NULL; 248 struct request *rq, *next_rq = NULL;
@@ -601,7 +601,8 @@ bsg_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
601} 601}
602 602
603static int __bsg_write(struct bsg_device *bd, const char __user *buf, 603static int __bsg_write(struct bsg_device *bd, const char __user *buf,
604 size_t count, ssize_t *bytes_written, int has_write_perm) 604 size_t count, ssize_t *bytes_written,
605 fmode_t has_write_perm)
605{ 606{
606 struct bsg_command *bc; 607 struct bsg_command *bc;
607 struct request *rq; 608 struct request *rq;
@@ -913,7 +914,7 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
913 case SG_EMULATED_HOST: 914 case SG_EMULATED_HOST:
914 case SCSI_IOCTL_SEND_COMMAND: { 915 case SCSI_IOCTL_SEND_COMMAND: {
915 void __user *uarg = (void __user *) arg; 916 void __user *uarg = (void __user *) arg;
916 return scsi_cmd_ioctl(file, bd->queue, NULL, cmd, uarg); 917 return scsi_cmd_ioctl(bd->queue, NULL, file->f_mode, cmd, uarg);
917 } 918 }
918 case SG_IO: { 919 case SG_IO: {
919 struct request *rq; 920 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 @@
27#include <linux/cdrom.h> 27#include <linux/cdrom.h>
28 28
29int blk_verify_command(struct blk_cmd_filter *filter, 29int blk_verify_command(struct blk_cmd_filter *filter,
30 unsigned char *cmd, int has_write_perm) 30 unsigned char *cmd, fmode_t has_write_perm)
31{ 31{
32 /* root can do any command. */ 32 /* root can do any command. */
33 if (capable(CAP_SYS_RAWIO)) 33 if (capable(CAP_SYS_RAWIO))
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
index 1e559fba7bdf..3d3e7a46f38c 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,
71 return ret; 71 return ret;
72} 72}
73 73
74static int compat_hdio_ioctl(struct inode *inode, struct file *file, 74static int compat_hdio_ioctl(struct block_device *bdev, fmode_t mode,
75 struct gendisk *disk, unsigned int cmd, unsigned long arg) 75 unsigned int cmd, unsigned long arg)
76{ 76{
77 mm_segment_t old_fs = get_fs(); 77 mm_segment_t old_fs = get_fs();
78 unsigned long kval; 78 unsigned long kval;
@@ -80,7 +80,7 @@ static int compat_hdio_ioctl(struct inode *inode, struct file *file,
80 int error; 80 int error;
81 81
82 set_fs(KERNEL_DS); 82 set_fs(KERNEL_DS);
83 error = blkdev_driver_ioctl(inode, file, disk, 83 error = __blkdev_driver_ioctl(bdev, mode,
84 cmd, (unsigned long)(&kval)); 84 cmd, (unsigned long)(&kval));
85 set_fs(old_fs); 85 set_fs(old_fs);
86 86
@@ -111,8 +111,8 @@ struct compat_cdrom_generic_command {
111 compat_caddr_t reserved[1]; 111 compat_caddr_t reserved[1];
112}; 112};
113 113
114static int compat_cdrom_read_audio(struct inode *inode, struct file *file, 114static int compat_cdrom_read_audio(struct block_device *bdev, fmode_t mode,
115 struct gendisk *disk, unsigned int cmd, unsigned long arg) 115 unsigned int cmd, unsigned long arg)
116{ 116{
117 struct cdrom_read_audio __user *cdread_audio; 117 struct cdrom_read_audio __user *cdread_audio;
118 struct compat_cdrom_read_audio __user *cdread_audio32; 118 struct compat_cdrom_read_audio __user *cdread_audio32;
@@ -134,12 +134,12 @@ static int compat_cdrom_read_audio(struct inode *inode, struct file *file,
134 if (put_user(datap, &cdread_audio->buf)) 134 if (put_user(datap, &cdread_audio->buf))
135 return -EFAULT; 135 return -EFAULT;
136 136
137 return blkdev_driver_ioctl(inode, file, disk, cmd, 137 return __blkdev_driver_ioctl(bdev, mode, cmd,
138 (unsigned long)cdread_audio); 138 (unsigned long)cdread_audio);
139} 139}
140 140
141static int compat_cdrom_generic_command(struct inode *inode, struct file *file, 141static int compat_cdrom_generic_command(struct block_device *bdev, fmode_t mode,
142 struct gendisk *disk, unsigned int cmd, unsigned long arg) 142 unsigned int cmd, unsigned long arg)
143{ 143{
144 struct cdrom_generic_command __user *cgc; 144 struct cdrom_generic_command __user *cgc;
145 struct compat_cdrom_generic_command __user *cgc32; 145 struct compat_cdrom_generic_command __user *cgc32;
@@ -167,7 +167,7 @@ static int compat_cdrom_generic_command(struct inode *inode, struct file *file,
167 put_user(compat_ptr(data), &cgc->reserved[0])) 167 put_user(compat_ptr(data), &cgc->reserved[0]))
168 return -EFAULT; 168 return -EFAULT;
169 169
170 return blkdev_driver_ioctl(inode, file, disk, cmd, (unsigned long)cgc); 170 return __blkdev_driver_ioctl(bdev, mode, cmd, (unsigned long)cgc);
171} 171}
172 172
173struct compat_blkpg_ioctl_arg { 173struct compat_blkpg_ioctl_arg {
@@ -177,7 +177,7 @@ struct compat_blkpg_ioctl_arg {
177 compat_caddr_t data; 177 compat_caddr_t data;
178}; 178};
179 179
180static int compat_blkpg_ioctl(struct inode *inode, struct file *file, 180static int compat_blkpg_ioctl(struct block_device *bdev, fmode_t mode,
181 unsigned int cmd, struct compat_blkpg_ioctl_arg __user *ua32) 181 unsigned int cmd, struct compat_blkpg_ioctl_arg __user *ua32)
182{ 182{
183 struct blkpg_ioctl_arg __user *a = compat_alloc_user_space(sizeof(*a)); 183 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,
196 if (err) 196 if (err)
197 return err; 197 return err;
198 198
199 return blkdev_ioctl(inode, file, cmd, (unsigned long)a); 199 return blkdev_ioctl(bdev, mode, cmd, (unsigned long)a);
200} 200}
201 201
202#define BLKBSZGET_32 _IOR(0x12, 112, int) 202#define BLKBSZGET_32 _IOR(0x12, 112, int)
@@ -308,8 +308,8 @@ static struct {
308 308
309#define NR_FD_IOCTL_TRANS ARRAY_SIZE(fd_ioctl_trans_table) 309#define NR_FD_IOCTL_TRANS ARRAY_SIZE(fd_ioctl_trans_table)
310 310
311static int compat_fd_ioctl(struct inode *inode, struct file *file, 311static int compat_fd_ioctl(struct block_device *bdev, fmode_t mode,
312 struct gendisk *disk, unsigned int cmd, unsigned long arg) 312 unsigned int cmd, unsigned long arg)
313{ 313{
314 mm_segment_t old_fs = get_fs(); 314 mm_segment_t old_fs = get_fs();
315 void *karg = NULL; 315 void *karg = NULL;
@@ -413,7 +413,7 @@ static int compat_fd_ioctl(struct inode *inode, struct file *file,
413 return -EINVAL; 413 return -EINVAL;
414 } 414 }
415 set_fs(KERNEL_DS); 415 set_fs(KERNEL_DS);
416 err = blkdev_driver_ioctl(inode, file, disk, kcmd, (unsigned long)karg); 416 err = __blkdev_driver_ioctl(bdev, mode, kcmd, (unsigned long)karg);
417 set_fs(old_fs); 417 set_fs(old_fs);
418 if (err) 418 if (err)
419 goto out; 419 goto out;
@@ -579,11 +579,9 @@ static int compat_blk_trace_setup(struct block_device *bdev, char __user *arg)
579 return 0; 579 return 0;
580} 580}
581 581
582static int compat_blkdev_driver_ioctl(struct inode *inode, struct file *file, 582static int compat_blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode,
583 struct gendisk *disk, unsigned cmd, unsigned long arg) 583 unsigned cmd, unsigned long arg)
584{ 584{
585 int ret;
586
587 switch (cmd) { 585 switch (cmd) {
588 case HDIO_GET_UNMASKINTR: 586 case HDIO_GET_UNMASKINTR:
589 case HDIO_GET_MULTCOUNT: 587 case HDIO_GET_MULTCOUNT:
@@ -596,7 +594,7 @@ static int compat_blkdev_driver_ioctl(struct inode *inode, struct file *file,
596 case HDIO_GET_ACOUSTIC: 594 case HDIO_GET_ACOUSTIC:
597 case HDIO_GET_ADDRESS: 595 case HDIO_GET_ADDRESS:
598 case HDIO_GET_BUSSTATE: 596 case HDIO_GET_BUSSTATE:
599 return compat_hdio_ioctl(inode, file, disk, cmd, arg); 597 return compat_hdio_ioctl(bdev, mode, cmd, arg);
600 case FDSETPRM32: 598 case FDSETPRM32:
601 case FDDEFPRM32: 599 case FDDEFPRM32:
602 case FDGETPRM32: 600 case FDGETPRM32:
@@ -606,11 +604,11 @@ static int compat_blkdev_driver_ioctl(struct inode *inode, struct file *file,
606 case FDPOLLDRVSTAT32: 604 case FDPOLLDRVSTAT32:
607 case FDGETFDCSTAT32: 605 case FDGETFDCSTAT32:
608 case FDWERRORGET32: 606 case FDWERRORGET32:
609 return compat_fd_ioctl(inode, file, disk, cmd, arg); 607 return compat_fd_ioctl(bdev, mode, cmd, arg);
610 case CDROMREADAUDIO: 608 case CDROMREADAUDIO:
611 return compat_cdrom_read_audio(inode, file, disk, cmd, arg); 609 return compat_cdrom_read_audio(bdev, mode, cmd, arg);
612 case CDROM_SEND_PACKET: 610 case CDROM_SEND_PACKET:
613 return compat_cdrom_generic_command(inode, file, disk, cmd, arg); 611 return compat_cdrom_generic_command(bdev, mode, cmd, arg);
614 612
615 /* 613 /*
616 * No handler required for the ones below, we just need to 614 * No handler required for the ones below, we just need to
@@ -679,55 +677,49 @@ static int compat_blkdev_driver_ioctl(struct inode *inode, struct file *file,
679 case DVD_WRITE_STRUCT: 677 case DVD_WRITE_STRUCT:
680 case DVD_AUTH: 678 case DVD_AUTH:
681 arg = (unsigned long)compat_ptr(arg); 679 arg = (unsigned long)compat_ptr(arg);
682 /* These intepret arg as an unsigned long, not as a pointer,
683 * so we must not do compat_ptr() conversion. */
684 case HDIO_SET_MULTCOUNT:
685 case HDIO_SET_UNMASKINTR:
686 case HDIO_SET_KEEPSETTINGS:
687 case HDIO_SET_32BIT:
688 case HDIO_SET_NOWERR:
689 case HDIO_SET_DMA:
690 case HDIO_SET_PIO_MODE:
691 case HDIO_SET_NICE:
692 case HDIO_SET_WCACHE:
693 case HDIO_SET_ACOUSTIC:
694 case HDIO_SET_BUSSTATE:
695 case HDIO_SET_ADDRESS:
696 case CDROMEJECT_SW:
697 case CDROM_SET_OPTIONS:
698 case CDROM_CLEAR_OPTIONS:
699 case CDROM_SELECT_SPEED:
700 case CDROM_SELECT_DISC:
701 case CDROM_MEDIA_CHANGED:
702 case CDROM_DRIVE_STATUS:
703 case CDROM_LOCKDOOR:
704 case CDROM_DEBUG:
705 break; 680 break;
706 default: 681 default:
707 /* unknown ioctl number */ 682 /* unknown ioctl number */
708 return -ENOIOCTLCMD; 683 return -ENOIOCTLCMD;
709 } 684 }
710 685
711 if (disk->fops->unlocked_ioctl) 686 return __blkdev_driver_ioctl(bdev, mode, cmd, arg);
712 return disk->fops->unlocked_ioctl(file, cmd, arg);
713
714 if (disk->fops->ioctl) {
715 lock_kernel();
716 ret = disk->fops->ioctl(inode, file, cmd, arg);
717 unlock_kernel();
718 return ret;
719 }
720
721 return -ENOTTY;
722} 687}
723 688
724static int compat_blkdev_locked_ioctl(struct inode *inode, struct file *file, 689/* Most of the generic ioctls are handled in the normal fallback path.
725 struct block_device *bdev, 690 This assumes the blkdev's low level compat_ioctl always returns
726 unsigned cmd, unsigned long arg) 691 ENOIOCTLCMD for unknown ioctls. */
692long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
727{ 693{
694 int ret = -ENOIOCTLCMD;
695 struct inode *inode = file->f_mapping->host;
696 struct block_device *bdev = inode->i_bdev;
697 struct gendisk *disk = bdev->bd_disk;
698 fmode_t mode = file->f_mode;
728 struct backing_dev_info *bdi; 699 struct backing_dev_info *bdi;
700 loff_t size;
701
702 if (file->f_flags & O_NDELAY)
703 mode |= FMODE_NDELAY_NOW;
729 704
730 switch (cmd) { 705 switch (cmd) {
706 case HDIO_GETGEO:
707 return compat_hdio_getgeo(disk, bdev, compat_ptr(arg));
708 case BLKFLSBUF:
709 case BLKROSET:
710 case BLKDISCARD:
711 /*
712 * the ones below are implemented in blkdev_locked_ioctl,
713 * but we call blkdev_ioctl, which gets the lock for us
714 */
715 case BLKRRPART:
716 return blkdev_ioctl(bdev, mode, cmd,
717 (unsigned long)compat_ptr(arg));
718 case BLKBSZSET_32:
719 return blkdev_ioctl(bdev, mode, BLKBSZSET,
720 (unsigned long)compat_ptr(arg));
721 case BLKPG:
722 return compat_blkpg_ioctl(bdev, mode, cmd, compat_ptr(arg));
731 case BLKRAGET: 723 case BLKRAGET:
732 case BLKFRAGET: 724 case BLKFRAGET:
733 if (!arg) 725 if (!arg)
@@ -753,65 +745,36 @@ static int compat_blkdev_locked_ioctl(struct inode *inode, struct file *file,
753 bdi = blk_get_backing_dev_info(bdev); 745 bdi = blk_get_backing_dev_info(bdev);
754 if (bdi == NULL) 746 if (bdi == NULL)
755 return -ENOTTY; 747 return -ENOTTY;
748 lock_kernel();
756 bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE; 749 bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE;
750 unlock_kernel();
757 return 0; 751 return 0;
758 case BLKGETSIZE: 752 case BLKGETSIZE:
759 if ((bdev->bd_inode->i_size >> 9) > ~0UL) 753 size = bdev->bd_inode->i_size;
754 if ((size >> 9) > ~0UL)
760 return -EFBIG; 755 return -EFBIG;
761 return compat_put_ulong(arg, bdev->bd_inode->i_size >> 9); 756 return compat_put_ulong(arg, size >> 9);
762 757
763 case BLKGETSIZE64_32: 758 case BLKGETSIZE64_32:
764 return compat_put_u64(arg, bdev->bd_inode->i_size); 759 return compat_put_u64(arg, bdev->bd_inode->i_size);
765 760
766 case BLKTRACESETUP32: 761 case BLKTRACESETUP32:
767 return compat_blk_trace_setup(bdev, compat_ptr(arg)); 762 lock_kernel();
763 ret = compat_blk_trace_setup(bdev, compat_ptr(arg));
764 unlock_kernel();
765 return ret;
768 case BLKTRACESTART: /* compatible */ 766 case BLKTRACESTART: /* compatible */
769 case BLKTRACESTOP: /* compatible */ 767 case BLKTRACESTOP: /* compatible */
770 case BLKTRACETEARDOWN: /* compatible */ 768 case BLKTRACETEARDOWN: /* compatible */
771 return blk_trace_ioctl(bdev, cmd, compat_ptr(arg)); 769 lock_kernel();
772 } 770 ret = blk_trace_ioctl(bdev, cmd, compat_ptr(arg));
773 return -ENOIOCTLCMD; 771 unlock_kernel();
774}
775
776/* Most of the generic ioctls are handled in the normal fallback path.
777 This assumes the blkdev's low level compat_ioctl always returns
778 ENOIOCTLCMD for unknown ioctls. */
779long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
780{
781 int ret = -ENOIOCTLCMD;
782 struct inode *inode = file->f_mapping->host;
783 struct block_device *bdev = inode->i_bdev;
784 struct gendisk *disk = bdev->bd_disk;
785
786 switch (cmd) {
787 case HDIO_GETGEO:
788 return compat_hdio_getgeo(disk, bdev, compat_ptr(arg));
789 case BLKFLSBUF:
790 case BLKROSET:
791 case BLKDISCARD:
792 /*
793 * the ones below are implemented in blkdev_locked_ioctl,
794 * but we call blkdev_ioctl, which gets the lock for us
795 */
796 case BLKRRPART:
797 return blkdev_ioctl(inode, file, cmd,
798 (unsigned long)compat_ptr(arg));
799 case BLKBSZSET_32:
800 return blkdev_ioctl(inode, file, BLKBSZSET,
801 (unsigned long)compat_ptr(arg));
802 case BLKPG:
803 return compat_blkpg_ioctl(inode, file, cmd, compat_ptr(arg));
804 }
805
806 lock_kernel();
807 ret = compat_blkdev_locked_ioctl(inode, file, bdev, cmd, arg);
808 /* FIXME: why do we assume -> compat_ioctl needs the BKL? */
809 if (ret == -ENOIOCTLCMD && disk->fops->compat_ioctl)
810 ret = disk->fops->compat_ioctl(file, cmd, arg);
811 unlock_kernel();
812
813 if (ret != -ENOIOCTLCMD)
814 return ret; 772 return ret;
815 773 default:
816 return compat_blkdev_driver_ioctl(inode, file, disk, cmd, arg); 774 if (disk->fops->compat_ioctl)
775 ret = disk->fops->compat_ioctl(bdev, mode, cmd, arg);
776 if (ret == -ENOIOCTLCMD)
777 ret = compat_blkdev_driver_ioctl(bdev, mode, cmd, arg);
778 return ret;
779 }
817} 780}
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)
201 return put_user(val, (u64 __user *)arg); 201 return put_user(val, (u64 __user *)arg);
202} 202}
203 203
204static int blkdev_locked_ioctl(struct file *file, struct block_device *bdev, 204int __blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode,
205 unsigned cmd, unsigned long arg) 205 unsigned cmd, unsigned long arg)
206{
207 struct backing_dev_info *bdi;
208 int ret, n;
209
210 switch (cmd) {
211 case BLKRAGET:
212 case BLKFRAGET:
213 if (!arg)
214 return -EINVAL;
215 bdi = blk_get_backing_dev_info(bdev);
216 if (bdi == NULL)
217 return -ENOTTY;
218 return put_long(arg, (bdi->ra_pages * PAGE_CACHE_SIZE) / 512);
219 case BLKROGET:
220 return put_int(arg, bdev_read_only(bdev) != 0);
221 case BLKBSZGET: /* get the logical block size (cf. BLKSSZGET) */
222 return put_int(arg, block_size(bdev));
223 case BLKSSZGET: /* get block device hardware sector size */
224 return put_int(arg, bdev_hardsect_size(bdev));
225 case BLKSECTGET:
226 return put_ushort(arg, bdev_get_queue(bdev)->max_sectors);
227 case BLKRASET:
228 case BLKFRASET:
229 if(!capable(CAP_SYS_ADMIN))
230 return -EACCES;
231 bdi = blk_get_backing_dev_info(bdev);
232 if (bdi == NULL)
233 return -ENOTTY;
234 bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE;
235 return 0;
236 case BLKBSZSET:
237 /* set the logical block size */
238 if (!capable(CAP_SYS_ADMIN))
239 return -EACCES;
240 if (!arg)
241 return -EINVAL;
242 if (get_user(n, (int __user *) arg))
243 return -EFAULT;
244 if (bd_claim(bdev, file) < 0)
245 return -EBUSY;
246 ret = set_blocksize(bdev, n);
247 bd_release(bdev);
248 return ret;
249 case BLKPG:
250 return blkpg_ioctl(bdev, (struct blkpg_ioctl_arg __user *) arg);
251 case BLKRRPART:
252 return blkdev_reread_part(bdev);
253 case BLKGETSIZE:
254 if ((bdev->bd_inode->i_size >> 9) > ~0UL)
255 return -EFBIG;
256 return put_ulong(arg, bdev->bd_inode->i_size >> 9);
257 case BLKGETSIZE64:
258 return put_u64(arg, bdev->bd_inode->i_size);
259 case BLKTRACESTART:
260 case BLKTRACESTOP:
261 case BLKTRACESETUP:
262 case BLKTRACETEARDOWN:
263 return blk_trace_ioctl(bdev, cmd, (char __user *) arg);
264 }
265 return -ENOIOCTLCMD;
266}
267
268int blkdev_driver_ioctl(struct inode *inode, struct file *file,
269 struct gendisk *disk, unsigned cmd, unsigned long arg)
270{ 206{
207 struct gendisk *disk = bdev->bd_disk;
271 int ret; 208 int ret;
272 if (disk->fops->unlocked_ioctl)
273 return disk->fops->unlocked_ioctl(file, cmd, arg);
274 209
275 if (disk->fops->ioctl) { 210 if (disk->fops->ioctl)
211 return disk->fops->ioctl(bdev, mode, cmd, arg);
212
213 if (disk->fops->locked_ioctl) {
276 lock_kernel(); 214 lock_kernel();
277 ret = disk->fops->ioctl(inode, file, cmd, arg); 215 ret = disk->fops->locked_ioctl(bdev, mode, cmd, arg);
278 unlock_kernel(); 216 unlock_kernel();
279 return ret; 217 return ret;
280 } 218 }
281 219
282 return -ENOTTY; 220 return -ENOTTY;
283} 221}
284EXPORT_SYMBOL_GPL(blkdev_driver_ioctl); 222/*
223 * For the record: _GPL here is only because somebody decided to slap it
224 * on the previous export. Sheer idiocy, since it wasn't copyrightable
225 * at all and could be open-coded without any exports by anybody who cares.
226 */
227EXPORT_SYMBOL_GPL(__blkdev_driver_ioctl);
285 228
286/* 229/*
287 * always keep this in sync with compat_blkdev_ioctl() and 230 * always keep this in sync with compat_blkdev_ioctl() and
288 * compat_blkdev_locked_ioctl() 231 * compat_blkdev_locked_ioctl()
289 */ 232 */
290int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd, 233int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
291 unsigned long arg) 234 unsigned long arg)
292{ 235{
293 struct block_device *bdev = inode->i_bdev;
294 struct gendisk *disk = bdev->bd_disk; 236 struct gendisk *disk = bdev->bd_disk;
237 struct backing_dev_info *bdi;
238 loff_t size;
295 int ret, n; 239 int ret, n;
296 240
297 switch(cmd) { 241 switch(cmd) {
@@ -299,7 +243,7 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
299 if (!capable(CAP_SYS_ADMIN)) 243 if (!capable(CAP_SYS_ADMIN))
300 return -EACCES; 244 return -EACCES;
301 245
302 ret = blkdev_driver_ioctl(inode, file, disk, cmd, arg); 246 ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg);
303 /* -EINVAL to handle old uncorrected drivers */ 247 /* -EINVAL to handle old uncorrected drivers */
304 if (ret != -EINVAL && ret != -ENOTTY) 248 if (ret != -EINVAL && ret != -ENOTTY)
305 return ret; 249 return ret;
@@ -311,7 +255,7 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
311 return 0; 255 return 0;
312 256
313 case BLKROSET: 257 case BLKROSET:
314 ret = blkdev_driver_ioctl(inode, file, disk, cmd, arg); 258 ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg);
315 /* -EINVAL to handle old uncorrected drivers */ 259 /* -EINVAL to handle old uncorrected drivers */
316 if (ret != -EINVAL && ret != -ENOTTY) 260 if (ret != -EINVAL && ret != -ENOTTY)
317 return ret; 261 return ret;
@@ -327,7 +271,7 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
327 case BLKDISCARD: { 271 case BLKDISCARD: {
328 uint64_t range[2]; 272 uint64_t range[2];
329 273
330 if (!(file->f_mode & FMODE_WRITE)) 274 if (!(mode & FMODE_WRITE))
331 return -EBADF; 275 return -EBADF;
332 276
333 if (copy_from_user(range, (void __user *)arg, sizeof(range))) 277 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,
357 return -EFAULT; 301 return -EFAULT;
358 return 0; 302 return 0;
359 } 303 }
360 } 304 case BLKRAGET:
361 305 case BLKFRAGET:
362 lock_kernel(); 306 if (!arg)
363 ret = blkdev_locked_ioctl(file, bdev, cmd, arg); 307 return -EINVAL;
364 unlock_kernel(); 308 bdi = blk_get_backing_dev_info(bdev);
365 if (ret != -ENOIOCTLCMD) 309 if (bdi == NULL)
310 return -ENOTTY;
311 return put_long(arg, (bdi->ra_pages * PAGE_CACHE_SIZE) / 512);
312 case BLKROGET:
313 return put_int(arg, bdev_read_only(bdev) != 0);
314 case BLKBSZGET: /* get the logical block size (cf. BLKSSZGET) */
315 return put_int(arg, block_size(bdev));
316 case BLKSSZGET: /* get block device hardware sector size */
317 return put_int(arg, bdev_hardsect_size(bdev));
318 case BLKSECTGET:
319 return put_ushort(arg, bdev_get_queue(bdev)->max_sectors);
320 case BLKRASET:
321 case BLKFRASET:
322 if(!capable(CAP_SYS_ADMIN))
323 return -EACCES;
324 bdi = blk_get_backing_dev_info(bdev);
325 if (bdi == NULL)
326 return -ENOTTY;
327 lock_kernel();
328 bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE;
329 unlock_kernel();
330 return 0;
331 case BLKBSZSET:
332 /* set the logical block size */
333 if (!capable(CAP_SYS_ADMIN))
334 return -EACCES;
335 if (!arg)
336 return -EINVAL;
337 if (get_user(n, (int __user *) arg))
338 return -EFAULT;
339 if (!(mode & FMODE_EXCL) && bd_claim(bdev, &bdev) < 0)
340 return -EBUSY;
341 ret = set_blocksize(bdev, n);
342 if (!(mode & FMODE_EXCL))
343 bd_release(bdev);
366 return ret; 344 return ret;
367 345 case BLKPG:
368 return blkdev_driver_ioctl(inode, file, disk, cmd, arg); 346 lock_kernel();
347 ret = blkpg_ioctl(bdev, (struct blkpg_ioctl_arg __user *) arg);
348 unlock_kernel();
349 break;
350 case BLKRRPART:
351 lock_kernel();
352 ret = blkdev_reread_part(bdev);
353 unlock_kernel();
354 break;
355 case BLKGETSIZE:
356 size = bdev->bd_inode->i_size;
357 if ((size >> 9) > ~0UL)
358 return -EFBIG;
359 return put_ulong(arg, size >> 9);
360 case BLKGETSIZE64:
361 return put_u64(arg, bdev->bd_inode->i_size);
362 case BLKTRACESTART:
363 case BLKTRACESTOP:
364 case BLKTRACESETUP:
365 case BLKTRACETEARDOWN:
366 lock_kernel();
367 ret = blk_trace_ioctl(bdev, cmd, (char __user *) arg);
368 unlock_kernel();
369 break;
370 default:
371 ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg);
372 }
373 return ret;
369} 374}
370EXPORT_SYMBOL_GPL(blkdev_ioctl); 375EXPORT_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)
190EXPORT_SYMBOL_GPL(blk_set_cmd_filter_defaults); 190EXPORT_SYMBOL_GPL(blk_set_cmd_filter_defaults);
191 191
192static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq, 192static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq,
193 struct sg_io_hdr *hdr, struct file *file) 193 struct sg_io_hdr *hdr, fmode_t mode)
194{ 194{
195 if (copy_from_user(rq->cmd, hdr->cmdp, hdr->cmd_len)) 195 if (copy_from_user(rq->cmd, hdr->cmdp, hdr->cmd_len))
196 return -EFAULT; 196 return -EFAULT;
197 if (blk_verify_command(&q->cmd_filter, rq->cmd, 197 if (blk_verify_command(&q->cmd_filter, rq->cmd, mode & FMODE_WRITE))
198 file->f_mode & FMODE_WRITE))
199 return -EPERM; 198 return -EPERM;
200 199
201 /* 200 /*
@@ -260,8 +259,8 @@ static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
260 return r; 259 return r;
261} 260}
262 261
263static int sg_io(struct file *file, struct request_queue *q, 262static int sg_io(struct request_queue *q, struct gendisk *bd_disk,
264 struct gendisk *bd_disk, struct sg_io_hdr *hdr) 263 struct sg_io_hdr *hdr, fmode_t mode)
265{ 264{
266 unsigned long start_time; 265 unsigned long start_time;
267 int writing = 0, ret = 0; 266 int writing = 0, ret = 0;
@@ -293,7 +292,7 @@ static int sg_io(struct file *file, struct request_queue *q,
293 if (!rq) 292 if (!rq)
294 return -ENOMEM; 293 return -ENOMEM;
295 294
296 if (blk_fill_sghdr_rq(q, rq, hdr, file)) { 295 if (blk_fill_sghdr_rq(q, rq, hdr, mode)) {
297 blk_put_request(rq); 296 blk_put_request(rq);
298 return -EFAULT; 297 return -EFAULT;
299 } 298 }
@@ -380,11 +379,11 @@ out:
380 * bytes in one int) where the lowest byte is the SCSI status. 379 * bytes in one int) where the lowest byte is the SCSI status.
381 */ 380 */
382#define OMAX_SB_LEN 16 /* For backward compatibility */ 381#define OMAX_SB_LEN 16 /* For backward compatibility */
383int sg_scsi_ioctl(struct file *file, struct request_queue *q, 382int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode,
384 struct gendisk *disk, struct scsi_ioctl_command __user *sic) 383 struct scsi_ioctl_command __user *sic)
385{ 384{
386 struct request *rq; 385 struct request *rq;
387 int err, write_perm = 0; 386 int err;
388 unsigned int in_len, out_len, bytes, opcode, cmdlen; 387 unsigned int in_len, out_len, bytes, opcode, cmdlen;
389 char *buffer = NULL, sense[SCSI_SENSE_BUFFERSIZE]; 388 char *buffer = NULL, sense[SCSI_SENSE_BUFFERSIZE];
390 389
@@ -426,11 +425,7 @@ int sg_scsi_ioctl(struct file *file, struct request_queue *q,
426 if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len)) 425 if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len))
427 goto error; 426 goto error;
428 427
429 /* scsi_ioctl passes NULL */ 428 err = blk_verify_command(&q->cmd_filter, rq->cmd, mode & FMODE_WRITE);
430 if (file && (file->f_mode & FMODE_WRITE))
431 write_perm = 1;
432
433 err = blk_verify_command(&q->cmd_filter, rq->cmd, write_perm);
434 if (err) 429 if (err)
435 goto error; 430 goto error;
436 431
@@ -522,8 +517,8 @@ static inline int blk_send_start_stop(struct request_queue *q,
522 return __blk_send_generic(q, bd_disk, GPCMD_START_STOP_UNIT, data); 517 return __blk_send_generic(q, bd_disk, GPCMD_START_STOP_UNIT, data);
523} 518}
524 519
525int scsi_cmd_ioctl(struct file *file, struct request_queue *q, 520int scsi_cmd_ioctl(struct request_queue *q, struct gendisk *bd_disk, fmode_t mode,
526 struct gendisk *bd_disk, unsigned int cmd, void __user *arg) 521 unsigned int cmd, void __user *arg)
527{ 522{
528 int err; 523 int err;
529 524
@@ -564,7 +559,7 @@ int scsi_cmd_ioctl(struct file *file, struct request_queue *q,
564 err = -EFAULT; 559 err = -EFAULT;
565 if (copy_from_user(&hdr, arg, sizeof(hdr))) 560 if (copy_from_user(&hdr, arg, sizeof(hdr)))
566 break; 561 break;
567 err = sg_io(file, q, bd_disk, &hdr); 562 err = sg_io(q, bd_disk, &hdr, mode);
568 if (err == -EFAULT) 563 if (err == -EFAULT)
569 break; 564 break;
570 565
@@ -612,7 +607,7 @@ int scsi_cmd_ioctl(struct file *file, struct request_queue *q,
612 hdr.cmdp = ((struct cdrom_generic_command __user*) arg)->cmd; 607 hdr.cmdp = ((struct cdrom_generic_command __user*) arg)->cmd;
613 hdr.cmd_len = sizeof(cgc.cmd); 608 hdr.cmd_len = sizeof(cgc.cmd);
614 609
615 err = sg_io(file, q, bd_disk, &hdr); 610 err = sg_io(q, bd_disk, &hdr, mode);
616 if (err == -EFAULT) 611 if (err == -EFAULT)
617 break; 612 break;
618 613
@@ -636,7 +631,7 @@ int scsi_cmd_ioctl(struct file *file, struct request_queue *q,
636 if (!arg) 631 if (!arg)
637 break; 632 break;
638 633
639 err = sg_scsi_ioctl(file, q, bd_disk, arg); 634 err = sg_scsi_ioctl(q, bd_disk, mode, arg);
640 break; 635 break;
641 case CDROMCLOSETRAY: 636 case CDROMCLOSETRAY:
642 err = blk_send_start_stop(q, bd_disk, 0x03); 637 err = blk_send_start_stop(q, bd_disk, 0x03);