aboutsummaryrefslogtreecommitdiffstats
path: root/fs
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 /fs
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 'fs')
-rw-r--r--fs/block_dev.c10
1 files changed, 2 insertions, 8 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 99d6af811747..693c2bf5d65e 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1345,13 +1345,12 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
1345 return ret; 1345 return ret;
1346 } 1346 }
1347 1347
1348 lock_kernel();
1349 restart: 1348 restart:
1350 1349
1351 ret = -ENXIO; 1350 ret = -ENXIO;
1352 disk = get_gendisk(bdev->bd_dev, &partno); 1351 disk = get_gendisk(bdev->bd_dev, &partno);
1353 if (!disk) 1352 if (!disk)
1354 goto out_unlock_kernel; 1353 goto out;
1355 1354
1356 mutex_lock_nested(&bdev->bd_mutex, for_part); 1355 mutex_lock_nested(&bdev->bd_mutex, for_part);
1357 if (!bdev->bd_openers) { 1356 if (!bdev->bd_openers) {
@@ -1431,7 +1430,6 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
1431 if (for_part) 1430 if (for_part)
1432 bdev->bd_part_count++; 1431 bdev->bd_part_count++;
1433 mutex_unlock(&bdev->bd_mutex); 1432 mutex_unlock(&bdev->bd_mutex);
1434 unlock_kernel();
1435 return 0; 1433 return 0;
1436 1434
1437 out_clear: 1435 out_clear:
@@ -1444,9 +1442,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
1444 bdev->bd_contains = NULL; 1442 bdev->bd_contains = NULL;
1445 out_unlock_bdev: 1443 out_unlock_bdev:
1446 mutex_unlock(&bdev->bd_mutex); 1444 mutex_unlock(&bdev->bd_mutex);
1447 out_unlock_kernel: 1445 out:
1448 unlock_kernel();
1449
1450 if (disk) 1446 if (disk)
1451 module_put(disk->fops->owner); 1447 module_put(disk->fops->owner);
1452 put_disk(disk); 1448 put_disk(disk);
@@ -1515,7 +1511,6 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part)
1515 struct block_device *victim = NULL; 1511 struct block_device *victim = NULL;
1516 1512
1517 mutex_lock_nested(&bdev->bd_mutex, for_part); 1513 mutex_lock_nested(&bdev->bd_mutex, for_part);
1518 lock_kernel();
1519 if (for_part) 1514 if (for_part)
1520 bdev->bd_part_count--; 1515 bdev->bd_part_count--;
1521 1516
@@ -1540,7 +1535,6 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part)
1540 victim = bdev->bd_contains; 1535 victim = bdev->bd_contains;
1541 bdev->bd_contains = NULL; 1536 bdev->bd_contains = NULL;
1542 } 1537 }
1543 unlock_kernel();
1544 mutex_unlock(&bdev->bd_mutex); 1538 mutex_unlock(&bdev->bd_mutex);
1545 bdput(bdev); 1539 bdput(bdev);
1546 if (victim) 1540 if (victim)