Skip to content

Commit

Permalink
block: push down BKL into .locked_ioctl
Browse files Browse the repository at this point in the history
As a preparation for the removal of the big kernel
lock in the block layer, this removes the BKL
from the common ioctl handling code, moving it
into every single driver still using it.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
  • Loading branch information
Arnd Bergmann authored and Jens Axboe committed Aug 7, 2010
1 parent 3448406 commit 8a6cfeb
Show file tree
Hide file tree
Showing 30 changed files with 253 additions and 85 deletions.
11 changes: 1 addition & 10 deletions block/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,18 +163,10 @@ int __blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode,
unsigned cmd, unsigned long arg)
{
struct gendisk *disk = bdev->bd_disk;
int ret;

if (disk->fops->ioctl)
return disk->fops->ioctl(bdev, mode, cmd, arg);

if (disk->fops->locked_ioctl) {
lock_kernel();
ret = disk->fops->locked_ioctl(bdev, mode, cmd, arg);
unlock_kernel();
return ret;
}

return -ENOTTY;
}
/*
Expand All @@ -185,8 +177,7 @@ int __blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode,
EXPORT_SYMBOL_GPL(__blkdev_driver_ioctl);

/*
* always keep this in sync with compat_blkdev_ioctl() and
* compat_blkdev_locked_ioctl()
* always keep this in sync with compat_blkdev_ioctl()
*/
int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
unsigned long arg)
Expand Down
17 changes: 15 additions & 2 deletions drivers/block/amiflop.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
#include <linux/hdreg.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/smp_lock.h>
#include <linux/amifdreg.h>
#include <linux/amifd.h>
#include <linux/buffer_head.h>
Expand Down Expand Up @@ -1423,7 +1424,7 @@ static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
return 0;
}

static int fd_ioctl(struct block_device *bdev, fmode_t mode,
static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long param)
{
struct amiga_floppy_struct *p = bdev->bd_disk->private_data;
Expand Down Expand Up @@ -1500,6 +1501,18 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode,
return 0;
}

static int fd_ioctl(struct block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long param)
{
int ret;

lock_kernel();
ret = fd_locked_ioctl(bdev, mode, cmd, param);
unlock_kernel();

return ret;
}

static void fd_probe(int dev)
{
unsigned long code;
Expand Down Expand Up @@ -1638,7 +1651,7 @@ static const struct block_device_operations floppy_fops = {
.owner = THIS_MODULE,
.open = floppy_open,
.release = floppy_release,
.locked_ioctl = fd_ioctl,
.ioctl = fd_ioctl,
.getgeo = fd_getgeo,
.media_changed = amiga_floppy_change,
};
Expand Down
18 changes: 15 additions & 3 deletions drivers/block/ataflop.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/smp_lock.h>

#include <asm/atafd.h>
#include <asm/atafdreg.h>
Expand Down Expand Up @@ -359,7 +360,7 @@ static void finish_fdc( void );
static void finish_fdc_done( int dummy );
static void setup_req_params( int drive );
static void redo_fd_request( void);
static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int
static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int
cmd, unsigned long param);
static void fd_probe( int drive );
static int fd_test_drive_present( int drive );
Expand Down Expand Up @@ -1480,7 +1481,7 @@ void do_fd_request(struct request_queue * q)
atari_enable_irq( IRQ_MFP_FDC );
}

static int fd_ioctl(struct block_device *bdev, fmode_t mode,
static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long param)
{
struct gendisk *disk = bdev->bd_disk;
Expand Down Expand Up @@ -1665,6 +1666,17 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode,
}
}

static int fd_ioctl(struct block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long arg)
{
int ret;

lock_kernel();
ret = fd_locked_ioctl(bdev, mode, cmd, arg);
unlock_kernel();

return ret;
}

/* Initialize the 'unit' variable for drive 'drive' */

Expand Down Expand Up @@ -1855,7 +1867,7 @@ static const struct block_device_operations floppy_fops = {
.owner = THIS_MODULE,
.open = floppy_open,
.release = floppy_release,
.locked_ioctl = fd_ioctl,
.ioctl = fd_ioctl,
.media_changed = check_floppy_change,
.revalidate_disk= floppy_revalidate,
};
Expand Down
5 changes: 4 additions & 1 deletion drivers/block/brd.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <linux/blkdev.h>
#include <linux/bio.h>
#include <linux/highmem.h>
#include <linux/smp_lock.h>
#include <linux/radix-tree.h>
#include <linux/buffer_head.h> /* invalidate_bh_lrus() */
#include <linux/slab.h>
Expand Down Expand Up @@ -401,6 +402,7 @@ static int brd_ioctl(struct block_device *bdev, fmode_t mode,
* ram device BLKFLSBUF has special semantics, we want to actually
* release and destroy the ramdisk data.
*/
lock_kernel();
mutex_lock(&bdev->bd_mutex);
error = -EBUSY;
if (bdev->bd_openers <= 1) {
Expand All @@ -417,13 +419,14 @@ static int brd_ioctl(struct block_device *bdev, fmode_t mode,
error = 0;
}
mutex_unlock(&bdev->bd_mutex);
unlock_kernel();

return error;
}

static const struct block_device_operations brd_fops = {
.owner = THIS_MODULE,
.locked_ioctl = brd_ioctl,
.ioctl = brd_ioctl,
#ifdef CONFIG_BLK_DEV_XIP
.direct_access = brd_direct_access,
#endif
Expand Down
8 changes: 5 additions & 3 deletions drivers/block/cciss.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@ static irqreturn_t do_cciss_intx(int irq, void *dev_id);
static irqreturn_t do_cciss_msix_intr(int irq, void *dev_id);
static int cciss_open(struct block_device *bdev, fmode_t mode);
static int cciss_release(struct gendisk *disk, fmode_t mode);
static int do_ioctl(struct block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long arg);
static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long arg);
static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo);
Expand Down Expand Up @@ -237,7 +239,7 @@ static const struct block_device_operations cciss_fops = {
.owner = THIS_MODULE,
.open = cciss_open,
.release = cciss_release,
.locked_ioctl = cciss_ioctl,
.ioctl = do_ioctl,
.getgeo = cciss_getgeo,
#ifdef CONFIG_COMPAT
.compat_ioctl = cciss_compat_ioctl,
Expand Down Expand Up @@ -1057,8 +1059,6 @@ static int cciss_release(struct gendisk *disk, fmode_t mode)
return 0;
}

#ifdef CONFIG_COMPAT

static int do_ioctl(struct block_device *bdev, fmode_t mode,
unsigned cmd, unsigned long arg)
{
Expand All @@ -1069,6 +1069,8 @@ static int do_ioctl(struct block_device *bdev, fmode_t mode,
return ret;
}

#ifdef CONFIG_COMPAT

static int cciss_ioctl32_passthru(struct block_device *bdev, fmode_t mode,
unsigned cmd, unsigned long arg);
static int cciss_ioctl32_big_passthru(struct block_device *bdev, fmode_t mode,
Expand Down
18 changes: 16 additions & 2 deletions drivers/block/cpqarray.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include <linux/seq_file.h>
#include <linux/init.h>
#include <linux/hdreg.h>
#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/blkdev.h>
#include <linux/genhd.h>
Expand Down Expand Up @@ -197,7 +198,7 @@ static const struct block_device_operations ida_fops = {
.owner = THIS_MODULE,
.open = ida_open,
.release = ida_release,
.locked_ioctl = ida_ioctl,
.ioctl = ida_ioctl,
.getgeo = ida_getgeo,
.revalidate_disk= ida_revalidate,
};
Expand Down Expand Up @@ -1128,7 +1129,7 @@ static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo)
* ida_ioctl does some miscellaneous stuff like reporting drive geometry,
* setting readahead and submitting commands from userspace to the controller.
*/
static int ida_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg)
static int ida_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg)
{
drv_info_t *drv = get_drv(bdev->bd_disk);
ctlr_info_t *host = get_host(bdev->bd_disk);
Expand Down Expand Up @@ -1192,6 +1193,19 @@ static int ida_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd,
}

}

static int ida_ioctl(struct block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long param)
{
int ret;

lock_kernel();
ret = ida_locked_ioctl(bdev, mode, cmd, param);
unlock_kernel();

return ret;
}

/*
* ida_ctlr_ioctl is for passing commands to the controller from userspace.
* The command block (io) has already been copied to kernel space for us,
Expand Down
17 changes: 15 additions & 2 deletions drivers/block/floppy.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ static int print_unex = 1;
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/bio.h>
#include <linux/smp_lock.h>
#include <linux/string.h>
#include <linux/jiffies.h>
#include <linux/fcntl.h>
Expand Down Expand Up @@ -3371,7 +3372,7 @@ static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
return 0;
}

static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd,
static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd,
unsigned long param)
{
int drive = (long)bdev->bd_disk->private_data;
Expand Down Expand Up @@ -3547,6 +3548,18 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd,
return 0;
}

static int fd_ioctl(struct block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long param)
{
int ret;

lock_kernel();
ret = fd_locked_ioctl(bdev, mode, cmd, param);
unlock_kernel();

return ret;
}

static void __init config_types(void)
{
bool has_drive = false;
Expand Down Expand Up @@ -3848,7 +3861,7 @@ static const struct block_device_operations floppy_fops = {
.owner = THIS_MODULE,
.open = floppy_open,
.release = floppy_release,
.locked_ioctl = fd_ioctl,
.ioctl = fd_ioctl,
.getgeo = fd_getgeo,
.media_changed = check_floppy_change,
.revalidate_disk = floppy_revalidate,
Expand Down
5 changes: 4 additions & 1 deletion drivers/block/nbd.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <linux/errno.h>
#include <linux/file.h>
#include <linux/ioctl.h>
#include <linux/smp_lock.h>
#include <linux/compiler.h>
#include <linux/err.h>
#include <linux/kernel.h>
Expand Down Expand Up @@ -716,17 +717,19 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
dprintk(DBG_IOCTL, "%s: nbd_ioctl cmd=%s(0x%x) arg=%lu\n",
lo->disk->disk_name, ioctl_cmd_to_ascii(cmd), cmd, arg);

lock_kernel();
mutex_lock(&lo->tx_lock);
error = __nbd_ioctl(bdev, lo, cmd, arg);
mutex_unlock(&lo->tx_lock);
unlock_kernel();

return error;
}

static const struct block_device_operations nbd_fops =
{
.owner = THIS_MODULE,
.locked_ioctl = nbd_ioctl,
.ioctl = nbd_ioctl,
};

/*
Expand Down
11 changes: 9 additions & 2 deletions drivers/block/paride/pcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_DLY};
#include <linux/cdrom.h>
#include <linux/spinlock.h>
#include <linux/blkdev.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h>

static DEFINE_SPINLOCK(pcd_lock);
Expand Down Expand Up @@ -238,7 +239,13 @@ static int pcd_block_ioctl(struct block_device *bdev, fmode_t mode,
unsigned cmd, unsigned long arg)
{
struct pcd_unit *cd = bdev->bd_disk->private_data;
return cdrom_ioctl(&cd->info, bdev, mode, cmd, arg);
int ret;

lock_kernel();
ret = cdrom_ioctl(&cd->info, bdev, mode, cmd, arg);
unlock_kernel();

return ret;
}

static int pcd_block_media_changed(struct gendisk *disk)
Expand All @@ -251,7 +258,7 @@ static const struct block_device_operations pcd_bdops = {
.owner = THIS_MODULE,
.open = pcd_block_open,
.release = pcd_block_release,
.locked_ioctl = pcd_block_ioctl,
.ioctl = pcd_block_ioctl,
.media_changed = pcd_block_media_changed,
};

Expand Down
5 changes: 4 additions & 1 deletion drivers/block/paride/pd.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_GEO, D_SBY, D_DLY, D_SLV};
#include <linux/blkdev.h>
#include <linux/blkpg.h>
#include <linux/kernel.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <linux/workqueue.h>

Expand Down Expand Up @@ -768,8 +769,10 @@ static int pd_ioctl(struct block_device *bdev, fmode_t mode,

switch (cmd) {
case CDROMEJECT:
lock_kernel();
if (disk->access == 1)
pd_special_command(disk, pd_eject);
unlock_kernel();
return 0;
default:
return -EINVAL;
Expand Down Expand Up @@ -812,7 +815,7 @@ static const struct block_device_operations pd_fops = {
.owner = THIS_MODULE,
.open = pd_open,
.release = pd_release,
.locked_ioctl = pd_ioctl,
.ioctl = pd_ioctl,
.getgeo = pd_getgeo,
.media_changed = pd_check_media,
.revalidate_disk= pd_revalidate
Expand Down
Loading

0 comments on commit 8a6cfeb

Please sign in to comment.