aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2010-07-08 04:18:46 -0400
committerJens Axboe <jaxboe@fusionio.com>2010-08-07 12:25:00 -0400
commit8a6cfeb6deca3a8fefd639d898b0d163c0b5d368 (patch)
tree9a633ad48c3b1ada0519ee7bade0602f940037f6
parent34484062445fe905bf02c72f87ddda21881acda3 (diff)
block: push down BKL into .locked_ioctl
As a preparation for the removal of the big kernel lock in the block layer, this removes the BKL from the common ioctl handling code, moving it into every single driver still using it. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Acked-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
-rw-r--r--block/ioctl.c11
-rw-r--r--drivers/block/amiflop.c17
-rw-r--r--drivers/block/ataflop.c18
-rw-r--r--drivers/block/brd.c5
-rw-r--r--drivers/block/cciss.c8
-rw-r--r--drivers/block/cpqarray.c18
-rw-r--r--drivers/block/floppy.c17
-rw-r--r--drivers/block/nbd.c5
-rw-r--r--drivers/block/paride/pcd.c11
-rw-r--r--drivers/block/paride/pd.c5
-rw-r--r--drivers/block/paride/pf.c6
-rw-r--r--drivers/block/pktcdvd.c13
-rw-r--r--drivers/block/swim.c5
-rw-r--r--drivers/block/swim3.c17
-rw-r--r--drivers/block/ub.c10
-rw-r--r--drivers/block/virtio_blk.c17
-rw-r--r--drivers/block/xd.c17
-rw-r--r--drivers/block/xen-blkfront.c2
-rw-r--r--drivers/cdrom/gdrom.c11
-rw-r--r--drivers/cdrom/viocd.c11
-rw-r--r--drivers/ide/ide-cd.c18
-rw-r--r--drivers/ide/ide-disk_ioctl.c9
-rw-r--r--drivers/ide/ide-floppy_ioctl.c12
-rw-r--r--drivers/ide/ide-gd.c2
-rw-r--r--drivers/ide/ide-tape.c10
-rw-r--r--drivers/message/i2o/i2o_block.c22
-rw-r--r--drivers/mtd/mtd_blkdevs.c5
-rw-r--r--drivers/scsi/sd.c17
-rw-r--r--drivers/scsi/sr.c18
-rw-r--r--include/linux/blkdev.h1
30 files changed, 253 insertions, 85 deletions
diff --git a/block/ioctl.c b/block/ioctl.c
index e8eb679f2f9b..1cfa8d449d90 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -163,18 +163,10 @@ int __blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode,
163 unsigned cmd, unsigned long arg) 163 unsigned cmd, unsigned long arg)
164{ 164{
165 struct gendisk *disk = bdev->bd_disk; 165 struct gendisk *disk = bdev->bd_disk;
166 int ret;
167 166
168 if (disk->fops->ioctl) 167 if (disk->fops->ioctl)
169 return disk->fops->ioctl(bdev, mode, cmd, arg); 168 return disk->fops->ioctl(bdev, mode, cmd, arg);
170 169
171 if (disk->fops->locked_ioctl) {
172 lock_kernel();
173 ret = disk->fops->locked_ioctl(bdev, mode, cmd, arg);
174 unlock_kernel();
175 return ret;
176 }
177
178 return -ENOTTY; 170 return -ENOTTY;
179} 171}
180/* 172/*
@@ -185,8 +177,7 @@ int __blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode,
185EXPORT_SYMBOL_GPL(__blkdev_driver_ioctl); 177EXPORT_SYMBOL_GPL(__blkdev_driver_ioctl);
186 178
187/* 179/*
188 * always keep this in sync with compat_blkdev_ioctl() and 180 * always keep this in sync with compat_blkdev_ioctl()
189 * compat_blkdev_locked_ioctl()
190 */ 181 */
191int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, 182int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
192 unsigned long arg) 183 unsigned long arg)
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 832798aa14f6..0fa26359304c 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -60,6 +60,7 @@
60#include <linux/hdreg.h> 60#include <linux/hdreg.h>
61#include <linux/delay.h> 61#include <linux/delay.h>
62#include <linux/init.h> 62#include <linux/init.h>
63#include <linux/smp_lock.h>
63#include <linux/amifdreg.h> 64#include <linux/amifdreg.h>
64#include <linux/amifd.h> 65#include <linux/amifd.h>
65#include <linux/buffer_head.h> 66#include <linux/buffer_head.h>
@@ -1423,7 +1424,7 @@ static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1423 return 0; 1424 return 0;
1424} 1425}
1425 1426
1426static int fd_ioctl(struct block_device *bdev, fmode_t mode, 1427static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode,
1427 unsigned int cmd, unsigned long param) 1428 unsigned int cmd, unsigned long param)
1428{ 1429{
1429 struct amiga_floppy_struct *p = bdev->bd_disk->private_data; 1430 struct amiga_floppy_struct *p = bdev->bd_disk->private_data;
@@ -1500,6 +1501,18 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode,
1500 return 0; 1501 return 0;
1501} 1502}
1502 1503
1504static int fd_ioctl(struct block_device *bdev, fmode_t mode,
1505 unsigned int cmd, unsigned long param)
1506{
1507 int ret;
1508
1509 lock_kernel();
1510 ret = fd_locked_ioctl(bdev, mode, cmd, param);
1511 unlock_kernel();
1512
1513 return ret;
1514}
1515
1503static void fd_probe(int dev) 1516static void fd_probe(int dev)
1504{ 1517{
1505 unsigned long code; 1518 unsigned long code;
@@ -1638,7 +1651,7 @@ static const struct block_device_operations floppy_fops = {
1638 .owner = THIS_MODULE, 1651 .owner = THIS_MODULE,
1639 .open = floppy_open, 1652 .open = floppy_open,
1640 .release = floppy_release, 1653 .release = floppy_release,
1641 .locked_ioctl = fd_ioctl, 1654 .ioctl = fd_ioctl,
1642 .getgeo = fd_getgeo, 1655 .getgeo = fd_getgeo,
1643 .media_changed = amiga_floppy_change, 1656 .media_changed = amiga_floppy_change,
1644}; 1657};
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
index e35cf59cbfde..1bb8bfcfdbd9 100644
--- a/drivers/block/ataflop.c
+++ b/drivers/block/ataflop.c
@@ -67,6 +67,7 @@
67#include <linux/delay.h> 67#include <linux/delay.h>
68#include <linux/init.h> 68#include <linux/init.h>
69#include <linux/blkdev.h> 69#include <linux/blkdev.h>
70#include <linux/smp_lock.h>
70 71
71#include <asm/atafd.h> 72#include <asm/atafd.h>
72#include <asm/atafdreg.h> 73#include <asm/atafdreg.h>
@@ -359,7 +360,7 @@ static void finish_fdc( void );
359static void finish_fdc_done( int dummy ); 360static void finish_fdc_done( int dummy );
360static void setup_req_params( int drive ); 361static void setup_req_params( int drive );
361static void redo_fd_request( void); 362static void redo_fd_request( void);
362static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int 363static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int
363 cmd, unsigned long param); 364 cmd, unsigned long param);
364static void fd_probe( int drive ); 365static void fd_probe( int drive );
365static int fd_test_drive_present( int drive ); 366static int fd_test_drive_present( int drive );
@@ -1480,7 +1481,7 @@ void do_fd_request(struct request_queue * q)
1480 atari_enable_irq( IRQ_MFP_FDC ); 1481 atari_enable_irq( IRQ_MFP_FDC );
1481} 1482}
1482 1483
1483static int fd_ioctl(struct block_device *bdev, fmode_t mode, 1484static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode,
1484 unsigned int cmd, unsigned long param) 1485 unsigned int cmd, unsigned long param)
1485{ 1486{
1486 struct gendisk *disk = bdev->bd_disk; 1487 struct gendisk *disk = bdev->bd_disk;
@@ -1665,6 +1666,17 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode,
1665 } 1666 }
1666} 1667}
1667 1668
1669static int fd_ioctl(struct block_device *bdev, fmode_t mode,
1670 unsigned int cmd, unsigned long arg)
1671{
1672 int ret;
1673
1674 lock_kernel();
1675 ret = fd_locked_ioctl(bdev, mode, cmd, arg);
1676 unlock_kernel();
1677
1678 return ret;
1679}
1668 1680
1669/* Initialize the 'unit' variable for drive 'drive' */ 1681/* Initialize the 'unit' variable for drive 'drive' */
1670 1682
@@ -1855,7 +1867,7 @@ static const struct block_device_operations floppy_fops = {
1855 .owner = THIS_MODULE, 1867 .owner = THIS_MODULE,
1856 .open = floppy_open, 1868 .open = floppy_open,
1857 .release = floppy_release, 1869 .release = floppy_release,
1858 .locked_ioctl = fd_ioctl, 1870 .ioctl = fd_ioctl,
1859 .media_changed = check_floppy_change, 1871 .media_changed = check_floppy_change,
1860 .revalidate_disk= floppy_revalidate, 1872 .revalidate_disk= floppy_revalidate,
1861}; 1873};
diff --git a/drivers/block/brd.c b/drivers/block/brd.c
index 1d2c18620f9a..1c7f63792ff8 100644
--- a/drivers/block/brd.c
+++ b/drivers/block/brd.c
@@ -15,6 +15,7 @@
15#include <linux/blkdev.h> 15#include <linux/blkdev.h>
16#include <linux/bio.h> 16#include <linux/bio.h>
17#include <linux/highmem.h> 17#include <linux/highmem.h>
18#include <linux/smp_lock.h>
18#include <linux/radix-tree.h> 19#include <linux/radix-tree.h>
19#include <linux/buffer_head.h> /* invalidate_bh_lrus() */ 20#include <linux/buffer_head.h> /* invalidate_bh_lrus() */
20#include <linux/slab.h> 21#include <linux/slab.h>
@@ -401,6 +402,7 @@ static int brd_ioctl(struct block_device *bdev, fmode_t mode,
401 * ram device BLKFLSBUF has special semantics, we want to actually 402 * ram device BLKFLSBUF has special semantics, we want to actually
402 * release and destroy the ramdisk data. 403 * release and destroy the ramdisk data.
403 */ 404 */
405 lock_kernel();
404 mutex_lock(&bdev->bd_mutex); 406 mutex_lock(&bdev->bd_mutex);
405 error = -EBUSY; 407 error = -EBUSY;
406 if (bdev->bd_openers <= 1) { 408 if (bdev->bd_openers <= 1) {
@@ -417,13 +419,14 @@ static int brd_ioctl(struct block_device *bdev, fmode_t mode,
417 error = 0; 419 error = 0;
418 } 420 }
419 mutex_unlock(&bdev->bd_mutex); 421 mutex_unlock(&bdev->bd_mutex);
422 unlock_kernel();
420 423
421 return error; 424 return error;
422} 425}
423 426
424static const struct block_device_operations brd_fops = { 427static const struct block_device_operations brd_fops = {
425 .owner = THIS_MODULE, 428 .owner = THIS_MODULE,
426 .locked_ioctl = brd_ioctl, 429 .ioctl = brd_ioctl,
427#ifdef CONFIG_BLK_DEV_XIP 430#ifdef CONFIG_BLK_DEV_XIP
428 .direct_access = brd_direct_access, 431 .direct_access = brd_direct_access,
429#endif 432#endif
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 11b377762b8e..a6c0494dd054 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -179,6 +179,8 @@ static irqreturn_t do_cciss_intx(int irq, void *dev_id);
179static irqreturn_t do_cciss_msix_intr(int irq, void *dev_id); 179static irqreturn_t do_cciss_msix_intr(int irq, void *dev_id);
180static int cciss_open(struct block_device *bdev, fmode_t mode); 180static int cciss_open(struct block_device *bdev, fmode_t mode);
181static int cciss_release(struct gendisk *disk, fmode_t mode); 181static int cciss_release(struct gendisk *disk, fmode_t mode);
182static int do_ioctl(struct block_device *bdev, fmode_t mode,
183 unsigned int cmd, unsigned long arg);
182static int cciss_ioctl(struct block_device *bdev, fmode_t mode, 184static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
183 unsigned int cmd, unsigned long arg); 185 unsigned int cmd, unsigned long arg);
184static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo); 186static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo);
@@ -237,7 +239,7 @@ static const struct block_device_operations cciss_fops = {
237 .owner = THIS_MODULE, 239 .owner = THIS_MODULE,
238 .open = cciss_open, 240 .open = cciss_open,
239 .release = cciss_release, 241 .release = cciss_release,
240 .locked_ioctl = cciss_ioctl, 242 .ioctl = do_ioctl,
241 .getgeo = cciss_getgeo, 243 .getgeo = cciss_getgeo,
242#ifdef CONFIG_COMPAT 244#ifdef CONFIG_COMPAT
243 .compat_ioctl = cciss_compat_ioctl, 245 .compat_ioctl = cciss_compat_ioctl,
@@ -1057,8 +1059,6 @@ static int cciss_release(struct gendisk *disk, fmode_t mode)
1057 return 0; 1059 return 0;
1058} 1060}
1059 1061
1060#ifdef CONFIG_COMPAT
1061
1062static int do_ioctl(struct block_device *bdev, fmode_t mode, 1062static int do_ioctl(struct block_device *bdev, fmode_t mode,
1063 unsigned cmd, unsigned long arg) 1063 unsigned cmd, unsigned long arg)
1064{ 1064{
@@ -1069,6 +1069,8 @@ static int do_ioctl(struct block_device *bdev, fmode_t mode,
1069 return ret; 1069 return ret;
1070} 1070}
1071 1071
1072#ifdef CONFIG_COMPAT
1073
1072static int cciss_ioctl32_passthru(struct block_device *bdev, fmode_t mode, 1074static int cciss_ioctl32_passthru(struct block_device *bdev, fmode_t mode,
1073 unsigned cmd, unsigned long arg); 1075 unsigned cmd, unsigned long arg);
1074static int cciss_ioctl32_big_passthru(struct block_device *bdev, fmode_t mode, 1076static int cciss_ioctl32_big_passthru(struct block_device *bdev, fmode_t mode,
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index abb4ec6690fc..c459aeea3c0c 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -35,6 +35,7 @@
35#include <linux/seq_file.h> 35#include <linux/seq_file.h>
36#include <linux/init.h> 36#include <linux/init.h>
37#include <linux/hdreg.h> 37#include <linux/hdreg.h>
38#include <linux/smp_lock.h>
38#include <linux/spinlock.h> 39#include <linux/spinlock.h>
39#include <linux/blkdev.h> 40#include <linux/blkdev.h>
40#include <linux/genhd.h> 41#include <linux/genhd.h>
@@ -197,7 +198,7 @@ static const struct block_device_operations ida_fops = {
197 .owner = THIS_MODULE, 198 .owner = THIS_MODULE,
198 .open = ida_open, 199 .open = ida_open,
199 .release = ida_release, 200 .release = ida_release,
200 .locked_ioctl = ida_ioctl, 201 .ioctl = ida_ioctl,
201 .getgeo = ida_getgeo, 202 .getgeo = ida_getgeo,
202 .revalidate_disk= ida_revalidate, 203 .revalidate_disk= ida_revalidate,
203}; 204};
@@ -1128,7 +1129,7 @@ static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1128 * ida_ioctl does some miscellaneous stuff like reporting drive geometry, 1129 * ida_ioctl does some miscellaneous stuff like reporting drive geometry,
1129 * setting readahead and submitting commands from userspace to the controller. 1130 * setting readahead and submitting commands from userspace to the controller.
1130 */ 1131 */
1131static int ida_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) 1132static int ida_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg)
1132{ 1133{
1133 drv_info_t *drv = get_drv(bdev->bd_disk); 1134 drv_info_t *drv = get_drv(bdev->bd_disk);
1134 ctlr_info_t *host = get_host(bdev->bd_disk); 1135 ctlr_info_t *host = get_host(bdev->bd_disk);
@@ -1192,6 +1193,19 @@ out_passthru:
1192 } 1193 }
1193 1194
1194} 1195}
1196
1197static int ida_ioctl(struct block_device *bdev, fmode_t mode,
1198 unsigned int cmd, unsigned long param)
1199{
1200 int ret;
1201
1202 lock_kernel();
1203 ret = ida_locked_ioctl(bdev, mode, cmd, param);
1204 unlock_kernel();
1205
1206 return ret;
1207}
1208
1195/* 1209/*
1196 * ida_ctlr_ioctl is for passing commands to the controller from userspace. 1210 * ida_ctlr_ioctl is for passing commands to the controller from userspace.
1197 * The command block (io) has already been copied to kernel space for us, 1211 * The command block (io) has already been copied to kernel space for us,
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 82c30f9f81ca..40419b066aa9 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -178,6 +178,7 @@ static int print_unex = 1;
178#include <linux/slab.h> 178#include <linux/slab.h>
179#include <linux/mm.h> 179#include <linux/mm.h>
180#include <linux/bio.h> 180#include <linux/bio.h>
181#include <linux/smp_lock.h>
181#include <linux/string.h> 182#include <linux/string.h>
182#include <linux/jiffies.h> 183#include <linux/jiffies.h>
183#include <linux/fcntl.h> 184#include <linux/fcntl.h>
@@ -3371,7 +3372,7 @@ static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
3371 return 0; 3372 return 0;
3372} 3373}
3373 3374
3374static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, 3375static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd,
3375 unsigned long param) 3376 unsigned long param)
3376{ 3377{
3377 int drive = (long)bdev->bd_disk->private_data; 3378 int drive = (long)bdev->bd_disk->private_data;
@@ -3547,6 +3548,18 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd,
3547 return 0; 3548 return 0;
3548} 3549}
3549 3550
3551static int fd_ioctl(struct block_device *bdev, fmode_t mode,
3552 unsigned int cmd, unsigned long param)
3553{
3554 int ret;
3555
3556 lock_kernel();
3557 ret = fd_locked_ioctl(bdev, mode, cmd, param);
3558 unlock_kernel();
3559
3560 return ret;
3561}
3562
3550static void __init config_types(void) 3563static void __init config_types(void)
3551{ 3564{
3552 bool has_drive = false; 3565 bool has_drive = false;
@@ -3848,7 +3861,7 @@ static const struct block_device_operations floppy_fops = {
3848 .owner = THIS_MODULE, 3861 .owner = THIS_MODULE,
3849 .open = floppy_open, 3862 .open = floppy_open,
3850 .release = floppy_release, 3863 .release = floppy_release,
3851 .locked_ioctl = fd_ioctl, 3864 .ioctl = fd_ioctl,
3852 .getgeo = fd_getgeo, 3865 .getgeo = fd_getgeo,
3853 .media_changed = check_floppy_change, 3866 .media_changed = check_floppy_change,
3854 .revalidate_disk = floppy_revalidate, 3867 .revalidate_disk = floppy_revalidate,
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 2e74e7d475ca..6751789fb379 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -24,6 +24,7 @@
24#include <linux/errno.h> 24#include <linux/errno.h>
25#include <linux/file.h> 25#include <linux/file.h>
26#include <linux/ioctl.h> 26#include <linux/ioctl.h>
27#include <linux/smp_lock.h>
27#include <linux/compiler.h> 28#include <linux/compiler.h>
28#include <linux/err.h> 29#include <linux/err.h>
29#include <linux/kernel.h> 30#include <linux/kernel.h>
@@ -716,9 +717,11 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
716 dprintk(DBG_IOCTL, "%s: nbd_ioctl cmd=%s(0x%x) arg=%lu\n", 717 dprintk(DBG_IOCTL, "%s: nbd_ioctl cmd=%s(0x%x) arg=%lu\n",
717 lo->disk->disk_name, ioctl_cmd_to_ascii(cmd), cmd, arg); 718 lo->disk->disk_name, ioctl_cmd_to_ascii(cmd), cmd, arg);
718 719
720 lock_kernel();
719 mutex_lock(&lo->tx_lock); 721 mutex_lock(&lo->tx_lock);
720 error = __nbd_ioctl(bdev, lo, cmd, arg); 722 error = __nbd_ioctl(bdev, lo, cmd, arg);
721 mutex_unlock(&lo->tx_lock); 723 mutex_unlock(&lo->tx_lock);
724 unlock_kernel();
722 725
723 return error; 726 return error;
724} 727}
@@ -726,7 +729,7 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
726static const struct block_device_operations nbd_fops = 729static const struct block_device_operations nbd_fops =
727{ 730{
728 .owner = THIS_MODULE, 731 .owner = THIS_MODULE,
729 .locked_ioctl = nbd_ioctl, 732 .ioctl = nbd_ioctl,
730}; 733};
731 734
732/* 735/*
diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c
index 71acf4e53356..daba7a62a663 100644
--- a/drivers/block/paride/pcd.c
+++ b/drivers/block/paride/pcd.c
@@ -138,6 +138,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_DLY};
138#include <linux/cdrom.h> 138#include <linux/cdrom.h>
139#include <linux/spinlock.h> 139#include <linux/spinlock.h>
140#include <linux/blkdev.h> 140#include <linux/blkdev.h>
141#include <linux/smp_lock.h>
141#include <asm/uaccess.h> 142#include <asm/uaccess.h>
142 143
143static DEFINE_SPINLOCK(pcd_lock); 144static DEFINE_SPINLOCK(pcd_lock);
@@ -238,7 +239,13 @@ static int pcd_block_ioctl(struct block_device *bdev, fmode_t mode,
238 unsigned cmd, unsigned long arg) 239 unsigned cmd, unsigned long arg)
239{ 240{
240 struct pcd_unit *cd = bdev->bd_disk->private_data; 241 struct pcd_unit *cd = bdev->bd_disk->private_data;
241 return cdrom_ioctl(&cd->info, bdev, mode, cmd, arg); 242 int ret;
243
244 lock_kernel();
245 ret = cdrom_ioctl(&cd->info, bdev, mode, cmd, arg);
246 unlock_kernel();
247
248 return ret;
242} 249}
243 250
244static int pcd_block_media_changed(struct gendisk *disk) 251static int pcd_block_media_changed(struct gendisk *disk)
@@ -251,7 +258,7 @@ static const struct block_device_operations pcd_bdops = {
251 .owner = THIS_MODULE, 258 .owner = THIS_MODULE,
252 .open = pcd_block_open, 259 .open = pcd_block_open,
253 .release = pcd_block_release, 260 .release = pcd_block_release,
254 .locked_ioctl = pcd_block_ioctl, 261 .ioctl = pcd_block_ioctl,
255 .media_changed = pcd_block_media_changed, 262 .media_changed = pcd_block_media_changed,
256}; 263};
257 264
diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
index 4e8b9bff3abe..c4d6ed9846ca 100644
--- a/drivers/block/paride/pd.c
+++ b/drivers/block/paride/pd.c
@@ -153,6 +153,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_GEO, D_SBY, D_DLY, D_SLV};
153#include <linux/blkdev.h> 153#include <linux/blkdev.h>
154#include <linux/blkpg.h> 154#include <linux/blkpg.h>
155#include <linux/kernel.h> 155#include <linux/kernel.h>
156#include <linux/smp_lock.h>
156#include <asm/uaccess.h> 157#include <asm/uaccess.h>
157#include <linux/workqueue.h> 158#include <linux/workqueue.h>
158 159
@@ -768,8 +769,10 @@ static int pd_ioctl(struct block_device *bdev, fmode_t mode,
768 769
769 switch (cmd) { 770 switch (cmd) {
770 case CDROMEJECT: 771 case CDROMEJECT:
772 lock_kernel();
771 if (disk->access == 1) 773 if (disk->access == 1)
772 pd_special_command(disk, pd_eject); 774 pd_special_command(disk, pd_eject);
775 unlock_kernel();
773 return 0; 776 return 0;
774 default: 777 default:
775 return -EINVAL; 778 return -EINVAL;
@@ -812,7 +815,7 @@ static const struct block_device_operations pd_fops = {
812 .owner = THIS_MODULE, 815 .owner = THIS_MODULE,
813 .open = pd_open, 816 .open = pd_open,
814 .release = pd_release, 817 .release = pd_release,
815 .locked_ioctl = pd_ioctl, 818 .ioctl = pd_ioctl,
816 .getgeo = pd_getgeo, 819 .getgeo = pd_getgeo,
817 .media_changed = pd_check_media, 820 .media_changed = pd_check_media,
818 .revalidate_disk= pd_revalidate 821 .revalidate_disk= pd_revalidate
diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c
index c059aab3006b..38b4d566b816 100644
--- a/drivers/block/paride/pf.c
+++ b/drivers/block/paride/pf.c
@@ -152,6 +152,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_LUN, D_DLY};
152#include <linux/spinlock.h> 152#include <linux/spinlock.h>
153#include <linux/blkdev.h> 153#include <linux/blkdev.h>
154#include <linux/blkpg.h> 154#include <linux/blkpg.h>
155#include <linux/smp_lock.h>
155#include <asm/uaccess.h> 156#include <asm/uaccess.h>
156 157
157static DEFINE_SPINLOCK(pf_spin_lock); 158static DEFINE_SPINLOCK(pf_spin_lock);
@@ -266,7 +267,7 @@ static const struct block_device_operations pf_fops = {
266 .owner = THIS_MODULE, 267 .owner = THIS_MODULE,
267 .open = pf_open, 268 .open = pf_open,
268 .release = pf_release, 269 .release = pf_release,
269 .locked_ioctl = pf_ioctl, 270 .ioctl = pf_ioctl,
270 .getgeo = pf_getgeo, 271 .getgeo = pf_getgeo,
271 .media_changed = pf_check_media, 272 .media_changed = pf_check_media,
272}; 273};
@@ -342,7 +343,10 @@ static int pf_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, u
342 343
343 if (pf->access != 1) 344 if (pf->access != 1)
344 return -EBUSY; 345 return -EBUSY;
346 lock_kernel();
345 pf_eject(pf); 347 pf_eject(pf);
348 unlock_kernel();
349
346 return 0; 350 return 0;
347} 351}
348 352
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 9f3e4454274b..40f1e31f42c4 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -57,6 +57,7 @@
57#include <linux/seq_file.h> 57#include <linux/seq_file.h>
58#include <linux/miscdevice.h> 58#include <linux/miscdevice.h>
59#include <linux/freezer.h> 59#include <linux/freezer.h>
60#include <linux/smp_lock.h>
60#include <linux/mutex.h> 61#include <linux/mutex.h>
61#include <linux/slab.h> 62#include <linux/slab.h>
62#include <scsi/scsi_cmnd.h> 63#include <scsi/scsi_cmnd.h>
@@ -2762,10 +2763,12 @@ out_mem:
2762static int pkt_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) 2763static int pkt_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg)
2763{ 2764{
2764 struct pktcdvd_device *pd = bdev->bd_disk->private_data; 2765 struct pktcdvd_device *pd = bdev->bd_disk->private_data;
2766 int ret;
2765 2767
2766 VPRINTK("pkt_ioctl: cmd %x, dev %d:%d\n", cmd, 2768 VPRINTK("pkt_ioctl: cmd %x, dev %d:%d\n", cmd,
2767 MAJOR(bdev->bd_dev), MINOR(bdev->bd_dev)); 2769 MAJOR(bdev->bd_dev), MINOR(bdev->bd_dev));
2768 2770
2771 lock_kernel();
2769 switch (cmd) { 2772 switch (cmd) {
2770 case CDROMEJECT: 2773 case CDROMEJECT:
2771 /* 2774 /*
@@ -2783,14 +2786,16 @@ static int pkt_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd,
2783 case CDROM_LAST_WRITTEN: 2786 case CDROM_LAST_WRITTEN:
2784 case CDROM_SEND_PACKET: 2787 case CDROM_SEND_PACKET:
2785 case SCSI_IOCTL_SEND_COMMAND: 2788 case SCSI_IOCTL_SEND_COMMAND:
2786 return __blkdev_driver_ioctl(pd->bdev, mode, cmd, arg); 2789 ret = __blkdev_driver_ioctl(pd->bdev, mode, cmd, arg);
2790 break;
2787 2791
2788 default: 2792 default:
2789 VPRINTK(DRIVER_NAME": Unknown ioctl for %s (%x)\n", pd->name, cmd); 2793 VPRINTK(DRIVER_NAME": Unknown ioctl for %s (%x)\n", pd->name, cmd);
2790 return -ENOTTY; 2794 ret = -ENOTTY;
2791 } 2795 }
2796 unlock_kernel();
2792 2797
2793 return 0; 2798 return ret;
2794} 2799}
2795 2800
2796static int pkt_media_changed(struct gendisk *disk) 2801static int pkt_media_changed(struct gendisk *disk)
@@ -2812,7 +2817,7 @@ static const struct block_device_operations pktcdvd_ops = {
2812 .owner = THIS_MODULE, 2817 .owner = THIS_MODULE,
2813 .open = pkt_open, 2818 .open = pkt_open,
2814 .release = pkt_close, 2819 .release = pkt_close,
2815 .locked_ioctl = pkt_ioctl, 2820 .ioctl = pkt_ioctl,
2816 .media_changed = pkt_media_changed, 2821 .media_changed = pkt_media_changed,
2817}; 2822};
2818 2823
diff --git a/drivers/block/swim.c b/drivers/block/swim.c
index e463657569ff..f04f74e3758f 100644
--- a/drivers/block/swim.c
+++ b/drivers/block/swim.c
@@ -20,6 +20,7 @@
20#include <linux/fd.h> 20#include <linux/fd.h>
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <linux/blkdev.h> 22#include <linux/blkdev.h>
23#include <linux/smp_lock.h>
23#include <linux/hdreg.h> 24#include <linux/hdreg.h>
24#include <linux/kernel.h> 25#include <linux/kernel.h>
25#include <linux/delay.h> 26#include <linux/delay.h>
@@ -690,7 +691,9 @@ static int floppy_ioctl(struct block_device *bdev, fmode_t mode,
690 case FDEJECT: 691 case FDEJECT:
691 if (fs->ref_count != 1) 692 if (fs->ref_count != 1)
692 return -EBUSY; 693 return -EBUSY;
694 lock_kernel();
693 err = floppy_eject(fs); 695 err = floppy_eject(fs);
696 unlock_kernel();
694 return err; 697 return err;
695 698
696 case FDGETPRM: 699 case FDGETPRM:
@@ -753,7 +756,7 @@ static const struct block_device_operations floppy_fops = {
753 .owner = THIS_MODULE, 756 .owner = THIS_MODULE,
754 .open = floppy_open, 757 .open = floppy_open,
755 .release = floppy_release, 758 .release = floppy_release,
756 .locked_ioctl = floppy_ioctl, 759 .ioctl = floppy_ioctl,
757 .getgeo = floppy_getgeo, 760 .getgeo = floppy_getgeo,
758 .media_changed = floppy_check_change, 761 .media_changed = floppy_check_change,
759 .revalidate_disk = floppy_revalidate, 762 .revalidate_disk = floppy_revalidate,
diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c
index ed6fb91123ab..f3657b2a5386 100644
--- a/drivers/block/swim3.c
+++ b/drivers/block/swim3.c
@@ -25,6 +25,7 @@
25#include <linux/ioctl.h> 25#include <linux/ioctl.h>
26#include <linux/blkdev.h> 26#include <linux/blkdev.h>
27#include <linux/interrupt.h> 27#include <linux/interrupt.h>
28#include <linux/smp_lock.h>
28#include <linux/module.h> 29#include <linux/module.h>
29#include <linux/spinlock.h> 30#include <linux/spinlock.h>
30#include <asm/io.h> 31#include <asm/io.h>
@@ -839,7 +840,7 @@ static int fd_eject(struct floppy_state *fs)
839static struct floppy_struct floppy_type = 840static struct floppy_struct floppy_type =
840 { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,NULL }; /* 7 1.44MB 3.5" */ 841 { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,NULL }; /* 7 1.44MB 3.5" */
841 842
842static int floppy_ioctl(struct block_device *bdev, fmode_t mode, 843static int floppy_locked_ioctl(struct block_device *bdev, fmode_t mode,
843 unsigned int cmd, unsigned long param) 844 unsigned int cmd, unsigned long param)
844{ 845{
845 struct floppy_state *fs = bdev->bd_disk->private_data; 846 struct floppy_state *fs = bdev->bd_disk->private_data;
@@ -867,6 +868,18 @@ static int floppy_ioctl(struct block_device *bdev, fmode_t mode,
867 return -ENOTTY; 868 return -ENOTTY;
868} 869}
869 870
871static int floppy_ioctl(struct block_device *bdev, fmode_t mode,
872 unsigned int cmd, unsigned long param)
873{
874 int ret;
875
876 lock_kernel();
877 ret = floppy_locked_ioctl(bdev, mode, cmd, param);
878 unlock_kernel();
879
880 return ret;
881}
882
870static int floppy_open(struct block_device *bdev, fmode_t mode) 883static int floppy_open(struct block_device *bdev, fmode_t mode)
871{ 884{
872 struct floppy_state *fs = bdev->bd_disk->private_data; 885 struct floppy_state *fs = bdev->bd_disk->private_data;
@@ -997,7 +1010,7 @@ static int floppy_revalidate(struct gendisk *disk)
997static const struct block_device_operations floppy_fops = { 1010static const struct block_device_operations floppy_fops = {
998 .open = floppy_open, 1011 .open = floppy_open,
999 .release = floppy_release, 1012 .release = floppy_release,
1000 .locked_ioctl = floppy_ioctl, 1013 .ioctl = floppy_ioctl,
1001 .media_changed = floppy_check_change, 1014 .media_changed = floppy_check_change,
1002 .revalidate_disk= floppy_revalidate, 1015 .revalidate_disk= floppy_revalidate,
1003}; 1016};
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index aaf27fb4efd6..102ed52d0e0f 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -28,6 +28,7 @@
28#include <linux/timer.h> 28#include <linux/timer.h>
29#include <linux/scatterlist.h> 29#include <linux/scatterlist.h>
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/smp_lock.h>
31#include <scsi/scsi.h> 32#include <scsi/scsi.h>
32 33
33#define DRV_NAME "ub" 34#define DRV_NAME "ub"
@@ -1729,8 +1730,13 @@ static int ub_bd_ioctl(struct block_device *bdev, fmode_t mode,
1729{ 1730{
1730 struct gendisk *disk = bdev->bd_disk; 1731 struct gendisk *disk = bdev->bd_disk;
1731 void __user *usermem = (void __user *) arg; 1732 void __user *usermem = (void __user *) arg;
1733 int ret;
1734
1735 lock_kernel();
1736 ret = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, usermem);
1737 unlock_kernel();
1732 1738
1733 return scsi_cmd_ioctl(disk->queue, disk, mode, cmd, usermem); 1739 return ret;
1734} 1740}
1735 1741
1736/* 1742/*
@@ -1794,7 +1800,7 @@ static const struct block_device_operations ub_bd_fops = {
1794 .owner = THIS_MODULE, 1800 .owner = THIS_MODULE,
1795 .open = ub_bd_open, 1801 .open = ub_bd_open,
1796 .release = ub_bd_release, 1802 .release = ub_bd_release,
1797 .locked_ioctl = ub_bd_ioctl, 1803 .ioctl = ub_bd_ioctl,
1798 .media_changed = ub_bd_media_changed, 1804 .media_changed = ub_bd_media_changed,
1799 .revalidate_disk = ub_bd_revalidate, 1805 .revalidate_disk = ub_bd_revalidate,
1800}; 1806};
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 0a3222fd4442..7b0f7b624adf 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -2,6 +2,7 @@
2#include <linux/spinlock.h> 2#include <linux/spinlock.h>
3#include <linux/slab.h> 3#include <linux/slab.h>
4#include <linux/blkdev.h> 4#include <linux/blkdev.h>
5#include <linux/smp_lock.h>
5#include <linux/hdreg.h> 6#include <linux/hdreg.h>
6#include <linux/virtio.h> 7#include <linux/virtio.h>
7#include <linux/virtio_blk.h> 8#include <linux/virtio_blk.h>
@@ -217,7 +218,7 @@ static int virtblk_get_id(struct gendisk *disk, char *id_str)
217 return blk_execute_rq(vblk->disk->queue, vblk->disk, req, false); 218 return blk_execute_rq(vblk->disk->queue, vblk->disk, req, false);
218} 219}
219 220
220static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, 221static int virtblk_locked_ioctl(struct block_device *bdev, fmode_t mode,
221 unsigned cmd, unsigned long data) 222 unsigned cmd, unsigned long data)
222{ 223{
223 struct gendisk *disk = bdev->bd_disk; 224 struct gendisk *disk = bdev->bd_disk;
@@ -243,6 +244,18 @@ static int virtblk_ioctl(struct block_device *bdev, fmode_t mode,
243 (void __user *)data); 244 (void __user *)data);
244} 245}
245 246
247static int virtblk_ioctl(struct block_device *bdev, fmode_t mode,
248 unsigned int cmd, unsigned long param)
249{
250 int ret;
251
252 lock_kernel();
253 ret = virtblk_locked_ioctl(bdev, mode, cmd, param);
254 unlock_kernel();
255
256 return ret;
257}
258
246/* We provide getgeo only to please some old bootloader/partitioning tools */ 259/* We provide getgeo only to please some old bootloader/partitioning tools */
247static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo) 260static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo)
248{ 261{
@@ -269,7 +282,7 @@ static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo)
269} 282}
270 283
271static const struct block_device_operations virtblk_fops = { 284static const struct block_device_operations virtblk_fops = {
272 .locked_ioctl = virtblk_ioctl, 285 .ioctl = virtblk_ioctl,
273 .owner = THIS_MODULE, 286 .owner = THIS_MODULE,
274 .getgeo = virtblk_getgeo, 287 .getgeo = virtblk_getgeo,
275}; 288};
diff --git a/drivers/block/xd.c b/drivers/block/xd.c
index b16a3a926cf2..d5a3cd750561 100644
--- a/drivers/block/xd.c
+++ b/drivers/block/xd.c
@@ -46,6 +46,7 @@
46#include <linux/init.h> 46#include <linux/init.h>
47#include <linux/wait.h> 47#include <linux/wait.h>
48#include <linux/blkdev.h> 48#include <linux/blkdev.h>
49#include <linux/smp_lock.h>
49#include <linux/blkpg.h> 50#include <linux/blkpg.h>
50#include <linux/delay.h> 51#include <linux/delay.h>
51#include <linux/io.h> 52#include <linux/io.h>
@@ -133,7 +134,7 @@ static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo);
133 134
134static const struct block_device_operations xd_fops = { 135static const struct block_device_operations xd_fops = {
135 .owner = THIS_MODULE, 136 .owner = THIS_MODULE,
136 .locked_ioctl = xd_ioctl, 137 .ioctl = xd_ioctl,
137 .getgeo = xd_getgeo, 138 .getgeo = xd_getgeo,
138}; 139};
139static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int); 140static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int);
@@ -347,7 +348,7 @@ static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
347} 348}
348 349
349/* xd_ioctl: handle device ioctl's */ 350/* xd_ioctl: handle device ioctl's */
350static int xd_ioctl(struct block_device *bdev, fmode_t mode, u_int cmd, u_long arg) 351static int xd_locked_ioctl(struct block_device *bdev, fmode_t mode, u_int cmd, u_long arg)
351{ 352{
352 switch (cmd) { 353 switch (cmd) {
353 case HDIO_SET_DMA: 354 case HDIO_SET_DMA:
@@ -375,6 +376,18 @@ static int xd_ioctl(struct block_device *bdev, fmode_t mode, u_int cmd, u_long a
375 } 376 }
376} 377}
377 378
379static int xd_ioctl(struct block_device *bdev, fmode_t mode,
380 unsigned int cmd, unsigned long param)
381{
382 int ret;
383
384 lock_kernel();
385 ret = xd_locked_ioctl(bdev, mode, cmd, param);
386 unlock_kernel();
387
388 return ret;
389}
390
378/* xd_readwrite: handle a read/write request */ 391/* xd_readwrite: handle a read/write request */
379static int xd_readwrite (u_char operation,XD_INFO *p,char *buffer,u_int block,u_int count) 392static int xd_readwrite (u_char operation,XD_INFO *p,char *buffer,u_int block,u_int count)
380{ 393{
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 76af65b654e3..9119cd3d56a4 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -1045,7 +1045,7 @@ static const struct block_device_operations xlvbd_block_fops =
1045 .open = blkif_open, 1045 .open = blkif_open,
1046 .release = blkif_release, 1046 .release = blkif_release,
1047 .getgeo = blkif_getgeo, 1047 .getgeo = blkif_getgeo,
1048 .locked_ioctl = blkif_ioctl, 1048 .ioctl = blkif_ioctl,
1049}; 1049};
1050 1050
1051 1051
diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c
index 5219b57deb36..1772fd914fb9 100644
--- a/drivers/cdrom/gdrom.c
+++ b/drivers/cdrom/gdrom.c
@@ -34,6 +34,7 @@
34#include <linux/blkdev.h> 34#include <linux/blkdev.h>
35#include <linux/interrupt.h> 35#include <linux/interrupt.h>
36#include <linux/device.h> 36#include <linux/device.h>
37#include <linux/smp_lock.h>
37#include <linux/wait.h> 38#include <linux/wait.h>
38#include <linux/workqueue.h> 39#include <linux/workqueue.h>
39#include <linux/platform_device.h> 40#include <linux/platform_device.h>
@@ -509,7 +510,13 @@ static int gdrom_bdops_mediachanged(struct gendisk *disk)
509static int gdrom_bdops_ioctl(struct block_device *bdev, fmode_t mode, 510static int gdrom_bdops_ioctl(struct block_device *bdev, fmode_t mode,
510 unsigned cmd, unsigned long arg) 511 unsigned cmd, unsigned long arg)
511{ 512{
512 return cdrom_ioctl(gd.cd_info, bdev, mode, cmd, arg); 513 int ret;
514
515 lock_kernel();
516 ret = cdrom_ioctl(gd.cd_info, bdev, mode, cmd, arg);
517 unlock_kernel();
518
519 return ret;
513} 520}
514 521
515static const struct block_device_operations gdrom_bdops = { 522static const struct block_device_operations gdrom_bdops = {
@@ -517,7 +524,7 @@ static const struct block_device_operations gdrom_bdops = {
517 .open = gdrom_bdops_open, 524 .open = gdrom_bdops_open,
518 .release = gdrom_bdops_release, 525 .release = gdrom_bdops_release,
519 .media_changed = gdrom_bdops_mediachanged, 526 .media_changed = gdrom_bdops_mediachanged,
520 .locked_ioctl = gdrom_bdops_ioctl, 527 .ioctl = gdrom_bdops_ioctl,
521}; 528};
522 529
523static irqreturn_t gdrom_command_interrupt(int irq, void *dev_id) 530static irqreturn_t gdrom_command_interrupt(int irq, void *dev_id)
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index 1fa6628d150b..16dada0627ee 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -42,6 +42,7 @@
42#include <linux/module.h> 42#include <linux/module.h>
43#include <linux/completion.h> 43#include <linux/completion.h>
44#include <linux/proc_fs.h> 44#include <linux/proc_fs.h>
45#include <linux/smp_lock.h>
45#include <linux/seq_file.h> 46#include <linux/seq_file.h>
46#include <linux/scatterlist.h> 47#include <linux/scatterlist.h>
47 48
@@ -167,7 +168,13 @@ static int viocd_blk_ioctl(struct block_device *bdev, fmode_t mode,
167 unsigned cmd, unsigned long arg) 168 unsigned cmd, unsigned long arg)
168{ 169{
169 struct disk_info *di = bdev->bd_disk->private_data; 170 struct disk_info *di = bdev->bd_disk->private_data;
170 return cdrom_ioctl(&di->viocd_info, bdev, mode, cmd, arg); 171 int ret;
172
173 lock_kernel();
174 ret = cdrom_ioctl(&di->viocd_info, bdev, mode, cmd, arg);
175 unlock_kernel();
176
177 return ret;
171} 178}
172 179
173static int viocd_blk_media_changed(struct gendisk *disk) 180static int viocd_blk_media_changed(struct gendisk *disk)
@@ -180,7 +187,7 @@ static const struct block_device_operations viocd_fops = {
180 .owner = THIS_MODULE, 187 .owner = THIS_MODULE,
181 .open = viocd_blk_open, 188 .open = viocd_blk_open,
182 .release = viocd_blk_release, 189 .release = viocd_blk_release,
183 .locked_ioctl = viocd_blk_ioctl, 190 .ioctl = viocd_blk_ioctl,
184 .media_changed = viocd_blk_media_changed, 191 .media_changed = viocd_blk_media_changed,
185}; 192};
186 193
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index ef7e3a9bee51..bf9f61a5c2f8 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -31,6 +31,7 @@
31#include <linux/delay.h> 31#include <linux/delay.h>
32#include <linux/timer.h> 32#include <linux/timer.h>
33#include <linux/seq_file.h> 33#include <linux/seq_file.h>
34#include <linux/smp_lock.h>
34#include <linux/slab.h> 35#include <linux/slab.h>
35#include <linux/interrupt.h> 36#include <linux/interrupt.h>
36#include <linux/errno.h> 37#include <linux/errno.h>
@@ -1654,7 +1655,7 @@ static int idecd_get_spindown(struct cdrom_device_info *cdi, unsigned long arg)
1654 return 0; 1655 return 0;
1655} 1656}
1656 1657
1657static int idecd_ioctl(struct block_device *bdev, fmode_t mode, 1658static int idecd_locked_ioctl(struct block_device *bdev, fmode_t mode,
1658 unsigned int cmd, unsigned long arg) 1659 unsigned int cmd, unsigned long arg)
1659{ 1660{
1660 struct cdrom_info *info = ide_drv_g(bdev->bd_disk, cdrom_info); 1661 struct cdrom_info *info = ide_drv_g(bdev->bd_disk, cdrom_info);
@@ -1676,6 +1677,19 @@ static int idecd_ioctl(struct block_device *bdev, fmode_t mode,
1676 return err; 1677 return err;
1677} 1678}
1678 1679
1680static int idecd_ioctl(struct block_device *bdev, fmode_t mode,
1681 unsigned int cmd, unsigned long arg)
1682{
1683 int ret;
1684
1685 lock_kernel();
1686 ret = idecd_locked_ioctl(bdev, mode, cmd, arg);
1687 unlock_kernel();
1688
1689 return ret;
1690}
1691
1692
1679static int idecd_media_changed(struct gendisk *disk) 1693static int idecd_media_changed(struct gendisk *disk)
1680{ 1694{
1681 struct cdrom_info *info = ide_drv_g(disk, cdrom_info); 1695 struct cdrom_info *info = ide_drv_g(disk, cdrom_info);
@@ -1696,7 +1710,7 @@ static const struct block_device_operations idecd_ops = {
1696 .owner = THIS_MODULE, 1710 .owner = THIS_MODULE,
1697 .open = idecd_open, 1711 .open = idecd_open,
1698 .release = idecd_release, 1712 .release = idecd_release,
1699 .locked_ioctl = idecd_ioctl, 1713 .ioctl = idecd_ioctl,
1700 .media_changed = idecd_media_changed, 1714 .media_changed = idecd_media_changed,
1701 .revalidate_disk = idecd_revalidate_disk 1715 .revalidate_disk = idecd_revalidate_disk
1702}; 1716};
diff --git a/drivers/ide/ide-disk_ioctl.c b/drivers/ide/ide-disk_ioctl.c
index 7b783dd7c0be..ec94c66918f6 100644
--- a/drivers/ide/ide-disk_ioctl.c
+++ b/drivers/ide/ide-disk_ioctl.c
@@ -1,6 +1,7 @@
1#include <linux/kernel.h> 1#include <linux/kernel.h>
2#include <linux/ide.h> 2#include <linux/ide.h>
3#include <linux/hdreg.h> 3#include <linux/hdreg.h>
4#include <linux/smp_lock.h>
4 5
5#include "ide-disk.h" 6#include "ide-disk.h"
6 7
@@ -18,9 +19,13 @@ int ide_disk_ioctl(ide_drive_t *drive, struct block_device *bdev, fmode_t mode,
18{ 19{
19 int err; 20 int err;
20 21
22 lock_kernel();
21 err = ide_setting_ioctl(drive, bdev, cmd, arg, ide_disk_ioctl_settings); 23 err = ide_setting_ioctl(drive, bdev, cmd, arg, ide_disk_ioctl_settings);
22 if (err != -EOPNOTSUPP) 24 if (err != -EOPNOTSUPP)
23 return err; 25 goto out;
24 26
25 return generic_ide_ioctl(drive, bdev, cmd, arg); 27 err = generic_ide_ioctl(drive, bdev, cmd, arg);
28out:
29 unlock_kernel();
30 return err;
26} 31}
diff --git a/drivers/ide/ide-floppy_ioctl.c b/drivers/ide/ide-floppy_ioctl.c
index 9c2288234dea..fd3d05ab3417 100644
--- a/drivers/ide/ide-floppy_ioctl.c
+++ b/drivers/ide/ide-floppy_ioctl.c
@@ -5,6 +5,7 @@
5#include <linux/kernel.h> 5#include <linux/kernel.h>
6#include <linux/ide.h> 6#include <linux/ide.h>
7#include <linux/cdrom.h> 7#include <linux/cdrom.h>
8#include <linux/smp_lock.h>
8 9
9#include <asm/unaligned.h> 10#include <asm/unaligned.h>
10 11
@@ -275,12 +276,15 @@ int ide_floppy_ioctl(ide_drive_t *drive, struct block_device *bdev,
275 void __user *argp = (void __user *)arg; 276 void __user *argp = (void __user *)arg;
276 int err; 277 int err;
277 278
278 if (cmd == CDROMEJECT || cmd == CDROM_LOCKDOOR) 279 lock_kernel();
279 return ide_floppy_lockdoor(drive, &pc, arg, cmd); 280 if (cmd == CDROMEJECT || cmd == CDROM_LOCKDOOR) {
281 err = ide_floppy_lockdoor(drive, &pc, arg, cmd);
282 goto out;
283 }
280 284
281 err = ide_floppy_format_ioctl(drive, &pc, mode, cmd, argp); 285 err = ide_floppy_format_ioctl(drive, &pc, mode, cmd, argp);
282 if (err != -ENOTTY) 286 if (err != -ENOTTY)
283 return err; 287 goto out;
284 288
285 /* 289 /*
286 * skip SCSI_IOCTL_SEND_COMMAND (deprecated) 290 * skip SCSI_IOCTL_SEND_COMMAND (deprecated)
@@ -293,5 +297,7 @@ int ide_floppy_ioctl(ide_drive_t *drive, struct block_device *bdev,
293 if (err == -ENOTTY) 297 if (err == -ENOTTY)
294 err = generic_ide_ioctl(drive, bdev, cmd, arg); 298 err = generic_ide_ioctl(drive, bdev, cmd, arg);
295 299
300out:
301 unlock_kernel();
296 return err; 302 return err;
297} 303}
diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c
index c102d23d9b38..883f0c979c9f 100644
--- a/drivers/ide/ide-gd.c
+++ b/drivers/ide/ide-gd.c
@@ -323,7 +323,7 @@ static const struct block_device_operations ide_gd_ops = {
323 .owner = THIS_MODULE, 323 .owner = THIS_MODULE,
324 .open = ide_gd_open, 324 .open = ide_gd_open,
325 .release = ide_gd_release, 325 .release = ide_gd_release,
326 .locked_ioctl = ide_gd_ioctl, 326 .ioctl = ide_gd_ioctl,
327 .getgeo = ide_gd_getgeo, 327 .getgeo = ide_gd_getgeo,
328 .media_changed = ide_gd_media_changed, 328 .media_changed = ide_gd_media_changed,
329 .unlock_native_capacity = ide_gd_unlock_native_capacity, 329 .unlock_native_capacity = ide_gd_unlock_native_capacity,
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 635fd72d4728..39b0a5c45f07 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -32,6 +32,7 @@
32#include <linux/errno.h> 32#include <linux/errno.h>
33#include <linux/genhd.h> 33#include <linux/genhd.h>
34#include <linux/seq_file.h> 34#include <linux/seq_file.h>
35#include <linux/smp_lock.h>
35#include <linux/slab.h> 36#include <linux/slab.h>
36#include <linux/pci.h> 37#include <linux/pci.h>
37#include <linux/ide.h> 38#include <linux/ide.h>
@@ -1927,9 +1928,14 @@ static int idetape_ioctl(struct block_device *bdev, fmode_t mode,
1927{ 1928{
1928 struct ide_tape_obj *tape = ide_drv_g(bdev->bd_disk, ide_tape_obj); 1929 struct ide_tape_obj *tape = ide_drv_g(bdev->bd_disk, ide_tape_obj);
1929 ide_drive_t *drive = tape->drive; 1930 ide_drive_t *drive = tape->drive;
1930 int err = generic_ide_ioctl(drive, bdev, cmd, arg); 1931 int err;
1932
1933 lock_kernel();
1934 err = generic_ide_ioctl(drive, bdev, cmd, arg);
1931 if (err == -EINVAL) 1935 if (err == -EINVAL)
1932 err = idetape_blkdev_ioctl(drive, cmd, arg); 1936 err = idetape_blkdev_ioctl(drive, cmd, arg);
1937 unlock_kernel();
1938
1933 return err; 1939 return err;
1934} 1940}
1935 1941
@@ -1937,7 +1943,7 @@ static const struct block_device_operations idetape_block_ops = {
1937 .owner = THIS_MODULE, 1943 .owner = THIS_MODULE,
1938 .open = idetape_open, 1944 .open = idetape_open,
1939 .release = idetape_release, 1945 .release = idetape_release,
1940 .locked_ioctl = idetape_ioctl, 1946 .ioctl = idetape_ioctl,
1941}; 1947};
1942 1948
1943static int ide_tape_probe(ide_drive_t *drive) 1949static int ide_tape_probe(ide_drive_t *drive)
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index b8233ff863e3..d1bdf8abe5db 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -53,7 +53,6 @@
53#include <linux/module.h> 53#include <linux/module.h>
54#include <linux/slab.h> 54#include <linux/slab.h>
55#include <linux/i2o.h> 55#include <linux/i2o.h>
56#include <linux/smp_lock.h>
57 56
58#include <linux/mempool.h> 57#include <linux/mempool.h>
59 58
@@ -653,40 +652,30 @@ static int i2o_block_ioctl(struct block_device *bdev, fmode_t mode,
653{ 652{
654 struct gendisk *disk = bdev->bd_disk; 653 struct gendisk *disk = bdev->bd_disk;
655 struct i2o_block_device *dev = disk->private_data; 654 struct i2o_block_device *dev = disk->private_data;
656 int ret = -ENOTTY;
657 655
658 /* Anyone capable of this syscall can do *real bad* things */ 656 /* Anyone capable of this syscall can do *real bad* things */
659 657
660 if (!capable(CAP_SYS_ADMIN)) 658 if (!capable(CAP_SYS_ADMIN))
661 return -EPERM; 659 return -EPERM;
662 660
663 lock_kernel();
664 switch (cmd) { 661 switch (cmd) {
665 case BLKI2OGRSTRAT: 662 case BLKI2OGRSTRAT:
666 ret = put_user(dev->rcache, (int __user *)arg); 663 return put_user(dev->rcache, (int __user *)arg);
667 break;
668 case BLKI2OGWSTRAT: 664 case BLKI2OGWSTRAT:
669 ret = put_user(dev->wcache, (int __user *)arg); 665 return put_user(dev->wcache, (int __user *)arg);
670 break;
671 case BLKI2OSRSTRAT: 666 case BLKI2OSRSTRAT:
672 ret = -EINVAL;
673 if (arg < 0 || arg > CACHE_SMARTFETCH) 667 if (arg < 0 || arg > CACHE_SMARTFETCH)
674 break; 668 return -EINVAL;
675 dev->rcache = arg; 669 dev->rcache = arg;
676 ret = 0;
677 break; 670 break;
678 case BLKI2OSWSTRAT: 671 case BLKI2OSWSTRAT:
679 ret = -EINVAL;
680 if (arg != 0 672 if (arg != 0
681 && (arg < CACHE_WRITETHROUGH || arg > CACHE_SMARTBACK)) 673 && (arg < CACHE_WRITETHROUGH || arg > CACHE_SMARTBACK))
682 break; 674 return -EINVAL;
683 dev->wcache = arg; 675 dev->wcache = arg;
684 ret = 0;
685 break; 676 break;
686 } 677 }
687 unlock_kernel(); 678 return -ENOTTY;
688
689 return ret;
690}; 679};
691 680
692/** 681/**
@@ -942,7 +931,6 @@ static const struct block_device_operations i2o_block_fops = {
942 .open = i2o_block_open, 931 .open = i2o_block_open,
943 .release = i2o_block_release, 932 .release = i2o_block_release,
944 .ioctl = i2o_block_ioctl, 933 .ioctl = i2o_block_ioctl,
945 .compat_ioctl = i2o_block_ioctl,
946 .getgeo = i2o_block_getgeo, 934 .getgeo = i2o_block_getgeo,
947 .media_changed = i2o_block_media_changed 935 .media_changed = i2o_block_media_changed
948}; 936};
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 475af42745cb..8c83b11a77d5 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -15,6 +15,7 @@
15#include <linux/blkdev.h> 15#include <linux/blkdev.h>
16#include <linux/blkpg.h> 16#include <linux/blkpg.h>
17#include <linux/spinlock.h> 17#include <linux/spinlock.h>
18#include <linux/smp_lock.h>
18#include <linux/hdreg.h> 19#include <linux/hdreg.h>
19#include <linux/init.h> 20#include <linux/init.h>
20#include <linux/mutex.h> 21#include <linux/mutex.h>
@@ -237,6 +238,7 @@ static int blktrans_ioctl(struct block_device *bdev, fmode_t mode,
237 if (!dev) 238 if (!dev)
238 return ret; 239 return ret;
239 240
241 lock_kernel();
240 mutex_lock(&dev->lock); 242 mutex_lock(&dev->lock);
241 243
242 if (!dev->mtd) 244 if (!dev->mtd)
@@ -250,6 +252,7 @@ static int blktrans_ioctl(struct block_device *bdev, fmode_t mode,
250 } 252 }
251unlock: 253unlock:
252 mutex_unlock(&dev->lock); 254 mutex_unlock(&dev->lock);
255 unlock_kernel();
253 blktrans_dev_put(dev); 256 blktrans_dev_put(dev);
254 return ret; 257 return ret;
255} 258}
@@ -258,7 +261,7 @@ static const struct block_device_operations mtd_blktrans_ops = {
258 .owner = THIS_MODULE, 261 .owner = THIS_MODULE,
259 .open = blktrans_open, 262 .open = blktrans_open,
260 .release = blktrans_release, 263 .release = blktrans_release,
261 .locked_ioctl = blktrans_ioctl, 264 .ioctl = blktrans_ioctl,
262 .getgeo = blktrans_getgeo, 265 .getgeo = blktrans_getgeo,
263}; 266};
264 267
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 1d0c4b7c3b69..633ac32b25c1 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -46,6 +46,7 @@
46#include <linux/blkdev.h> 46#include <linux/blkdev.h>
47#include <linux/blkpg.h> 47#include <linux/blkpg.h>
48#include <linux/delay.h> 48#include <linux/delay.h>
49#include <linux/smp_lock.h>
49#include <linux/mutex.h> 50#include <linux/mutex.h>
50#include <linux/string_helpers.h> 51#include <linux/string_helpers.h>
51#include <linux/async.h> 52#include <linux/async.h>
@@ -924,6 +925,7 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode,
924 SCSI_LOG_IOCTL(1, printk("sd_ioctl: disk=%s, cmd=0x%x\n", 925 SCSI_LOG_IOCTL(1, printk("sd_ioctl: disk=%s, cmd=0x%x\n",
925 disk->disk_name, cmd)); 926 disk->disk_name, cmd));
926 927
928 lock_kernel();
927 /* 929 /*
928 * If we are in the middle of error recovery, don't let anyone 930 * If we are in the middle of error recovery, don't let anyone
929 * else try and use this device. Also, if error recovery fails, it 931 * else try and use this device. Also, if error recovery fails, it
@@ -933,7 +935,7 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode,
933 error = scsi_nonblockable_ioctl(sdp, cmd, p, 935 error = scsi_nonblockable_ioctl(sdp, cmd, p,
934 (mode & FMODE_NDELAY) != 0); 936 (mode & FMODE_NDELAY) != 0);
935 if (!scsi_block_when_processing_errors(sdp) || !error) 937 if (!scsi_block_when_processing_errors(sdp) || !error)
936 return error; 938 goto out;
937 939
938 /* 940 /*
939 * Send SCSI addressing ioctls directly to mid level, send other 941 * Send SCSI addressing ioctls directly to mid level, send other
@@ -943,13 +945,18 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode,
943 switch (cmd) { 945 switch (cmd) {
944 case SCSI_IOCTL_GET_IDLUN: 946 case SCSI_IOCTL_GET_IDLUN:
945 case SCSI_IOCTL_GET_BUS_NUMBER: 947 case SCSI_IOCTL_GET_BUS_NUMBER:
946 return scsi_ioctl(sdp, cmd, p); 948 error = scsi_ioctl(sdp, cmd, p);
949 break;
947 default: 950 default:
948 error = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, p); 951 error = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, p);
949 if (error != -ENOTTY) 952 if (error != -ENOTTY)
950 return error; 953 break;
954 error = scsi_ioctl(sdp, cmd, p);
955 break;
951 } 956 }
952 return scsi_ioctl(sdp, cmd, p); 957out:
958 unlock_kernel();
959 return error;
953} 960}
954 961
955static void set_media_not_present(struct scsi_disk *sdkp) 962static void set_media_not_present(struct scsi_disk *sdkp)
@@ -1123,7 +1130,7 @@ static const struct block_device_operations sd_fops = {
1123 .owner = THIS_MODULE, 1130 .owner = THIS_MODULE,
1124 .open = sd_open, 1131 .open = sd_open,
1125 .release = sd_release, 1132 .release = sd_release,
1126 .locked_ioctl = sd_ioctl, 1133 .ioctl = sd_ioctl,
1127 .getgeo = sd_getgeo, 1134 .getgeo = sd_getgeo,
1128#ifdef CONFIG_COMPAT 1135#ifdef CONFIG_COMPAT
1129 .compat_ioctl = sd_compat_ioctl, 1136 .compat_ioctl = sd_compat_ioctl,
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 0a90abc7f140..d42fa6468f41 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -44,6 +44,7 @@
44#include <linux/init.h> 44#include <linux/init.h>
45#include <linux/blkdev.h> 45#include <linux/blkdev.h>
46#include <linux/mutex.h> 46#include <linux/mutex.h>
47#include <linux/smp_lock.h>
47#include <linux/slab.h> 48#include <linux/slab.h>
48#include <asm/uaccess.h> 49#include <asm/uaccess.h>
49 50
@@ -493,6 +494,8 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
493 void __user *argp = (void __user *)arg; 494 void __user *argp = (void __user *)arg;
494 int ret; 495 int ret;
495 496
497 lock_kernel();
498
496 /* 499 /*
497 * Send SCSI addressing ioctls directly to mid level, send other 500 * Send SCSI addressing ioctls directly to mid level, send other
498 * ioctls to cdrom/block level. 501 * ioctls to cdrom/block level.
@@ -500,12 +503,13 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
500 switch (cmd) { 503 switch (cmd) {
501 case SCSI_IOCTL_GET_IDLUN: 504 case SCSI_IOCTL_GET_IDLUN:
502 case SCSI_IOCTL_GET_BUS_NUMBER: 505 case SCSI_IOCTL_GET_BUS_NUMBER:
503 return scsi_ioctl(sdev, cmd, argp); 506 ret = scsi_ioctl(sdev, cmd, argp);
507 goto out;
504 } 508 }
505 509
506 ret = cdrom_ioctl(&cd->cdi, bdev, mode, cmd, arg); 510 ret = cdrom_ioctl(&cd->cdi, bdev, mode, cmd, arg);
507 if (ret != -ENOSYS) 511 if (ret != -ENOSYS)
508 return ret; 512 goto out;
509 513
510 /* 514 /*
511 * ENODEV means that we didn't recognise the ioctl, or that we 515 * ENODEV means that we didn't recognise the ioctl, or that we
@@ -516,8 +520,12 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
516 ret = scsi_nonblockable_ioctl(sdev, cmd, argp, 520 ret = scsi_nonblockable_ioctl(sdev, cmd, argp,
517 (mode & FMODE_NDELAY) != 0); 521 (mode & FMODE_NDELAY) != 0);
518 if (ret != -ENODEV) 522 if (ret != -ENODEV)
519 return ret; 523 goto out;
520 return scsi_ioctl(sdev, cmd, argp); 524 ret = scsi_ioctl(sdev, cmd, argp);
525
526out:
527 unlock_kernel();
528 return ret;
521} 529}
522 530
523static int sr_block_media_changed(struct gendisk *disk) 531static int sr_block_media_changed(struct gendisk *disk)
@@ -531,7 +539,7 @@ static const struct block_device_operations sr_bdops =
531 .owner = THIS_MODULE, 539 .owner = THIS_MODULE,
532 .open = sr_block_open, 540 .open = sr_block_open,
533 .release = sr_block_release, 541 .release = sr_block_release,
534 .locked_ioctl = sr_block_ioctl, 542 .ioctl = sr_block_ioctl,
535 .media_changed = sr_block_media_changed, 543 .media_changed = sr_block_media_changed,
536 /* 544 /*
537 * No compat_ioctl for now because sr_block_ioctl never 545 * No compat_ioctl for now because sr_block_ioctl never
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index baf5258f5985..a8b05fc80c6d 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1246,7 +1246,6 @@ static inline int blk_integrity_rq(struct request *rq)
1246struct block_device_operations { 1246struct block_device_operations {
1247 int (*open) (struct block_device *, fmode_t); 1247 int (*open) (struct block_device *, fmode_t);
1248 int (*release) (struct gendisk *, fmode_t); 1248 int (*release) (struct gendisk *, fmode_t);
1249 int (*locked_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
1250 int (*ioctl) (struct block_device *, fmode_t, unsigned, unsigned long); 1249 int (*ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
1251 int (*compat_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long); 1250 int (*compat_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
1252 int (*direct_access) (struct block_device *, sector_t, 1251 int (*direct_access) (struct block_device *, sector_t,