aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/md.c
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/md/md.c
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/md/md.c')
-rw-r--r--drivers/md/md.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 1893af678779..700c96edf9b2 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -36,6 +36,7 @@
36#include <linux/blkdev.h> 36#include <linux/blkdev.h>
37#include <linux/sysctl.h> 37#include <linux/sysctl.h>
38#include <linux/seq_file.h> 38#include <linux/seq_file.h>
39#include <linux/smp_lock.h>
39#include <linux/buffer_head.h> /* for invalidate_bdev */ 40#include <linux/buffer_head.h> /* for invalidate_bdev */
40#include <linux/poll.h> 41#include <linux/poll.h>
41#include <linux/ctype.h> 42#include <linux/ctype.h>
@@ -5902,6 +5903,7 @@ static int md_open(struct block_device *bdev, fmode_t mode)
5902 mddev_t *mddev = mddev_find(bdev->bd_dev); 5903 mddev_t *mddev = mddev_find(bdev->bd_dev);
5903 int err; 5904 int err;
5904 5905
5906 lock_kernel();
5905 if (mddev->gendisk != bdev->bd_disk) { 5907 if (mddev->gendisk != bdev->bd_disk) {
5906 /* we are racing with mddev_put which is discarding this 5908 /* we are racing with mddev_put which is discarding this
5907 * bd_disk. 5909 * bd_disk.
@@ -5910,6 +5912,7 @@ static int md_open(struct block_device *bdev, fmode_t mode)
5910 /* Wait until bdev->bd_disk is definitely gone */ 5912 /* Wait until bdev->bd_disk is definitely gone */
5911 flush_scheduled_work(); 5913 flush_scheduled_work();
5912 /* Then retry the open from the top */ 5914 /* Then retry the open from the top */
5915 unlock_kernel();
5913 return -ERESTARTSYS; 5916 return -ERESTARTSYS;
5914 } 5917 }
5915 BUG_ON(mddev != bdev->bd_disk->private_data); 5918 BUG_ON(mddev != bdev->bd_disk->private_data);
@@ -5923,6 +5926,7 @@ static int md_open(struct block_device *bdev, fmode_t mode)
5923 5926
5924 check_disk_size_change(mddev->gendisk, bdev); 5927 check_disk_size_change(mddev->gendisk, bdev);
5925 out: 5928 out:
5929 unlock_kernel();
5926 return err; 5930 return err;
5927} 5931}
5928 5932
@@ -5931,8 +5935,10 @@ static int md_release(struct gendisk *disk, fmode_t mode)
5931 mddev_t *mddev = disk->private_data; 5935 mddev_t *mddev = disk->private_data;
5932 5936
5933 BUG_ON(!mddev); 5937 BUG_ON(!mddev);
5938 lock_kernel();
5934 atomic_dec(&mddev->openers); 5939 atomic_dec(&mddev->openers);
5935 mddev_put(mddev); 5940 mddev_put(mddev);
5941 unlock_kernel();
5936 5942
5937 return 0; 5943 return 0;
5938} 5944}