aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2010-08-07 12:25:34 -0400
committerJens Axboe <jaxboe@fusionio.com>2010-08-07 12:25:34 -0400
commit6e9624b8caec290d28b4c6d9ec75749df6372b87 (patch)
tree47225b544e1da82742795553dc4e8aa70c17afdc /drivers/block
parent8a6cfeb6deca3a8fefd639d898b0d163c0b5d368 (diff)
block: push down BKL into .open and .release
The open and release block_device_operations are currently called with the BKL held. In order to change that, we must first make sure that all drivers that currently rely on this have no regressions. This blindly pushes the BKL into all .open and .release operations for all block drivers to prepare for the next step. The drivers can subsequently replace the BKL with their own locks or remove it completely when it can be shown that it is not needed. The functions blkdev_get and blkdev_put are the only remaining users of the big kernel lock in the block layer, besides a few uses in the ioctl code, none of which need to serialize with blkdev_{get,put}. Most of these two functions is also under the protection of bdev->bd_mutex, including the actual calls to ->open and ->release, and the common code does not access any global data structures that need the BKL. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Acked-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/DAC960.c13
-rw-r--r--drivers/block/amiflop.c12
-rw-r--r--drivers/block/aoe/aoeblk.c4
-rw-r--r--drivers/block/ataflop.c14
-rw-r--r--drivers/block/cciss.c23
-rw-r--r--drivers/block/cpqarray.c22
-rw-r--r--drivers/block/drbd/drbd_main.c4
-rw-r--r--drivers/block/floppy.c5
-rw-r--r--drivers/block/loop.c5
-rw-r--r--drivers/block/paride/pcd.c10
-rw-r--r--drivers/block/paride/pd.c4
-rw-r--r--drivers/block/paride/pf.c20
-rw-r--r--drivers/block/pktcdvd.c5
-rw-r--r--drivers/block/swim.c15
-rw-r--r--drivers/block/swim3.c15
-rw-r--r--drivers/block/ub.c17
-rw-r--r--drivers/block/viodasd.c19
-rw-r--r--drivers/block/xen-blkfront.c7
-rw-r--r--drivers/block/xsysace.c6
-rw-r--r--drivers/block/z2ram.c13
20 files changed, 207 insertions, 26 deletions
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index c5f22bb0a48e..4e2c367fec11 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -79,23 +79,28 @@ static int DAC960_open(struct block_device *bdev, fmode_t mode)
79 struct gendisk *disk = bdev->bd_disk; 79 struct gendisk *disk = bdev->bd_disk;
80 DAC960_Controller_T *p = disk->queue->queuedata; 80 DAC960_Controller_T *p = disk->queue->queuedata;
81 int drive_nr = (long)disk->private_data; 81 int drive_nr = (long)disk->private_data;
82 int ret = -ENXIO;
82 83
84 lock_kernel();
83 if (p->FirmwareType == DAC960_V1_Controller) { 85 if (p->FirmwareType == DAC960_V1_Controller) {
84 if (p->V1.LogicalDriveInformation[drive_nr]. 86 if (p->V1.LogicalDriveInformation[drive_nr].
85 LogicalDriveState == DAC960_V1_LogicalDrive_Offline) 87 LogicalDriveState == DAC960_V1_LogicalDrive_Offline)
86 return -ENXIO; 88 goto out;
87 } else { 89 } else {
88 DAC960_V2_LogicalDeviceInfo_T *i = 90 DAC960_V2_LogicalDeviceInfo_T *i =
89 p->V2.LogicalDeviceInformation[drive_nr]; 91 p->V2.LogicalDeviceInformation[drive_nr];
90 if (!i || i->LogicalDeviceState == DAC960_V2_LogicalDevice_Offline) 92 if (!i || i->LogicalDeviceState == DAC960_V2_LogicalDevice_Offline)
91 return -ENXIO; 93 goto out;
92 } 94 }
93 95
94 check_disk_change(bdev); 96 check_disk_change(bdev);
95 97
96 if (!get_capacity(p->disks[drive_nr])) 98 if (!get_capacity(p->disks[drive_nr]))
97 return -ENXIO; 99 goto out;
98 return 0; 100 ret = 0;
101out:
102 unlock_kernel();
103 return ret;
99} 104}
100 105
101static int DAC960_getgeo(struct block_device *bdev, struct hd_geometry *geo) 106static int DAC960_getgeo(struct block_device *bdev, struct hd_geometry *geo)
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 0fa26359304c..76f114f0bba3 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -1555,10 +1555,13 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)
1555 int old_dev; 1555 int old_dev;
1556 unsigned long flags; 1556 unsigned long flags;
1557 1557
1558 lock_kernel();
1558 old_dev = fd_device[drive]; 1559 old_dev = fd_device[drive];
1559 1560
1560 if (fd_ref[drive] && old_dev != system) 1561 if (fd_ref[drive] && old_dev != system) {
1562 unlock_kernel();
1561 return -EBUSY; 1563 return -EBUSY;
1564 }
1562 1565
1563 if (mode & (FMODE_READ|FMODE_WRITE)) { 1566 if (mode & (FMODE_READ|FMODE_WRITE)) {
1564 check_disk_change(bdev); 1567 check_disk_change(bdev);
@@ -1571,8 +1574,10 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)
1571 fd_deselect (drive); 1574 fd_deselect (drive);
1572 rel_fdc(); 1575 rel_fdc();
1573 1576
1574 if (wrprot) 1577 if (wrprot) {
1578 unlock_kernel();
1575 return -EROFS; 1579 return -EROFS;
1580 }
1576 } 1581 }
1577 } 1582 }
1578 1583
@@ -1589,6 +1594,7 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)
1589 printk(KERN_INFO "fd%d: accessing %s-disk with %s-layout\n",drive, 1594 printk(KERN_INFO "fd%d: accessing %s-disk with %s-layout\n",drive,
1590 unit[drive].type->name, data_types[system].name); 1595 unit[drive].type->name, data_types[system].name);
1591 1596
1597 unlock_kernel();
1592 return 0; 1598 return 0;
1593} 1599}
1594 1600
@@ -1597,6 +1603,7 @@ static int floppy_release(struct gendisk *disk, fmode_t mode)
1597 struct amiga_floppy_struct *p = disk->private_data; 1603 struct amiga_floppy_struct *p = disk->private_data;
1598 int drive = p - unit; 1604 int drive = p - unit;
1599 1605
1606 lock_kernel();
1600 if (unit[drive].dirty == 1) { 1607 if (unit[drive].dirty == 1) {
1601 del_timer (flush_track_timer + drive); 1608 del_timer (flush_track_timer + drive);
1602 non_int_flush_track (drive); 1609 non_int_flush_track (drive);
@@ -1610,6 +1617,7 @@ static int floppy_release(struct gendisk *disk, fmode_t mode)
1610/* the mod_use counter is handled this way */ 1617/* the mod_use counter is handled this way */
1611 floppy_off (drive | 0x40000000); 1618 floppy_off (drive | 0x40000000);
1612#endif 1619#endif
1620 unlock_kernel();
1613 return 0; 1621 return 0;
1614} 1622}
1615 1623
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
index 65deffde60ac..a946929735a5 100644
--- a/drivers/block/aoe/aoeblk.c
+++ b/drivers/block/aoe/aoeblk.c
@@ -12,6 +12,7 @@
12#include <linux/slab.h> 12#include <linux/slab.h>
13#include <linux/genhd.h> 13#include <linux/genhd.h>
14#include <linux/netdevice.h> 14#include <linux/netdevice.h>
15#include <linux/smp_lock.h>
15#include "aoe.h" 16#include "aoe.h"
16 17
17static struct kmem_cache *buf_pool_cache; 18static struct kmem_cache *buf_pool_cache;
@@ -124,13 +125,16 @@ aoeblk_open(struct block_device *bdev, fmode_t mode)
124 struct aoedev *d = bdev->bd_disk->private_data; 125 struct aoedev *d = bdev->bd_disk->private_data;
125 ulong flags; 126 ulong flags;
126 127
128 lock_kernel();
127 spin_lock_irqsave(&d->lock, flags); 129 spin_lock_irqsave(&d->lock, flags);
128 if (d->flags & DEVFL_UP) { 130 if (d->flags & DEVFL_UP) {
129 d->nopen++; 131 d->nopen++;
130 spin_unlock_irqrestore(&d->lock, flags); 132 spin_unlock_irqrestore(&d->lock, flags);
133 unlock_kernel();
131 return 0; 134 return 0;
132 } 135 }
133 spin_unlock_irqrestore(&d->lock, flags); 136 spin_unlock_irqrestore(&d->lock, flags);
137 unlock_kernel();
134 return -ENODEV; 138 return -ENODEV;
135} 139}
136 140
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
index 1bb8bfcfdbd9..aceb96476524 100644
--- a/drivers/block/ataflop.c
+++ b/drivers/block/ataflop.c
@@ -1850,22 +1850,34 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)
1850 return 0; 1850 return 0;
1851} 1851}
1852 1852
1853static int floppy_unlocked_open(struct block_device *bdev, fmode_t mode)
1854{
1855 int ret;
1856
1857 lock_kernel();
1858 ret = floppy_open(bdev, mode);
1859 unlock_kernel();
1860
1861 return ret;
1862}
1853 1863
1854static int floppy_release(struct gendisk *disk, fmode_t mode) 1864static int floppy_release(struct gendisk *disk, fmode_t mode)
1855{ 1865{
1856 struct atari_floppy_struct *p = disk->private_data; 1866 struct atari_floppy_struct *p = disk->private_data;
1867 lock_kernel();
1857 if (p->ref < 0) 1868 if (p->ref < 0)
1858 p->ref = 0; 1869 p->ref = 0;
1859 else if (!p->ref--) { 1870 else if (!p->ref--) {
1860 printk(KERN_ERR "floppy_release with fd_ref == 0"); 1871 printk(KERN_ERR "floppy_release with fd_ref == 0");
1861 p->ref = 0; 1872 p->ref = 0;
1862 } 1873 }
1874 unlock_kernel();
1863 return 0; 1875 return 0;
1864} 1876}
1865 1877
1866static const struct block_device_operations floppy_fops = { 1878static const struct block_device_operations floppy_fops = {
1867 .owner = THIS_MODULE, 1879 .owner = THIS_MODULE,
1868 .open = floppy_open, 1880 .open = floppy_unlocked_open,
1869 .release = floppy_release, 1881 .release = floppy_release,
1870 .ioctl = fd_ioctl, 1882 .ioctl = fd_ioctl,
1871 .media_changed = check_floppy_change, 1883 .media_changed = check_floppy_change,
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index a6c0494dd054..665a470310a9 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -178,6 +178,7 @@ static void do_cciss_request(struct request_queue *q);
178static irqreturn_t do_cciss_intx(int irq, void *dev_id); 178static 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_unlocked_open(struct block_device *bdev, fmode_t mode);
181static int cciss_release(struct gendisk *disk, fmode_t mode); 182static int cciss_release(struct gendisk *disk, fmode_t mode);
182static int do_ioctl(struct block_device *bdev, fmode_t mode, 183static int do_ioctl(struct block_device *bdev, fmode_t mode,
183 unsigned int cmd, unsigned long arg); 184 unsigned int cmd, unsigned long arg);
@@ -237,7 +238,7 @@ static int cciss_compat_ioctl(struct block_device *, fmode_t,
237 238
238static const struct block_device_operations cciss_fops = { 239static const struct block_device_operations cciss_fops = {
239 .owner = THIS_MODULE, 240 .owner = THIS_MODULE,
240 .open = cciss_open, 241 .open = cciss_unlocked_open,
241 .release = cciss_release, 242 .release = cciss_release,
242 .ioctl = do_ioctl, 243 .ioctl = do_ioctl,
243 .getgeo = cciss_getgeo, 244 .getgeo = cciss_getgeo,
@@ -1042,13 +1043,28 @@ static int cciss_open(struct block_device *bdev, fmode_t mode)
1042 return 0; 1043 return 0;
1043} 1044}
1044 1045
1046static int cciss_unlocked_open(struct block_device *bdev, fmode_t mode)
1047{
1048 int ret;
1049
1050 lock_kernel();
1051 ret = cciss_open(bdev, mode);
1052 unlock_kernel();
1053
1054 return ret;
1055}
1056
1045/* 1057/*
1046 * Close. Sync first. 1058 * Close. Sync first.
1047 */ 1059 */
1048static int cciss_release(struct gendisk *disk, fmode_t mode) 1060static int cciss_release(struct gendisk *disk, fmode_t mode)
1049{ 1061{
1050 ctlr_info_t *host = get_host(disk); 1062 ctlr_info_t *host;
1051 drive_info_struct *drv = get_drv(disk); 1063 drive_info_struct *drv;
1064
1065 lock_kernel();
1066 host = get_host(disk);
1067 drv = get_drv(disk);
1052 1068
1053#ifdef CCISS_DEBUG 1069#ifdef CCISS_DEBUG
1054 printk(KERN_DEBUG "cciss_release %s\n", disk->disk_name); 1070 printk(KERN_DEBUG "cciss_release %s\n", disk->disk_name);
@@ -1056,6 +1072,7 @@ static int cciss_release(struct gendisk *disk, fmode_t mode)
1056 1072
1057 drv->usage_count--; 1073 drv->usage_count--;
1058 host->usage_count--; 1074 host->usage_count--;
1075 unlock_kernel();
1059 return 0; 1076 return 0;
1060} 1077}
1061 1078
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index c459aeea3c0c..28937b661564 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -158,7 +158,7 @@ static int sendcmd(
158 unsigned int blkcnt, 158 unsigned int blkcnt,
159 unsigned int log_unit ); 159 unsigned int log_unit );
160 160
161static int ida_open(struct block_device *bdev, fmode_t mode); 161static int ida_unlocked_open(struct block_device *bdev, fmode_t mode);
162static int ida_release(struct gendisk *disk, fmode_t mode); 162static int ida_release(struct gendisk *disk, fmode_t mode);
163static int ida_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg); 163static int ida_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg);
164static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo); 164static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo);
@@ -196,7 +196,7 @@ static inline ctlr_info_t *get_host(struct gendisk *disk)
196 196
197static const struct block_device_operations ida_fops = { 197static const struct block_device_operations ida_fops = {
198 .owner = THIS_MODULE, 198 .owner = THIS_MODULE,
199 .open = ida_open, 199 .open = ida_unlocked_open,
200 .release = ida_release, 200 .release = ida_release,
201 .ioctl = ida_ioctl, 201 .ioctl = ida_ioctl,
202 .getgeo = ida_getgeo, 202 .getgeo = ida_getgeo,
@@ -841,13 +841,29 @@ static int ida_open(struct block_device *bdev, fmode_t mode)
841 return 0; 841 return 0;
842} 842}
843 843
844static int ida_unlocked_open(struct block_device *bdev, fmode_t mode)
845{
846 int ret;
847
848 lock_kernel();
849 ret = ida_open(bdev, mode);
850 unlock_kernel();
851
852 return ret;
853}
854
844/* 855/*
845 * Close. Sync first. 856 * Close. Sync first.
846 */ 857 */
847static int ida_release(struct gendisk *disk, fmode_t mode) 858static int ida_release(struct gendisk *disk, fmode_t mode)
848{ 859{
849 ctlr_info_t *host = get_host(disk); 860 ctlr_info_t *host;
861
862 lock_kernel();
863 host = get_host(disk);
850 host->usage_count--; 864 host->usage_count--;
865 unlock_kernel();
866
851 return 0; 867 return 0;
852} 868}
853 869
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index e2ab13d99d69..d2b6764a7b1f 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2604,6 +2604,7 @@ static int drbd_open(struct block_device *bdev, fmode_t mode)
2604 unsigned long flags; 2604 unsigned long flags;
2605 int rv = 0; 2605 int rv = 0;
2606 2606
2607 lock_kernel();
2607 spin_lock_irqsave(&mdev->req_lock, flags); 2608 spin_lock_irqsave(&mdev->req_lock, flags);
2608 /* to have a stable mdev->state.role 2609 /* to have a stable mdev->state.role
2609 * and no race with updating open_cnt */ 2610 * and no race with updating open_cnt */
@@ -2618,6 +2619,7 @@ static int drbd_open(struct block_device *bdev, fmode_t mode)
2618 if (!rv) 2619 if (!rv)
2619 mdev->open_cnt++; 2620 mdev->open_cnt++;
2620 spin_unlock_irqrestore(&mdev->req_lock, flags); 2621 spin_unlock_irqrestore(&mdev->req_lock, flags);
2622 unlock_kernel();
2621 2623
2622 return rv; 2624 return rv;
2623} 2625}
@@ -2625,7 +2627,9 @@ static int drbd_open(struct block_device *bdev, fmode_t mode)
2625static int drbd_release(struct gendisk *gd, fmode_t mode) 2627static int drbd_release(struct gendisk *gd, fmode_t mode)
2626{ 2628{
2627 struct drbd_conf *mdev = gd->private_data; 2629 struct drbd_conf *mdev = gd->private_data;
2630 lock_kernel();
2628 mdev->open_cnt--; 2631 mdev->open_cnt--;
2632 unlock_kernel();
2629 return 0; 2633 return 0;
2630} 2634}
2631 2635
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 40419b066aa9..3126d5122b2b 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -3616,6 +3616,7 @@ static int floppy_release(struct gendisk *disk, fmode_t mode)
3616{ 3616{
3617 int drive = (long)disk->private_data; 3617 int drive = (long)disk->private_data;
3618 3618
3619 lock_kernel();
3619 mutex_lock(&open_lock); 3620 mutex_lock(&open_lock);
3620 if (UDRS->fd_ref < 0) 3621 if (UDRS->fd_ref < 0)
3621 UDRS->fd_ref = 0; 3622 UDRS->fd_ref = 0;
@@ -3626,6 +3627,7 @@ static int floppy_release(struct gendisk *disk, fmode_t mode)
3626 if (!UDRS->fd_ref) 3627 if (!UDRS->fd_ref)
3627 opened_bdev[drive] = NULL; 3628 opened_bdev[drive] = NULL;
3628 mutex_unlock(&open_lock); 3629 mutex_unlock(&open_lock);
3630 unlock_kernel();
3629 3631
3630 return 0; 3632 return 0;
3631} 3633}
@@ -3643,6 +3645,7 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)
3643 int res = -EBUSY; 3645 int res = -EBUSY;
3644 char *tmp; 3646 char *tmp;
3645 3647
3648 lock_kernel();
3646 mutex_lock(&open_lock); 3649 mutex_lock(&open_lock);
3647 old_dev = UDRS->fd_device; 3650 old_dev = UDRS->fd_device;
3648 if (opened_bdev[drive] && opened_bdev[drive] != bdev) 3651 if (opened_bdev[drive] && opened_bdev[drive] != bdev)
@@ -3719,6 +3722,7 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)
3719 goto out; 3722 goto out;
3720 } 3723 }
3721 mutex_unlock(&open_lock); 3724 mutex_unlock(&open_lock);
3725 unlock_kernel();
3722 return 0; 3726 return 0;
3723out: 3727out:
3724 if (UDRS->fd_ref < 0) 3728 if (UDRS->fd_ref < 0)
@@ -3729,6 +3733,7 @@ out:
3729 opened_bdev[drive] = NULL; 3733 opened_bdev[drive] = NULL;
3730out2: 3734out2:
3731 mutex_unlock(&open_lock); 3735 mutex_unlock(&open_lock);
3736 unlock_kernel();
3732 return res; 3737 return res;
3733} 3738}
3734 3739
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index d285a5481965..f3c636d23718 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -67,6 +67,7 @@
67#include <linux/compat.h> 67#include <linux/compat.h>
68#include <linux/suspend.h> 68#include <linux/suspend.h>
69#include <linux/freezer.h> 69#include <linux/freezer.h>
70#include <linux/smp_lock.h>
70#include <linux/writeback.h> 71#include <linux/writeback.h>
71#include <linux/buffer_head.h> /* for invalidate_bdev() */ 72#include <linux/buffer_head.h> /* for invalidate_bdev() */
72#include <linux/completion.h> 73#include <linux/completion.h>
@@ -1408,9 +1409,11 @@ static int lo_open(struct block_device *bdev, fmode_t mode)
1408{ 1409{
1409 struct loop_device *lo = bdev->bd_disk->private_data; 1410 struct loop_device *lo = bdev->bd_disk->private_data;
1410 1411
1412 lock_kernel();
1411 mutex_lock(&lo->lo_ctl_mutex); 1413 mutex_lock(&lo->lo_ctl_mutex);
1412 lo->lo_refcnt++; 1414 lo->lo_refcnt++;
1413 mutex_unlock(&lo->lo_ctl_mutex); 1415 mutex_unlock(&lo->lo_ctl_mutex);
1416 unlock_kernel();
1414 1417
1415 return 0; 1418 return 0;
1416} 1419}
@@ -1420,6 +1423,7 @@ static int lo_release(struct gendisk *disk, fmode_t mode)
1420 struct loop_device *lo = disk->private_data; 1423 struct loop_device *lo = disk->private_data;
1421 int err; 1424 int err;
1422 1425
1426 lock_kernel();
1423 mutex_lock(&lo->lo_ctl_mutex); 1427 mutex_lock(&lo->lo_ctl_mutex);
1424 1428
1425 if (--lo->lo_refcnt) 1429 if (--lo->lo_refcnt)
@@ -1444,6 +1448,7 @@ static int lo_release(struct gendisk *disk, fmode_t mode)
1444out: 1448out:
1445 mutex_unlock(&lo->lo_ctl_mutex); 1449 mutex_unlock(&lo->lo_ctl_mutex);
1446out_unlocked: 1450out_unlocked:
1451 lock_kernel();
1447 return 0; 1452 return 0;
1448} 1453}
1449 1454
diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c
index daba7a62a663..76f8565e1e8d 100644
--- a/drivers/block/paride/pcd.c
+++ b/drivers/block/paride/pcd.c
@@ -225,13 +225,21 @@ static char *pcd_buf; /* buffer for request in progress */
225static int pcd_block_open(struct block_device *bdev, fmode_t mode) 225static int pcd_block_open(struct block_device *bdev, fmode_t mode)
226{ 226{
227 struct pcd_unit *cd = bdev->bd_disk->private_data; 227 struct pcd_unit *cd = bdev->bd_disk->private_data;
228 return cdrom_open(&cd->info, bdev, mode); 228 int ret;
229
230 lock_kernel();
231 ret = cdrom_open(&cd->info, bdev, mode);
232 unlock_kernel();
233
234 return ret;
229} 235}
230 236
231static int pcd_block_release(struct gendisk *disk, fmode_t mode) 237static int pcd_block_release(struct gendisk *disk, fmode_t mode)
232{ 238{
233 struct pcd_unit *cd = disk->private_data; 239 struct pcd_unit *cd = disk->private_data;
240 lock_kernel();
234 cdrom_release(&cd->info, mode); 241 cdrom_release(&cd->info, mode);
242 unlock_kernel();
235 return 0; 243 return 0;
236} 244}
237 245
diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
index c4d6ed9846ca..985f0d4f1d1e 100644
--- a/drivers/block/paride/pd.c
+++ b/drivers/block/paride/pd.c
@@ -736,12 +736,14 @@ static int pd_open(struct block_device *bdev, fmode_t mode)
736{ 736{
737 struct pd_unit *disk = bdev->bd_disk->private_data; 737 struct pd_unit *disk = bdev->bd_disk->private_data;
738 738
739 lock_kernel();
739 disk->access++; 740 disk->access++;
740 741
741 if (disk->removable) { 742 if (disk->removable) {
742 pd_special_command(disk, pd_media_check); 743 pd_special_command(disk, pd_media_check);
743 pd_special_command(disk, pd_door_lock); 744 pd_special_command(disk, pd_door_lock);
744 } 745 }
746 unlock_kernel();
745 return 0; 747 return 0;
746} 748}
747 749
@@ -783,8 +785,10 @@ static int pd_release(struct gendisk *p, fmode_t mode)
783{ 785{
784 struct pd_unit *disk = p->private_data; 786 struct pd_unit *disk = p->private_data;
785 787
788 lock_kernel();
786 if (!--disk->access && disk->removable) 789 if (!--disk->access && disk->removable)
787 pd_special_command(disk, pd_door_unlock); 790 pd_special_command(disk, pd_door_unlock);
791 unlock_kernel();
788 792
789 return 0; 793 return 0;
790} 794}
diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c
index 38b4d566b816..4457b494882a 100644
--- a/drivers/block/paride/pf.c
+++ b/drivers/block/paride/pf.c
@@ -300,20 +300,26 @@ static void __init pf_init_units(void)
300static int pf_open(struct block_device *bdev, fmode_t mode) 300static int pf_open(struct block_device *bdev, fmode_t mode)
301{ 301{
302 struct pf_unit *pf = bdev->bd_disk->private_data; 302 struct pf_unit *pf = bdev->bd_disk->private_data;
303 int ret;
303 304
305 lock_kernel();
304 pf_identify(pf); 306 pf_identify(pf);
305 307
308 ret = -ENODEV;
306 if (pf->media_status == PF_NM) 309 if (pf->media_status == PF_NM)
307 return -ENODEV; 310 goto out;
308 311
312 ret = -EROFS;
309 if ((pf->media_status == PF_RO) && (mode & FMODE_WRITE)) 313 if ((pf->media_status == PF_RO) && (mode & FMODE_WRITE))
310 return -EROFS; 314 goto out;
311 315
316 ret = 0;
312 pf->access++; 317 pf->access++;
313 if (pf->removable) 318 if (pf->removable)
314 pf_lock(pf, 1); 319 pf_lock(pf, 1);
315 320out:
316 return 0; 321 unlock_kernel();
322 return ret;
317} 323}
318 324
319static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo) 325static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo)
@@ -354,14 +360,18 @@ static int pf_release(struct gendisk *disk, fmode_t mode)
354{ 360{
355 struct pf_unit *pf = disk->private_data; 361 struct pf_unit *pf = disk->private_data;
356 362
357 if (pf->access <= 0) 363 lock_kernel();
364 if (pf->access <= 0) {
365 unlock_kernel();
358 return -EINVAL; 366 return -EINVAL;
367 }
359 368
360 pf->access--; 369 pf->access--;
361 370
362 if (!pf->access && pf->removable) 371 if (!pf->access && pf->removable)
363 pf_lock(pf, 0); 372 pf_lock(pf, 0);
364 373
374 unlock_kernel();
365 return 0; 375 return 0;
366 376
367} 377}
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 40f1e31f42c4..b1cbeb59bb76 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -2383,6 +2383,7 @@ static int pkt_open(struct block_device *bdev, fmode_t mode)
2383 2383
2384 VPRINTK(DRIVER_NAME": entering open\n"); 2384 VPRINTK(DRIVER_NAME": entering open\n");
2385 2385
2386 lock_kernel();
2386 mutex_lock(&ctl_mutex); 2387 mutex_lock(&ctl_mutex);
2387 pd = pkt_find_dev_from_minor(MINOR(bdev->bd_dev)); 2388 pd = pkt_find_dev_from_minor(MINOR(bdev->bd_dev));
2388 if (!pd) { 2389 if (!pd) {
@@ -2410,6 +2411,7 @@ static int pkt_open(struct block_device *bdev, fmode_t mode)
2410 } 2411 }
2411 2412
2412 mutex_unlock(&ctl_mutex); 2413 mutex_unlock(&ctl_mutex);
2414 unlock_kernel();
2413 return 0; 2415 return 0;
2414 2416
2415out_dec: 2417out_dec:
@@ -2417,6 +2419,7 @@ out_dec:
2417out: 2419out:
2418 VPRINTK(DRIVER_NAME": failed open (%d)\n", ret); 2420 VPRINTK(DRIVER_NAME": failed open (%d)\n", ret);
2419 mutex_unlock(&ctl_mutex); 2421 mutex_unlock(&ctl_mutex);
2422 unlock_kernel();
2420 return ret; 2423 return ret;
2421} 2424}
2422 2425
@@ -2425,6 +2428,7 @@ static int pkt_close(struct gendisk *disk, fmode_t mode)
2425 struct pktcdvd_device *pd = disk->private_data; 2428 struct pktcdvd_device *pd = disk->private_data;
2426 int ret = 0; 2429 int ret = 0;
2427 2430
2431 lock_kernel();
2428 mutex_lock(&ctl_mutex); 2432 mutex_lock(&ctl_mutex);
2429 pd->refcnt--; 2433 pd->refcnt--;
2430 BUG_ON(pd->refcnt < 0); 2434 BUG_ON(pd->refcnt < 0);
@@ -2433,6 +2437,7 @@ static int pkt_close(struct gendisk *disk, fmode_t mode)
2433 pkt_release_dev(pd, flush); 2437 pkt_release_dev(pd, flush);
2434 } 2438 }
2435 mutex_unlock(&ctl_mutex); 2439 mutex_unlock(&ctl_mutex);
2440 unlock_kernel();
2436 return ret; 2441 return ret;
2437} 2442}
2438 2443
diff --git a/drivers/block/swim.c b/drivers/block/swim.c
index f04f74e3758f..2e46815876df 100644
--- a/drivers/block/swim.c
+++ b/drivers/block/swim.c
@@ -662,11 +662,23 @@ out:
662 return err; 662 return err;
663} 663}
664 664
665static int floppy_unlocked_open(struct block_device *bdev, fmode_t mode)
666{
667 int ret;
668
669 lock_kernel();
670 ret = floppy_open(bdev, mode);
671 unlock_kernel();
672
673 return ret;
674}
675
665static int floppy_release(struct gendisk *disk, fmode_t mode) 676static int floppy_release(struct gendisk *disk, fmode_t mode)
666{ 677{
667 struct floppy_state *fs = disk->private_data; 678 struct floppy_state *fs = disk->private_data;
668 struct swim __iomem *base = fs->swd->base; 679 struct swim __iomem *base = fs->swd->base;
669 680
681 lock_kernel();
670 if (fs->ref_count < 0) 682 if (fs->ref_count < 0)
671 fs->ref_count = 0; 683 fs->ref_count = 0;
672 else if (fs->ref_count > 0) 684 else if (fs->ref_count > 0)
@@ -674,6 +686,7 @@ static int floppy_release(struct gendisk *disk, fmode_t mode)
674 686
675 if (fs->ref_count == 0) 687 if (fs->ref_count == 0)
676 swim_motor(base, OFF); 688 swim_motor(base, OFF);
689 unlock_kernel();
677 690
678 return 0; 691 return 0;
679} 692}
@@ -754,7 +767,7 @@ static int floppy_revalidate(struct gendisk *disk)
754 767
755static const struct block_device_operations floppy_fops = { 768static const struct block_device_operations floppy_fops = {
756 .owner = THIS_MODULE, 769 .owner = THIS_MODULE,
757 .open = floppy_open, 770 .open = floppy_unlocked_open,
758 .release = floppy_release, 771 .release = floppy_release,
759 .ioctl = floppy_ioctl, 772 .ioctl = floppy_ioctl,
760 .getgeo = floppy_getgeo, 773 .getgeo = floppy_getgeo,
diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c
index f3657b2a5386..cc6a3864822c 100644
--- a/drivers/block/swim3.c
+++ b/drivers/block/swim3.c
@@ -949,15 +949,28 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)
949 return 0; 949 return 0;
950} 950}
951 951
952static int floppy_unlocked_open(struct block_device *bdev, fmode_t mode)
953{
954 int ret;
955
956 lock_kernel();
957 ret = floppy_open(bdev, mode);
958 unlock_kernel();
959
960 return ret;
961}
962
952static int floppy_release(struct gendisk *disk, fmode_t mode) 963static int floppy_release(struct gendisk *disk, fmode_t mode)
953{ 964{
954 struct floppy_state *fs = disk->private_data; 965 struct floppy_state *fs = disk->private_data;
955 struct swim3 __iomem *sw = fs->swim3; 966 struct swim3 __iomem *sw = fs->swim3;
967 lock_kernel();
956 if (fs->ref_count > 0 && --fs->ref_count == 0) { 968 if (fs->ref_count > 0 && --fs->ref_count == 0) {
957 swim3_action(fs, MOTOR_OFF); 969 swim3_action(fs, MOTOR_OFF);
958 out_8(&sw->control_bic, 0xff); 970 out_8(&sw->control_bic, 0xff);
959 swim3_select(fs, RELAX); 971 swim3_select(fs, RELAX);
960 } 972 }
973 unlock_kernel();
961 return 0; 974 return 0;
962} 975}
963 976
@@ -1008,7 +1021,7 @@ static int floppy_revalidate(struct gendisk *disk)
1008} 1021}
1009 1022
1010static const struct block_device_operations floppy_fops = { 1023static const struct block_device_operations floppy_fops = {
1011 .open = floppy_open, 1024 .open = floppy_unlocked_open,
1012 .release = floppy_release, 1025 .release = floppy_release,
1013 .ioctl = floppy_ioctl, 1026 .ioctl = floppy_ioctl,
1014 .media_changed = floppy_check_change, 1027 .media_changed = floppy_check_change,
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index 102ed52d0e0f..c48e14878582 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -1711,6 +1711,18 @@ err_open:
1711 return rc; 1711 return rc;
1712} 1712}
1713 1713
1714static int ub_bd_unlocked_open(struct block_device *bdev, fmode_t mode)
1715{
1716 int ret;
1717
1718 lock_kernel();
1719 ret = ub_bd_open(bdev, mode);
1720 unlock_kernel();
1721
1722 return ret;
1723}
1724
1725
1714/* 1726/*
1715 */ 1727 */
1716static int ub_bd_release(struct gendisk *disk, fmode_t mode) 1728static int ub_bd_release(struct gendisk *disk, fmode_t mode)
@@ -1718,7 +1730,10 @@ static int ub_bd_release(struct gendisk *disk, fmode_t mode)
1718 struct ub_lun *lun = disk->private_data; 1730 struct ub_lun *lun = disk->private_data;
1719 struct ub_dev *sc = lun->udev; 1731 struct ub_dev *sc = lun->udev;
1720 1732
1733 lock_kernel();
1721 ub_put(sc); 1734 ub_put(sc);
1735 unlock_kernel();
1736
1722 return 0; 1737 return 0;
1723} 1738}
1724 1739
@@ -1798,7 +1813,7 @@ static int ub_bd_media_changed(struct gendisk *disk)
1798 1813
1799static const struct block_device_operations ub_bd_fops = { 1814static const struct block_device_operations ub_bd_fops = {
1800 .owner = THIS_MODULE, 1815 .owner = THIS_MODULE,
1801 .open = ub_bd_open, 1816 .open = ub_bd_unlocked_open,
1802 .release = ub_bd_release, 1817 .release = ub_bd_release,
1803 .ioctl = ub_bd_ioctl, 1818 .ioctl = ub_bd_ioctl,
1804 .media_changed = ub_bd_media_changed, 1819 .media_changed = ub_bd_media_changed,
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
index 5663d3c284c8..f651e51a3319 100644
--- a/drivers/block/viodasd.c
+++ b/drivers/block/viodasd.c
@@ -41,6 +41,7 @@
41#include <linux/errno.h> 41#include <linux/errno.h>
42#include <linux/init.h> 42#include <linux/init.h>
43#include <linux/string.h> 43#include <linux/string.h>
44#include <linux/smp_lock.h>
44#include <linux/dma-mapping.h> 45#include <linux/dma-mapping.h>
45#include <linux/completion.h> 46#include <linux/completion.h>
46#include <linux/device.h> 47#include <linux/device.h>
@@ -175,6 +176,18 @@ static int viodasd_open(struct block_device *bdev, fmode_t mode)
175 return 0; 176 return 0;
176} 177}
177 178
179static int viodasd_unlocked_open(struct block_device *bdev, fmode_t mode)
180{
181 int ret;
182
183 lock_kernel();
184 ret = viodasd_open(bdev, mode);
185 unlock_kernel();
186
187 return ret;
188}
189
190
178/* 191/*
179 * External release entry point. 192 * External release entry point.
180 */ 193 */
@@ -183,6 +196,7 @@ static int viodasd_release(struct gendisk *disk, fmode_t mode)
183 struct viodasd_device *d = disk->private_data; 196 struct viodasd_device *d = disk->private_data;
184 HvLpEvent_Rc hvrc; 197 HvLpEvent_Rc hvrc;
185 198
199 lock_kernel();
186 /* Send the event to OS/400. We DON'T expect a response */ 200 /* Send the event to OS/400. We DON'T expect a response */
187 hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, 201 hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
188 HvLpEvent_Type_VirtualIo, 202 HvLpEvent_Type_VirtualIo,
@@ -195,6 +209,9 @@ static int viodasd_release(struct gendisk *disk, fmode_t mode)
195 0, 0, 0); 209 0, 0, 0);
196 if (hvrc != 0) 210 if (hvrc != 0)
197 pr_warning("HV close call failed %d\n", (int)hvrc); 211 pr_warning("HV close call failed %d\n", (int)hvrc);
212
213 unlock_kernel();
214
198 return 0; 215 return 0;
199} 216}
200 217
@@ -219,7 +236,7 @@ static int viodasd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
219 */ 236 */
220static const struct block_device_operations viodasd_fops = { 237static const struct block_device_operations viodasd_fops = {
221 .owner = THIS_MODULE, 238 .owner = THIS_MODULE,
222 .open = viodasd_open, 239 .open = viodasd_unlocked_open,
223 .release = viodasd_release, 240 .release = viodasd_release,
224 .getgeo = viodasd_getgeo, 241 .getgeo = viodasd_getgeo,
225}; 242};
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 9119cd3d56a4..91374282755d 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -41,6 +41,7 @@
41#include <linux/cdrom.h> 41#include <linux/cdrom.h>
42#include <linux/module.h> 42#include <linux/module.h>
43#include <linux/slab.h> 43#include <linux/slab.h>
44#include <linux/smp_lock.h>
44#include <linux/scatterlist.h> 45#include <linux/scatterlist.h>
45 46
46#include <xen/xen.h> 47#include <xen/xen.h>
@@ -1018,13 +1019,18 @@ static int blkfront_is_ready(struct xenbus_device *dev)
1018static int blkif_open(struct block_device *bdev, fmode_t mode) 1019static int blkif_open(struct block_device *bdev, fmode_t mode)
1019{ 1020{
1020 struct blkfront_info *info = bdev->bd_disk->private_data; 1021 struct blkfront_info *info = bdev->bd_disk->private_data;
1022
1023 lock_kernel();
1021 info->users++; 1024 info->users++;
1025 unlock_kernel();
1026
1022 return 0; 1027 return 0;
1023} 1028}
1024 1029
1025static int blkif_release(struct gendisk *disk, fmode_t mode) 1030static int blkif_release(struct gendisk *disk, fmode_t mode)
1026{ 1031{
1027 struct blkfront_info *info = disk->private_data; 1032 struct blkfront_info *info = disk->private_data;
1033 lock_kernel();
1028 info->users--; 1034 info->users--;
1029 if (info->users == 0) { 1035 if (info->users == 0) {
1030 /* Check whether we have been instructed to close. We will 1036 /* Check whether we have been instructed to close. We will
@@ -1036,6 +1042,7 @@ static int blkif_release(struct gendisk *disk, fmode_t mode)
1036 if (state == XenbusStateClosing && info->is_ready) 1042 if (state == XenbusStateClosing && info->is_ready)
1037 blkfront_closing(dev); 1043 blkfront_closing(dev);
1038 } 1044 }
1045 unlock_kernel();
1039 return 0; 1046 return 0;
1040} 1047}
1041 1048
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c
index ac278ac908d5..b71888b909a0 100644
--- a/drivers/block/xsysace.c
+++ b/drivers/block/xsysace.c
@@ -89,6 +89,7 @@
89#include <linux/delay.h> 89#include <linux/delay.h>
90#include <linux/slab.h> 90#include <linux/slab.h>
91#include <linux/blkdev.h> 91#include <linux/blkdev.h>
92#include <linux/smp_lock.h>
92#include <linux/ata.h> 93#include <linux/ata.h>
93#include <linux/hdreg.h> 94#include <linux/hdreg.h>
94#include <linux/platform_device.h> 95#include <linux/platform_device.h>
@@ -901,11 +902,14 @@ static int ace_open(struct block_device *bdev, fmode_t mode)
901 902
902 dev_dbg(ace->dev, "ace_open() users=%i\n", ace->users + 1); 903 dev_dbg(ace->dev, "ace_open() users=%i\n", ace->users + 1);
903 904
905 lock_kernel();
904 spin_lock_irqsave(&ace->lock, flags); 906 spin_lock_irqsave(&ace->lock, flags);
905 ace->users++; 907 ace->users++;
906 spin_unlock_irqrestore(&ace->lock, flags); 908 spin_unlock_irqrestore(&ace->lock, flags);
907 909
908 check_disk_change(bdev); 910 check_disk_change(bdev);
911 unlock_kernel();
912
909 return 0; 913 return 0;
910} 914}
911 915
@@ -917,6 +921,7 @@ static int ace_release(struct gendisk *disk, fmode_t mode)
917 921
918 dev_dbg(ace->dev, "ace_release() users=%i\n", ace->users - 1); 922 dev_dbg(ace->dev, "ace_release() users=%i\n", ace->users - 1);
919 923
924 lock_kernel();
920 spin_lock_irqsave(&ace->lock, flags); 925 spin_lock_irqsave(&ace->lock, flags);
921 ace->users--; 926 ace->users--;
922 if (ace->users == 0) { 927 if (ace->users == 0) {
@@ -924,6 +929,7 @@ static int ace_release(struct gendisk *disk, fmode_t mode)
924 ace_out(ace, ACE_CTRL, val & ~ACE_CTRL_LOCKREQ); 929 ace_out(ace, ACE_CTRL, val & ~ACE_CTRL_LOCKREQ);
925 } 930 }
926 spin_unlock_irqrestore(&ace->lock, flags); 931 spin_unlock_irqrestore(&ace->lock, flags);
932 unlock_kernel();
927 return 0; 933 return 0;
928} 934}
929 935
diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c
index 9114654b54d9..d75b2bb601ad 100644
--- a/drivers/block/z2ram.c
+++ b/drivers/block/z2ram.c
@@ -33,6 +33,7 @@
33#include <linux/module.h> 33#include <linux/module.h>
34#include <linux/blkdev.h> 34#include <linux/blkdev.h>
35#include <linux/bitops.h> 35#include <linux/bitops.h>
36#include <linux/smp_lock.h>
36#include <linux/slab.h> 37#include <linux/slab.h>
37 38
38#include <asm/setup.h> 39#include <asm/setup.h>
@@ -153,6 +154,7 @@ static int z2_open(struct block_device *bdev, fmode_t mode)
153 154
154 device = MINOR(bdev->bd_dev); 155 device = MINOR(bdev->bd_dev);
155 156
157 lock_kernel();
156 if ( current_device != -1 && current_device != device ) 158 if ( current_device != -1 && current_device != device )
157 { 159 {
158 rc = -EBUSY; 160 rc = -EBUSY;
@@ -294,20 +296,25 @@ static int z2_open(struct block_device *bdev, fmode_t mode)
294 set_capacity(z2ram_gendisk, z2ram_size >> 9); 296 set_capacity(z2ram_gendisk, z2ram_size >> 9);
295 } 297 }
296 298
299 unlock_kernel();
297 return 0; 300 return 0;
298 301
299err_out_kfree: 302err_out_kfree:
300 kfree(z2ram_map); 303 kfree(z2ram_map);
301err_out: 304err_out:
305 unlock_kernel();
302 return rc; 306 return rc;
303} 307}
304 308
305static int 309static int
306z2_release(struct gendisk *disk, fmode_t mode) 310z2_release(struct gendisk *disk, fmode_t mode)
307{ 311{
308 if ( current_device == -1 ) 312 lock_kernel();
309 return 0; 313 if ( current_device == -1 ) {
310 314 unlock_kernel();
315 return 0;
316 }
317 unlock_kernel();
311 /* 318 /*
312 * FIXME: unmap memory 319 * FIXME: unmap memory
313 */ 320 */