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>
This commit is contained in:
Arnd Bergmann
2010-08-07 18:25:34 +02:00
committato da Jens Axboe
parent 8a6cfeb6de
commit 6e9624b8ca
39 ha cambiato i file con 334 aggiunte e 48 eliminazioni

Vedi File

@@ -1591,17 +1591,19 @@ static struct ide_driver ide_cdrom_driver = {
static int idecd_open(struct block_device *bdev, fmode_t mode)
{
struct cdrom_info *info = ide_cd_get(bdev->bd_disk);
int rc = -ENOMEM;
struct cdrom_info *info;
int rc = -ENXIO;
lock_kernel();
info = ide_cd_get(bdev->bd_disk);
if (!info)
return -ENXIO;
goto out;
rc = cdrom_open(&info->devinfo, bdev, mode);
if (rc < 0)
ide_cd_put(info);
out:
unlock_kernel();
return rc;
}
@@ -1609,9 +1611,11 @@ static int idecd_release(struct gendisk *disk, fmode_t mode)
{
struct cdrom_info *info = ide_drv_g(disk, cdrom_info);
lock_kernel();
cdrom_release(&info->devinfo, mode);
ide_cd_put(info);
unlock_kernel();
return 0;
}

Vedi File

@@ -1,3 +1,4 @@
#include <linux/smp_lock.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/string.h>
@@ -237,6 +238,18 @@ out_put_idkp:
return ret;
}
static int ide_gd_unlocked_open(struct block_device *bdev, fmode_t mode)
{
int ret;
lock_kernel();
ret = ide_gd_open(bdev, mode);
unlock_kernel();
return ret;
}
static int ide_gd_release(struct gendisk *disk, fmode_t mode)
{
struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
@@ -244,6 +257,7 @@ static int ide_gd_release(struct gendisk *disk, fmode_t mode)
ide_debug_log(IDE_DBG_FUNC, "enter");
lock_kernel();
if (idkp->openers == 1)
drive->disk_ops->flush(drive);
@@ -255,6 +269,7 @@ static int ide_gd_release(struct gendisk *disk, fmode_t mode)
idkp->openers--;
ide_disk_put(idkp);
unlock_kernel();
return 0;
}
@@ -321,7 +336,7 @@ static int ide_gd_ioctl(struct block_device *bdev, fmode_t mode,
static const struct block_device_operations ide_gd_ops = {
.owner = THIS_MODULE,
.open = ide_gd_open,
.open = ide_gd_unlocked_open,
.release = ide_gd_release,
.ioctl = ide_gd_ioctl,
.getgeo = ide_gd_getgeo,

Vedi File

@@ -1907,7 +1907,11 @@ static const struct file_operations idetape_fops = {
static int idetape_open(struct block_device *bdev, fmode_t mode)
{
struct ide_tape_obj *tape = ide_tape_get(bdev->bd_disk, false, 0);
struct ide_tape_obj *tape;
lock_kernel();
tape = ide_tape_get(bdev->bd_disk, false, 0);
unlock_kernel();
if (!tape)
return -ENXIO;
@@ -1919,7 +1923,10 @@ static int idetape_release(struct gendisk *disk, fmode_t mode)
{
struct ide_tape_obj *tape = ide_drv_g(disk, ide_tape_obj);
lock_kernel();
ide_tape_put(tape);
unlock_kernel();
return 0;
}