block: replace BKL with global mutex
Subsystems (24)
PATCH 1/1 block: replace BKL with global mutex
The block layer is one of the remaining users of the Big Kernel Lock. In there, it is used mainly for serializing the blkdev_get and blkdev_put functions and some ioctl implementations as well as some less common open functions of related character devices following a previous pushdown and parts of the blktrace code.
The only one that seems to be a bit nasty is the blkdev_get function which is actually recursive and may try to get the BKL twice.
All users except the one in blkdev_get seem to be outermost locks, meaning we don't rely on the release-on-sleep semantics to avoid deadlocks.
The ctl_mutex (pktcdvd.ko), raw_mutex (raw.ko), state_mutex (dasd.ko), reconfig_mutex (md.ko), and jfs_log_mutex (jfs.ko) may be held when blkdev_get is called, but as far as I can tell, these mutexes are never acquired from any of the functions that get converted in this patch.
In order to get rid of the BKL, this introduces a new global mutex called blkdev_mutex, which replaces the BKL in all drivers that directly interact with the block layer. In case of blkdev_get, the mutex is moved outside of the function itself in order to avoid the recursive taking of blkdev_mutex.
Testing so far has shown no problems whatsoever from this patch, but the usage in blkdev_get may introduce extra latencies, and I may have missed corner cases where an block device ioctl function sleeps for a significant amount of time, which may be harmful to the performance of other threads.
---
Jens, would you consider this patch for 2.6.36 and take it into your -next tree?
block/bsg.c | 2 -- block/compat_ioctl.c | 8 ++++---- block/ioctl.c | 24 ++++++++++++------------ drivers/block/DAC960.c | 4 ++-- drivers/block/cciss.c | 4 ++-- drivers/scsi/sg.c | 4 ++-- fs/block_dev.c | 20 +++++++++++++------- include/linux/blkdev.h | 6 ++++++ kernel/trace/blktrace.c | 14 ++++++++------ 9 files changed, 49 insertions(+), 37 deletions(-)
block/bsg.c +0 -2
@@ -843,9 +843,7 @@ static int bsg_open(struct inode *inode, struct file *file) {struct bsg_device *bd; -lock_kernel (); bd =bsg_get_device (inode, file); -unlock_kernel ();if (IS_ERR (bd))return PTR_ERR (bd);
block/compat_ioctl.c +4 -4
@@ -802,16 +802,16 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)return compat_put_u64 (arg, bdev->bd_inode->i_size);case BLKTRACESETUP32 : -lock_kernel (); +mutex_lock (&blkdev_mutex); ret =compat_blk_trace_setup (bdev,compat_ptr (arg)); -unlock_kernel (); +mutex_unlock (&blkdev_mutex);return ret;case BLKTRACESTART :/* compatible */ case BLKTRACESTOP :/* compatible */ case BLKTRACETEARDOWN :/* compatible */ -lock_kernel (); +mutex_lock (&blkdev_mutex); ret =blk_trace_ioctl (bdev, cmd,compat_ptr (arg)); -unlock_kernel (); +mutex_unlock (&blkdev_mutex);return ret;default :if (disk->fops->compat_ioctl)
block/ioctl.c +12 -12
@@ -169,9 +169,9 @@ int __blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode,return disk->fops->ioctl (bdev, mode, cmd, arg);if (disk->fops->locked_ioctl) { -lock_kernel (); +mutex_lock (&blkdev_mutex); ret = disk->fops->locked_ioctl (bdev, mode, cmd, arg); -unlock_kernel (); +mutex_unlock (&blkdev_mutex);return ret; }
@@ -206,10 +206,10 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,if (ret != -EINVAL && ret != -ENOTTY )return ret; -lock_kernel (); +mutex_lock (&blkdev_mutex);fsync_bdev (bdev);invalidate_bdev (bdev); -unlock_kernel (); +mutex_unlock (&blkdev_mutex);return 0 ;case BLKROSET :
@@ -221,9 +221,9 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,return -EACCES ;if (get_user (n, (int __user *)(arg)))return -EFAULT ; -lock_kernel (); +mutex_lock (&blkdev_mutex);set_device_ro (bdev, n); -unlock_kernel (); +mutex_unlock (&blkdev_mutex);return 0 ;case BLKDISCARD : {
@@ -309,14 +309,14 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,bd_release (bdev);return ret;case BLKPG : -lock_kernel (); +mutex_lock (&blkdev_mutex); ret =blkpg_ioctl (bdev, (struct blkpg_ioctl_arg __user *) arg); -unlock_kernel (); +mutex_unlock (&blkdev_mutex);break ;case BLKRRPART : -lock_kernel (); +mutex_lock (&blkdev_mutex); ret =blkdev_reread_part (bdev); -unlock_kernel (); +mutex_unlock (&blkdev_mutex);break ;case BLKGETSIZE : size = bdev->bd_inode->i_size;
@@ -329,9 +329,9 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,case BLKTRACESTOP :case BLKTRACESETUP :case BLKTRACETEARDOWN : -lock_kernel (); +mutex_lock (&blkdev_mutex); ret =blk_trace_ioctl (bdev, cmd, (char __user *) arg); -unlock_kernel (); +mutex_unlock (&blkdev_mutex);break ;default : ret =__blkdev_driver_ioctl (bdev, mode, cmd, arg);
drivers/block/DAC960.c +2 -2
@@ -6620,7 +6620,7 @@ static long DAC960_gam_ioctl(struct file *file, unsigned int Request,long ErrorCode =0 ;if (!capable (CAP_SYS_ADMIN ))return -EACCES ; -lock_kernel (); +mutex_lock (&blkdev_mutex);switch (Request) {case DAC960_IOCTL_GET_CONTROLLER_COUNT :
@@ -7051,7 +7051,7 @@ static long DAC960_gam_ioctl(struct file *file, unsigned int Request,default : ErrorCode = -ENOTTY ; } -unlock_kernel (); +mutex_unlock (&blkdev_mutex);return ErrorCode; }
drivers/block/cciss.c +2 -2
@@ -1027,9 +1027,9 @@ static int do_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, unsigned long arg) { int ret; -lock_kernel (); +mutex_lock (&blkdev_mutex); ret =cciss_ioctl (bdev, mode, cmd, arg); -unlock_kernel (); +mutex_unlock (&blkdev_mutex);return ret; }
drivers/scsi/sg.c +2 -2
@@ -229,7 +229,7 @@ sg_open(struct inode *inode, struct file *filp)int res;int retval; -lock_kernel (); +mutex_lock (&blkdev_mutex);nonseekable_open (inode, filp);SCSI_LOG_TIMEOUT (3 ,printk ("sg_open: dev=%d, flags=0x%x\n" , dev, flags)); sdp =sg_get_dev (dev);
@@ -307,7 +307,7 @@ error_out: sg_put:if (sdp)sg_put_dev (sdp); -unlock_kernel (); +mutex_unlock (&blkdev_mutex);return retval; }
fs/block_dev.c +13 -7
@@ -29,6 +29,9 @@#include <asm/uaccess.h> #include "internal.h" +DEFINE_MUTEX (blkdev_mutex); +EXPORT_SYMBOL_GPL (blkdev_mutex); +struct bdev_inode {struct block_device bdev;struct inode vfs_inode;
@@ -1321,7 +1324,6 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)return ret; } -lock_kernel (); restart: ret = -ENXIO ;
@@ -1407,7 +1409,6 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)if (for_part) bdev->bd_part_count++;mutex_unlock (&bdev->bd_mutex); -unlock_kernel ();return 0 ; out_clear:
@@ -1421,7 +1422,6 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) out_unlock_bdev:mutex_unlock (&bdev->bd_mutex); out_unlock_kernel: -unlock_kernel ();if (disk)module_put (disk->fops->owner);
@@ -1433,7 +1433,11 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)int blkdev_get (struct block_device *bdev,fmode_t mode) { -return __blkdev_get (bdev, mode,0 ); +int ret; +mutex_lock (&blkdev_mutex); + ret =__blkdev_get (bdev, mode,0 ); +mutex_unlock (&blkdev_mutex); +return ret; }EXPORT_SYMBOL (blkdev_get);
@@ -1491,7 +1495,6 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part)struct block_device *victim =NULL ;mutex_lock_nested (&bdev->bd_mutex, for_part); -lock_kernel ();if (for_part) bdev->bd_part_count--;
@@ -1516,7 +1519,6 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part) victim = bdev->bd_contains; bdev->bd_contains =NULL ; } -unlock_kernel ();mutex_unlock (&bdev->bd_mutex);bdput (bdev);if (victim)
@@ -1526,7 +1528,11 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part)int blkdev_put (struct block_device *bdev,fmode_t mode) { -return __blkdev_put (bdev, mode,0 ); +int ret; +mutex_lock (&blkdev_mutex); + ret =__blkdev_put (bdev, mode,0 ); +mutex_unlock (&blkdev_mutex); +return ret; }EXPORT_SYMBOL (blkdev_put);
include/linux/blkdev.h +6 -0
@@ -1340,6 +1340,12 @@ struct block_device_operations {extern int __blkdev_driver_ioctl (struct block_device *,fmode_t ,unsigned int ,unsigned long ); + +/* +* replaces the big kernel lock in the block subsystem +*/ +extern struct mutex blkdev_mutex; +#else /* CONFIG_BLOCK */ /* * stubs for when the block layer is configured out
kernel/trace/blktrace.c +8 -6
@@ -305,7 +305,7 @@ static int blk_dropped_open(struct inode *inode, struct file *filp) { filp->private_data = inode->i_private; -return 0 ; +return nonseekable_open (inode, filp); } static ssize_t blk_dropped_read(struct file *filp, char __user *buffer,
@@ -323,13 +323,14 @@ static const struct file_operations blk_dropped_fops = { .owner = THIS_MODULE, .open = blk_dropped_open, .read = blk_dropped_read, + .llseek = no_llseek, };static int blk_msg_open (struct inode *inode,struct file *filp) { filp->private_data = inode->i_private; -return 0 ; +return nonseekable_open (inode, filp); } static ssize_t blk_msg_write(struct file *filp, const char __user *buffer,
@@ -362,6 +363,7 @@ static const struct file_operations blk_msg_fops = { .owner = THIS_MODULE, .open = blk_msg_open, .write = blk_msg_write, + .llseek = no_llseek, };/*
@@ -1601,7 +1603,7 @@ static ssize_t sysfs_blk_trace_attr_show(struct device *dev,struct block_device *bdev;ssize_t ret = -ENXIO ; -lock_kernel (); +mutex_lock (&blkdev_mutex); bdev =bdget (part_devt (p));if (bdev ==NULL ) goto out_unlock_kernel;
@@ -1633,7 +1635,7 @@ out_unlock_bdev: out_bdput:bdput (bdev); out_unlock_kernel: -unlock_kernel (); +mutex_unlock (&blkdev_mutex);return ret; }
@@ -1663,7 +1665,7 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev, ret = -ENXIO ; -lock_kernel (); +mutex_lock (&blkdev_mutex); p =dev_to_part (dev); bdev =bdget (part_devt (p));if (bdev ==NULL )
@@ -1703,7 +1705,7 @@ out_unlock_bdev: out_bdput:bdput (bdev); out_unlock_kernel: -unlock_kernel (); +mutex_unlock (&blkdev_mutex); out:return ret ? ret : count; }
Signature · 1 line
1.7.0.4
NAK. You're really only creation a mini-BKL here without sorting out the locking. Please go through the individual callers and sort them out. Start by pushing the remaining ioctls to the unlocked version and moving the BKL into the ->open and ->release methods.
PATCH 1/1 block: push down BKL into .locked_ioctl
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.
--- block/ioctl.c | 11 +---------- drivers/block/amiflop.c | 15 ++++++++++++++- drivers/block/ataflop.c | 14 +++++++++++++- drivers/block/brd.c | 5 ++++- drivers/block/cciss.c | 8 +++++--- drivers/block/cpqarray.c | 18 ++++++++++++++++-- drivers/block/floppy.c | 15 ++++++++++++++- drivers/block/nbd.c | 5 ++++- drivers/block/paride/pcd.c | 11 +++++++++-- drivers/block/paride/pd.c | 5 ++++- drivers/block/paride/pf.c | 6 +++++- drivers/block/pktcdvd.c | 11 ++++++++--- drivers/block/swim.c | 5 ++++- drivers/block/swim3.c | 15 ++++++++++++++- drivers/block/ub.c | 10 ++++++++-- drivers/block/virtio_blk.c | 15 ++++++++++++++- drivers/block/xd.c | 15 ++++++++++++++- drivers/block/xd.h | 2 +- drivers/block/xen-blkfront.c | 2 +- drivers/cdrom/gdrom.c | 11 +++++++++-- drivers/cdrom/viocd.c | 11 +++++++++-- drivers/ide/ide-cd.c | 16 +++++++++++++++- drivers/ide/ide-disk_ioctl.c | 9 +++++++-- drivers/ide/ide-floppy_ioctl.c | 12 +++++++++--- drivers/ide/ide-gd.c | 2 +- drivers/ide/ide-tape.c | 10 ++++++++-- drivers/message/i2o/i2o_block.c | 15 ++++++++++++++- drivers/mtd/mtd_blkdevs.c | 5 ++++- drivers/scsi/sd.c | 15 ++++++++++++++- drivers/scsi/sr.c | 15 ++++++++++++++- include/linux/blkdev.h | 1 - 31 files changed, 257 insertions(+), 53 deletions(-)
Quoted 5 lines · On Tuesday 01 June 2010 23:37:55 Christoph Hellwig wrote:
NAK. You're really only creation a mini-BKL here without sorting out the locking. Please go through the individual callers and sort them out. Start by pushing the remaining ioctls to the unlocked version and moving the BKL into the ->open and ->release methods.
Ok, here comes the first step. Can you be more specific about what you mean with the open and release methods? Do you mean the sg.c and bsg.c chrdev file operations?
Arnd
block/ioctl.c +1 -10
@@ -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 ; }/*
@@ -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)
drivers/block/amiflop.c +14 -1
@@ -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>
@@ -1500,6 +1501,18 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode,return 0 ; } +static int fd_unlocked_ioctl (struct block_device *bdev,fmode_t mode, +unsigned int cmd,unsigned long param) +{ +int ret; + +lock_kernel (); + ret =fd_ioctl (bdev, mode, cmd, param); +unlock_kernel (); + +return ret; +} +static void fd_probe (int dev) {unsigned long code;
@@ -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_unlocked_ioctl, .getgeo = fd_getgeo, .media_changed = amiga_floppy_change, };
drivers/block/ataflop.c +13 -1
@@ -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>
@@ -1665,6 +1666,17 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode, } } +static int fd_unlocked_ioctl (struct block_device *bdev,fmode_t mode, +unsigned int cmd,unsigned long arg) +{ +int ret; + +lock_kernel (); + ret =fd_ioctl (bdev, mode, cmd, arg); +unlock_kernel (); + +return ret; +}/* Initialize the 'unit' variable for drive 'drive' */
@@ -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_unlocked_ioctl, .media_changed = check_floppy_change, .revalidate_disk= floppy_revalidate, };
drivers/block/brd.c +4 -1
@@ -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>
@@ -355,6 +356,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 ) {
@@ -371,13 +373,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
drivers/block/cciss.c +5 -3
@@ -170,6 +170,8 @@ static void do_cciss_request(struct request_queue *q);static irqreturn_t do_cciss_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);
@@ -223,7 +225,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,
@@ -1021,8 +1023,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) {
@@ -1033,6 +1033,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,
drivers/block/cpqarray.c +16 -2
@@ -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>
@@ -159,7 +160,7 @@ static int sendcmd(static int ida_open (struct block_device *bdev,fmode_t mode);static int ida_release (struct gendisk *disk,fmode_t mode); -static int ida_ioctl (struct block_device *bdev,fmode_t mode,unsigned int cmd,unsigned long arg); +static int ida_unlocked_ioctl (struct block_device *bdev,fmode_t mode,unsigned int cmd,unsigned long arg);static int ida_getgeo (struct block_device *bdev,struct hd_geometry *geo);static int ida_ctlr_ioctl (ctlr_info_t *h,int dsk,ida_ioctl_t *io);
@@ -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_unlocked_ioctl, .getgeo = ida_getgeo, .revalidate_disk= ida_revalidate, };
@@ -1192,6 +1193,19 @@ out_passthru: } } + +static int ida_unlocked_ioctl (struct block_device *bdev,fmode_t mode, +unsigned int cmd,unsigned long param) +{ +int ret; + +lock_kernel (); + ret =ida_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,
drivers/block/floppy.c +14 -1
@@ -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>
@@ -3593,6 +3594,18 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd,return 0 ; } +static int fd_unlocked_ioctl (struct block_device *bdev,fmode_t mode, +unsigned int cmd,unsigned long param) +{ +int ret; + +lock_kernel (); + ret =fd_ioctl (bdev, mode, cmd, param); +unlock_kernel (); + +return ret; +} +static void __init config_types (void ) {bool has_drive = false;
@@ -3893,7 +3906,7 @@ static const struct block_device_operations floppy_fops = { .owner = THIS_MODULE, .open = floppy_open, .release = floppy_release, - .locked_ioctl = fd_ioctl, + .ioctl = fd_unlocked_ioctl, .getgeo = fd_getgeo, .media_changed = check_floppy_change, .revalidate_disk = floppy_revalidate,
drivers/block/nbd.c +4 -1
@@ -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>
@@ -716,9 +717,11 @@ 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; }
@@ -726,7 +729,7 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode,static const struct block_device_operations nbd_fops = { .owner =THIS_MODULE , - .locked_ioctl = nbd_ioctl, + .ioctl = nbd_ioctl, };/*
drivers/block/paride/pcd.c +9 -2
@@ -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);
@@ -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)
@@ -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, };
drivers/block/paride/pd.c +4 -1
@@ -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>
@@ -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 ;
@@ -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
drivers/block/paride/pf.c +5 -1
@@ -152,6 +152,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_LUN, D_DLY};#include <linux/spinlock.h> #include <linux/blkdev.h> #include <linux/blkpg.h> +#include <linux/smp_lock.h> #include <asm/uaccess.h> static DEFINE_SPINLOCK (pf_spin_lock);
@@ -266,7 +267,7 @@ static const struct block_device_operations pf_fops = { .owner = THIS_MODULE, .open = pf_open, .release = pf_release, - .locked_ioctl = pf_ioctl, + .ioctl = pf_ioctl, .getgeo = pf_getgeo, .media_changed = pf_check_media, };
@@ -342,7 +343,10 @@ static int pf_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, uif (pf->access !=1 )return -EBUSY ; +lock_kernel ();pf_eject (pf); +unlock_kernel (); +return 0 ; }
drivers/block/pktcdvd.c +8 -3
@@ -57,6 +57,7 @@#include <linux/seq_file.h> #include <linux/miscdevice.h> #include <linux/freezer.h> +#include <linux/smp_lock.h> #include <linux/mutex.h> #include <linux/slab.h> #include <scsi/scsi_cmnd.h>
@@ -2762,10 +2763,12 @@ out_mem:static int pkt_ioctl (struct block_device *bdev,fmode_t mode,unsigned int cmd,unsigned long arg) {struct pktcdvd_device *pd = bdev->bd_disk->private_data; +int ret;VPRINTK ("pkt_ioctl: cmd %x, dev %d:%d\n" , cmd,MAJOR (bdev->bd_dev),MINOR (bdev->bd_dev)); +lock_kernel ();switch (cmd) {case CDROMEJECT :/*
@@ -2783,12 +2786,14 @@ static int pkt_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd,case CDROM_LAST_WRITTEN :case CDROM_SEND_PACKET :case SCSI_IOCTL_SEND_COMMAND : -return __blkdev_driver_ioctl (pd->bdev, mode, cmd, arg); + ret =__blkdev_driver_ioctl (pd->bdev, mode, cmd, arg); +break ;default :VPRINTK (DRIVER_NAME ": Unknown ioctl for %s (%x)\n" , pd->name, cmd); -return -ENOTTY ; + ret = -ENOTTY ; } +unlock_kernel ();return 0 ; }
@@ -2812,7 +2817,7 @@ static const struct block_device_operations pktcdvd_ops = { .owner = THIS_MODULE, .open = pkt_open, .release = pkt_close, - .locked_ioctl = pkt_ioctl, + .ioctl = pkt_ioctl, .media_changed = pkt_media_changed, };
drivers/block/swim.c +4 -1
@@ -20,6 +20,7 @@#include <linux/fd.h> #include <linux/slab.h> #include <linux/blkdev.h> +#include <linux/smp_lock.h> #include <linux/hdreg.h> #include <linux/kernel.h> #include <linux/delay.h>
@@ -690,7 +691,9 @@ static int floppy_ioctl(struct block_device *bdev, fmode_t mode,case FDEJECT :if (fs->ref_count !=1 )return -EBUSY ; +lock_kernel (); err =floppy_eject (fs); +unlock_kernel ();return err;case FDGETPRM :
@@ -753,7 +756,7 @@ static const struct block_device_operations floppy_fops = { .owner = THIS_MODULE, .open = floppy_open, .release = floppy_release, - .locked_ioctl = floppy_ioctl, + .ioctl = floppy_ioctl, .getgeo = floppy_getgeo, .media_changed = floppy_check_change, .revalidate_disk = floppy_revalidate,
drivers/block/swim3.c +14 -1
@@ -25,6 +25,7 @@#include <linux/ioctl.h> #include <linux/blkdev.h> #include <linux/interrupt.h> +#include <linux/smp_lock.h> #include <linux/module.h> #include <linux/spinlock.h> #include <asm/io.h>
@@ -867,6 +868,18 @@ static int floppy_ioctl(struct block_device *bdev, fmode_t mode,return -ENOTTY ; } +static int floppy_unlocked_ioctl (struct block_device *bdev,fmode_t mode, +unsigned int cmd,unsigned long param) +{ +int ret; + +lock_kernel (); + ret =floppy_ioctl (bdev, mode, cmd, param); +unlock_kernel (); + +return ret; +} +static int floppy_open (struct block_device *bdev,fmode_t mode) {struct floppy_state *fs = bdev->bd_disk->private_data;
@@ -997,7 +1010,7 @@ static int floppy_revalidate(struct gendisk *disk)static const struct block_device_operations floppy_fops = { .open = floppy_open, .release = floppy_release, - .locked_ioctl = floppy_ioctl, + .ioctl = floppy_unlocked_ioctl, .media_changed = floppy_check_change, .revalidate_disk= floppy_revalidate, };
drivers/block/ub.c +8 -2
@@ -28,6 +28,7 @@#include <linux/timer.h> #include <linux/scatterlist.h> #include <linux/slab.h> +#include <linux/smp_lock.h> #include <scsi/scsi.h> #define DRV_NAME "ub"
@@ -1729,8 +1730,13 @@ static int ub_bd_ioctl(struct block_device *bdev, fmode_t mode, {struct gendisk *disk = bdev->bd_disk;void __user *usermem = (void __user *) arg; +int ret; + +lock_kernel (); + ret =scsi_cmd_ioctl (disk->queue, disk, mode, cmd, usermem); +unlock_kernel (); -return scsi_cmd_ioctl (disk->queue, disk, mode, cmd, usermem); +return ret; }/*
@@ -1794,7 +1800,7 @@ static const struct block_device_operations ub_bd_fops = { .owner = THIS_MODULE, .open = ub_bd_open, .release = ub_bd_release, - .locked_ioctl = ub_bd_ioctl, + .ioctl = ub_bd_ioctl, .media_changed = ub_bd_media_changed, .revalidate_disk = ub_bd_revalidate, };
drivers/block/virtio_blk.c +14 -1
@@ -2,6 +2,7 @@#include <linux/spinlock.h> #include <linux/slab.h> #include <linux/blkdev.h> +#include <linux/smp_lock.h> #include <linux/hdreg.h> #include <linux/virtio.h> #include <linux/virtio_blk.h>
@@ -245,6 +246,18 @@ static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, (void __user *)data); } +static int virtblk_unlocked_ioctl (struct block_device *bdev,fmode_t mode, +unsigned int cmd,unsigned long param) +{ +int ret; + +lock_kernel (); + ret =virtblk_ioctl (bdev, mode, cmd, param); +unlock_kernel (); + +return ret; +} +/* We provide getgeo only to please some old bootloader/partitioning tools */ static int virtblk_getgeo (struct block_device *bd,struct hd_geometry *geo) {
@@ -271,7 +284,7 @@ static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo) }static const struct block_device_operations virtblk_fops = { - .locked_ioctl = virtblk_ioctl, + .ioctl = virtblk_unlocked_ioctl, .owner =THIS_MODULE , .getgeo = virtblk_getgeo, };
drivers/block/xd.c +14 -1
@@ -46,6 +46,7 @@#include <linux/init.h> #include <linux/wait.h> #include <linux/blkdev.h> +#include <linux/smp_lock.h> #include <linux/blkpg.h> #include <linux/delay.h> #include <linux/io.h>
@@ -133,7 +134,7 @@ static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo);static const struct block_device_operations xd_fops = { .owner =THIS_MODULE , - .locked_ioctl = xd_ioctl, + .ioctl = xd_unlocked_ioctl, .getgeo = xd_getgeo, };static DECLARE_WAIT_QUEUE_HEAD (xd_wait_int);
@@ -375,6 +376,18 @@ static int xd_ioctl(struct block_device *bdev, fmode_t mode, u_int cmd, u_long a } } +static int xd_unlocked_ioctl (struct block_device *bdev,fmode_t mode, +unsigned int cmd,unsigned long param) +{ +int ret; + +lock_kernel (); + ret =xd_ioctl (bdev, mode, cmd, param); +unlock_kernel (); + +return ret; +} +/* xd_readwrite: handle a read/write request */ static int xd_readwrite (u_char operation,XD_INFO *p,char *buffer,u_int block,u_int count) {
drivers/block/xd.h +1 -1
@@ -105,7 +105,7 @@ static u_char xd_detect (u_char *controller, unsigned int *address);static u_char xd_initdrives (void (*init_drive)(u_char drive));static void do_xd_request (struct request_queue * q); -static int xd_ioctl (struct block_device *bdev,fmode_t mode,unsigned int cmd,unsigned long arg); +static int xd_unlocked_ioctl (struct block_device *bdev,fmode_t mode,unsigned int cmd,unsigned long arg);static int xd_readwrite (u_char operation,XD_INFO *disk,char *buffer,u_int block,u_int count);static void xd_recalibrate (u_char drive);
drivers/block/xen-blkfront.c +1 -1
@@ -1046,7 +1046,7 @@ static const struct block_device_operations xlvbd_block_fops = .open = blkif_open, .release = blkif_release, .getgeo = blkif_getgeo, - .locked_ioctl = blkif_ioctl, + .ioctl = blkif_ioctl, };
drivers/cdrom/gdrom.c +9 -2
@@ -32,6 +32,7 @@#include <linux/blkdev.h> #include <linux/interrupt.h> #include <linux/device.h> +#include <linux/smp_lock.h> #include <linux/wait.h> #include <linux/workqueue.h> #include <linux/platform_device.h>
@@ -509,7 +510,13 @@ static int gdrom_bdops_mediachanged(struct gendisk *disk)static int gdrom_bdops_ioctl (struct block_device *bdev,fmode_t mode,unsigned cmd,unsigned long arg) { -return cdrom_ioctl (gd.cd_info, bdev, mode, cmd, arg); +int ret; + +lock_kernel (); + ret =cdrom_ioctl (gd.cd_info, bdev, mode, cmd, arg); +unlock_kernel (); + +return ret; }static const struct block_device_operations gdrom_bdops = {
@@ -517,7 +524,7 @@ static const struct block_device_operations gdrom_bdops = { .open = gdrom_bdops_open, .release = gdrom_bdops_release, .media_changed = gdrom_bdops_mediachanged, - .locked_ioctl = gdrom_bdops_ioctl, + .ioctl = gdrom_bdops_ioctl, };static irqreturn_t gdrom_command_interrupt (int irq,void *dev_id)
drivers/cdrom/viocd.c +9 -2
@@ -40,6 +40,7 @@#include <linux/module.h> #include <linux/completion.h> #include <linux/proc_fs.h> +#include <linux/smp_lock.h> #include <linux/seq_file.h> #include <linux/scatterlist.h>
@@ -168,7 +169,13 @@ static int viocd_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, unsigned long arg) {struct disk_info *di = bdev->bd_disk->private_data; -return cdrom_ioctl (&di->viocd_info, bdev, mode, cmd, arg); +int ret; + +lock_kernel (); + ret =cdrom_ioctl (&di->viocd_info, bdev, mode, cmd, arg); +unlock_kernel (); + +return ret; }static int viocd_blk_media_changed (struct gendisk *disk)
@@ -181,7 +188,7 @@ static const struct block_device_operations viocd_fops = { .owner = THIS_MODULE, .open = viocd_blk_open, .release = viocd_blk_release, - .locked_ioctl = viocd_blk_ioctl, + .ioctl = viocd_blk_ioctl, .media_changed = viocd_blk_media_changed, };
drivers/ide/ide-cd.c +15 -1
@@ -31,6 +31,7 @@#include <linux/delay.h> #include <linux/timer.h> #include <linux/seq_file.h> +#include <linux/smp_lock.h> #include <linux/slab.h> #include <linux/interrupt.h> #include <linux/errno.h>
@@ -1670,6 +1671,19 @@ static int idecd_ioctl(struct block_device *bdev, fmode_t mode,return err; } +static int idecd_unlocked_ioctl (struct block_device *bdev,fmode_t mode, +unsigned int cmd,unsigned long arg) +{ +int ret; + +lock_kernel (); + ret =idecd_ioctl (bdev, mode, cmd, arg); +unlock_kernel (); + +return ret; +} + +static int idecd_media_changed (struct gendisk *disk) {struct cdrom_info *info =ide_drv_g (disk, cdrom_info);
@@ -1690,7 +1704,7 @@ static const struct block_device_operations idecd_ops = { .owner = THIS_MODULE, .open = idecd_open, .release = idecd_release, - .locked_ioctl = idecd_ioctl, + .ioctl = idecd_unlocked_ioctl, .media_changed = idecd_media_changed, .revalidate_disk = idecd_revalidate_disk };
drivers/ide/ide-disk_ioctl.c +7 -2
@@ -1,6 +1,7 @@#include <linux/kernel.h> #include <linux/ide.h> #include <linux/hdreg.h> +#include <linux/smp_lock.h> #include "ide-disk.h"
@@ -18,9 +19,13 @@ int ide_disk_ioctl(ide_drive_t *drive, struct block_device *bdev, fmode_t mode, {int err; +lock_kernel (); err =ide_setting_ioctl (drive, bdev, cmd, arg, ide_disk_ioctl_settings);if (err != -EOPNOTSUPP ) -return err; + goto out; -return generic_ide_ioctl (drive, bdev, cmd, arg); + err =generic_ide_ioctl (drive, bdev, cmd, arg); +out: +unlock_kernel (); +return err; }
drivers/ide/ide-floppy_ioctl.c +9 -3
@@ -5,6 +5,7 @@#include <linux/kernel.h> #include <linux/ide.h> #include <linux/cdrom.h> +#include <linux/smp_lock.h> #include <asm/unaligned.h>
@@ -275,12 +276,15 @@ int ide_floppy_ioctl(ide_drive_t *drive, struct block_device *bdev,void __user *argp = (void __user *)arg;int err; -if (cmd ==CDROMEJECT || cmd ==CDROM_LOCKDOOR ) -return ide_floppy_lockdoor (drive, &pc, arg, cmd); +lock_kernel (); +if (cmd ==CDROMEJECT || cmd ==CDROM_LOCKDOOR ) { + err =ide_floppy_lockdoor (drive, &pc, arg, cmd); + goto out; + } err =ide_floppy_format_ioctl (drive, &pc, mode, cmd, argp);if (err != -ENOTTY ) -return err; + goto out;/* * skip SCSI_IOCTL_SEND_COMMAND (deprecated)
@@ -293,5 +297,7 @@ int ide_floppy_ioctl(ide_drive_t *drive, struct block_device *bdev,if (err == -ENOTTY ) err =generic_ide_ioctl (drive, bdev, cmd, arg); +out: +unlock_kernel ();return err; }
drivers/ide/ide-gd.c +1 -1
@@ -323,7 +323,7 @@ static const struct block_device_operations ide_gd_ops = { .owner = THIS_MODULE, .open = ide_gd_open, .release = ide_gd_release, - .locked_ioctl = ide_gd_ioctl, + .ioctl = ide_gd_ioctl, .getgeo = ide_gd_getgeo, .media_changed = ide_gd_media_changed, .unlock_native_capacity = ide_gd_unlock_native_capacity,
drivers/ide/ide-tape.c +8 -2
@@ -32,6 +32,7 @@#include <linux/errno.h> #include <linux/genhd.h> #include <linux/seq_file.h> +#include <linux/smp_lock.h> #include <linux/slab.h> #include <linux/pci.h> #include <linux/ide.h>
@@ -1926,9 +1927,14 @@ static int idetape_ioctl(struct block_device *bdev, fmode_t mode, {struct ide_tape_obj *tape =ide_drv_g (bdev->bd_disk, ide_tape_obj);ide_drive_t *drive = tape->drive; -int err =generic_ide_ioctl (drive, bdev, cmd, arg); +int err; + +lock_kernel (); + err =generic_ide_ioctl (drive, bdev, cmd, arg);if (err == -EINVAL ) err =idetape_blkdev_ioctl (drive, cmd, arg); +unlock_kernel (); +return err; }
@@ -1936,7 +1942,7 @@ static const struct block_device_operations idetape_block_ops = { .owner = THIS_MODULE, .open = idetape_open, .release = idetape_release, - .locked_ioctl = idetape_ioctl, + .ioctl = idetape_ioctl, };static int ide_tape_probe (ide_drive_t *drive)
drivers/message/i2o/i2o_block.c +14 -1
@@ -53,6 +53,7 @@#include <linux/module.h> #include <linux/slab.h> #include <linux/i2o.h> +#include <linux/smp_lock.h> #include <linux/mempool.h>
@@ -678,6 +679,18 @@ static int i2o_block_ioctl(struct block_device *bdev, fmode_t mode,return -ENOTTY ; }; +static int i2o_block_unlocked_ioctl (struct block_device *bdev,fmode_t mode, +unsigned int cmd,unsigned long arg) +{ +int ret; + +lock_kernel (); + ret =i2o_block_ioctl (bdev, mode, cmd, arg); +unlock_kernel (); + +return ret; +} +/** * i2o_block_media_changed - Have we seen a media change? * @disk: gendisk which should be verified
@@ -930,7 +943,7 @@ static const struct block_device_operations i2o_block_fops = { .owner = THIS_MODULE, .open = i2o_block_open, .release = i2o_block_release, - .locked_ioctl = i2o_block_ioctl, + .ioctl = i2o_block_unlocked_ioctl, .getgeo = i2o_block_getgeo, .media_changed = i2o_block_media_changed };
drivers/mtd/mtd_blkdevs.c +4 -1
@@ -15,6 +15,7 @@#include <linux/blkdev.h> #include <linux/blkpg.h> #include <linux/spinlock.h> +#include <linux/smp_lock.h> #include <linux/hdreg.h> #include <linux/init.h> #include <linux/mutex.h>
@@ -237,6 +238,7 @@ static int blktrans_ioctl(struct block_device *bdev, fmode_t mode,if (!dev)return ret; +lock_kernel ();mutex_lock (&dev->lock);if (!dev->mtd)
@@ -250,6 +252,7 @@ static int blktrans_ioctl(struct block_device *bdev, fmode_t mode, } unlock:mutex_unlock (&dev->lock); +unlock_kernel ();blktrans_dev_put (dev);return ret; }
@@ -258,7 +261,7 @@ static const struct block_device_operations mtd_blktrans_ops = { .owner = THIS_MODULE, .open = blktrans_open, .release = blktrans_release, - .locked_ioctl = blktrans_ioctl, + .ioctl = blktrans_ioctl, .getgeo = blktrans_getgeo, };
drivers/scsi/sd.c +14 -1
@@ -46,6 +46,7 @@#include <linux/blkdev.h> #include <linux/blkpg.h> #include <linux/delay.h> +#include <linux/smp_lock.h> #include <linux/mutex.h> #include <linux/string_helpers.h> #include <linux/async.h>
@@ -914,6 +915,18 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode,return scsi_ioctl (sdp, cmd, p); } +static int sd_unlocked_ioctl (struct block_device *bdev,fmode_t mode, +unsigned int cmd,unsigned long arg) +{ +int ret; + +lock_kernel (); + ret =sd_ioctl (bdev, mode, cmd, arg); +unlock_kernel (); + +return ret; +} +static void set_media_not_present (struct scsi_disk *sdkp) { sdkp->media_present =0 ;
@@ -1094,7 +1107,7 @@ static const struct block_device_operations sd_fops = { .owner = THIS_MODULE, .open = sd_open, .release = sd_release, - .locked_ioctl = sd_ioctl, + .ioctl = sd_unlocked_ioctl, .getgeo = sd_getgeo, #ifdef CONFIG_COMPAT .compat_ioctl = sd_compat_ioctl,
drivers/scsi/sr.c +14 -1
@@ -44,6 +44,7 @@#include <linux/init.h> #include <linux/blkdev.h> #include <linux/mutex.h> +#include <linux/smp_lock.h> #include <linux/slab.h> #include <asm/uaccess.h>
@@ -520,6 +521,18 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,return scsi_ioctl (sdev, cmd, argp); } +static int sr_block_unlocked_ioctl (struct block_device *bdev,fmode_t mode, +unsigned int cmd,unsigned long arg) +{ +int ret; + +lock_kernel (); + ret =sr_block_ioctl (bdev, mode, cmd, arg); +unlock_kernel (); + +return ret; +} +static int sr_block_media_changed (struct gendisk *disk) {struct scsi_cd *cd =scsi_cd (disk);
@@ -531,7 +544,7 @@ static const struct block_device_operations sr_bdops = .owner = THIS_MODULE, .open = sr_block_open, .release = sr_block_release, - .locked_ioctl = sr_block_ioctl, + .ioctl = sr_block_unlocked_ioctl, .media_changed = sr_block_media_changed,/* * No compat_ioctl for now because sr_block_ioctl never
include/linux/blkdev.h +0 -1
@@ -1324,7 +1324,6 @@ static inline int blk_integrity_rq(struct request *rq)struct block_device_operations {int (*open) (struct block_device *,fmode_t );int (*release) (struct gendisk *,fmode_t ); -int (*locked_ioctl) (struct block_device *,fmode_t ,unsigned ,unsigned long );int (*ioctl) (struct block_device *,fmode_t ,unsigned ,unsigned long );int (*compat_ioctl) (struct block_device *,fmode_t ,unsigned ,unsigned long ); int (*direct_access) (struct block_device *, sector_t,
Signature · 1 line
1.7.0.4
Re: [PATCH] block: push down BKL into .locked_ioctl
Quoted 3 lines
Ok, here comes the first step. Can you be more specific about what you mean with the open and release methods? Do you mean the
sg.candbsg.cchrdev file operations?
No, the open and release methods in struct block_device_operations. After this the driver API for block devices is BKL free, which is an important step. To get there the locking in blkdev_get/put needs to be sorted out first, though.
The ioctl pushdown patch looks good to me, btw.
PATCH 1/1 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.
---
Quoted 8 lines · Christoph Hellwig
Quoted 3 lines
Ok, here comes the first step. Can you be more specific about what you mean with the open and release methods? Do you mean the
sg.candbsg.cchrdev file operations?No, the open and release methods in struct
block_device_operations. After this the driver API for block devices is BKL free, which is an important step. To get there the locking in blkdev_get/put needs to be sorted out first, though.
I see. I hoped that I could get around fixing the blkdev_get/put locking, since I'm not really familiar with that code. Maybe someone else can step in for that. I can certainly do the patch to add the BKL to all open/release block_device_operations, which does not require deep understanding of what is actually getting locked.
Quoted 1 line
The ioctl pushdown patch looks good to me, btw.
ok.
Arnd
---
arch/um/drivers/ubd_kern.c | 7 ++++++- drivers/block/DAC960.c | 13 +++++++++---- drivers/block/amiflop.c | 12 ++++++++++-- drivers/block/aoe/aoeblk.c | 3 +++ drivers/block/ataflop.c | 14 +++++++++++++- drivers/block/cciss.c | 24 ++++++++++++++++++++---- drivers/block/cpqarray.c | 22 +++++++++++++++++++--- drivers/block/drbd/drbd_main.c | 4 ++++ drivers/block/floppy.c | 5 +++++ drivers/block/loop.c | 5 +++++ drivers/block/paride/pcd.c | 10 +++++++++- drivers/block/paride/pd.c | 4 ++++ drivers/block/paride/pf.c | 20 +++++++++++++++----- drivers/block/pktcdvd.c | 5 +++++ drivers/block/swim.c | 15 ++++++++++++++- drivers/block/swim3.c | 15 ++++++++++++++- drivers/block/ub.c | 17 ++++++++++++++++- drivers/block/viodasd.c | 19 ++++++++++++++++++- drivers/block/xen-blkfront.c | 7 +++++++ drivers/block/xsysace.c | 6 ++++++ drivers/block/z2ram.c | 13 ++++++++++--- drivers/cdrom/gdrom.c | 8 +++++++- drivers/cdrom/viocd.c | 10 +++++++++- drivers/ide/ide-cd.c | 14 +++++++++----- drivers/ide/ide-gd.c | 17 ++++++++++++++++- drivers/ide/ide-tape.c | 9 ++++++++- drivers/md/dm.c | 7 +++++++ drivers/md/md.c | 6 ++++++ drivers/memstick/core/mspro_block.c | 9 ++++++++- drivers/message/i2o/i2o_block.c | 4 ++++ drivers/mmc/card/block.c | 5 +++++ drivers/mtd/mtd_blkdevs.c | 6 +++++- drivers/s390/block/dasd.c | 6 ++++++ drivers/s390/block/dcssblk.c | 5 +++++ drivers/s390/char/tape_block.c | 8 +++++++- drivers/scsi/sd.c | 5 +++++ drivers/scsi/sr.c | 7 ++++++- drivers/staging/hv/blkvsc_drv.c | 5 +++++ 38 files changed, 330 insertions(+), 41 deletions(-)
arch/um/drivers/ubd_kern.c +6 -1
@@ -33,6 +33,7 @@#include "linux/mm.h" #include "linux/slab.h" #include "linux/vmalloc.h" +#include "linux/smp_lock.h" #include "linux/blkpg.h" #include "linux/genhd.h" #include "linux/spinlock.h"
@@ -1098,6 +1099,7 @@ static int ubd_open(struct block_device *bdev, fmode_t mode)struct ubd *ubd_dev = disk->private_data;int err =0 ; +lock_kernel ();if (ubd_dev->count ==0 ){ err =ubd_open_dev (ubd_dev);if (err){
@@ -1115,7 +1117,8 @@ static int ubd_open(struct block_device *bdev, fmode_t mode)if(--ubd_dev->count == 0) ubd_close_dev(ubd_dev); err = -EROFS; }*/ - out: +out: +unlock_kernel ();return err; }
@@ -1123,8 +1126,10 @@ static int ubd_release(struct gendisk *disk, fmode_t mode) {struct ubd *ubd_dev = disk->private_data; +lock_kernel ();if (--ubd_dev->count ==0 )ubd_close_dev (ubd_dev); +unlock_kernel ();return 0 ; }
drivers/block/DAC960.c +9 -4
@@ -79,23 +79,28 @@ static int DAC960_open(struct block_device *bdev, fmode_t mode)struct gendisk *disk = bdev->bd_disk;DAC960_Controller_T *p = disk->queue->queuedata;int drive_nr = (long )disk->private_data; +int ret = -ENXIO ; +lock_kernel ();if (p->FirmwareType == DAC960_V1_Controller) {if (p->V1.LogicalDriveInformation[drive_nr]. LogicalDriveState == DAC960_V1_LogicalDrive_Offline) -return -ENXIO ; + goto out; }else {DAC960_V2_LogicalDeviceInfo_T *i = p->V2.LogicalDeviceInformation[drive_nr];if (!i || i->LogicalDeviceState == DAC960_V2_LogicalDevice_Offline) -return -ENXIO ; + goto out; }check_disk_change (bdev);if (!get_capacity (p->disks[drive_nr])) -return -ENXIO ; -return 0 ; + goto out; + ret =0 ; +out: +unlock_kernel (); +return ret; }static int DAC960_getgeo (struct block_device *bdev,struct hd_geometry *geo)
drivers/block/amiflop.c +10 -2
@@ -1555,10 +1555,13 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)int old_dev;unsigned long flags; +lock_kernel (); old_dev = fd_device[drive]; -if (fd_ref[drive] && old_dev != system) +if (fd_ref[drive] && old_dev != system) { +unlock_kernel ();return -EBUSY ; + }if (mode & (FMODE_READ |FMODE_WRITE )) {check_disk_change (bdev);
@@ -1571,8 +1574,10 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)fd_deselect (drive);rel_fdc (); -if (wrprot) +if (wrprot) { +unlock_kernel ();return -EROFS ; + } } }
@@ -1589,6 +1594,7 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)printk (KERN_INFO "fd%d: accessing %s-disk with %s-layout\n" ,drive, unit[drive].type->name, data_types[system].name); +unlock_kernel ();return 0 ; }
@@ -1597,6 +1603,7 @@ static int floppy_release(struct gendisk *disk, fmode_t mode)struct amiga_floppy_struct *p = disk->private_data;int drive = p - unit; +lock_kernel ();if (unit[drive].dirty ==1 ) {del_timer (flush_track_timer + drive);non_int_flush_track (drive);
@@ -1610,6 +1617,7 @@ static int floppy_release(struct gendisk *disk, fmode_t mode)/* the mod_use counter is handled this way */ floppy_off (drive |0x40000000 );#endif +unlock_kernel ();return 0 ; }
drivers/block/aoe/aoeblk.c +3 -0
@@ -124,13 +124,16 @@ aoeblk_open(struct block_device *bdev, fmode_t mode)struct aoedev *d = bdev->bd_disk->private_data;ulong flags; +lock_kernel ();spin_lock_irqsave (&d->lock, flags);if (d->flags &DEVFL_UP ) { d->nopen++;spin_unlock_irqrestore (&d->lock, flags); +unlock_kernel ();return 0 ; }spin_unlock_irqrestore (&d->lock, flags); +unlock_kernel ();return -ENODEV ; }
drivers/block/ataflop.c +13 -1
@@ -1850,22 +1850,34 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)return 0 ; } +static int floppy_unlocked_open (struct block_device *bdev,fmode_t mode) +{ +int ret; + +lock_kernel (); + ret =floppy_open (bdev, mode); +unlock_kernel (); + +return ret; +}static int floppy_release (struct gendisk *disk,fmode_t mode) {struct atari_floppy_struct *p = disk->private_data; +lock_kernel ();if (p->ref <0 ) p->ref =0 ;else if (!p->ref--) {printk (KERN_ERR "floppy_release with fd_ref == 0" ); p->ref =0 ; } +unlock_kernel ();return 0 ; }static const struct block_device_operations floppy_fops = { .owner =THIS_MODULE , - .open = floppy_open, + .open = floppy_unlocked_open, .release = floppy_release, .ioctl = fd_unlocked_ioctl, .media_changed = check_floppy_change,
drivers/block/cciss.c +20 -4
@@ -168,7 +168,7 @@ static LIST_HEAD(scan_q);static void do_cciss_request (struct request_queue *q);static irqreturn_t do_cciss_intr (int irq,void *dev_id); -static int cciss_open (struct block_device *bdev,fmode_t mode); +static int cciss_unlocked_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);
@@ -223,7 +223,7 @@ static int cciss_compat_ioctl(struct block_device *, fmode_t,static const struct block_device_operations cciss_fops = { .owner =THIS_MODULE , - .open = cciss_open, + .open = cciss_unlocked_open, .release = cciss_release, .ioctl = do_ioctl, .getgeo = cciss_getgeo,
@@ -1006,13 +1006,28 @@ static int cciss_open(struct block_device *bdev, fmode_t mode)return 0 ; } +static int cciss_unlocked_open (struct block_device *bdev,fmode_t mode) +{ +int ret; + +lock_kernel (); + ret =cciss_open (bdev, mode); +unlock_kernel (); + +return ret; +} +/* * Close. Sync first. */ static int cciss_release (struct gendisk *disk,fmode_t mode) { -ctlr_info_t *host =get_host (disk); -drive_info_struct *drv =get_drv (disk); +ctlr_info_t *host; +drive_info_struct *drv; + +lock_kernel (); + host =get_host (disk); + drv =get_drv (disk);#ifdef CCISS_DEBUG printk (KERN_DEBUG "cciss_release %s\n" , disk->disk_name);
@@ -1020,6 +1035,7 @@ static int cciss_release(struct gendisk *disk, fmode_t mode) drv->usage_count--; host->usage_count--; +unlock_kernel ();return 0 ; }
drivers/block/cpqarray.c +19 -3
@@ -158,7 +158,7 @@ static int sendcmd(unsigned int blkcnt, unsigned int log_unit ); -static int ida_open (struct block_device *bdev,fmode_t mode); +static int ida_unlocked_open (struct block_device *bdev,fmode_t mode);static int ida_release (struct gendisk *disk,fmode_t mode);static int ida_unlocked_ioctl (struct block_device *bdev,fmode_t mode,unsigned int cmd,unsigned long arg);static int ida_getgeo (struct block_device *bdev,struct hd_geometry *geo);
@@ -196,7 +196,7 @@ static inline ctlr_info_t *get_host(struct gendisk *disk)static const struct block_device_operations ida_fops = { .owner =THIS_MODULE , - .open = ida_open, + .open = ida_unlocked_open, .release = ida_release, .ioctl = ida_unlocked_ioctl, .getgeo = ida_getgeo,
@@ -841,13 +841,29 @@ static int ida_open(struct block_device *bdev, fmode_t mode)return 0 ; } +static int ida_unlocked_open (struct block_device *bdev,fmode_t mode) +{ +int ret; + +lock_kernel (); + ret =ida_open (bdev, mode); +unlock_kernel (); + +return ret; +} +/* * Close. Sync first. */ static int ida_release (struct gendisk *disk,fmode_t mode) { -ctlr_info_t *host =get_host (disk); +ctlr_info_t *host; + +lock_kernel (); + host =get_host (disk); host->usage_count--; +unlock_kernel (); +return 0 ; }
drivers/block/drbd/drbd_main.c +4 -0
@@ -2619,6 +2619,7 @@ static int drbd_open(struct block_device *bdev, fmode_t mode)unsigned long flags;int rv =0 ; +lock_kernel ();spin_lock_irqsave (&mdev->req_lock, flags);/* to have a stable mdev->state.role * and no race with updating open_cnt */
@@ -2633,6 +2634,7 @@ static int drbd_open(struct block_device *bdev, fmode_t mode)if (!rv) mdev->open_cnt++;spin_unlock_irqrestore (&mdev->req_lock, flags); +unlock_kernel ();return rv; }
@@ -2640,7 +2642,9 @@ static int drbd_open(struct block_device *bdev, fmode_t mode)static int drbd_release (struct gendisk *gd,fmode_t mode) {struct drbd_conf *mdev = gd->private_data; +lock_kernel (); mdev->open_cnt--; +unlock_kernel ();return 0 ; }
drivers/block/floppy.c +5 -0
@@ -3662,6 +3662,7 @@ static int floppy_release(struct gendisk *disk, fmode_t mode) {int drive = (long )disk->private_data; +lock_kernel ();mutex_lock (&open_lock);if (UDRS ->fd_ref <0 )UDRS ->fd_ref =0 ;
@@ -3672,6 +3673,7 @@ static int floppy_release(struct gendisk *disk, fmode_t mode)if (!UDRS ->fd_ref) opened_bdev[drive] =NULL ;mutex_unlock (&open_lock); +unlock_kernel ();return 0 ; }
@@ -3689,6 +3691,7 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)int res = -EBUSY ;char *tmp; +lock_kernel ();mutex_lock (&open_lock); old_dev =UDRS ->fd_device;if (opened_bdev[drive] && opened_bdev[drive] != bdev)
@@ -3765,6 +3768,7 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) goto out; }mutex_unlock (&open_lock); +unlock_kernel ();return 0 ; out:if (UDRS ->fd_ref <0 )
@@ -3775,6 +3779,7 @@ out: opened_bdev[drive] =NULL ; out2:mutex_unlock (&open_lock); +unlock_kernel ();return res; }
drivers/block/loop.c +5 -0
@@ -67,6 +67,7 @@#include <linux/compat.h> #include <linux/suspend.h> #include <linux/freezer.h> +#include <linux/smp_lock.h> #include <linux/writeback.h> #include <linux/buffer_head.h> /* for invalidate_bdev() */ #include <linux/completion.h>
@@ -1408,9 +1409,11 @@ static int lo_open(struct block_device *bdev, fmode_t mode) {struct loop_device *lo = bdev->bd_disk->private_data; +lock_kernel ();mutex_lock (&lo->lo_ctl_mutex); lo->lo_refcnt++;mutex_unlock (&lo->lo_ctl_mutex); +unlock_kernel ();return 0 ; }
@@ -1420,6 +1423,7 @@ static int lo_release(struct gendisk *disk, fmode_t mode)struct loop_device *lo = disk->private_data;int err; +lock_kernel ();mutex_lock (&lo->lo_ctl_mutex);if (--lo->lo_refcnt)
@@ -1444,6 +1448,7 @@ static int lo_release(struct gendisk *disk, fmode_t mode) out:mutex_unlock (&lo->lo_ctl_mutex); out_unlocked: +lock_kernel ();return 0 ; }
drivers/block/paride/pcd.c +9 -1
@@ -225,13 +225,21 @@ static char *pcd_buf; /* buffer for request in progress */static int pcd_block_open (struct block_device *bdev,fmode_t mode) {struct pcd_unit *cd = bdev->bd_disk->private_data; -return cdrom_open (&cd->info, bdev, mode); +int ret; + +lock_kernel (); + ret =cdrom_open (&cd->info, bdev, mode); +unlock_kernel (); + +return ret; }static int pcd_block_release (struct gendisk *disk,fmode_t mode) {struct pcd_unit *cd = disk->private_data; +lock_kernel ();cdrom_release (&cd->info, mode); +unlock_kernel ();return 0 ; }
drivers/block/paride/pd.c +4 -0
@@ -736,12 +736,14 @@ static int pd_open(struct block_device *bdev, fmode_t mode) {struct pd_unit *disk = bdev->bd_disk->private_data; +lock_kernel (); disk->access++;if (disk->removable) {pd_special_command (disk, pd_media_check);pd_special_command (disk, pd_door_lock); } +unlock_kernel ();return 0 ; }
@@ -783,8 +785,10 @@ static int pd_release(struct gendisk *p, fmode_t mode) {struct pd_unit *disk = p->private_data; +lock_kernel ();if (!--disk->access && disk->removable)pd_special_command (disk, pd_door_unlock); +unlock_kernel ();return 0 ; }
drivers/block/paride/pf.c +15 -5
@@ -300,20 +300,26 @@ static void __init pf_init_units(void)static int pf_open (struct block_device *bdev,fmode_t mode) {struct pf_unit *pf = bdev->bd_disk->private_data; +int ret; +lock_kernel ();pf_identify (pf); + ret = -ENODEV ;if (pf->media_status ==PF_NM ) -return -ENODEV ; + goto out; + ret = -EROFS ;if ((pf->media_status ==PF_RO ) && (mode &FMODE_WRITE )) -return -EROFS ; + goto out; + ret =0 ; pf->access++;if (pf->removable)pf_lock (pf,1 ); - -return 0 ; +out: +unlock_kernel (); +return ret; }static 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) {struct pf_unit *pf = disk->private_data; -if (pf->access <=0 ) +lock_kernel (); +if (pf->access <=0 ) { +unlock_kernel ();return -EINVAL ; + } pf->access--;if (!pf->access && pf->removable)pf_lock (pf,0 ); +unlock_kernel ();return 0 ; }
drivers/block/pktcdvd.c +5 -0
@@ -2383,6 +2383,7 @@ static int pkt_open(struct block_device *bdev, fmode_t mode)VPRINTK (DRIVER_NAME ": entering open\n" ); +lock_kernel ();mutex_lock (&ctl_mutex); pd =pkt_find_dev_from_minor (MINOR (bdev->bd_dev));if (!pd) {
@@ -2410,6 +2411,7 @@ static int pkt_open(struct block_device *bdev, fmode_t mode) }mutex_unlock (&ctl_mutex); +unlock_kernel ();return 0 ; out_dec:
@@ -2417,6 +2419,7 @@ out_dec: out:VPRINTK (DRIVER_NAME ": failed open (%d)\n" , ret);mutex_unlock (&ctl_mutex); +unlock_kernel ();return ret; }
@@ -2425,6 +2428,7 @@ static int pkt_close(struct gendisk *disk, fmode_t mode)struct pktcdvd_device *pd = disk->private_data;int ret =0 ; +lock_kernel ();mutex_lock (&ctl_mutex); pd->refcnt--;BUG_ON (pd->refcnt <0 );
@@ -2433,6 +2437,7 @@ static int pkt_close(struct gendisk *disk, fmode_t mode)pkt_release_dev (pd, flush); }mutex_unlock (&ctl_mutex); +unlock_kernel ();return ret; }
drivers/block/swim.c +14 -1
@@ -662,11 +662,23 @@ out:return err; } +static int floppy_unlocked_open (struct block_device *bdev,fmode_t mode) +{ +int ret; + +lock_kernel (); + ret =floppy_open (bdev, mode); +unlock_kernel (); + +return ret; +} +static int floppy_release (struct gendisk *disk,fmode_t mode) {struct floppy_state *fs = disk->private_data;struct swim __iomem *base = fs->swd->base; +lock_kernel ();if (fs->ref_count <0 ) fs->ref_count =0 ;else if (fs->ref_count >0 )
@@ -674,6 +686,7 @@ static int floppy_release(struct gendisk *disk, fmode_t mode)if (fs->ref_count ==0 )swim_motor (base,OFF ); +unlock_kernel ();return 0 ; }
@@ -754,7 +767,7 @@ static int floppy_revalidate(struct gendisk *disk)static const struct block_device_operations floppy_fops = { .owner =THIS_MODULE , - .open = floppy_open, + .open = floppy_unlocked_open, .release = floppy_release, .ioctl = floppy_ioctl, .getgeo = floppy_getgeo,
drivers/block/swim3.c +14 -1
@@ -949,15 +949,28 @@ static int floppy_open(struct block_device *bdev, fmode_t mode)return 0 ; } +static int floppy_unlocked_open (struct block_device *bdev,fmode_t mode) +{ +int ret; + +lock_kernel (); + ret =floppy_open (bdev, mode); +unlock_kernel (); + +return ret; +} +static int floppy_release (struct gendisk *disk,fmode_t mode) {struct floppy_state *fs = disk->private_data;struct swim3 __iomem *sw = fs->swim3; +lock_kernel ();if (fs->ref_count >0 && --fs->ref_count ==0 ) {swim3_action (fs,MOTOR_OFF );out_8 (&sw->control_bic,0xff );swim3_select (fs,RELAX ); } +unlock_kernel ();return 0 ; }
@@ -1008,7 +1021,7 @@ static int floppy_revalidate(struct gendisk *disk) }static const struct block_device_operations floppy_fops = { - .open = floppy_open, + .open = floppy_unlocked_open, .release = floppy_release, .ioctl = floppy_unlocked_ioctl, .media_changed = floppy_check_change,
drivers/block/ub.c +16 -1
@@ -1711,6 +1711,18 @@ err_open:return rc; } +static int ub_bd_unlocked_open (struct block_device *bdev,fmode_t mode) +{ +int ret; + +lock_kernel (); + ret =ub_bd_open (bdev, mode); +unlock_kernel (); + +return ret; +} + +/* */ static int ub_bd_release (struct gendisk *disk,fmode_t mode)
@@ -1718,7 +1730,10 @@ static int ub_bd_release(struct gendisk *disk, fmode_t mode)struct ub_lun *lun = disk->private_data;struct ub_dev *sc = lun->udev; +lock_kernel ();ub_put (sc); +unlock_kernel (); +return 0 ; }
@@ -1798,7 +1813,7 @@ static int ub_bd_media_changed(struct gendisk *disk)static const struct block_device_operations ub_bd_fops = { .owner =THIS_MODULE , - .open = ub_bd_open, + .open = ub_bd_unlocked_open, .release = ub_bd_release, .ioctl = ub_bd_ioctl, .media_changed = ub_bd_media_changed,
drivers/block/viodasd.c +18 -1
@@ -41,6 +41,7 @@#include <linux/errno.h> #include <linux/init.h> #include <linux/string.h> +#include <linux/smp_lock.h> #include <linux/dma-mapping.h> #include <linux/completion.h> #include <linux/device.h>
@@ -175,6 +176,18 @@ static int viodasd_open(struct block_device *bdev, fmode_t mode)return 0 ; } +static int viodasd_unlocked_open (struct block_device *bdev,fmode_t mode) +{ +int ret; + +lock_kernel (); + ret =viodasd_open (bdev, mode); +unlock_kernel (); + +return ret; +} + +/* * External release entry point. */
@@ -183,6 +196,7 @@ static int viodasd_release(struct gendisk *disk, fmode_t mode)struct viodasd_device *d = disk->private_data;HvLpEvent_Rc hvrc; +lock_kernel ();/* Send the event to OS/400. We DON'T expect a response */ hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, HvLpEvent_Type_VirtualIo,
@@ -195,6 +209,9 @@ static int viodasd_release(struct gendisk *disk, fmode_t mode) 0, 0, 0);if (hvrc !=0 )pr_warning ("HV close call failed %d\n" , (int )hvrc); + +unlock_kernel (); +return 0 ; }
@@ -219,7 +236,7 @@ static int viodasd_getgeo(struct block_device *bdev, struct hd_geometry *geo)*/ static const struct block_device_operations viodasd_fops = { .owner =THIS_MODULE , - .open = viodasd_open, + .open = viodasd_unlocked_open, .release = viodasd_release, .getgeo = viodasd_getgeo, };
drivers/block/xen-blkfront.c +7 -0
@@ -41,6 +41,7 @@#include <linux/cdrom.h> #include <linux/module.h> #include <linux/slab.h> +#include <linux/smp_lock.h> #include <linux/scatterlist.h> #include <xen/xen.h>
@@ -1019,13 +1020,18 @@ static int blkfront_is_ready(struct xenbus_device *dev)static int blkif_open (struct block_device *bdev,fmode_t mode) {struct blkfront_info *info = bdev->bd_disk->private_data; + +lock_kernel (); info->users++; +unlock_kernel (); +return 0 ; }static int blkif_release (struct gendisk *disk,fmode_t mode) {struct blkfront_info *info = disk->private_data; +lock_kernel (); info->users--;if (info->users ==0 ) {/* Check whether we have been instructed to close. We will
@@ -1037,6 +1043,7 @@ static int blkif_release(struct gendisk *disk, fmode_t mode)if (state == XenbusStateClosing && info->is_ready)blkfront_closing (dev); } +unlock_kernel ();return 0 ; }
drivers/block/xsysace.c +6 -0
@@ -89,6 +89,7 @@#include <linux/delay.h> #include <linux/slab.h> #include <linux/blkdev.h> +#include <linux/smp_lock.h> #include <linux/ata.h> #include <linux/hdreg.h> #include <linux/platform_device.h>
@@ -901,11 +902,14 @@ static int ace_open(struct block_device *bdev, fmode_t mode)dev_dbg (ace->dev,"ace_open() users=%i\n" , ace->users +1 ); +lock_kernel ();spin_lock_irqsave (&ace->lock, flags); ace->users++;spin_unlock_irqrestore (&ace->lock, flags);check_disk_change (bdev); +unlock_kernel (); +return 0 ; }
@@ -917,6 +921,7 @@ static int ace_release(struct gendisk *disk, fmode_t mode)dev_dbg (ace->dev,"ace_release() users=%i\n" , ace->users -1 ); +lock_kernel ();spin_lock_irqsave (&ace->lock, flags); ace->users--;if (ace->users ==0 ) {
@@ -924,6 +929,7 @@ static int ace_release(struct gendisk *disk, fmode_t mode)ace_out (ace,ACE_CTRL , val & ~ACE_CTRL_LOCKREQ ); }spin_unlock_irqrestore (&ace->lock, flags); +unlock_kernel ();return 0 ; }
drivers/block/z2ram.c +10 -3
@@ -33,6 +33,7 @@#include <linux/module.h> #include <linux/blkdev.h> #include <linux/bitops.h> +#include <linux/smp_lock.h> #include <linux/slab.h> #include <asm/setup.h>
@@ -153,6 +154,7 @@ static int z2_open(struct block_device *bdev, fmode_t mode) device =MINOR (bdev->bd_dev); +lock_kernel ();if ( current_device !=-1 && current_device != device ) { rc = -EBUSY ;
@@ -294,20 +296,25 @@ static int z2_open(struct block_device *bdev, fmode_t mode)set_capacity (z2ram_gendisk, z2ram_size >>9 ); } +unlock_kernel ();return 0 ; err_out_kfree:kfree (z2ram_map); err_out: +unlock_kernel ();return rc; }static int z2_release (struct gendisk *disk,fmode_t mode) { -if ( current_device ==-1 ) -return 0 ; - +lock_kernel (); +if ( current_device ==-1 ) { +unlock_kernel (); +return 0 ; + } +unlock_kernel ();/* * FIXME: unmap memory */
drivers/cdrom/gdrom.c +7 -1
@@ -493,12 +493,18 @@ static struct cdrom_device_ops gdrom_ops = {static int gdrom_bdops_open (struct block_device *bdev,fmode_t mode) { -return cdrom_open (gd.cd_info, bdev, mode); +int ret; +lock_kernel (); + ret =cdrom_open (gd.cd_info, bdev, mode); +unlock_kernel (); +return ret; }static int gdrom_bdops_release (struct gendisk *disk,fmode_t mode) { +lock_kernel ();cdrom_release (gd.cd_info, mode); +unlock_kernel ();return 0 ; }
drivers/cdrom/viocd.c +9 -1
@@ -155,13 +155,21 @@ static const struct file_operations proc_viocd_operations = {static int viocd_blk_open (struct block_device *bdev,fmode_t mode) {struct disk_info *di = bdev->bd_disk->private_data; -return cdrom_open (&di->viocd_info, bdev, mode); +int ret; + +lock_kernel (); + ret =cdrom_open (&di->viocd_info, bdev, mode); +unlock_kernel (); + +return ret; }static int viocd_blk_release (struct gendisk *disk,fmode_t mode) {struct disk_info *di = disk->private_data; +lock_kernel ();cdrom_release (&di->viocd_info, mode); +unlock_kernel ();return 0 ; }
drivers/ide/ide-cd.c +9 -5
@@ -1585,17 +1585,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; }
@@ -1603,9 +1605,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 ; }
drivers/ide/ide-gd.c +16 -1
@@ -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,
drivers/ide/ide-tape.c +8 -1
@@ -1906,7 +1906,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 ;
@@ -1918,7 +1922,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 ; }
drivers/md/dm.c +7 -0
@@ -15,6 +15,7 @@#include <linux/blkpg.h> #include <linux/bio.h> #include <linux/buffer_head.h> +#include <linux/smp_lock.h> #include <linux/mempool.h> #include <linux/slab.h> #include <linux/idr.h>
@@ -338,6 +339,7 @@ static int dm_blk_open(struct block_device *bdev, fmode_t mode) {struct mapped_device *md; +lock_kernel ();spin_lock (&_minor_lock); md = bdev->bd_disk->private_data;
@@ -355,6 +357,7 @@ static int dm_blk_open(struct block_device *bdev, fmode_t mode) out:spin_unlock (&_minor_lock); +unlock_kernel ();return md ?0 : -ENXIO ; }
@@ -362,8 +365,12 @@ out:static int dm_blk_close (struct gendisk *disk,fmode_t mode) {struct mapped_device *md = disk->private_data; + +lock_kernel ();atomic_dec (&md->open_count);dm_put (md); +unlock_kernel (); +return 0 ; }
drivers/md/md.c +6 -0
@@ -36,6 +36,7 @@#include <linux/blkdev.h> #include <linux/sysctl.h> #include <linux/seq_file.h> +#include <linux/smp_lock.h> #include <linux/buffer_head.h> /* for invalidate_bdev */ #include <linux/poll.h> #include <linux/ctype.h>
@@ -5876,6 +5877,7 @@ static int md_open(struct block_device *bdev, fmode_t mode)mddev_t *mddev =mddev_find (bdev->bd_dev);int err; +lock_kernel ();if (mddev->gendisk != bdev->bd_disk) {/* we are racing with mddev_put which is discarding this * bd_disk.
@@ -5884,6 +5886,7 @@ static int md_open(struct block_device *bdev, fmode_t mode)/* Wait until bdev->bd_disk is definitely gone */ flush_scheduled_work ();/* Then retry the open from the top */ +unlock_kernel ();return -ERESTARTSYS ; }BUG_ON (mddev != bdev->bd_disk->private_data);
@@ -5896,6 +5899,7 @@ static int md_open(struct block_device *bdev, fmode_t mode)mutex_unlock (&mddev->open_mutex); out: +unlock_kernel ();return err; }
@@ -5904,8 +5908,10 @@ static int md_release(struct gendisk *disk, fmode_t mode)mddev_t *mddev = disk->private_data;BUG_ON (!mddev); +lock_kernel ();atomic_dec (&mddev->openers);mddev_put (mddev); +unlock_kernel ();return 0 ; }
drivers/memstick/core/mspro_block.c +8 -1
@@ -18,6 +18,7 @@#include <linux/kthread.h> #include <linux/delay.h> #include <linux/slab.h> +#include <linux/smp_lock.h> #include <linux/memstick.h> #define DRIVER_NAME "mspro_block"
@@ -179,6 +180,7 @@ static int mspro_block_bd_open(struct block_device *bdev, fmode_t mode)struct mspro_block_data *msb = disk->private_data;int rc = -ENXIO ; +lock_kernel ();mutex_lock (&mspro_block_disk_lock);if (msb && msb->card) {
@@ -190,6 +192,7 @@ static int mspro_block_bd_open(struct block_device *bdev, fmode_t mode) }mutex_unlock (&mspro_block_disk_lock); +unlock_kernel ();return rc; }
@@ -221,7 +224,11 @@ static int mspro_block_disk_release(struct gendisk *disk)static int mspro_block_bd_release (struct gendisk *disk,fmode_t mode) { -return mspro_block_disk_release (disk); +int ret; +lock_kernel (); + ret =mspro_block_disk_release (disk); +unlock_kernel (); +return ret; } static int mspro_block_bd_getgeo(struct block_device *bdev,
drivers/message/i2o/i2o_block.c +4 -0
@@ -578,6 +578,7 @@ static int i2o_block_open(struct block_device *bdev, fmode_t mode)if (!dev->i2o_dev)return -ENODEV ; +lock_kernel ();if (dev->power >0x1f )i2o_block_device_power (dev,0x02 );
@@ -586,6 +587,7 @@ static int i2o_block_open(struct block_device *bdev, fmode_t mode)i2o_block_device_lock (dev->i2o_dev,-1 );osm_debug ("Ready.\n" ); +unlock_kernel ();return 0 ; };
@@ -616,6 +618,7 @@ static int i2o_block_release(struct gendisk *disk, fmode_t mode)if (!dev->i2o_dev)return 0 ; +lock_kernel ();i2o_block_device_flush (dev->i2o_dev);i2o_block_device_unlock (dev->i2o_dev,-1 );
@@ -626,6 +629,7 @@ static int i2o_block_release(struct gendisk *disk, fmode_t mode) operation =0x24 ;i2o_block_device_power (dev, operation); +unlock_kernel ();return 0 ; }
drivers/mmc/card/block.c +5 -0
@@ -29,6 +29,7 @@#include <linux/kdev_t.h> #include <linux/blkdev.h> #include <linux/mutex.h> +#include <linux/smp_lock.h> #include <linux/scatterlist.h> #include <linux/string_helpers.h>
@@ -107,6 +108,7 @@ static int mmc_blk_open(struct block_device *bdev, fmode_t mode)struct mmc_blk_data *md =mmc_blk_get (bdev->bd_disk);int ret = -ENXIO ; +lock_kernel ();if (md) {if (md->usage ==2 )check_disk_change (bdev);
@@ -117,6 +119,7 @@ static int mmc_blk_open(struct block_device *bdev, fmode_t mode) ret = -EROFS ; } } +unlock_kernel ();return ret; }
@@ -125,7 +128,9 @@ static int mmc_blk_release(struct gendisk *disk, fmode_t mode) {struct mmc_blk_data *md = disk->private_data; +lock_kernel ();mmc_blk_put (md); +unlock_kernel ();return 0 ; }
drivers/mtd/mtd_blkdevs.c +5 -1
@@ -165,8 +165,9 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode)int ret;if (!dev) -return -ERESTARTSYS ; +return -ERESTARTSYS ;/* FIXME: busy loop! -arnd*/ +lock_kernel ();mutex_lock (&dev->lock);if (!dev->mtd) {
@@ -183,6 +184,7 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode) unlock:mutex_unlock (&dev->lock);blktrans_dev_put (dev); +unlock_kernel ();return ret; }
@@ -194,6 +196,7 @@ static int blktrans_release(struct gendisk *disk, fmode_t mode)if (!dev)return ret; +lock_kernel ();mutex_lock (&dev->lock);/* Release one reference, we sure its not the last one here*/
@@ -206,6 +209,7 @@ static int blktrans_release(struct gendisk *disk, fmode_t mode) unlock:mutex_unlock (&dev->lock);blktrans_dev_put (dev); +unlock_kernel ();return ret; }
drivers/s390/block/dasd.c +6 -0
@@ -21,6 +21,7 @@#include <linux/hdreg.h> #include <linux/async.h> #include <linux/mutex.h> +#include <linux/smp_lock.h> #include <asm/ccwdev.h> #include <asm/ebcdic.h>
@@ -2235,6 +2236,7 @@ static int dasd_open(struct block_device *bdev, fmode_t mode)if (!block)return -ENODEV ; +lock_kernel (); base = block->base;atomic_inc (&block->open_count);if (test_bit (DASD_FLAG_OFFLINE , &base->flags)) {
@@ -2269,12 +2271,14 @@ static int dasd_open(struct block_device *bdev, fmode_t mode) goto out; } +unlock_kernel ();return 0 ; out:module_put (base->discipline->owner); unlock:atomic_dec (&block->open_count); +unlock_kernel ();return rc; }
@@ -2282,8 +2286,10 @@ static int dasd_release(struct gendisk *disk, fmode_t mode) {struct dasd_block *block = disk->private_data; +lock_kernel ();atomic_dec (&block->open_count);module_put (block->base->discipline->owner); +unlock_kernel ();return 0 ; }
drivers/s390/block/dcssblk.c +5 -0
@@ -14,6 +14,7 @@#include <linux/init.h> #include <linux/slab.h> #include <linux/blkdev.h> +#include <linux/smp_lock.h> #include <linux/completion.h> #include <linux/interrupt.h> #include <linux/platform_device.h>
@@ -775,6 +776,7 @@ dcssblk_open(struct block_device *bdev, fmode_t mode)struct dcssblk_dev_info *dev_info;int rc; +lock_kernel (); dev_info = bdev->bd_disk->private_data;if (NULL == dev_info) { rc = -ENODEV ;
@@ -784,6 +786,7 @@ dcssblk_open(struct block_device *bdev, fmode_t mode) bdev->bd_block_size =4096 ; rc =0 ; out: +unlock_kernel ();return rc; }
@@ -794,6 +797,7 @@ dcssblk_release(struct gendisk *disk, fmode_t mode)struct segment_info *entry;int rc; +lock_kernel ();if (!dev_info) { rc = -ENODEV ; goto out;
@@ -811,6 +815,7 @@ dcssblk_release(struct gendisk *disk, fmode_t mode)up_write (&dcssblk_devices_sem); rc =0 ; out: +unlock_kernel ();return rc; }
drivers/s390/char/tape_block.c +7 -1
@@ -16,6 +16,7 @@#include <linux/fs.h> #include <linux/module.h> #include <linux/blkdev.h> +#include <linux/smp_lock.h> #include <linux/interrupt.h> #include <linux/buffer_head.h> #include <linux/kernel.h>
@@ -361,6 +362,7 @@ tapeblock_open(struct block_device *bdev, fmode_t mode)struct tape_device * device;int rc; +lock_kernel (); device =tape_get_device (disk->private_data);if (device->required_tapemarks) {
@@ -384,12 +386,14 @@ tapeblock_open(struct block_device *bdev, fmode_t mode)* is called. */ tape_state_set (device,TS_BLKUSE ); +unlock_kernel ();return 0 ; release:tape_release (device); put_device:tape_put_device (device); +unlock_kernel ();return rc; }
@@ -403,10 +407,12 @@ static int tapeblock_release(struct gendisk *disk, fmode_t mode) {struct tape_device *device = disk->private_data; - + +lock_kernel ();tape_state_set (device,TS_IN_USE );tape_release (device);tape_put_device (device); +unlock_kernel ();return 0 ; }
drivers/scsi/sd.c +5 -0
@@ -757,6 +757,7 @@ static int sd_open(struct block_device *bdev, fmode_t mode)SCSI_LOG_HLQUEUE (3 ,sd_printk (KERN_INFO , sdkp,"sd_open\n" )); +lock_kernel (); sdev = sdkp->device;/*
@@ -800,10 +801,12 @@ static int sd_open(struct block_device *bdev, fmode_t mode)scsi_set_medium_removal (sdev,SCSI_REMOVAL_PREVENT ); } +unlock_kernel ();return 0 ; error_out:scsi_disk_put (sdkp); +unlock_kernel ();return retval; }
@@ -825,6 +828,7 @@ static int sd_release(struct gendisk *disk, fmode_t mode)SCSI_LOG_HLQUEUE (3 ,sd_printk (KERN_INFO , sdkp,"sd_release\n" )); +lock_kernel ();if (!--sdkp->openers && sdev->removable) {if (scsi_block_when_processing_errors (sdev))scsi_set_medium_removal (sdev,SCSI_REMOVAL_ALLOW );
@@ -835,6 +839,7 @@ static int sd_release(struct gendisk *disk, fmode_t mode)* XXX is followed by a "rmmod sd_mod"? */ scsi_disk_put (sdkp); +unlock_kernel ();return 0 ; }
drivers/scsi/sr.c +6 -1
@@ -467,22 +467,27 @@ static int sr_prep_fn(struct request_queue *q, struct request *rq)static int sr_block_open (struct block_device *bdev,fmode_t mode) { -struct scsi_cd *cd =scsi_cd_get (bdev->bd_disk); +struct scsi_cd *cd;int ret = -ENXIO ; +lock_kernel (); + cd =scsi_cd_get (bdev->bd_disk);if (cd) { ret =cdrom_open (&cd->cdi, bdev, mode);if (ret)scsi_cd_put (cd); } +unlock_kernel ();return ret; }static int sr_block_release (struct gendisk *disk,fmode_t mode) {struct scsi_cd *cd =scsi_cd (disk); +lock_kernel ();cdrom_release (&cd->cdi, mode);scsi_cd_put (cd); +unlock_kernel ();return 0 ; }
drivers/staging/hv/blkvsc_drv.c +5 -0
@@ -25,6 +25,7 @@#include <linux/major.h> #include <linux/delay.h> #include <linux/hdreg.h> +#include <linux/smp_lock.h> #include <linux/slab.h> #include <scsi/scsi.h> #include <scsi/scsi_cmnd.h>
@@ -1324,6 +1325,7 @@ static int blkvsc_open(struct block_device *bdev, fmode_t mode)DPRINT_DBG (BLKVSC_DRV ,"- users %d disk %s\n" , blkdev->users, blkdev->gd->disk_name); +lock_kernel ();spin_lock (&blkdev->lock);if (!blkdev->users && blkdev->device_type ==DVD_TYPE ) {
@@ -1335,6 +1337,7 @@ static int blkvsc_open(struct block_device *bdev, fmode_t mode) blkdev->users++;spin_unlock (&blkdev->lock); +unlock_kernel ();return 0 ; }
@@ -1345,6 +1348,7 @@ static int blkvsc_release(struct gendisk *disk, fmode_t mode)DPRINT_DBG (BLKVSC_DRV ,"- users %d disk %s\n" , blkdev->users, blkdev->gd->disk_name); +lock_kernel ();spin_lock (&blkdev->lock);if (blkdev->users ==1 ) {spin_unlock (&blkdev->lock);
@@ -1355,6 +1359,7 @@ static int blkvsc_release(struct gendisk *disk, fmode_t mode) blkdev->users--;spin_unlock (&blkdev->lock); +unlock_kernel ();return 0 ; }