aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/paride/pf.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/block/paride/pf.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/block/paride/pf.c')
-rw-r--r--drivers/block/paride/pf.c20
1 files changed, 15 insertions, 5 deletions
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}