summaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2010-08-07 18:25:34 +0200
committerJens Axboe <jaxboe@fusionio.com>2010-08-07 18:25:34 +0200
commit6e9624b8caec290d28b4c6d9ec75749df6372b87 (patch)
tree47225b544e1da82742795553dc4e8aa70c17afdc /drivers/scsi
parent8a6cfeb6deca3a8fefd639d898b0d163c0b5d368 (diff)
downloadlinux-6e9624b8caec290d28b4c6d9ec75749df6372b87.tar.bz2
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/scsi')
-rw-r--r--drivers/scsi/sd.c5
-rw-r--r--drivers/scsi/sr.c7
2 files changed, 11 insertions, 1 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 633ac32b25c1..01680c7c8507 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -795,6 +795,7 @@ static int sd_open(struct block_device *bdev, fmode_t mode)
SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_open\n"));
+ lock_kernel();
sdev = sdkp->device;
/*
@@ -838,10 +839,12 @@ static int sd_open(struct block_device *bdev, fmode_t mode)
scsi_set_medium_removal(sdev, SCSI_REMOVAL_PREVENT);
}
+ unlock_kernel();
return 0;
error_out:
scsi_disk_put(sdkp);
+ unlock_kernel();
return retval;
}
@@ -863,6 +866,7 @@ static int sd_release(struct gendisk *disk, fmode_t mode)
SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_release\n"));
+ lock_kernel();
if (!--sdkp->openers && sdev->removable) {
if (scsi_block_when_processing_errors(sdev))
scsi_set_medium_removal(sdev, SCSI_REMOVAL_ALLOW);
@@ -873,6 +877,7 @@ static int sd_release(struct gendisk *disk, fmode_t mode)
* XXX is followed by a "rmmod sd_mod"?
*/
scsi_disk_put(sdkp);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index d42fa6468f41..ba9c3e0387ce 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -467,22 +467,27 @@ static int sr_prep_fn(struct request_queue *q, struct request *rq)
static int sr_block_open(struct block_device *bdev, fmode_t mode)
{
- struct scsi_cd *cd = scsi_cd_get(bdev->bd_disk);
+ struct scsi_cd *cd;
int ret = -ENXIO;
+ lock_kernel();
+ cd = scsi_cd_get(bdev->bd_disk);
if (cd) {
ret = cdrom_open(&cd->cdi, bdev, mode);
if (ret)
scsi_cd_put(cd);
}
+ unlock_kernel();
return ret;
}
static int sr_block_release(struct gendisk *disk, fmode_t mode)
{
struct scsi_cd *cd = scsi_cd(disk);
+ lock_kernel();
cdrom_release(&cd->cdi, mode);
scsi_cd_put(cd);
+ unlock_kernel();
return 0;
}