summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/blackfin/mach-bf561/coreb.c1
-rw-r--r--arch/cris/arch-v10/drivers/eeprom.c4
-rw-r--r--arch/cris/arch-v10/drivers/gpio.c3
-rw-r--r--arch/cris/arch-v10/drivers/i2c.c2
-rw-r--r--arch/cris/arch-v10/drivers/sync_serial.c34
-rw-r--r--arch/cris/arch-v32/drivers/cryptocop.c3
-rw-r--r--arch/cris/arch-v32/drivers/i2c.c2
-rw-r--r--arch/cris/arch-v32/drivers/mach-a3/gpio.c4
-rw-r--r--arch/cris/arch-v32/drivers/mach-fs/gpio.c5
-rw-r--r--arch/cris/arch-v32/drivers/sync_serial.c33
-rw-r--r--arch/m68k/bvme6000/rtc.c7
-rw-r--r--arch/m68k/mvme16x/rtc.c4
-rw-r--r--arch/mips/basler/excite/excite_iodev.c9
-rw-r--r--arch/mips/kernel/rtlx.c7
-rw-r--r--arch/mips/kernel/vpe.c12
-rw-r--r--arch/mips/sibyte/common/sb_tbprof.c25
-rw-r--r--arch/parisc/kernel/perf.c4
-rw-r--r--arch/s390/crypto/prng.c2
-rw-r--r--arch/sh/boards/landisk/gio.c10
-rw-r--r--arch/sparc/kernel/apc.c2
-rw-r--r--arch/sparc64/kernel/time.c7
-rw-r--r--arch/um/drivers/harddog_kern.c3
-rw-r--r--arch/um/drivers/mmapper_kern.c2
-rw-r--r--arch/um/drivers/random.c3
-rw-r--r--arch/x86/kernel/apm_32.c4
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_64.c4
-rw-r--r--arch/x86/kernel/cpuid.c25
-rw-r--r--arch/x86/kernel/microcode.c2
-rw-r--r--arch/x86/kernel/msr.c16
-rw-r--r--block/bsg.c7
-rw-r--r--drivers/block/aoe/aoechr.c7
-rw-r--r--drivers/block/paride/pg.c22
-rw-r--r--drivers/block/paride/pt.c7
-rw-r--r--drivers/bluetooth/hci_vhci.c14
-rw-r--r--drivers/char/agp/frontend.c4
-rw-r--r--drivers/char/apm-emulation.c3
-rw-r--r--drivers/char/briq_panel.c9
-rw-r--r--drivers/char/cs5535_gpio.c2
-rw-r--r--drivers/char/ds1286.c4
-rw-r--r--drivers/char/ds1620.c9
-rw-r--r--drivers/char/dsp56k.c16
-rw-r--r--drivers/char/dtlk.c3
-rw-r--r--drivers/char/efirtc.c2
-rw-r--r--drivers/char/genrtc.c7
-rw-r--r--drivers/char/hpet.c4
-rw-r--r--drivers/char/hw_random/core.c2
-rw-r--r--drivers/char/ip2/ip2main.c34
-rw-r--r--drivers/char/ip27-rtc.c4
-rw-r--r--drivers/char/ipmi/ipmi_devintf.c10
-rw-r--r--drivers/char/ipmi/ipmi_watchdog.c3
-rw-r--r--drivers/char/lcd.c3
-rw-r--r--drivers/char/lp.c38
-rw-r--r--drivers/char/mbcs.c5
-rw-r--r--drivers/char/mem.c10
-rw-r--r--drivers/char/misc.c3
-rw-r--r--drivers/char/mwave/mwavedd.c2
-rw-r--r--drivers/char/nvram.c4
-rw-r--r--drivers/char/pc8736x_gpio.c2
-rw-r--r--drivers/char/ppdev.c2
-rw-r--r--drivers/char/raw.c3
-rw-r--r--drivers/char/rtc.c4
-rw-r--r--drivers/char/scx200_gpio.c2
-rw-r--r--drivers/char/snsc.c5
-rw-r--r--drivers/char/sonypi.c3
-rw-r--r--drivers/char/tb0219.c2
-rw-r--r--drivers/char/tlclk.c19
-rw-r--r--drivers/char/tpm/tpm.c5
-rw-r--r--drivers/char/tty_io.c41
-rw-r--r--drivers/char/vc_screen.c9
-rw-r--r--drivers/char/viotape.c3
-rw-r--r--drivers/char/vr41xx_giu.c2
-rw-r--r--drivers/char/xilinx_hwicap/xilinx_hwicap.c6
-rw-r--r--drivers/gpu/drm/drm_fops.c9
-rw-r--r--drivers/hid/hidraw.c3
-rw-r--r--drivers/i2c/i2c-dev.c22
-rw-r--r--drivers/ide/ide-tape.c7
-rw-r--r--drivers/infiniband/core/ucm.c2
-rw-r--r--drivers/infiniband/core/ucma.c3
-rw-r--r--drivers/infiniband/core/user_mad.c13
-rw-r--r--drivers/infiniband/core/uverbs_main.c13
-rw-r--r--drivers/infiniband/hw/ipath/ipath_file_ops.c2
-rw-r--r--drivers/input/input.c16
-rw-r--r--drivers/input/misc/hp_sdc_rtc.c2
-rw-r--r--drivers/input/misc/uinput.c3
-rw-r--r--drivers/input/mousedev.c12
-rw-r--r--drivers/input/serio/serio_raw.c6
-rw-r--r--drivers/isdn/capi/capi.c17
-rw-r--r--drivers/isdn/hardware/eicon/divamnt.c16
-rw-r--r--drivers/isdn/hardware/eicon/divasi.c2
-rw-r--r--drivers/isdn/hardware/eicon/divasmain.c2
-rw-r--r--drivers/isdn/i4l/isdn_common.c3
-rw-r--r--drivers/macintosh/adb.c18
-rw-r--r--drivers/macintosh/ans-lcd.c2
-rw-r--r--drivers/macintosh/smu.c3
-rw-r--r--drivers/macintosh/via-pmu.c3
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.c4
-rw-r--r--drivers/media/radio/miropcm20-rds.c4
-rw-r--r--drivers/media/video/videodev.c4
-rw-r--r--drivers/message/fusion/mptctl.c6
-rw-r--r--drivers/message/i2o/i2o_config.c12
-rw-r--r--drivers/misc/hdpuftrs/hdpu_cpustate.c9
-rw-r--r--drivers/misc/phantom.c9
-rw-r--r--drivers/misc/sony-laptop.c3
-rw-r--r--drivers/mtd/mtdchar.c22
-rw-r--r--drivers/mtd/ubi/cdev.c7
-rw-r--r--drivers/net/ppp_generic.c2
-rw-r--r--drivers/net/tun.c13
-rw-r--r--drivers/net/wan/cosa.c22
-rw-r--r--drivers/parisc/eisa_eeprom.c3
-rw-r--r--drivers/pcmcia/pcmcia_ioctl.c25
-rw-r--r--drivers/rtc/rtc-dev.c12
-rw-r--r--drivers/rtc/rtc-m41t80.c7
-rw-r--r--drivers/s390/block/dasd_eer.c6
-rw-r--r--drivers/s390/char/fs3270.c23
-rw-r--r--drivers/s390/char/monreader.c4
-rw-r--r--drivers/s390/char/monwriter.c3
-rw-r--r--drivers/s390/char/tape_char.c12
-rw-r--r--drivers/s390/char/vmcp.c4
-rw-r--r--drivers/s390/char/vmlogrdr.c8
-rw-r--r--drivers/s390/char/vmur.c12
-rw-r--r--drivers/s390/char/vmwatchdog.c7
-rw-r--r--drivers/s390/crypto/zcrypt_api.c3
-rw-r--r--drivers/sbus/char/bpp.c3
-rw-r--r--drivers/sbus/char/cpwatchdog.c4
-rw-r--r--drivers/sbus/char/display7seg.c1
-rw-r--r--drivers/sbus/char/envctrl.c2
-rw-r--r--drivers/sbus/char/flash.c6
-rw-r--r--drivers/sbus/char/jsflash.c13
-rw-r--r--drivers/sbus/char/openprom.c3
-rw-r--r--drivers/sbus/char/riowatchdog.c2
-rw-r--r--drivers/sbus/char/rtc.c3
-rw-r--r--drivers/sbus/char/uctrl.c3
-rw-r--r--drivers/sbus/char/vfc_dev.c5
-rw-r--r--drivers/scsi/3w-9xxx.c3
-rw-r--r--drivers/scsi/3w-xxxx.c3
-rw-r--r--drivers/scsi/aacraid/linit.c3
-rw-r--r--drivers/scsi/ch.c4
-rw-r--r--drivers/scsi/dpt_i2o.c5
-rw-r--r--drivers/scsi/gdth.c3
-rw-r--r--drivers/scsi/megaraid.c5
-rw-r--r--drivers/scsi/megaraid/megaraid_mm.c2
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.c2
-rw-r--r--drivers/scsi/osst.c15
-rw-r--r--drivers/scsi/scsi_tgt_if.c2
-rw-r--r--drivers/scsi/sg.c16
-rw-r--r--drivers/scsi/st.c11
-rw-r--r--drivers/spi/spidev.c3
-rw-r--r--drivers/telephony/phonedev.c3
-rw-r--r--drivers/uio/uio.c17
-rw-r--r--drivers/usb/core/devio.c2
-rw-r--r--drivers/usb/core/file.c3
-rw-r--r--drivers/usb/gadget/printer.c3
-rw-r--r--drivers/usb/mon/mon_bin.c6
-rw-r--r--drivers/video/fbmem.c15
-rw-r--r--fs/char_dev.c7
-rw-r--r--fs/cifs/cifsfs.c2
-rw-r--r--fs/dlm/user.c9
-rw-r--r--fs/ecryptfs/file.c3
-rw-r--r--fs/fat/cache.c2
-rw-r--r--fs/fat/dir.c4
-rw-r--r--fs/fat/file.c6
-rw-r--r--fs/fat/inode.c26
-rw-r--r--fs/fcntl.c3
-rw-r--r--fs/gfs2/ops_file.c4
-rw-r--r--fs/msdos/namei.c35
-rw-r--r--fs/ncpfs/file.c12
-rw-r--r--fs/nfs/file.c6
-rw-r--r--fs/ocfs2/stack_user.c3
-rw-r--r--fs/read_write.c38
-rw-r--r--fs/smbfs/file.c11
-rw-r--r--fs/vfat/namei.c35
-rw-r--r--include/linux/fs.h3
-rw-r--r--include/linux/smp_lock.h13
-rw-r--r--kernel/pm_qos_params.c7
-rw-r--r--net/irda/irnet/irnet.h1
-rw-r--r--net/irda/irnet/irnet_ppp.c3
-rw-r--r--sound/core/pcm_native.c8
-rw-r--r--sound/core/sound.c15
-rw-r--r--sound/sound_core.c5
179 files changed, 1092 insertions, 350 deletions
diff --git a/arch/blackfin/mach-bf561/coreb.c b/arch/blackfin/mach-bf561/coreb.c
index 1b44e9e6dc3..8598098c084 100644
--- a/arch/blackfin/mach-bf561/coreb.c
+++ b/arch/blackfin/mach-bf561/coreb.c
@@ -194,6 +194,7 @@ static loff_t coreb_lseek(struct file *file, loff_t offset, int origin)
return ret;
}
+/* No BKL needed here */
static int coreb_open(struct inode *inode, struct file *file)
{
spin_lock_irq(&coreb_lock);
diff --git a/arch/cris/arch-v10/drivers/eeprom.c b/arch/cris/arch-v10/drivers/eeprom.c
index f1cac9dc75b..1f2ae909d3e 100644
--- a/arch/cris/arch-v10/drivers/eeprom.c
+++ b/arch/cris/arch-v10/drivers/eeprom.c
@@ -28,6 +28,7 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
+#include <linux/smp_lock.h>
#include <linux/wait.h>
#include <asm/uaccess.h>
#include "i2c.h"
@@ -375,10 +376,9 @@ int __init eeprom_init(void)
}
/* Opens the device. */
-
static int eeprom_open(struct inode * inode, struct file * file)
{
-
+ cycle_kernel_lock();
if(iminor(inode) != EEPROM_MINOR_NR)
return -ENXIO;
if(imajor(inode) != EEPROM_MAJOR_NR)
diff --git a/arch/cris/arch-v10/drivers/gpio.c b/arch/cris/arch-v10/drivers/gpio.c
index 68a998bd106..86048e697eb 100644
--- a/arch/cris/arch-v10/drivers/gpio.c
+++ b/arch/cris/arch-v10/drivers/gpio.c
@@ -16,6 +16,7 @@
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/fs.h>
+#include <linux/smp_lock.h>
#include <linux/string.h>
#include <linux/poll.h>
#include <linux/init.h>
@@ -323,6 +324,7 @@ gpio_open(struct inode *inode, struct file *filp)
if (!priv)
return -ENOMEM;
+ lock_kernel();
priv->minor = p;
/* initialize the io/alarm struct */
@@ -357,6 +359,7 @@ gpio_open(struct inode *inode, struct file *filp)
alarmlist = priv;
spin_unlock_irqrestore(&gpio_lock, flags);
+ unlock_kernel();
return 0;
}
diff --git a/arch/cris/arch-v10/drivers/i2c.c b/arch/cris/arch-v10/drivers/i2c.c
index d6d22067d0c..2797e67ce4f 100644
--- a/arch/cris/arch-v10/drivers/i2c.c
+++ b/arch/cris/arch-v10/drivers/i2c.c
@@ -15,6 +15,7 @@
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/fs.h>
@@ -566,6 +567,7 @@ i2c_readreg(unsigned char theSlave, unsigned char theReg)
static int
i2c_open(struct inode *inode, struct file *filp)
{
+ cycle_kernel_lock();
return 0;
}
diff --git a/arch/cris/arch-v10/drivers/sync_serial.c b/arch/cris/arch-v10/drivers/sync_serial.c
index 069546e342c..91fea623c7c 100644
--- a/arch/cris/arch-v10/drivers/sync_serial.c
+++ b/arch/cris/arch-v10/drivers/sync_serial.c
@@ -21,6 +21,7 @@
#include <linux/interrupt.h>
#include <linux/poll.h>
#include <linux/init.h>
+#include <linux/smp_lock.h>
#include <linux/timer.h>
#include <asm/irq.h>
#include <asm/dma.h>
@@ -443,18 +444,21 @@ static int sync_serial_open(struct inode *inode, struct file *file)
int dev = MINOR(inode->i_rdev);
struct sync_port *port;
int mode;
+ int err = -EBUSY;
+ lock_kernel();
DEBUG(printk(KERN_DEBUG "Open sync serial port %d\n", dev));
if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled) {
DEBUG(printk(KERN_DEBUG "Invalid minor %d\n", dev));
- return -ENODEV;
+ err = -ENODEV;
+ goto out;
}
port = &ports[dev];
/* Allow open this device twice (assuming one reader and one writer) */
if (port->busy == 2) {
DEBUG(printk(KERN_DEBUG "Device is busy.. \n"));
- return -EBUSY;
+ goto out;
}
if (port->init_irqs) {
if (port->use_dma) {
@@ -465,14 +469,14 @@ static int sync_serial_open(struct inode *inode, struct file *file)
&ports[0])) {
printk(KERN_CRIT "Can't alloc "
"sync serial port 1 IRQ");
- return -EBUSY;
+ goto out;
} else if (request_irq(25, rx_interrupt, 0,
"synchronous serial 1 dma rx",
&ports[0])) {
free_irq(24, &port[0]);
printk(KERN_CRIT "Can't alloc "
"sync serial port 1 IRQ");
- return -EBUSY;
+ goto out;
} else if (cris_request_dma(8,
"synchronous serial 1 dma tr",
DMA_VERBOSE_ON_ERROR,
@@ -482,7 +486,7 @@ static int sync_serial_open(struct inode *inode, struct file *file)
printk(KERN_CRIT "Can't alloc "
"sync serial port 1 "
"TX DMA channel");
- return -EBUSY;
+ goto out;
} else if (cris_request_dma(9,
"synchronous serial 1 dma rec",
DMA_VERBOSE_ON_ERROR,
@@ -493,7 +497,7 @@ static int sync_serial_open(struct inode *inode, struct file *file)
printk(KERN_CRIT "Can't alloc "
"sync serial port 1 "
"RX DMA channel");
- return -EBUSY;
+ goto out;
}
#endif
RESET_DMA(8); WAIT_DMA(8);
@@ -520,14 +524,14 @@ static int sync_serial_open(struct inode *inode, struct file *file)
&ports[1])) {
printk(KERN_CRIT "Can't alloc "
"sync serial port 3 IRQ");
- return -EBUSY;
+ goto out;
} else if (request_irq(21, rx_interrupt, 0,
"synchronous serial 3 dma rx",
&ports[1])) {
free_irq(20, &ports[1]);
printk(KERN_CRIT "Can't alloc "
"sync serial port 3 IRQ");
- return -EBUSY;
+ goto out;
} else if (cris_request_dma(4,
"synchronous serial 3 dma tr",
DMA_VERBOSE_ON_ERROR,
@@ -537,7 +541,7 @@ static int sync_serial_open(struct inode *inode, struct file *file)
printk(KERN_CRIT "Can't alloc "
"sync serial port 3 "
"TX DMA channel");
- return -EBUSY;
+ goto out;
} else if (cris_request_dma(5,
"synchronous serial 3 dma rec",
DMA_VERBOSE_ON_ERROR,
@@ -548,7 +552,7 @@ static int sync_serial_open(struct inode *inode, struct file *file)
printk(KERN_CRIT "Can't alloc "
"sync serial port 3 "
"RX DMA channel");
- return -EBUSY;
+ goto out;
}
#endif
RESET_DMA(4); WAIT_DMA(4);
@@ -581,7 +585,7 @@ static int sync_serial_open(struct inode *inode, struct file *file)
&ports[0])) {
printk(KERN_CRIT "Can't alloc "
"sync serial manual irq");
- return -EBUSY;
+ goto out;
}
} else if (port == &ports[1]) {
if (request_irq(8,
@@ -591,7 +595,7 @@ static int sync_serial_open(struct inode *inode, struct file *file)
&ports[1])) {
printk(KERN_CRIT "Can't alloc "
"sync serial manual irq");
- return -EBUSY;
+ goto out;
}
}
port->init_irqs = 0;
@@ -620,7 +624,11 @@ static int sync_serial_open(struct inode *inode, struct file *file)
*R_IRQ_MASK1_SET = 1 << port->data_avail_bit;
DEBUG(printk(KERN_DEBUG "sser%d rec started\n", dev));
}
- return 0;
+ ret = 0;
+
+out:
+ unlock_kernel();
+ return ret;
}
static int sync_serial_release(struct inode *inode, struct file *file)
diff --git a/arch/cris/arch-v32/drivers/cryptocop.c b/arch/cris/arch-v32/drivers/cryptocop.c
index 9fb58202be9..67c61ea8681 100644
--- a/arch/cris/arch-v32/drivers/cryptocop.c
+++ b/arch/cris/arch-v32/drivers/cryptocop.c
@@ -11,6 +11,7 @@
#include <linux/string.h>
#include <linux/fs.h>
#include <linux/mm.h>
+#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/stddef.h>
@@ -2302,11 +2303,11 @@ static int cryptocop_job_setup(struct cryptocop_prio_job **pj, struct cryptocop_
return 0;
}
-
static int cryptocop_open(struct inode *inode, struct file *filp)
{
int p = iminor(inode);
+ cycle_kernel_lock();
if (p != CRYPTOCOP_MINOR) return -EINVAL;
filp->private_data = NULL;
diff --git a/arch/cris/arch-v32/drivers/i2c.c b/arch/cris/arch-v32/drivers/i2c.c
index c2fb7a5c139..179e7b80433 100644
--- a/arch/cris/arch-v32/drivers/i2c.c
+++ b/arch/cris/arch-v32/drivers/i2c.c
@@ -33,6 +33,7 @@
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/init.h>
+#include <linux/smp_lock.h>
#include <asm/etraxi2c.h>
@@ -636,6 +637,7 @@ i2c_readreg(unsigned char theSlave, unsigned char theReg)
static int
i2c_open(struct inode *inode, struct file *filp)
{
+ cycle_kernel_lock();
return 0;
}
diff --git a/arch/cris/arch-v32/drivers/mach-a3/gpio.c b/arch/cris/arch-v32/drivers/mach-a3/gpio.c
index de107dad9f4..ef98608e506 100644
--- a/arch/cris/arch-v32/drivers/mach-a3/gpio.c
+++ b/arch/cris/arch-v32/drivers/mach-a3/gpio.c
@@ -23,6 +23,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
#include <asm/etraxgpio.h>
#include <hwregs/reg_map.h>
@@ -390,6 +391,8 @@ static int gpio_open(struct inode *inode, struct file *filp)
if (!priv)
return -ENOMEM;
+
+ lock_kernel();
memset(priv, 0, sizeof(*priv));
priv->minor = p;
@@ -412,6 +415,7 @@ static int gpio_open(struct inode *inode, struct file *filp)
spin_unlock_irq(&gpio_lock);
}
+ unlock_kernel();
return 0;
}
diff --git a/arch/cris/arch-v32/drivers/mach-fs/gpio.c b/arch/cris/arch-v32/drivers/mach-fs/gpio.c
index 7863fd4efc2..fe1fde89388 100644
--- a/arch/cris/arch-v32/drivers/mach-fs/gpio.c
+++ b/arch/cris/arch-v32/drivers/mach-fs/gpio.c
@@ -22,6 +22,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
#include <asm/etraxgpio.h>
#include <hwregs/reg_map.h>
@@ -426,9 +427,10 @@ gpio_open(struct inode *inode, struct file *filp)
return -EINVAL;
priv = kmalloc(sizeof(struct gpio_private), GFP_KERNEL);
-
if (!priv)
return -ENOMEM;
+
+ lock_kernel();
memset(priv, 0, sizeof(*priv));
priv->minor = p;
@@ -449,6 +451,7 @@ gpio_open(struct inode *inode, struct file *filp)
alarmlist = priv;
spin_unlock_irq(&alarm_lock);
+ unlock_kernel();
return 0;
}
diff --git a/arch/cris/arch-v32/drivers/sync_serial.c b/arch/cris/arch-v32/drivers/sync_serial.c
index 47c377df6fb..d2a0fbf5341 100644
--- a/arch/cris/arch-v32/drivers/sync_serial.c
+++ b/arch/cris/arch-v32/drivers/sync_serial.c
@@ -14,6 +14,7 @@
#include <linux/major.h>
#include <linux/sched.h>
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/poll.h>
#include <linux/init.h>
@@ -429,23 +430,26 @@ static inline int sync_data_avail_to_end(struct sync_port *port)
static int sync_serial_open(struct inode *inode, struct file *file)
{
int dev = iminor(inode);
+ int ret = -EBUSY;
sync_port *port;
reg_dma_rw_cfg cfg = {.en = regk_dma_yes};
reg_dma_rw_intr_mask intr_mask = {.data = regk_dma_yes};
+ lock_kernel();
DEBUG(printk(KERN_DEBUG "Open sync serial port %d\n", dev));
if (dev < 0 || dev >= NBR_PORTS || !ports[dev].enabled)
{
DEBUG(printk(KERN_DEBUG "Invalid minor %d\n", dev));
- return -ENODEV;
+ ret = -ENODEV;
+ goto out;
}
port = &ports[dev];
/* Allow open this device twice (assuming one reader and one writer) */
if (port->busy == 2)
{
DEBUG(printk(KERN_DEBUG "Device is busy.. \n"));
- return -EBUSY;
+ goto out;
}
@@ -459,7 +463,7 @@ static int sync_serial_open(struct inode *inode, struct file *file)
"synchronous serial 0 dma tr",
&ports[0])) {
printk(KERN_CRIT "Can't allocate sync serial port 0 IRQ");
- return -EBUSY;
+ goto out;
} else if (request_irq(DMA_IN_INTR_VECT,
rx_interrupt,
0,
@@ -467,7 +471,7 @@ static int sync_serial_open(struct inode *inode, struct file *file)
&ports[0])) {
free_irq(DMA_OUT_INTR_VECT, &port[0]);
printk(KERN_CRIT "Can't allocate sync serial port 0 IRQ");
- return -EBUSY;
+ goto out;
} else if (crisv32_request_dma(OUT_DMA_NBR,
"synchronous serial 0 dma tr",
DMA_VERBOSE_ON_ERROR,
@@ -476,7 +480,7 @@ static int sync_serial_open(struct inode *inode, struct file *file)
free_irq(DMA_OUT_INTR_VECT, &port[0]);
free_irq(DMA_IN_INTR_VECT, &port[0]);
printk(KERN_CRIT "Can't allocate sync serial port 0 TX DMA channel");
- return -EBUSY;
+ goto out;
} else if (crisv32_request_dma(IN_DMA_NBR,
"synchronous serial 0 dma rec",
DMA_VERBOSE_ON_ERROR,
@@ -486,7 +490,7 @@ static int sync_serial_open(struct inode *inode, struct file *file)
free_irq(DMA_OUT_INTR_VECT, &port[0]);
free_irq(DMA_IN_INTR_VECT, &port[0]);
printk(KERN_CRIT "Can't allocate sync serial port 1 RX DMA channel");
- return -EBUSY;
+ goto out;
}
#endif
}
@@ -499,7 +503,7 @@ static int sync_serial_open(struct inode *inode, struct file *file)
"synchronous serial 1 dma tr",
&ports[1])) {
printk(KERN_CRIT "Can't allocate sync serial port 1 IRQ");
- return -EBUSY;
+ goto out;
} else if (request_irq(DMA7_INTR_VECT,
rx_interrupt,
0,
@@ -507,7 +511,7 @@ static int sync_serial_open(struct inode *inode, struct file *file)
&ports[1])) {
free_irq(DMA6_INTR_VECT, &ports[1]);
printk(KERN_CRIT "Can't allocate sync serial port 3 IRQ");
- return -EBUSY;
+ goto out;
} else if (crisv32_request_dma(
SYNC_SER1_TX_DMA_NBR,
"synchronous serial 1 dma tr",
@@ -517,7 +521,7 @@ static int sync_serial_open(struct inode *inode, struct file *file)
free_irq(DMA6_INTR_VECT, &ports[1]);
free_irq(DMA7_INTR_VECT, &ports[1]);
printk(KERN_CRIT "Can't allocate sync serial port 3 TX DMA channel");
- return -EBUSY;
+ goto out;
} else if (crisv32_request_dma(
SYNC_SER1_RX_DMA_NBR,
"synchronous serial 3 dma rec",
@@ -528,7 +532,7 @@ static int sync_serial_open(struct inode *inode, struct file *file)
free_irq(DMA6_INTR_VECT, &ports[1]);
free_irq(DMA7_INTR_VECT, &ports[1]);
printk(KERN_CRIT "Can't allocate sync serial port 3 RX DMA channel");
- return -EBUSY;
+ goto out;
}
#endif
}
@@ -554,7 +558,7 @@ static int sync_serial_open(struct inode *inode, struct file *file)
"synchronous serial manual irq",
&ports[0])) {
printk("Can't allocate sync serial manual irq");
- return -EBUSY;
+ goto out;
}
}
#ifdef CONFIG_ETRAXFS
@@ -565,7 +569,7 @@ static int sync_serial_open(struct inode *inode, struct file *file)
"synchronous serial manual irq",
&ports[1])) {
printk(KERN_CRIT "Can't allocate sync serial manual irq");
- return -EBUSY;
+ goto out;
}
}
#endif
@@ -578,7 +582,10 @@ static int sync_serial_open(struct inode *inode, struct file *file)
} /* port->init_irqs */
port->busy++;
- return 0;
+ ret = 0;
+out:
+ unlock_kernel();
+ return ret;
}
static int sync_serial_release(struct inode *inode, struct file *file)
diff --git a/arch/m68k/bvme6000/rtc.c b/arch/m68k/bvme6000/rtc.c
index a812d03879f..e8ac3f7d72d 100644
--- a/arch/m68k/bvme6000/rtc.c
+++ b/arch/m68k/bvme6000/rtc.c
@@ -10,6 +10,7 @@
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <linux/ioport.h>
#include <linux/capability.h>
#include <linux/fcntl.h>
@@ -140,10 +141,14 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
static int rtc_open(struct inode *inode, struct file *file)
{
- if(rtc_status)
+ lock_kernel();
+ if(rtc_status) {
+ unlock_kernel();
return -EBUSY;
+ }
rtc_status = 1;
+ unlock_kernel();
return 0;
}
diff --git a/arch/m68k/mvme16x/rtc.c b/arch/m68k/mvme16x/rtc.c
index e341387787a..432a9f13b2e 100644
--- a/arch/m68k/mvme16x/rtc.c
+++ b/arch/m68k/mvme16x/rtc.c
@@ -10,6 +10,7 @@
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <linux/ioport.h>
#include <linux/capability.h>
#include <linux/fcntl.h>
@@ -127,11 +128,14 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
static int rtc_open(struct inode *inode, struct file *file)
{
+ lock_kernel();
if( !atomic_dec_and_test(&rtc_ready) )
{
atomic_inc( &rtc_ready );
+ unlock_kernel();
return -EBUSY;
}
+ unlock_kernel();
return 0;
}
diff --git a/arch/mips/basler/excite/excite_iodev.c b/arch/mips/basler/excite/excite_iodev.c
index 476d20e08d0..a1e3526b4a9 100644
--- a/arch/mips/basler/excite/excite_iodev.c
+++ b/arch/mips/basler/excite/excite_iodev.c
@@ -26,6 +26,7 @@
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/miscdevice.h>
+#include <linux/smp_lock.h>
#include "excite_iodev.h"
@@ -110,8 +111,14 @@ static int __exit iodev_remove(struct device *dev)
static int iodev_open(struct inode *i, struct file *f)
{
- return request_irq(iodev_irq, iodev_irqhdl, IRQF_DISABLED,
+ int ret;
+
+ lock_kernel();
+ ret = request_irq(iodev_irq, iodev_irqhdl, IRQF_DISABLED,
iodev_name, &miscdev);
+ unlock_kernel();
+
+ return ret;
}
static int iodev_release(struct inode *i, struct file *f)
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c
index b88f1c18ff4..b5564196123 100644
--- a/arch/mips/kernel/rtlx.c
+++ b/arch/mips/kernel/rtlx.c
@@ -28,6 +28,7 @@
#include <linux/vmalloc.h>
#include <linux/elf.h>
#include <linux/seq_file.h>
+#include <linux/smp_lock.h>
#include <linux/syscalls.h>
#include <linux/moduleloader.h>
#include <linux/interrupt.h>
@@ -392,8 +393,12 @@ out:
static int file_open(struct inode *inode, struct file *filp)
{
int minor = iminor(inode);
+ int err;
- return rtlx_open(minor, (filp->f_flags & O_NONBLOCK) ? 0 : 1);
+ lock_kernel();
+ err = rtlx_open(minor, (filp->f_flags & O_NONBLOCK) ? 0 : 1);
+ unlock_kernel();
+ return err;
}
static int file_release(struct inode *inode, struct file *filp)
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index 2794501ff30..972b2d2b840 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -38,6 +38,7 @@
#include <linux/vmalloc.h>
#include <linux/elf.h>
#include <linux/seq_file.h>
+#include <linux/smp_lock.h>
#include <linux/syscalls.h>
#include <linux/moduleloader.h>
#include <linux/interrupt.h>
@@ -1050,17 +1051,20 @@ static int vpe_open(struct inode *inode, struct file *filp)
enum vpe_state state;
struct vpe_notifications *not;
struct vpe *v;
- int ret;
+ int ret, err = 0;
+ lock_kernel();
if (minor != iminor(inode)) {
/* assume only 1 device at the moment. */
printk(KERN_WARNING "VPE loader: only vpe1 is supported\n");
- return -ENODEV;
+ err = -ENODEV;
+ goto out;
}
if ((v = get_vpe(tclimit)) == NULL) {
printk(KERN_WARNING "VPE loader: unable to get vpe\n");
- return -ENODEV;
+ err = -ENODEV;
+ goto out;
}
state = xchg(&v->state, VPE_STATE_INUSE);
@@ -1100,6 +1104,8 @@ static int vpe_open(struct inode *inode, struct file *filp)
v->shared_ptr = NULL;
v->__start = 0;
+out:
+ unlock_kernel();
return 0;
}
diff --git a/arch/mips/sibyte/common/sb_tbprof.c b/arch/mips/sibyte/common/sb_tbprof.c
index 63b444eaf01..28b012ab8dc 100644
--- a/arch/mips/sibyte/common/sb_tbprof.c
+++ b/arch/mips/sibyte/common/sb_tbprof.c
@@ -28,6 +28,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <linux/vmalloc.h>
#include <linux/fs.h>
#include <linux/errno.h>
@@ -402,18 +403,26 @@ static int sbprof_zbprof_stop(void)
static int sbprof_tb_open(struct inode *inode, struct file *filp)
{
int minor;
+ int err = 0;
+ lock_kernel();
minor = iminor(inode);
- if (minor != 0)
- return -ENODEV;
+ if (minor != 0) {
+ err = -ENODEV;
+ goto out;
+ }
- if (xchg(&sbp.open, SB_OPENING) != SB_CLOSED)
- return -EBUSY;
+ if (xchg(&sbp.open, SB_OPENING) != SB_CLOSED) {
+ err = -EBUSY;
+ goto out;
+ }
memset(&sbp, 0, sizeof(struct sbprof_tb));
sbp.sbprof_tbbuf = vmalloc(MAX_TBSAMPLE_BYTES);
- if (!sbp.sbprof_tbbuf)
- return -ENOMEM;
+ if (!sbp.sbprof_tbbuf) {
+ err = -ENOMEM;
+ goto out;
+ }
memset(sbp.sbprof_tbbuf, 0, MAX_TBSAMPLE_BYTES);
init_waitqueue_head(&sbp.tb_sync);
init_waitqueue_head(&sbp.tb_read);
@@ -421,7 +430,9 @@ static int sbprof_tb_open(struct inode *inode, struct file *filp)
sbp.open = SB_OPEN;
- return 0;
+ out:
+ unlock_kernel();
+ return err;
}
static int sbprof_tb_release(struct inode *inode, struct file *filp)
diff --git a/arch/parisc/kernel/perf.c b/arch/parisc/kernel/perf.c
index 89d6d5ad44b..f696f57faa1 100644
--- a/arch/parisc/kernel/perf.c
+++ b/arch/parisc/kernel/perf.c
@@ -46,6 +46,7 @@
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/miscdevice.h>
+#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <asm/uaccess.h>
@@ -260,13 +261,16 @@ printk("Preparing to start counters\n");
*/
static int perf_open(struct inode *inode, struct file *file)
{
+ lock_kernel();
spin_lock(&perf_lock);
if (perf_enabled) {
spin_unlock(&perf_lock);
+ unlock_kernel();
return -EBUSY;
}
perf_enabled = 1;
spin_unlock(&perf_lock);
+ unlock_kernel();
return 0;
}
diff --git a/arch/s390/crypto/prng.c b/arch/s390/crypto/prng.c
index 6a4300b3ff5..eca724d229e 100644
--- a/arch/s390/crypto/prng.c
+++ b/arch/s390/crypto/prng.c
@@ -6,6 +6,7 @@
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/smp_lock.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
@@ -48,6 +49,7 @@ static unsigned char parm_block[32] = {
static int prng_open(struct inode *inode, struct file *file)
{
+ cycle_kernel_lock();
return nonseekable_open(inode, file);
}
diff --git a/arch/sh/boards/landisk/gio.c b/arch/sh/boards/landisk/gio.c
index 17025080db3..0c15b0a50b9 100644
--- a/arch/sh/boards/landisk/gio.c
+++ b/arch/sh/boards/landisk/gio.c
@@ -14,6 +14,7 @@
*/
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/smp_lock.h>
#include <linux/kdev_t.h>
#include <linux/cdev.h>
#include <linux/fs.h>
@@ -32,17 +33,20 @@ static int openCnt;
static int gio_open(struct inode *inode, struct file *filp)
{
int minor;
+ int ret = -ENOENT;
+ lock_kernel();
minor = MINOR(inode->i_rdev);
if (minor < DEVCOUNT) {
if (openCnt > 0) {
- return -EALREADY;
+ ret = -EALREADY;
} else {
openCnt++;
- return 0;
+ ret = 0;
}
}
- return -ENOENT;
+ unlock_kernel();
+ return ret;
}
static int gio_close(struct inode *inode, struct file *filp)
diff --git a/arch/sparc/kernel/apc.c b/arch/sparc/kernel/apc.c
index d06a405ca71..6707422c984 100644
--- a/arch/sparc/kernel/apc.c
+++ b/arch/sparc/kernel/apc.c
@@ -10,6 +10,7 @@
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
+#include <linux/smp_lock.h>
#include <linux/pm.h>
#include <asm/io.h>
@@ -75,6 +76,7 @@ static inline void apc_free(void)
static int apc_open(struct inode *inode, struct file *f)
{
+ cycle_kernel_lock();
return 0;
}
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index e5d238970c7..bedc4c159b1 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -11,6 +11,7 @@
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/string.h>
@@ -1659,10 +1660,14 @@ static int mini_rtc_ioctl(struct inode *inode, struct file *file,
static int mini_rtc_open(struct inode *inode, struct file *file)
{
- if (mini_rtc_status & RTC_IS_OPEN)
+ lock_kernel();
+ if (mini_rtc_status & RTC_IS_OPEN) {
+ unlock_kernel();
return -EBUSY;
+ }
mini_rtc_status |= RTC_IS_OPEN;
+ unlock_kernel();
return 0;
}
diff --git a/arch/um/drivers/harddog_kern.c b/arch/um/drivers/harddog_kern.c
index a9ad4bd6d95..d332503fa1b 100644
--- a/arch/um/drivers/harddog_kern.c
+++ b/arch/um/drivers/harddog_kern.c
@@ -66,6 +66,7 @@ static int harddog_open(struct inode *inode, struct file *file)
int err = -EBUSY;
char *sock = NULL;
+ lock_kernel();
spin_lock(&lock);
if(timer_alive)
goto err;
@@ -82,9 +83,11 @@ static int harddog_open(struct inode *inode, struct file *file)
timer_alive = 1;
spin_unlock(&lock);
+ unlock_kernel();
return nonseekable_open(inode, file);
err:
spin_unlock(&lock);
+ unlock_kernel();
return err;
}
diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
index 67b2f55a602..eb240323c40 100644
--- a/arch/um/drivers/mmapper_kern.c
+++ b/arch/um/drivers/mmapper_kern.c
@@ -16,6 +16,7 @@
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/mm.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include "mem_user.h"
@@ -77,6 +78,7 @@ out:
static int mmapper_open(struct inode *inode, struct file *file)
{
+ cycle_kernel_lock();
return 0;
}
diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c
index 4949044773b..6eabb7022a2 100644
--- a/arch/um/drivers/random.c
+++ b/arch/um/drivers/random.c
@@ -7,6 +7,7 @@
* of the GNU General Public License, incorporated herein by reference.
*/
#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
@@ -33,6 +34,8 @@ static DECLARE_WAIT_QUEUE_HEAD(host_read_wait);
static int rng_dev_open (struct inode *inode, struct file *filp)
{
+ cycle_kernel_lock();
+
/* enforce read-only access to this chrdev */
if ((filp->f_mode & FMODE_READ) == 0)
return -EINVAL;
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index 00e6d137095..75cb5da4ea0 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -204,6 +204,7 @@
#include <linux/module.h>
#include <linux/poll.h>
+#include <linux/smp_lock.h>
#include <linux/types.h>
#include <linux/stddef.h>
#include <linux/timer.h>
@@ -1549,10 +1550,12 @@ static int do_open(struct inode *inode, struct file *filp)
{
struct apm_user *as;
+ lock_kernel();
as = kmalloc(sizeof(*as), GFP_KERNEL);
if (as == NULL) {
printk(KERN_ERR "apm: cannot allocate struct of size %d bytes\n",
sizeof(*as));
+ unlock_kernel();
return -ENOMEM;
}
as->magic = APM_BIOS_MAGIC;
@@ -1574,6 +1577,7 @@ static int do_open(struct inode *inode, struct file *filp)
user_list = as;
spin_unlock(&user_list_lock);
filp->private_data = as;
+ unlock_kernel();
return 0;
}
diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c
index 501ca1cea27..98741074518 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_64.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_64.c
@@ -9,6 +9,7 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include <linux/string.h>
#include <linux/rcupdate.h>
#include <linux/kallsyms.h>
@@ -532,10 +533,12 @@ static int open_exclu; /* already open exclusive? */
static int mce_open(struct inode *inode, struct file *file)
{
+ lock_kernel();
spin_lock(&mce_state_lock);
if (open_exclu || (open_count && (file->f_flags & O_EXCL))) {
spin_unlock(&mce_state_lock);
+ unlock_kernel();
return -EBUSY;
}
@@ -544,6 +547,7 @@ static int mce_open(struct inode *inode, struct file *file)
open_count++;
spin_unlock(&mce_state_lock);
+ unlock_kernel();
return nonseekable_open(inode, file);
}
diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c
index daff52a6224..71f1c2654be 100644
--- a/arch/x86/kernel/cpuid.c
+++ b/arch/x86/kernel/cpuid.c
@@ -33,6 +33,7 @@
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/smp.h>
+#include <linux/smp_lock.h>
#include <linux/major.h>
#include <linux/fs.h>
#include <linux/smp_lock.h>
@@ -107,15 +108,23 @@ static ssize_t cpuid_read(struct file *file, char __user *buf,
static int cpuid_open(struct inode *inode, struct file *file)
{
- unsigned int cpu = iminor(file->f_path.dentry->d_inode);
- struct cpuinfo_x86 *c = &cpu_data(cpu);
-
- if (cpu >= NR_CPUS || !cpu_online(cpu))
- return -ENXIO; /* No such CPU */
+ unsigned int cpu;
+ struct cpuinfo_x86 *c;
+ int ret = 0;
+
+ lock_kernel();
+
+ cpu = iminor(file->f_path.dentry->d_inode);
+ if (cpu >= NR_CPUS || !cpu_online(cpu)) {
+ ret = -ENXIO; /* No such CPU */
+ goto out;
+ }
+ c = &cpu_data(cpu);
if (c->cpuid_level < 0)
- return -EIO; /* CPUID not supported */
-
- return 0;
+ ret = -EIO; /* CPUID not supported */
+out:
+ unlock_kernel();
+ return ret;
}
/*
diff --git a/arch/x86/kernel/microcode.c b/arch/x86/kernel/microcode.c
index 9758fea87c5..f47ba8156f3 100644
--- a/arch/x86/kernel/microcode.c
+++ b/arch/x86/kernel/microcode.c
@@ -76,6 +76,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include <linux/cpumask.h>
#include <linux/module.h>
#include <linux/slab.h>
@@ -423,6 +424,7 @@ out:
static int microcode_open (struct inode *unused1, struct file *unused2)
{
+ cycle_kernel_lock();
return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
}
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
index 1f3abe048e9..a153b3905f6 100644
--- a/arch/x86/kernel/msr.c
+++ b/arch/x86/kernel/msr.c
@@ -117,12 +117,20 @@ static int msr_open(struct inode *inode, struct file *file)
{
unsigned int cpu = iminor(file->f_path.dentry->d_inode);
struct cpuinfo_x86 *c = &cpu_data(cpu);
+ int ret = 0;
- if (cpu >= NR_CPUS || !cpu_online(cpu))
- return -ENXIO; /* No such CPU */
- if (!cpu_has(c, X86_FEATURE_MSR))
- return -EIO; /* MSR not supported */
+ lock_kernel();
+ cpu = iminor(file->f_path.dentry->d_inode);
+ if (cpu >= NR_CPUS || !cpu_online(cpu)) {
+ ret = -ENXIO; /* No such CPU */
+ goto out;
+ }
+ c = &cpu_data(cpu);
+ if (!cpu_has(c, X86_FEATURE_MSR))
+ ret = -EIO; /* MSR not supported */
+out:
+ unlock_kernel();
return 0;
}
diff --git a/block/bsg.c b/block/bsg.c
index 93e757d7174..0b3b282f038 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -19,6 +19,7 @@
#include <linux/uio.h>
#include <linux/idr.h>
#include <linux/bsg.h>
+#include <linux/smp_lock.h>
#include <scsi/scsi.h>
#include <scsi/scsi_ioctl.h>
@@ -851,7 +852,11 @@ static struct bsg_device *bsg_get_device(struct inode *inode, struct file *file)
static int bsg_open(struct inode *inode, struct file *file)
{
- struct bsg_device *bd = bsg_get_device(inode, file);
+ struct bsg_device *bd;
+
+ lock_kernel();
+ bd = bsg_get_device(inode, file);
+ unlock_kernel();
if (IS_ERR(bd))
return PTR_ERR(bd);
diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c
index e8e60e7a2e7..d1de68a3192 100644
--- a/drivers/block/aoe/aoechr.c
+++ b/drivers/block/aoe/aoechr.c
@@ -7,6 +7,7 @@
#include <linux/hdreg.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
+#include <linux/smp_lock.h>
#include "aoe.h"
enum {
@@ -174,12 +175,16 @@ aoechr_open(struct inode *inode, struct file *filp)
{
int n, i;
+ lock_kernel();
n = iminor(inode);
filp->private_data = (void *) (unsigned long) n;
for (i = 0; i < ARRAY_SIZE(chardevs); ++i)
- if (chardevs[i].minor == n)
+ if (chardevs[i].minor == n) {
+ unlock_kernel();
return 0;
+ }
+ unlock_kernel();
return -EINVAL;
}
diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c
index ab86e23ddc6..9d92636350e 100644
--- a/drivers/block/paride/pg.c
+++ b/drivers/block/paride/pg.c
@@ -162,6 +162,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_DLY};
#include <linux/pg.h>
#include <linux/device.h>
#include <linux/sched.h> /* current, TASK_* */
+#include <linux/smp_lock.h>
#include <linux/jiffies.h>
#include <asm/uaccess.h>
@@ -515,12 +516,18 @@ static int pg_open(struct inode *inode, struct file *file)
{
int unit = iminor(inode) & 0x7f;
struct pg *dev = &devices[unit];
+ int ret = 0;
- if ((unit >= PG_UNITS) || (!dev->present))
- return -ENODEV;
+ lock_kernel();
+ if ((unit >= PG_UNITS) || (!dev->present)) {
+ ret = -ENODEV;
+ goto out;
+ }
- if (test_and_set_bit(0, &dev->access))
- return -EBUSY;
+ if (test_and_set_bit(0, &dev->access)) {
+ ret = -EBUSY;
+ goto out;
+ }
if (dev->busy) {
pg_reset(dev);
@@ -533,12 +540,15 @@ static int pg_open(struct inode *inode, struct file *file)
if (dev->bufptr == NULL) {
clear_bit(0, &dev->access);
printk("%s: buffer allocation failed\n", dev->name);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto out;
}
file->private_data = dev;
- return 0;
+out:
+ unlock_kernel();
+ return ret;
}
static int pg_release(struct inode *inode, struct file *file)
diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c
index 27455ee1e9d..5c74c3574a5 100644
--- a/drivers/block/paride/pt.c
+++ b/drivers/block/paride/pt.c
@@ -650,8 +650,11 @@ static int pt_open(struct inode *inode, struct file *file)
struct pt_unit *tape = pt + unit;
int err;
- if (unit >= PT_UNITS || (!tape->present))
+ lock_kernel();
+ if (unit >= PT_UNITS || (!tape->present)) {
+ unlock_kernel();
return -ENODEV;
+ }
err = -EBUSY;
if (!atomic_dec_and_test(&tape->available))
@@ -678,10 +681,12 @@ static int pt_open(struct inode *inode, struct file *file)
}
file->private_data = tape;
+ unlock_kernel();
return 0;
out:
atomic_inc(&tape->available);
+ unlock_kernel();
return err;
}
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
index 0638730a4a1..d97700aa54a 100644
--- a/drivers/bluetooth/hci_vhci.c
+++ b/drivers/bluetooth/hci_vhci.c
@@ -28,6 +28,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/sched.h>
@@ -263,9 +264,11 @@ static int vhci_open(struct inode *inode, struct file *file)
skb_queue_head_init(&data->readq);
init_waitqueue_head(&data->read_wait);
+ lock_kernel();
hdev = hci_alloc_dev();
if (!hdev) {
kfree(data);
+ unlock_kernel();
return -ENOMEM;
}
@@ -286,10 +289,12 @@ static int vhci_open(struct inode *inode, struct file *file)
BT_ERR("Can't register HCI device");
kfree(data);
hci_free_dev(hdev);
+ unlock_kernel();
return -EBUSY;
}
file->private_data = data;
+ unlock_kernel();
return nonseekable_open(inode, file);
}
@@ -313,18 +318,21 @@ static int vhci_release(struct inode *inode, struct file *file)
static int vhci_fasync(int fd, struct file *file, int on)
{
struct vhci_data *data = file->private_data;
- int err;
+ int err = 0;
+ lock_kernel();
err = fasync_helper(fd, file, on, &data->fasync);
if (err < 0)
- return err;
+ goto out;
if (on)
data->flags |= VHCI_FASYNC;
else
data->flags &= ~VHCI_FASYNC;
- return 0;
+out:
+ unlock_kernel();
+ return err;
}
static const struct file_operations vhci_fops = {
diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c
index e6cb1ab03e0..a96f3197e60 100644
--- a/drivers/char/agp/frontend.c
+++ b/drivers/char/agp/frontend.c
@@ -39,6 +39,7 @@
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include "agp.h"
@@ -677,6 +678,7 @@ static int agp_open(struct inode *inode, struct file *file)
struct agp_client *client;
int rc = -ENXIO;
+ lock_kernel();
mutex_lock(&(agp_fe.agp_mutex));
if (minor != AGPGART_MINOR)
@@ -703,12 +705,14 @@ static int agp_open(struct inode *inode, struct file *file)
agp_insert_file_private(priv);
DBG("private=%p, client=%p", priv, client);
mutex_unlock(&(agp_fe.agp_mutex));
+ unlock_kernel();
return 0;
err_out_nomem:
rc = -ENOMEM;
err_out:
mutex_unlock(&(agp_fe.agp_mutex));
+ unlock_kernel();
return rc;
}
diff --git a/drivers/char/apm-emulation.c b/drivers/char/apm-emulation.c
index cdd876dbb2b..da8a1658a27 100644
--- a/drivers/char/apm-emulation.c
+++ b/drivers/char/apm-emulation.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/poll.h>
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/miscdevice.h>
@@ -416,6 +417,7 @@ static int apm_open(struct inode * inode, struct file * filp)
{
struct apm_user *as;
+ lock_kernel();
as = kzalloc(sizeof(*as), GFP_KERNEL);
if (as) {
/*
@@ -435,6 +437,7 @@ static int apm_open(struct inode * inode, struct file * filp)
filp->private_data = as;
}
+ unlock_kernel();
return as ? 0 : -ENOMEM;
}
diff --git a/drivers/char/briq_panel.c b/drivers/char/briq_panel.c
index b6f2639f903..d8cff909001 100644
--- a/drivers/char/briq_panel.c
+++ b/drivers/char/briq_panel.c
@@ -6,6 +6,7 @@
#include <linux/module.h>
+#include <linux/smp_lock.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/tty.h>
@@ -67,11 +68,15 @@ static void set_led(char state)
static int briq_panel_open(struct inode *ino, struct file *filep)
{
- /* enforce single access */
- if (vfd_is_open)
+ lock_kernel();
+ /* enforce single access, vfd_is_open is protected by BKL */
+ if (vfd_is_open) {
+ unlock_kernel();
return -EBUSY;
+ }
vfd_is_open = 1;
+ unlock_kernel();
return 0;
}
diff --git a/drivers/char/cs5535_gpio.c b/drivers/char/cs5535_gpio.c
index c0a4a0bb509..04ba906b488 100644
--- a/drivers/char/cs5535_gpio.c
+++ b/drivers/char/cs5535_gpio.c
@@ -17,6 +17,7 @@
#include <linux/cdev.h>
#include <linux/ioport.h>
#include <linux/pci.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -157,6 +158,7 @@ static int cs5535_gpio_open(struct inode *inode, struct file *file)
{
u32 m = iminor(inode);
+ cycle_kernel_lock();
/* the mask says which pins are usable by this driver */
if ((mask & (1 << m)) == 0)
return -EINVAL;
diff --git a/drivers/char/ds1286.c b/drivers/char/ds1286.c
index ea35ab2c990..fb584938c9c 100644
--- a/drivers/char/ds1286.c
+++ b/drivers/char/ds1286.c
@@ -27,6 +27,7 @@
* option) any later version.
*/
#include <linux/ds1286.h>
+#include <linux/smp_lock.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
@@ -252,6 +253,7 @@ static int ds1286_ioctl(struct inode *inode, struct file *file,
static int ds1286_open(struct inode *inode, struct file *file)
{
+ lock_kernel();
spin_lock_irq(&ds1286_lock);
if (ds1286_status & RTC_IS_OPEN)
@@ -260,10 +262,12 @@ static int ds1286_open(struct inode *inode, struct file *file)
ds1286_status |= RTC_IS_OPEN;
spin_unlock_irq(&ds1286_lock);
+ unlock_kernel();
return 0;
out_busy:
spin_lock_irq(&ds1286_lock);
+ unlock_kernel();
return -EBUSY;
}
diff --git a/drivers/char/ds1620.c b/drivers/char/ds1620.c
index 334ad5bbe6b..34275c6f1da 100644
--- a/drivers/char/ds1620.c
+++ b/drivers/char/ds1620.c
@@ -8,6 +8,7 @@
#include <linux/proc_fs.h>
#include <linux/capability.h>
#include <linux/init.h>
+#include <linux/smp_lock.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
@@ -208,6 +209,12 @@ static void ds1620_read_state(struct therm *therm)
therm->hi = cvt_9_to_int(ds1620_in(THERM_READ_TH, 9));
}
+static int ds1620_open(struct inode *inode, struct file *file)
+{
+ cycle_kernel_lock();
+ return nonseekable_open(inode, file);
+}
+
static ssize_t
ds1620_read(struct file *file, char __user *buf, size_t count, loff_t *ptr)
{
@@ -336,7 +343,7 @@ static struct proc_dir_entry *proc_therm_ds1620;
static const struct file_operations ds1620_fops = {
.owner = THIS_MODULE,
- .open = nonseekable_open,
+ .open = ds1620_open,
.read = ds1620_read,
.ioctl = ds1620_ioctl,
};
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c
index a69c6528326..7bf7485377e 100644
--- a/drivers/char/dsp56k.c
+++ b/drivers/char/dsp56k.c
@@ -33,6 +33,7 @@
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/device.h>
+#include <linux/smp_lock.h>
#include <asm/atarihw.h>
#include <asm/traps.h>
@@ -436,13 +437,17 @@ static unsigned int dsp56k_poll(struct file *file, poll_table *wait)
static int dsp56k_open(struct inode *inode, struct file *file)
{
int dev = iminor(inode) & 0x0f;
+ int ret = 0;
+ lock_kernel();
switch(dev)
{
case DSP56K_DEV_56001:
- if (test_and_set_bit(0, &dsp56k.in_use))
- return -EBUSY;
+ if (test_and_set_bit(0, &dsp56k.in_use)) {
+ ret = -EBUSY;
+ goto out;
+ }
dsp56k.timeout = TIMEOUT;
dsp56k.maxio = MAXIO;
@@ -458,10 +463,11 @@ static int dsp56k_open(struct inode *inode, struct file *file)
break;
default:
- return -ENODEV;
+ ret = -ENODEV;
}
-
- return 0;
+out:
+ unlock_kernel();
+ return ret;
}
static int dsp56k_release(struct inode *inode, struct file *file)
diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c
index abde6ddefe6..6b900b297cc 100644
--- a/drivers/char/dtlk.c
+++ b/drivers/char/dtlk.c
@@ -56,6 +56,7 @@
#include <linux/errno.h> /* for -EBUSY */
#include <linux/ioport.h> /* for request_region */
#include <linux/delay.h> /* for loops_per_jiffy */
+#include <linux/smp_lock.h> /* cycle_kernel_lock() */
#include <asm/io.h> /* for inb_p, outb_p, inb, outb, etc. */
#include <asm/uaccess.h> /* for get_user, etc. */
#include <linux/wait.h> /* for wait_queue */
@@ -288,10 +289,12 @@ static int dtlk_ioctl(struct inode *inode,
}
}
+/* Note that nobody ever sets dtlk_busy... */
static int dtlk_open(struct inode *inode, struct file *file)
{
TRACE_TEXT("(dtlk_open");
+ cycle_kernel_lock();
nonseekable_open(inode, file);
switch (iminor(inode)) {
case DTLK_MINOR:
diff --git a/drivers/char/efirtc.c b/drivers/char/efirtc.c
index 49233f58987..d57ca3e4e53 100644
--- a/drivers/char/efirtc.c
+++ b/drivers/char/efirtc.c
@@ -28,6 +28,7 @@
*/
+#include <linux/smp_lock.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
@@ -272,6 +273,7 @@ efi_rtc_open(struct inode *inode, struct file *file)
* We do accept multiple open files at the same time as we
* synchronize on the per call operation.
*/
+ cycle_kernel_lock();
return 0;
}
diff --git a/drivers/char/genrtc.c b/drivers/char/genrtc.c
index 69f0a2993af..aac0985a572 100644
--- a/drivers/char/genrtc.c
+++ b/drivers/char/genrtc.c
@@ -51,6 +51,7 @@
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/proc_fs.h>
+#include <linux/smp_lock.h>
#include <linux/workqueue.h>
#include <asm/uaccess.h>
@@ -338,12 +339,16 @@ static int gen_rtc_ioctl(struct inode *inode, struct file *file,
static int gen_rtc_open(struct inode *inode, struct file *file)
{
- if (gen_rtc_status & RTC_IS_OPEN)
+ lock_kernel();
+ if (gen_rtc_status & RTC_IS_OPEN) {
+ unlock_kernel();
return -EBUSY;
+ }
gen_rtc_status |= RTC_IS_OPEN;
gen_rtc_irq_data = 0;
irq_active = 0;
+ unlock_kernel();
return 0;
}
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index e7fb0bca366..fb0a85a1eb3 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -14,6 +14,7 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/smp_lock.h>
#include <linux/types.h>
#include <linux/miscdevice.h>
#include <linux/major.h>
@@ -193,6 +194,7 @@ static int hpet_open(struct inode *inode, struct file *file)
if (file->f_mode & FMODE_WRITE)
return -EINVAL;
+ lock_kernel();
spin_lock_irq(&hpet_lock);
for (devp = NULL, hpetp = hpets; hpetp && !devp; hpetp = hpetp->hp_next)
@@ -207,6 +209,7 @@ static int hpet_open(struct inode *inode, struct file *file)
if (!devp) {
spin_unlock_irq(&hpet_lock);
+ unlock_kernel();
return -EBUSY;
}
@@ -214,6 +217,7 @@ static int hpet_open(struct inode *inode, struct file *file)
devp->hd_irqdata = 0;
devp->hd_flags |= HPET_OPEN;
spin_unlock_irq(&hpet_lock);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index 662d60e44e9..e5d583c84e4 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -37,6 +37,7 @@
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
@@ -86,6 +87,7 @@ static int rng_dev_open(struct inode *inode, struct file *filp)
return -EINVAL;
if (filp->f_mode & FMODE_WRITE)
return -EINVAL;
+ cycle_kernel_lock();
return 0;
}
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c
index c12cf8fc4be..61b6fe4156b 100644
--- a/drivers/char/ip2/ip2main.c
+++ b/drivers/char/ip2/ip2main.c
@@ -98,6 +98,7 @@
#include <linux/major.h>
#include <linux/wait.h>
#include <linux/device.h>
+#include <linux/smp_lock.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
@@ -2908,42 +2909,11 @@ ip2_ipl_ioctl ( struct inode *pInode, struct file *pFile, UINT cmd, ULONG arg )
static int
ip2_ipl_open( struct inode *pInode, struct file *pFile )
{
- unsigned int iplminor = iminor(pInode);
- i2eBordStrPtr pB;
- i2ChanStrPtr pCh;
#ifdef IP2DEBUG_IPL
printk (KERN_DEBUG "IP2IPL: open\n" );
#endif
-
- switch(iplminor) {
- // These are the IPL devices
- case 0:
- case 4:
- case 8:
- case 12:
- break;
-
- // These are the status devices
- case 1:
- case 5:
- case 9:
- case 13:
- break;
-
- // These are the debug devices
- case 2:
- case 6:
- case 10:
- case 14:
- pB = i2BoardPtrTable[iplminor / 4];
- pCh = (i2ChanStrPtr) pB->i2eChannelPtr;
- break;
-
- // This is the trace device
- case 3:
- break;
- }
+ cycle_kernel_lock();
return 0;
}
diff --git a/drivers/char/ip27-rtc.c b/drivers/char/ip27-rtc.c
index 86e6538a77b..ec9d0443d92 100644
--- a/drivers/char/ip27-rtc.c
+++ b/drivers/char/ip27-rtc.c
@@ -27,6 +27,7 @@
#include <linux/bcd.h>
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/smp_lock.h>
#include <linux/types.h>
#include <linux/miscdevice.h>
#include <linux/ioport.h>
@@ -163,15 +164,18 @@ static long rtc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
static int rtc_open(struct inode *inode, struct file *file)
{
+ lock_kernel();
spin_lock_irq(&rtc_lock);
if (rtc_status & RTC_IS_OPEN) {
spin_unlock_irq(&rtc_lock);
+ unlock_kernel();
return -EBUSY;
}
rtc_status |= RTC_IS_OPEN;
spin_unlock_irq(&rtc_lock);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index 0246a2b8ce4..c11a4048345 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -43,6 +43,7 @@
#include <linux/init.h>
#include <linux/device.h>
#include <linux/compat.h>
+#include <linux/smp_lock.h>
struct ipmi_file_private
{
@@ -100,7 +101,9 @@ static int ipmi_fasync(int fd, struct file *file, int on)
struct ipmi_file_private *priv = file->private_data;
int result;
+ lock_kernel(); /* could race against open() otherwise */
result = fasync_helper(fd, file, on, &priv->fasync_queue);
+ unlock_kernel();
return (result);
}
@@ -121,6 +124,7 @@ static int ipmi_open(struct inode *inode, struct file *file)
if (!priv)
return -ENOMEM;
+ lock_kernel();
priv->file = file;
rv = ipmi_create_user(if_num,
@@ -129,7 +133,7 @@ static int ipmi_open(struct inode *inode, struct file *file)
&(priv->user));
if (rv) {
kfree(priv);
- return rv;
+ goto out;
}
file->private_data = priv;
@@ -144,7 +148,9 @@ static int ipmi_open(struct inode *inode, struct file *file)
priv->default_retries = -1;
priv->default_retry_time_ms = 0;
- return 0;
+out:
+ unlock_kernel();
+ return rv;
}
static int ipmi_release(struct inode *inode, struct file *file)
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index 0e6df289cb4..235fab0bdf7 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -35,6 +35,7 @@
#include <linux/moduleparam.h>
#include <linux/ipmi.h>
#include <linux/ipmi_smi.h>
+#include <linux/smp_lock.h>
#include <linux/watchdog.h>
#include <linux/miscdevice.h>
#include <linux/init.h>
@@ -818,6 +819,8 @@ static int ipmi_open(struct inode *ino, struct file *filep)
if (test_and_set_bit(0, &ipmi_wdog_open))
return -EBUSY;
+ cycle_kernel_lock();
+
/*
* Don't start the timer now, let it start on the
* first heartbeat.
diff --git a/drivers/char/lcd.c b/drivers/char/lcd.c
index 4fe9206f84d..1c29b20e4f4 100644
--- a/drivers/char/lcd.c
+++ b/drivers/char/lcd.c
@@ -20,6 +20,7 @@
#include <linux/mc146818rtc.h>
#include <linux/netdevice.h>
#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <asm/io.h>
@@ -414,6 +415,8 @@ static int lcd_ioctl(struct inode *inode, struct file *file,
static int lcd_open(struct inode *inode, struct file *file)
{
+ cycle_kernel_lock();
+
if (!lcd_present)
return -ENXIO;
else
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index 60ac642752b..71abb4c33aa 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -126,6 +126,7 @@
#include <linux/device.h>
#include <linux/wait.h>
#include <linux/jiffies.h>
+#include <linux/smp_lock.h>
#include <linux/parport.h>
#undef LP_STATS
@@ -489,14 +490,21 @@ static ssize_t lp_read(struct file * file, char __user * buf,
static int lp_open(struct inode * inode, struct file * file)
{
unsigned int minor = iminor(inode);
+ int ret = 0;
- if (minor >= LP_NO)
- return -ENXIO;
- if ((LP_F(minor) & LP_EXIST) == 0)
- return -ENXIO;
- if (test_and_set_bit(LP_BUSY_BIT_POS, &LP_F(minor)))
- return -EBUSY;
-
+ lock_kernel();
+ if (minor >= LP_NO) {
+ ret = -ENXIO;
+ goto out;
+ }
+ if ((LP_F(minor) & LP_EXIST) == 0) {
+ ret = -ENXIO;
+ goto out;
+ }
+ if (test_and_set_bit(LP_BUSY_BIT_POS, &LP_F(minor))) {
+ ret = -EBUSY;
+ goto out;
+ }
/* If ABORTOPEN is set and the printer is offline or out of paper,
we may still want to open it to perform ioctl()s. Therefore we
have commandeered O_NONBLOCK, even though it is being used in
@@ -510,21 +518,25 @@ static int lp_open(struct inode * inode, struct file * file)
if (status & LP_POUTPA) {
printk(KERN_INFO "lp%d out of paper\n", minor);
LP_F(minor) &= ~LP_BUSY;
- return -ENOSPC;
+ ret = -ENOSPC;
+ goto out;
} else if (!(status & LP_PSELECD)) {
printk(KERN_INFO "lp%d off-line\n", minor);
LP_F(minor) &= ~LP_BUSY;
- return -EIO;
+ ret = -EIO;
+ goto out;
} else if (!(status & LP_PERRORP)) {
printk(KERN_ERR "lp%d printer error\n", minor);
LP_F(minor) &= ~LP_BUSY;
- return -EIO;
+ ret = -EIO;
+ goto out;
}
}
lp_table[minor].lp_buffer = kmalloc(LP_BUFFER_SIZE, GFP_KERNEL);
if (!lp_table[minor].lp_buffer) {
LP_F(minor) &= ~LP_BUSY;
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto out;
}
/* Determine if the peripheral supports ECP mode */
lp_claim_parport_or_block (&lp_table[minor]);
@@ -540,7 +552,9 @@ static int lp_open(struct inode * inode, struct file * file)
parport_negotiate (lp_table[minor].dev->port, IEEE1284_MODE_COMPAT);
lp_release_parport (&lp_table[minor]);
lp_table[minor].current_mode = IEEE1284_MODE_COMPAT;
- return 0;
+out:
+ unlock_kernel();
+ return ret;
}
static int lp_release(struct inode * inode, struct file * file)
diff --git a/drivers/char/mbcs.c b/drivers/char/mbcs.c
index f4716ad7348..acd8e9ed474 100644
--- a/drivers/char/mbcs.c
+++ b/drivers/char/mbcs.c
@@ -24,6 +24,7 @@
#include <linux/mm.h>
#include <linux/uio.h>
#include <linux/mutex.h>
+#include <linux/smp_lock.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/system.h>
@@ -382,15 +383,19 @@ static int mbcs_open(struct inode *ip, struct file *fp)
struct mbcs_soft *soft;
int minor;
+ lock_kernel();
minor = iminor(ip);
+ /* Nothing protects access to this list... */
list_for_each_entry(soft, &soft_list, list) {
if (soft->nasid == minor) {
fp->private_data = soft->cxdev;
+ unlock_kernel();
return 0;
}
}
+ unlock_kernel();
return -ENODEV;
}
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 934ffafedae..070e22e8ea9 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -26,6 +26,7 @@
#include <linux/bootmem.h>
#include <linux/splice.h>
#include <linux/pfn.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -889,6 +890,9 @@ static const struct file_operations kmsg_fops = {
static int memory_open(struct inode * inode, struct file * filp)
{
+ int ret = 0;
+
+ lock_kernel();
switch (iminor(inode)) {
case 1:
filp->f_op = &mem_fops;
@@ -932,11 +936,13 @@ static int memory_open(struct inode * inode, struct file * filp)
break;
#endif
default:
+ unlock_kernel();
return -ENXIO;
}
if (filp->f_op && filp->f_op->open)
- return filp->f_op->open(inode,filp);
- return 0;
+ ret = filp->f_op->open(inode,filp);
+ unlock_kernel();
+ return ret;
}
static const struct file_operations memory_fops = {
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index eaace0db0ff..6e1563c3d30 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -49,6 +49,7 @@
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kmod.h>
+#include <linux/smp_lock.h>
/*
* Head entry for the doubly linked miscdevice list
@@ -118,6 +119,7 @@ static int misc_open(struct inode * inode, struct file * file)
int err = -ENODEV;
const struct file_operations *old_fops, *new_fops = NULL;
+ lock_kernel();
mutex_lock(&misc_mtx);
list_for_each_entry(c, &misc_list, list) {
@@ -155,6 +157,7 @@ static int misc_open(struct inode * inode, struct file * file)
fops_put(old_fops);
fail:
mutex_unlock(&misc_mtx);
+ unlock_kernel();
return err;
}
diff --git a/drivers/char/mwave/mwavedd.c b/drivers/char/mwave/mwavedd.c
index 8d14823b051..50243fcd87e 100644
--- a/drivers/char/mwave/mwavedd.c
+++ b/drivers/char/mwave/mwavedd.c
@@ -56,6 +56,7 @@
#include <linux/serial.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <linux/serial_8250.h>
#include "smapi.h"
@@ -100,6 +101,7 @@ static int mwave_open(struct inode *inode, struct file *file)
PRINTK_2(TRACE_MWAVE,
"mwavedd::mwave_open, exit return retval %x\n", retval);
+ cycle_kernel_lock();
return retval;
}
diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c
index 98dec380af4..197cd7a0c33 100644
--- a/drivers/char/nvram.c
+++ b/drivers/char/nvram.c
@@ -107,6 +107,7 @@
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -333,12 +334,14 @@ nvram_ioctl(struct inode *inode, struct file *file,
static int
nvram_open(struct inode *inode, struct file *file)
{
+ lock_kernel();
spin_lock(&nvram_state_lock);
if ((nvram_open_cnt && (file->f_flags & O_EXCL)) ||
(nvram_open_mode & NVRAM_EXCL) ||
((file->f_mode & 2) && (nvram_open_mode & NVRAM_WRITE))) {
spin_unlock(&nvram_state_lock);
+ unlock_kernel();
return -EBUSY;
}
@@ -349,6 +352,7 @@ nvram_open(struct inode *inode, struct file *file)
nvram_open_cnt++;
spin_unlock(&nvram_state_lock);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/char/pc8736x_gpio.c b/drivers/char/pc8736x_gpio.c
index ecfaf180e5b..b930de50407 100644
--- a/drivers/char/pc8736x_gpio.c
+++ b/drivers/char/pc8736x_gpio.c
@@ -20,6 +20,7 @@
#include <linux/mutex.h>
#include <linux/nsc_gpio.h>
#include <linux/platform_device.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#define DEVNAME "pc8736x_gpio"
@@ -217,6 +218,7 @@ static int pc8736x_gpio_open(struct inode *inode, struct file *file)
unsigned m = iminor(inode);
file->private_data = &pc8736x_gpio_ops;
+ cycle_kernel_lock();
dev_dbg(&pdev->dev, "open %d\n", m);
if (m >= PC8736X_GPIO_CT)
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
index 3aab837d948..f6e6acadd9a 100644
--- a/drivers/char/ppdev.c
+++ b/drivers/char/ppdev.c
@@ -66,6 +66,7 @@
#include <linux/poll.h>
#include <linux/major.h>
#include <linux/ppdev.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#define PP_VERSION "ppdev: user-space parallel port driver"
@@ -638,6 +639,7 @@ static int pp_open (struct inode * inode, struct file * file)
unsigned int minor = iminor(inode);
struct pp_struct *pp;
+ cycle_kernel_lock();
if (minor >= PARPORT_MAX)
return -ENXIO;
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index bbfa0e241cb..505fcbe884a 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -19,6 +19,7 @@
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/mutex.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
@@ -53,6 +54,7 @@ static int raw_open(struct inode *inode, struct file *filp)
return 0;
}
+ lock_kernel();
mutex_lock(&raw_mutex);
/*
@@ -79,6 +81,7 @@ static int raw_open(struct inode *inode, struct file *filp)
bdev->bd_inode->i_mapping;
filp->private_data = bdev;
mutex_unlock(&raw_mutex);
+ unlock_kernel();
return 0;
out2:
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index 909cac93fa2..fa92a8af5a5 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -73,6 +73,7 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
#include <linux/sysctl.h>
#include <linux/wait.h>
#include <linux/bcd.h>
@@ -734,6 +735,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
* needed here. Or anywhere else in this driver. */
static int rtc_open(struct inode *inode, struct file *file)
{
+ lock_kernel();
spin_lock_irq(&rtc_lock);
if (rtc_status & RTC_IS_OPEN)
@@ -743,10 +745,12 @@ static int rtc_open(struct inode *inode, struct file *file)
rtc_irq_data = 0;
spin_unlock_irq(&rtc_lock);
+ unlock_kernel();
return 0;
out_busy:
spin_unlock_irq(&rtc_lock);
+ unlock_kernel();
return -EBUSY;
}
diff --git a/drivers/char/scx200_gpio.c b/drivers/char/scx200_gpio.c
index 99e5272e3c5..1d9100561c8 100644
--- a/drivers/char/scx200_gpio.c
+++ b/drivers/char/scx200_gpio.c
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -51,6 +52,7 @@ static int scx200_gpio_open(struct inode *inode, struct file *file)
unsigned m = iminor(inode);
file->private_data = &scx200_gpio_ops;
+ cycle_kernel_lock();
if (m >= MAX_PINS)
return -EINVAL;
return nonseekable_open(inode, file);
diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c
index 8fe099a4106..0b799ac1b04 100644
--- a/drivers/char/snsc.c
+++ b/drivers/char/snsc.c
@@ -21,6 +21,7 @@
#include <linux/poll.h>
#include <linux/module.h>
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <asm/sn/io.h>
#include <asm/sn/sn_sal.h>
#include <asm/sn/module.h>
@@ -104,6 +105,7 @@ scdrv_open(struct inode *inode, struct file *file)
file->private_data = sd;
/* hook this subchannel up to the system controller interrupt */
+ lock_kernel();
rv = request_irq(SGI_UART_VECTOR, scdrv_interrupt,
IRQF_SHARED | IRQF_DISABLED,
SYSCTL_BASENAME, sd);
@@ -111,9 +113,10 @@ scdrv_open(struct inode *inode, struct file *file)
ia64_sn_irtr_close(sd->sd_nasid, sd->sd_subch);
kfree(sd);
printk("%s: irq request failed (%d)\n", __func__, rv);
+ unlock_kernel();
return -EBUSY;
}
-
+ unlock_kernel();
return 0;
}
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index 58533de5902..85e0eb76eea 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -49,6 +49,7 @@
#include <linux/err.h>
#include <linux/kfifo.h>
#include <linux/platform_device.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -906,12 +907,14 @@ static int sonypi_misc_release(struct inode *inode, struct file *file)
static int sonypi_misc_open(struct inode *inode, struct file *file)
{
+ lock_kernel();
mutex_lock(&sonypi_device.lock);
/* Flush input queue on first open */
if (!sonypi_device.open_count)
kfifo_reset(sonypi_device.fifo);
sonypi_device.open_count++;
mutex_unlock(&sonypi_device.lock);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/char/tb0219.c b/drivers/char/tb0219.c
index 4c431cb7cf1..6062b62800f 100644
--- a/drivers/char/tb0219.c
+++ b/drivers/char/tb0219.c
@@ -21,6 +21,7 @@
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/smp_lock.h>
#include <asm/io.h>
#include <asm/reboot.h>
@@ -236,6 +237,7 @@ static int tanbac_tb0219_open(struct inode *inode, struct file *file)
{
unsigned int minor;
+ cycle_kernel_lock();
minor = iminor(inode);
switch (minor) {
case 0:
diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c
index 35e58030d29..8f2284be68e 100644
--- a/drivers/char/tlclk.c
+++ b/drivers/char/tlclk.c
@@ -36,6 +36,7 @@
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
#include <linux/timer.h>
#include <linux/sysfs.h>
#include <linux/device.h>
@@ -204,11 +205,14 @@ static int tlclk_open(struct inode *inode, struct file *filp)
{
int result;
- if (test_and_set_bit(0, &useflags))
- return -EBUSY;
+ lock_kernel();
+ if (test_and_set_bit(0, &useflags)) {
+ result = -EBUSY;
/* this legacy device is always one per system and it doesn't
* know how to handle multiple concurrent clients.
*/
+ goto out;
+ }
/* Make sure there is no interrupt pending while
* initialising interrupt handler */
@@ -218,13 +222,14 @@ static int tlclk_open(struct inode *inode, struct file *filp)
* we can't share this IRQ */
result = request_irq(telclk_interrupt, &tlclk_interrupt,
IRQF_DISABLED, "telco_clock", tlclk_interrupt);
- if (result == -EBUSY) {
+ if (result == -EBUSY)
printk(KERN_ERR "tlclk: Interrupt can't be reserved.\n");
- return -EBUSY;
- }
- inb(TLCLK_REG6); /* Clear interrupt events */
+ else
+ inb(TLCLK_REG6); /* Clear interrupt events */
- return 0;
+out:
+ unlock_kernel();
+ return result;
}
static int tlclk_release(struct inode *inode, struct file *filp)
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index a5d8bcb4000..e1fc193d939 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -26,6 +26,7 @@
#include <linux/poll.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
#include "tpm.h"
@@ -897,6 +898,7 @@ int tpm_open(struct inode *inode, struct file *file)
int rc = 0, minor = iminor(inode);
struct tpm_chip *chip = NULL, *pos;
+ lock_kernel();
spin_lock(&driver_lock);
list_for_each_entry(pos, &tpm_chip_list, list) {
@@ -926,16 +928,19 @@ int tpm_open(struct inode *inode, struct file *file)
if (chip->data_buffer == NULL) {
chip->num_opens--;
put_device(chip->dev);
+ unlock_kernel();
return -ENOMEM;
}
atomic_set(&chip->data_pending, 0);
file->private_data = chip;
+ unlock_kernel();
return 0;
err_out:
spin_unlock(&driver_lock);
+ unlock_kernel();
return rc;
}
EXPORT_SYMBOL_GPL(tpm_open);
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 750131010af..047a17339f8 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -2665,7 +2665,7 @@ static void release_dev(struct file *filp)
* ->siglock protects ->signal/->sighand
*/
-static int tty_open(struct inode *inode, struct file *filp)
+static int __tty_open(struct inode *inode, struct file *filp)
{
struct tty_struct *tty;
int noctty, retval;
@@ -2779,6 +2779,19 @@ got_driver:
return 0;
}
+/* BKL pushdown: scary code avoidance wrapper */
+static int tty_open(struct inode *inode, struct file *filp)
+{
+ int ret;
+
+ lock_kernel();
+ ret = __tty_open(inode, filp);
+ unlock_kernel();
+ return ret;
+}
+
+
+
#ifdef CONFIG_UNIX98_PTYS
/**
* ptmx_open - open a unix 98 pty master
@@ -2792,7 +2805,7 @@ got_driver:
* allocated_ptys_lock handles the list of free pty numbers
*/
-static int ptmx_open(struct inode *inode, struct file *filp)
+static int __ptmx_open(struct inode *inode, struct file *filp)
{
struct tty_struct *tty;
int retval;
@@ -2831,6 +2844,16 @@ out:
devpts_kill_index(index);
return retval;
}
+
+static int ptmx_open(struct inode *inode, struct file *filp)
+{
+ int ret;
+
+ lock_kernel();
+ ret = __ptmx_open(inode, filp);
+ unlock_kernel();
+ return ret;
+}
#endif
/**
@@ -2886,15 +2909,16 @@ static int tty_fasync(int fd, struct file *filp, int on)
{
struct tty_struct *tty;
unsigned long flags;
- int retval;
+ int retval = 0;
+ lock_kernel();
tty = (struct tty_struct *)filp->private_data;
if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync"))
- return 0;
+ goto out;
retval = fasync_helper(fd, filp, on, &tty->fasync);
if (retval <= 0)
- return retval;
+ goto out;
if (on) {
enum pid_type type;
@@ -2912,12 +2936,15 @@ static int tty_fasync(int fd, struct file *filp, int on)
spin_unlock_irqrestore(&tty->ctrl_lock, flags);
retval = __f_setown(filp, pid, type, 0);
if (retval)
- return retval;
+ goto out;
} else {
if (!tty->fasync && !waitqueue_active(&tty->read_wait))
tty->minimum_to_wake = N_TTY_BUF_SIZE;
}
- return 0;
+ retval = 0;
+out:
+ unlock_kernel();
+ return retval;
}
/**
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c
index 83aeedda200..eebfad2777d 100644
--- a/drivers/char/vc_screen.c
+++ b/drivers/char/vc_screen.c
@@ -34,6 +34,7 @@
#include <linux/kbd_kern.h>
#include <linux/console.h>
#include <linux/device.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/byteorder.h>
@@ -460,9 +461,13 @@ static int
vcs_open(struct inode *inode, struct file *filp)
{
unsigned int currcons = iminor(inode) & 127;
+ int ret = 0;
+
+ lock_kernel();
if(currcons && !vc_cons_allocated(currcons-1))
- return -ENXIO;
- return 0;
+ ret = -ENXIO;
+ unlock_kernel();
+ return ret;
}
static const struct file_operations vcs_fops = {
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index c39ddaff5e8..977f7d35e76 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -46,6 +46,7 @@
#include <linux/completion.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/ioctls.h>
@@ -687,6 +688,7 @@ static int viotap_open(struct inode *inode, struct file *file)
if (op == NULL)
return -ENOMEM;
+ lock_kernel();
get_dev_info(file->f_path.dentry->d_inode, &devi);
/* Note: We currently only support one mode! */
@@ -717,6 +719,7 @@ static int viotap_open(struct inode *inode, struct file *file)
free_op:
free_op_struct(op);
+ unlock_kernel();
return ret;
}
diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c
index e5ed09192be..ffe9b4e3072 100644
--- a/drivers/char/vr41xx_giu.c
+++ b/drivers/char/vr41xx_giu.c
@@ -27,6 +27,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/types.h>
@@ -547,6 +548,7 @@ static int gpio_open(struct inode *inode, struct file *file)
{
unsigned int pin;
+ cycle_kernel_lock();
pin = iminor(inode);
if (pin >= giu_nr_pins)
return -EBADF;
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
index 3edf1fc1296..1e1b81e57cd 100644
--- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c
+++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
@@ -85,6 +85,7 @@
#include <linux/poll.h>
#include <linux/proc_fs.h>
#include <linux/mutex.h>
+#include <linux/smp_lock.h>
#include <linux/sysctl.h>
#include <linux/version.h>
#include <linux/fs.h>
@@ -504,11 +505,12 @@ static int hwicap_open(struct inode *inode, struct file *file)
struct hwicap_drvdata *drvdata;
int status;
+ lock_kernel();
drvdata = container_of(inode->i_cdev, struct hwicap_drvdata, cdev);
status = mutex_lock_interruptible(&drvdata->sem);
if (status)
- return status;
+ goto out;
if (drvdata->is_open) {
status = -EBUSY;
@@ -528,6 +530,8 @@ static int hwicap_open(struct inode *inode, struct file *file)
error:
mutex_unlock(&drvdata->sem);
+ out:
+ unlock_kernel();
return status;
}
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index d2e6da85f58..851a53f1acc 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -37,6 +37,7 @@
#include "drmP.h"
#include "drm_sarea.h"
#include <linux/poll.h>
+#include <linux/smp_lock.h>
static int drm_open_helper(struct inode *inode, struct file *filp,
struct drm_device * dev);
@@ -174,12 +175,14 @@ int drm_stub_open(struct inode *inode, struct file *filp)
DRM_DEBUG("\n");
+ /* BKL pushdown: note that nothing else serializes idr_find() */
+ lock_kernel();
minor = idr_find(&drm_minors_idr, minor_id);
if (!minor)
- return -ENODEV;
+ goto out;
if (!(dev = minor->dev))
- return -ENODEV;
+ goto out;
old_fops = filp->f_op;
filp->f_op = fops_get(&dev->driver->fops);
@@ -189,6 +192,8 @@ int drm_stub_open(struct inode *inode, struct file *filp)
}
fops_put(old_fops);
+out:
+ unlock_kernel();
return err;
}
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 1ca6f4635ee..2fde6c63f47 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -30,6 +30,7 @@
#include <linux/major.h>
#include <linux/hid.h>
#include <linux/mutex.h>
+#include <linux/smp_lock.h>
#include <linux/hidraw.h>
@@ -157,6 +158,7 @@ static int hidraw_open(struct inode *inode, struct file *file)
struct hidraw_list *list;
int err = 0;
+ lock_kernel();
if (!(list = kzalloc(sizeof(struct hidraw_list), GFP_KERNEL))) {
err = -ENOMEM;
goto out;
@@ -183,6 +185,7 @@ static int hidraw_open(struct inode *inode, struct file *file)
out_unlock:
spin_unlock(&minors_lock);
out:
+ unlock_kernel();
return err;
}
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index d34c14c81c2..006a5857256 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -34,6 +34,7 @@
#include <linux/list.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
static struct i2c_driver i2cdev_driver;
@@ -441,14 +442,20 @@ static int i2cdev_open(struct inode *inode, struct file *file)
struct i2c_client *client;
struct i2c_adapter *adap;
struct i2c_dev *i2c_dev;
+ int ret = 0;
+ lock_kernel();
i2c_dev = i2c_dev_get_by_minor(minor);
- if (!i2c_dev)
- return -ENODEV;
+ if (!i2c_dev) {
+ ret = -ENODEV;
+ goto out;
+ }
adap = i2c_get_adapter(i2c_dev->adap->nr);
- if (!adap)
- return -ENODEV;
+ if (!adap) {
+ ret = -ENODEV;
+ goto out;
+ }
/* This creates an anonymous i2c_client, which may later be
* pointed to some address using I2C_SLAVE or I2C_SLAVE_FORCE.
@@ -460,7 +467,8 @@ static int i2cdev_open(struct inode *inode, struct file *file)
client = kzalloc(sizeof(*client), GFP_KERNEL);
if (!client) {
i2c_put_adapter(adap);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto out;
}
snprintf(client->name, I2C_NAME_SIZE, "i2c-dev %d", adap->nr);
client->driver = &i2cdev_driver;
@@ -468,7 +476,9 @@ static int i2cdev_open(struct inode *inode, struct file *file)
client->adapter = adap;
file->private_data = client;
- return 0;
+out:
+ unlock_kernel();
+ return ret;
}
static int i2cdev_release(struct inode *inode, struct file *file)
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 1e1f26331a2..a3d228302d2 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -2421,9 +2421,12 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp)
if (i >= MAX_HWIFS * MAX_DRIVES)
return -ENXIO;
+ lock_kernel();
tape = ide_tape_chrdev_get(i);
- if (!tape)
+ if (!tape) {
+ unlock_kernel();
return -ENXIO;
+ }
debug_log(DBG_CHRDEV, "Enter %s\n", __func__);
@@ -2482,10 +2485,12 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp)
}
}
}
+ unlock_kernel();
return 0;
out_put_tape:
ide_tape_put(tape);
+ unlock_kernel();
return retval;
}
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c
index d7a6881b571..b25675faaaf 100644
--- a/drivers/infiniband/core/ucm.c
+++ b/drivers/infiniband/core/ucm.c
@@ -45,6 +45,7 @@
#include <linux/cdev.h>
#include <linux/idr.h>
#include <linux/mutex.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
@@ -1159,6 +1160,7 @@ static int ib_ucm_open(struct inode *inode, struct file *filp)
{
struct ib_ucm_file *file;
+ cycle_kernel_lock();
file = kmalloc(sizeof(*file), GFP_KERNEL);
if (!file)
return -ENOMEM;
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index ca4cf3a511a..195f97302fe 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -38,6 +38,7 @@
#include <linux/in.h>
#include <linux/in6.h>
#include <linux/miscdevice.h>
+#include <linux/smp_lock.h>
#include <rdma/rdma_user_cm.h>
#include <rdma/ib_marshall.h>
@@ -1156,6 +1157,7 @@ static int ucma_open(struct inode *inode, struct file *filp)
if (!file)
return -ENOMEM;
+ lock_kernel();
INIT_LIST_HEAD(&file->event_list);
INIT_LIST_HEAD(&file->ctx_list);
init_waitqueue_head(&file->poll_wait);
@@ -1163,6 +1165,7 @@ static int ucma_open(struct inode *inode, struct file *filp)
filp->private_data = file;
file->filp = filp;
+ unlock_kernel();
return 0;
}
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c
index 840ede9ae96..208c7f34323 100644
--- a/drivers/infiniband/core/user_mad.c
+++ b/drivers/infiniband/core/user_mad.c
@@ -777,6 +777,19 @@ static long ib_umad_compat_ioctl(struct file *filp, unsigned int cmd,
}
#endif
+/*
+ * ib_umad_open() does not need the BKL:
+ *
+ * - umad_port[] accesses are protected by port_lock, the
+ * ib_umad_port structures are properly reference counted, and
+ * everything else is purely local to the file being created, so
+ * races against other open calls are not a problem;
+ * - the ioctl method does not affect any global state outside of the
+ * file structure being operated on;
+ * - the port is added to umad_port[] as the last part of module
+ * initialization so the open method will either immediately run
+ * -ENXIO, or all required initialization will be done.
+ */
static int ib_umad_open(struct inode *inode, struct file *filp)
{
struct ib_umad_port *port;
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index caed42bf7ef..0f34858e31e 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -610,6 +610,18 @@ static int ib_uverbs_mmap(struct file *filp, struct vm_area_struct *vma)
return file->device->ib_dev->mmap(file->ucontext, vma);
}
+/*
+ * ib_uverbs_open() does not need the BKL:
+ *
+ * - dev_table[] accesses are protected by map_lock, the
+ * ib_uverbs_device structures are properly reference counted, and
+ * everything else is purely local to the file being created, so
+ * races against other open calls are not a problem;
+ * - there is no ioctl method to race against;
+ * - the device is added to dev_table[] as the last part of module
+ * initialization, the open method will either immediately run
+ * -ENXIO, or all required initialization will be done.
+ */
static int ib_uverbs_open(struct inode *inode, struct file *filp)
{
struct ib_uverbs_device *dev;
@@ -651,7 +663,6 @@ err_module:
err:
kref_put(&dev->ref, ib_uverbs_release_dev);
-
return ret;
}
diff --git a/drivers/infiniband/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c
index b472b15637f..35f301c88b5 100644
--- a/drivers/infiniband/hw/ipath/ipath_file_ops.c
+++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c
@@ -39,6 +39,7 @@
#include <linux/highmem.h>
#include <linux/io.h>
#include <linux/jiffies.h>
+#include <linux/smp_lock.h>
#include <asm/pgtable.h>
#include "ipath_kernel.h"
@@ -1815,6 +1816,7 @@ done:
static int ipath_open(struct inode *in, struct file *fp)
{
/* The real work is performed later in ipath_assign_port() */
+ cycle_kernel_lock();
fp->private_data = kzalloc(sizeof(struct ipath_filedata), GFP_KERNEL);
return fp->private_data ? 0 : -ENOMEM;
}
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 27006fc1830..408df0bd6be 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -21,6 +21,7 @@
#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/rcupdate.h>
+#include <linux/smp_lock.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
MODULE_DESCRIPTION("Input core");
@@ -1588,13 +1589,17 @@ EXPORT_SYMBOL(input_unregister_handle);
static int input_open_file(struct inode *inode, struct file *file)
{
- struct input_handler *handler = input_table[iminor(inode) >> 5];
+ struct input_handler *handler;
const struct file_operations *old_fops, *new_fops = NULL;
int err;
+ lock_kernel();
/* No load-on-demand here? */
- if (!handler || !(new_fops = fops_get(handler->fops)))
- return -ENODEV;
+ handler = input_table[iminor(inode) >> 5];
+ if (!handler || !(new_fops = fops_get(handler->fops))) {
+ err = -ENODEV;
+ goto out;
+ }
/*
* That's _really_ odd. Usually NULL ->open means "nothing special",
@@ -1602,7 +1607,8 @@ static int input_open_file(struct inode *inode, struct file *file)
*/
if (!new_fops->open) {
fops_put(new_fops);
- return -ENODEV;
+ err = -ENODEV;
+ goto out;
}
old_fops = file->f_op;
file->f_op = new_fops;
@@ -1614,6 +1620,8 @@ static int input_open_file(struct inode *inode, struct file *file)
file->f_op = fops_get(old_fops);
}
fops_put(old_fops);
+out:
+ unlock_kernel();
return err;
}
diff --git a/drivers/input/misc/hp_sdc_rtc.c b/drivers/input/misc/hp_sdc_rtc.c
index 45e5d05b01d..49d8abfe38f 100644
--- a/drivers/input/misc/hp_sdc_rtc.c
+++ b/drivers/input/misc/hp_sdc_rtc.c
@@ -35,6 +35,7 @@
#include <linux/hp_sdc.h>
#include <linux/errno.h>
+#include <linux/smp_lock.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/module.h>
@@ -408,6 +409,7 @@ static unsigned int hp_sdc_rtc_poll(struct file *file, poll_table *wait)
static int hp_sdc_rtc_open(struct inode *inode, struct file *file)
{
+ cycle_kernel_lock();
return 0;
}
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index a56ad4ba8fe..2bcfa0b3506 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -37,6 +37,7 @@
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/uinput.h>
+#include <linux/smp_lock.h>
static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
{
@@ -222,6 +223,7 @@ static int uinput_open(struct inode *inode, struct file *file)
if (!newdev)
return -ENOMEM;
+ lock_kernel();
mutex_init(&newdev->mutex);
spin_lock_init(&newdev->requests_lock);
init_waitqueue_head(&newdev->requests_waitq);
@@ -229,6 +231,7 @@ static int uinput_open(struct inode *inode, struct file *file)
newdev->state = UIST_NEW_DEVICE;
file->private_data = newdev;
+ unlock_kernel();
return 0;
}
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index b989748598a..8137e50ded8 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -14,6 +14,7 @@
#define MOUSEDEV_MIX 31
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <linux/poll.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -545,16 +546,21 @@ static int mousedev_open(struct inode *inode, struct file *file)
if (i >= MOUSEDEV_MINORS)
return -ENODEV;
+ lock_kernel();
error = mutex_lock_interruptible(&mousedev_table_mutex);
- if (error)
+ if (error) {
+ unlock_kernel();
return error;
+ }
mousedev = mousedev_table[i];
if (mousedev)
get_device(&mousedev->dev);
mutex_unlock(&mousedev_table_mutex);
- if (!mousedev)
+ if (!mousedev) {
+ unlock_kernel();
return -ENODEV;
+ }
client = kzalloc(sizeof(struct mousedev_client), GFP_KERNEL);
if (!client) {
@@ -573,6 +579,7 @@ static int mousedev_open(struct inode *inode, struct file *file)
goto err_free_client;
file->private_data = client;
+ unlock_kernel();
return 0;
err_free_client:
@@ -580,6 +587,7 @@ static int mousedev_open(struct inode *inode, struct file *file)
kfree(client);
err_put_mousedev:
put_device(&mousedev->dev);
+ unlock_kernel();
return error;
}
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
index 0403622ae26..c9397c8ee97 100644
--- a/drivers/input/serio/serio_raw.c
+++ b/drivers/input/serio/serio_raw.c
@@ -10,6 +10,7 @@
*/
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <linux/poll.h>
#include <linux/module.h>
#include <linux/serio.h>
@@ -81,9 +82,10 @@ static int serio_raw_open(struct inode *inode, struct file *file)
struct serio_raw_list *list;
int retval = 0;
+ lock_kernel();
retval = mutex_lock_interruptible(&serio_raw_mutex);
if (retval)
- return retval;
+ goto out_bkl;
if (!(serio_raw = serio_raw_locate(iminor(inode)))) {
retval = -ENODEV;
@@ -108,6 +110,8 @@ static int serio_raw_open(struct inode *inode, struct file *file)
out:
mutex_unlock(&serio_raw_mutex);
+out_bkl:
+ unlock_kernel();
return retval;
}
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index 6ca0bb949ad..2095153582f 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -20,6 +20,7 @@
#include <linux/signal.h>
#include <linux/mutex.h>
#include <linux/mm.h>
+#include <linux/smp_lock.h>
#include <linux/timer.h>
#include <linux/wait.h>
#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
@@ -983,13 +984,17 @@ capi_ioctl(struct inode *inode, struct file *file,
static int
capi_open(struct inode *inode, struct file *file)
{
+ int ret;
+
+ lock_kernel();
if (file->private_data)
- return -EEXIST;
-
- if ((file->private_data = capidev_alloc()) == NULL)
- return -ENOMEM;
-
- return nonseekable_open(inode, file);
+ ret = -EEXIST;
+ else if ((file->private_data = capidev_alloc()) == NULL)
+ ret = -ENOMEM;
+ else
+ ret = nonseekable_open(inode, file);
+ unlock_kernel();
+ return ret;
}
static int
diff --git a/drivers/isdn/hardware/eicon/divamnt.c b/drivers/isdn/hardware/eicon/divamnt.c
index c9092897424..1e85f743214 100644
--- a/drivers/isdn/hardware/eicon/divamnt.c
+++ b/drivers/isdn/hardware/eicon/divamnt.c
@@ -14,6 +14,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/poll.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include "platform.h"
@@ -127,14 +128,19 @@ static unsigned int maint_poll(struct file *file, poll_table * wait)
static int maint_open(struct inode *ino, struct file *filep)
{
+ int ret;
+
+ lock_kernel();
/* only one open is allowed, so we test
it atomically */
if (test_and_set_bit(0, &opened))
- return (-EBUSY);
-
- filep->private_data = NULL;
-
- return nonseekable_open(ino, filep);
+ ret = -EBUSY;
+ else {
+ filep->private_data = NULL;
+ ret = nonseekable_open(ino, filep);
+ }
+ unlock_kernel();
+ return ret;
}
static int maint_close(struct inode *ino, struct file *filep)
diff --git a/drivers/isdn/hardware/eicon/divasi.c b/drivers/isdn/hardware/eicon/divasi.c
index 78f141e7746..f4969fe0a05 100644
--- a/drivers/isdn/hardware/eicon/divasi.c
+++ b/drivers/isdn/hardware/eicon/divasi.c
@@ -17,6 +17,7 @@
#include <linux/poll.h>
#include <linux/proc_fs.h>
#include <linux/skbuff.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include "platform.h"
@@ -400,6 +401,7 @@ static unsigned int um_idi_poll(struct file *file, poll_table * wait)
static int um_idi_open(struct inode *inode, struct file *file)
{
+ cycle_kernel_lock();
return (0);
}
diff --git a/drivers/isdn/hardware/eicon/divasmain.c b/drivers/isdn/hardware/eicon/divasmain.c
index 16a874bb156..fbbcb27fb68 100644
--- a/drivers/isdn/hardware/eicon/divasmain.c
+++ b/drivers/isdn/hardware/eicon/divasmain.c
@@ -21,6 +21,7 @@
#include <linux/list.h>
#include <linux/poll.h>
#include <linux/kmod.h>
+#include <linux/smp_lock.h>
#include "platform.h"
#undef ID_MASK
@@ -580,6 +581,7 @@ xdi_copy_from_user(void *os_handle, void *dst, const void __user *src, int lengt
*/
static int divas_open(struct inode *inode, struct file *file)
{
+ cycle_kernel_lock();
return (0);
}
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
index 8d8c6b73616..7188c59a76f 100644
--- a/drivers/isdn/i4l/isdn_common.c
+++ b/drivers/isdn/i4l/isdn_common.c
@@ -1732,7 +1732,7 @@ isdn_open(struct inode *ino, struct file *filep)
int chidx;
int retval = -ENODEV;
-
+ lock_kernel();
if (minor == ISDN_MINOR_STATUS) {
infostruct *p;
@@ -1783,6 +1783,7 @@ isdn_open(struct inode *ino, struct file *filep)
#endif
out:
nonseekable_open(ino, filep);
+ unlock_kernel();
return retval;
}
diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
index dbaad39020a..40c70ba62bf 100644
--- a/drivers/macintosh/adb.c
+++ b/drivers/macintosh/adb.c
@@ -644,12 +644,18 @@ do_adb_query(struct adb_request *req)
static int adb_open(struct inode *inode, struct file *file)
{
struct adbdev_state *state;
+ int ret = 0;
- if (iminor(inode) > 0 || adb_controller == NULL)
- return -ENXIO;
+ lock_kernel();
+ if (iminor(inode) > 0 || adb_controller == NULL) {
+ ret = -ENXIO;
+ goto out;
+ }
state = kmalloc(sizeof(struct adbdev_state), GFP_KERNEL);
- if (state == 0)
- return -ENOMEM;
+ if (state == 0) {
+ ret = -ENOMEM;
+ goto out;
+ }
file->private_data = state;
spin_lock_init(&state->lock);
atomic_set(&state->n_pending, 0);
@@ -657,7 +663,9 @@ static int adb_open(struct inode *inode, struct file *file)
init_waitqueue_head(&state->wait_queue);
state->inuse = 1;
- return 0;
+out:
+ unlock_kernel();
+ return ret;
}
static int adb_release(struct inode *inode, struct file *file)
diff --git a/drivers/macintosh/ans-lcd.c b/drivers/macintosh/ans-lcd.c
index 73c50bc0209..6a822189325 100644
--- a/drivers/macintosh/ans-lcd.c
+++ b/drivers/macintosh/ans-lcd.c
@@ -3,6 +3,7 @@
*/
#include <linux/types.h>
+#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/miscdevice.h>
@@ -119,6 +120,7 @@ anslcd_ioctl( struct inode * inode, struct file * file,
static int
anslcd_open( struct inode * inode, struct file * file )
{
+ cycle_kernel_lock();
return 0;
}
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
index d86d57af282..32cb0298f88 100644
--- a/drivers/macintosh/smu.c
+++ b/drivers/macintosh/smu.c
@@ -19,6 +19,7 @@
* the userland interface
*/
+#include <linux/smp_lock.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/device.h>
@@ -1086,10 +1087,12 @@ static int smu_open(struct inode *inode, struct file *file)
pp->mode = smu_file_commands;
init_waitqueue_head(&pp->wait);
+ lock_kernel();
spin_lock_irqsave(&smu_clist_lock, flags);
list_add(&pp->list, &smu_clist);
spin_unlock_irqrestore(&smu_clist_lock, flags);
file->private_data = pp;
+ unlock_kernel();
return 0;
}
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index d6365a9f063..d524dc245a2 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -18,6 +18,7 @@
*
*/
#include <stdarg.h>
+#include <linux/smp_lock.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
@@ -2047,6 +2048,7 @@ pmu_open(struct inode *inode, struct file *file)
pp->rb_get = pp->rb_put = 0;
spin_lock_init(&pp->lock);
init_waitqueue_head(&pp->wait);
+ lock_kernel();
spin_lock_irqsave(&all_pvt_lock, flags);
#if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT)
pp->backlight_locker = 0;
@@ -2054,6 +2056,7 @@ pmu_open(struct inode *inode, struct file *file)
list_add(&pp->list, &all_pmu_pvt);
spin_unlock_irqrestore(&all_pvt_lock, flags);
file->private_data = pp;
+ unlock_kernel();
return 0;
}
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
index 8b56d929f7f..e208a60c048 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -32,6 +32,7 @@
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/mutex.h>
+#include <linux/smp_lock.h>
#include "dvbdev.h"
static int dvbdev_debug;
@@ -74,6 +75,7 @@ static int dvb_device_open(struct inode *inode, struct file *file)
{
struct dvb_device *dvbdev;
+ lock_kernel();
dvbdev = dvbdev_find_device (iminor(inode));
if (dvbdev && dvbdev->fops) {
@@ -90,8 +92,10 @@ static int dvb_device_open(struct inode *inode, struct file *file)
file->f_op = fops_get(old_fops);
}
fops_put(old_fops);
+ unlock_kernel();
return err;
}
+ unlock_kernel();
return -ENODEV;
}
diff --git a/drivers/media/radio/miropcm20-rds.c b/drivers/media/radio/miropcm20-rds.c
index 06dfed9ef4c..3e840f74d45 100644
--- a/drivers/media/radio/miropcm20-rds.c
+++ b/drivers/media/radio/miropcm20-rds.c
@@ -12,6 +12,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
@@ -27,13 +28,16 @@ static int rds_f_open(struct inode *in, struct file *fi)
if (rds_users)
return -EBUSY;
+ lock_kernel();
rds_users++;
if ((text_buffer=kmalloc(66, GFP_KERNEL)) == 0) {
rds_users--;
printk(KERN_NOTICE "aci-rds: Out of memory by open()...\n");
+ unlock_kernel();
return -ENOMEM;
}
+ unlock_kernel();
return 0;
}
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c
index 67a661cf521..7649860a388 100644
--- a/drivers/media/video/videodev.c
+++ b/drivers/media/video/videodev.c
@@ -36,6 +36,7 @@
#include <linux/init.h>
#include <linux/kmod.h>
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/system.h>
@@ -442,6 +443,7 @@ static int video_open(struct inode *inode, struct file *file)
if(minor>=VIDEO_NUM_DEVICES)
return -ENODEV;
+ lock_kernel();
mutex_lock(&videodev_lock);
vfl=video_device[minor];
if(vfl==NULL) {
@@ -451,6 +453,7 @@ static int video_open(struct inode *inode, struct file *file)
vfl=video_device[minor];
if (vfl==NULL) {
mutex_unlock(&videodev_lock);
+ unlock_kernel();
return -ENODEV;
}
}
@@ -464,6 +467,7 @@ static int video_open(struct inode *inode, struct file *file)
}
fops_put(old_fops);
mutex_unlock(&videodev_lock);
+ unlock_kernel();
return err;
}
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index e630b50966e..c5946560c4e 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -548,11 +548,15 @@ static int
mptctl_fasync(int fd, struct file *filep, int mode)
{
MPT_ADAPTER *ioc;
+ int ret;
+ lock_kernel();
list_for_each_entry(ioc, &ioc_list, list)
ioc->aen_event_read_flag=0;
- return fasync_helper(fd, filep, mode, &async_queue);
+ ret = fasync_helper(fd, filep, mode, &async_queue);
+ unlock_kernel();
+ return ret;
}
static int
diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c
index c0fb77dc19b..4238de98d4a 100644
--- a/drivers/message/i2o/i2o_config.c
+++ b/drivers/message/i2o/i2o_config.c
@@ -1061,6 +1061,7 @@ static int cfg_open(struct inode *inode, struct file *file)
if (!tmp)
return -ENOMEM;
+ lock_kernel();
file->private_data = (void *)(i2o_cfg_info_id++);
tmp->fp = file;
tmp->fasync = NULL;
@@ -1074,6 +1075,7 @@ static int cfg_open(struct inode *inode, struct file *file)
spin_lock_irqsave(&i2o_config_lock, flags);
open_files = tmp;
spin_unlock_irqrestore(&i2o_config_lock, flags);
+ unlock_kernel();
return 0;
}
@@ -1082,15 +1084,17 @@ static int cfg_fasync(int fd, struct file *fp, int on)
{
ulong id = (ulong) fp->private_data;
struct i2o_cfg_info *p;
+ int ret = -EBADF;
+ lock_kernel();
for (p = open_files; p; p = p->next)
if (p->q_id == id)
break;
- if (!p)
- return -EBADF;
-
- return fasync_helper(fd, fp, on, &p->fasync);
+ if (p)
+ ret = fasync_helper(fd, fp, on, &p->fasync);
+ unlock_kernel();
+ return ret;
}
static int cfg_release(struct inode *inode, struct file *file)
diff --git a/drivers/misc/hdpuftrs/hdpu_cpustate.c b/drivers/misc/hdpuftrs/hdpu_cpustate.c
index ff51ab67231..176fe4e09d3 100644
--- a/drivers/misc/hdpuftrs/hdpu_cpustate.c
+++ b/drivers/misc/hdpuftrs/hdpu_cpustate.c
@@ -17,6 +17,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
#include <linux/miscdevice.h>
#include <linux/proc_fs.h>
#include <linux/hdpu_features.h>
@@ -151,7 +152,13 @@ static ssize_t cpustate_write(struct file *file, const char *buf,
static int cpustate_open(struct inode *inode, struct file *file)
{
- return cpustate_get_ref((file->f_flags & O_EXCL));
+ int ret;
+
+ lock_kernel();
+ ret = cpustate_get_ref((file->f_flags & O_EXCL));
+ unlock_kernel();
+
+ return ret;
}
static int cpustate_release(struct inode *inode, struct file *file)
diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c
index 71d1c84e2fa..18616247009 100644
--- a/drivers/misc/phantom.c
+++ b/drivers/misc/phantom.c
@@ -22,6 +22,7 @@
#include <linux/interrupt.h>
#include <linux/cdev.h>
#include <linux/phantom.h>
+#include <linux/smp_lock.h>
#include <asm/atomic.h>
#include <asm/io.h>
@@ -212,13 +213,17 @@ static int phantom_open(struct inode *inode, struct file *file)
struct phantom_device *dev = container_of(inode->i_cdev,
struct phantom_device, cdev);
+ lock_kernel();
nonseekable_open(inode, file);
- if (mutex_lock_interruptible(&dev->open_lock))
+ if (mutex_lock_interruptible(&dev->open_lock)) {
+ unlock_kernel();
return -ERESTARTSYS;
+ }
if (dev->opened) {
mutex_unlock(&dev->open_lock);
+ unlock_kernel();
return -EINVAL;
}
@@ -229,7 +234,7 @@ static int phantom_open(struct inode *inode, struct file *file)
atomic_set(&dev->counter, 0);
dev->opened++;
mutex_unlock(&dev->open_lock);
-
+ unlock_kernel();
return 0;
}
diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c
index 00e48e2a9c1..60775be2282 100644
--- a/drivers/misc/sony-laptop.c
+++ b/drivers/misc/sony-laptop.c
@@ -46,6 +46,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
+#include <linux/smp_lock.h>
#include <linux/types.h>
#include <linux/backlight.h>
#include <linux/platform_device.h>
@@ -1927,8 +1928,10 @@ static int sonypi_misc_release(struct inode *inode, struct file *file)
static int sonypi_misc_open(struct inode *inode, struct file *file)
{
/* Flush input queue on first open */
+ lock_kernel();
if (atomic_inc_return(&sonypi_compat.open_count) == 1)
kfifo_reset(sonypi_compat.fifo);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 5d3ac512ce1..129d429cd2d 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/compatmac.h>
@@ -86,6 +87,7 @@ static int mtd_open(struct inode *inode, struct file *file)
{
int minor = iminor(inode);
int devnum = minor >> 1;
+ int ret = 0;
struct mtd_info *mtd;
struct mtd_file_info *mfi;
@@ -98,31 +100,39 @@ static int mtd_open(struct inode *inode, struct file *file)
if ((file->f_mode & 2) && (minor & 1))
return -EACCES;
+ lock_kernel();
mtd = get_mtd_device(NULL, devnum);
- if (IS_ERR(mtd))
- return PTR_ERR(mtd);
+ if (IS_ERR(mtd)) {
+ ret = PTR_ERR(mtd);
+ goto out;
+ }
if (MTD_ABSENT == mtd->type) {
put_mtd_device(mtd);
- return -ENODEV;
+ ret = -ENODEV;
+ goto out;
}
/* You can't open it RW if it's not a writeable device */
if ((file->f_mode & 2) && !(mtd->flags & MTD_WRITEABLE)) {
put_mtd_device(mtd);
- return -EACCES;
+ ret = -EACCES;
+ goto out;
}
mfi = kzalloc(sizeof(*mfi), GFP_KERNEL);
if (!mfi) {
put_mtd_device(mtd);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto out;
}
mfi->mtd = mtd;
file->private_data = mfi;
- return 0;
+out:
+ unlock_kernel();
+ return ret;
} /* mtd_open */
/*====================================================================*/
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c
index 9d6aae5449b..89193ba9451 100644
--- a/drivers/mtd/ubi/cdev.c
+++ b/drivers/mtd/ubi/cdev.c
@@ -39,6 +39,7 @@
#include <linux/stat.h>
#include <linux/ioctl.h>
#include <linux/capability.h>
+#include <linux/smp_lock.h>
#include <mtd/ubi-user.h>
#include <asm/uaccess.h>
#include <asm/div64.h>
@@ -103,9 +104,12 @@ static int vol_cdev_open(struct inode *inode, struct file *file)
struct ubi_volume_desc *desc;
int vol_id = iminor(inode) - 1, mode, ubi_num;
+ lock_kernel();
ubi_num = ubi_major2num(imajor(inode));
- if (ubi_num < 0)
+ if (ubi_num < 0) {
+ unlock_kernel();
return ubi_num;
+ }
if (file->f_mode & FMODE_WRITE)
mode = UBI_READWRITE;
@@ -115,6 +119,7 @@ static int vol_cdev_open(struct inode *inode, struct file *file)
dbg_msg("open volume %d, mode %d", vol_id, mode);
desc = ubi_open_volume(ubi_num, vol_id, mode);
+ unlock_kernel();
if (IS_ERR(desc))
return PTR_ERR(desc);
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 1f4ca2b54a7..83625fdff3d 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -39,6 +39,7 @@
#include <linux/if_arp.h>
#include <linux/ip.h>
#include <linux/tcp.h>
+#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/rwsem.h>
#include <linux/stddef.h>
@@ -353,6 +354,7 @@ static const int npindex_to_ethertype[NUM_NP] = {
*/
static int ppp_open(struct inode *inode, struct file *file)
{
+ cycle_kernel_lock();
/*
* This could (should?) be enforced by the permissions on /dev/ppp.
*/
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index b9018bfa0a9..eba1271b973 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -48,6 +48,7 @@
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <linux/poll.h>
#include <linux/fcntl.h>
#include <linux/init.h>
@@ -802,22 +803,26 @@ static int tun_chr_fasync(int fd, struct file *file, int on)
DBG(KERN_INFO "%s: tun_chr_fasync %d\n", tun->dev->name, on);
+ lock_kernel();
if ((ret = fasync_helper(fd, file, on, &tun->fasync)) < 0)
- return ret;
+ goto out;
if (on) {
ret = __f_setown(file, task_pid(current), PIDTYPE_PID, 0);
if (ret)
- return ret;
+ goto out;
tun->flags |= TUN_FASYNC;
} else
tun->flags &= ~TUN_FASYNC;
-
- return 0;
+ ret = 0;
+out:
+ unlock_kernel();
+ return ret;
}
static int tun_chr_open(struct inode *inode, struct file * file)
{
+ cycle_kernel_lock();
DBG1(KERN_INFO "tunX: tun_chr_open\n");
file->private_data = NULL;
return 0;
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index b0fce1387ea..5827324e9d9 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -92,6 +92,7 @@
#include <linux/spinlock.h>
#include <linux/mutex.h>
#include <linux/device.h>
+#include <linux/smp_lock.h>
#undef COSA_SLOW_IO /* for testing purposes only */
@@ -970,15 +971,21 @@ static int cosa_open(struct inode *inode, struct file *file)
struct channel_data *chan;
unsigned long flags;
int n;
+ int ret = 0;
+ lock_kernel();
if ((n=iminor(file->f_path.dentry->d_inode)>>CARD_MINOR_BITS)
- >= nr_cards)
- return -ENODEV;
+ >= nr_cards) {
+ ret = -ENODEV;
+ goto out;
+ }
cosa = cosa_cards+n;
if ((n=iminor(file->f_path.dentry->d_inode)
- & ((1<<CARD_MINOR_BITS)-1)) >= cosa->nchannels)
- return -ENODEV;
+ & ((1<<CARD_MINOR_BITS)-1)) >= cosa->nchannels) {
+ ret = -ENODEV;
+ goto out;
+ }
chan = cosa->chan + n;
file->private_data = chan;
@@ -987,7 +994,8 @@ static int cosa_open(struct inode *inode, struct file *file)
if (chan->usage < 0) { /* in netdev mode */
spin_unlock_irqrestore(&cosa->lock, flags);
- return -EBUSY;
+ ret = -EBUSY;
+ goto out;
}
cosa->usage++;
chan->usage++;
@@ -996,7 +1004,9 @@ static int cosa_open(struct inode *inode, struct file *file)
chan->setup_rx = chrdev_setup_rx;
chan->rx_done = chrdev_rx_done;
spin_unlock_irqrestore(&cosa->lock, flags);
- return 0;
+out:
+ unlock_kernel();
+ return ret;
}
static int cosa_release(struct inode *inode, struct file *file)
diff --git a/drivers/parisc/eisa_eeprom.c b/drivers/parisc/eisa_eeprom.c
index 86e9c84a965..5ac207932fd 100644
--- a/drivers/parisc/eisa_eeprom.c
+++ b/drivers/parisc/eisa_eeprom.c
@@ -24,6 +24,7 @@
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <linux/fs.h>
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -83,6 +84,8 @@ static int eisa_eeprom_ioctl(struct inode *inode, struct file *file,
static int eisa_eeprom_open(struct inode *inode, struct file *file)
{
+ cycle_kernel_lock();
+
if (file->f_mode & 2)
return -EINVAL;
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c
index afd00e7bbbe..419f97fc9a6 100644
--- a/drivers/pcmcia/pcmcia_ioctl.c
+++ b/drivers/pcmcia/pcmcia_ioctl.c
@@ -27,6 +27,7 @@
#include <linux/proc_fs.h>
#include <linux/poll.h>
#include <linux/pci.h>
+#include <linux/smp_lock.h>
#include <linux/workqueue.h>
#include <pcmcia/cs_types.h>
@@ -545,20 +546,27 @@ static int ds_open(struct inode *inode, struct file *file)
struct pcmcia_socket *s;
user_info_t *user;
static int warning_printed = 0;
+ int ret = 0;
ds_dbg(0, "ds_open(socket %d)\n", i);
+ lock_kernel();
s = pcmcia_get_socket_by_nr(i);
- if (!s)
- return -ENODEV;
+ if (!s) {
+ ret = -ENODEV;
+ goto out;
+ }
s = pcmcia_get_socket(s);
- if (!s)
- return -ENODEV;
+ if (!s) {
+ ret = -ENODEV;
+ goto out;
+ }
if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
if (s->pcmcia_state.busy) {
pcmcia_put_socket(s);
- return -EBUSY;
+ ret = -EBUSY;
+ goto out;
}
else
s->pcmcia_state.busy = 1;
@@ -567,7 +575,8 @@ static int ds_open(struct inode *inode, struct file *file)
user = kmalloc(sizeof(user_info_t), GFP_KERNEL);
if (!user) {
pcmcia_put_socket(s);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto out;
}
user->event_tail = user->event_head = 0;
user->next = s->user;
@@ -589,7 +598,9 @@ static int ds_open(struct inode *inode, struct file *file)
if (s->pcmcia_state.present)
queue_event(user, CS_EVENT_CARD_INSERTION);
- return 0;
+out:
+ unlock_kernel();
+ return ret;
} /* ds_open */
/*====================================================================*/
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
index 90dfa0df747..0114a78b7cb 100644
--- a/drivers/rtc/rtc-dev.c
+++ b/drivers/rtc/rtc-dev.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/rtc.h>
+#include <linux/smp_lock.h>
#include "rtc-core.h"
static dev_t rtc_devt;
@@ -26,8 +27,11 @@ static int rtc_dev_open(struct inode *inode, struct file *file)
struct rtc_device, char_dev);
const struct rtc_class_ops *ops = rtc->ops;
- if (test_and_set_bit_lock(RTC_DEV_BUSY, &rtc->flags))
- return -EBUSY;
+ lock_kernel();
+ if (test_and_set_bit_lock(RTC_DEV_BUSY, &rtc->flags)) {
+ err = -EBUSY;
+ goto out;
+ }
file->private_data = rtc;
@@ -37,11 +41,13 @@ static int rtc_dev_open(struct inode *inode, struct file *file)
rtc->irq_data = 0;
spin_unlock_irq(&rtc->irq_lock);
- return 0;
+ goto out;
}
/* something has gone wrong */
clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags);
+out:
+ unlock_kernel();
return err;
}
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index a3e0880b38f..0a19c06019b 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -17,6 +17,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <linux/string.h>
#include <linux/i2c.h>
#include <linux/rtc.h>
@@ -655,12 +656,16 @@ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
static int wdt_open(struct inode *inode, struct file *file)
{
if (MINOR(inode->i_rdev) == WATCHDOG_MINOR) {
- if (test_and_set_bit(0, &wdt_is_open))
+ lock_kernel();
+ if (test_and_set_bit(0, &wdt_is_open)) {
+ unlock_kernel();
return -EBUSY;
+ }
/*
* Activate
*/
wdt_is_open = 1;
+ unlock_kernel();
return 0;
}
return -ENODEV;
diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c
index 6e53ab606e9..29da4413ad4 100644
--- a/drivers/s390/block/dasd_eer.c
+++ b/drivers/s390/block/dasd_eer.c
@@ -15,6 +15,7 @@
#include <linux/device.h>
#include <linux/poll.h>
#include <linux/mutex.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
@@ -525,6 +526,7 @@ static int dasd_eer_open(struct inode *inp, struct file *filp)
eerb = kzalloc(sizeof(struct eerbuffer), GFP_KERNEL);
if (!eerb)
return -ENOMEM;
+ lock_kernel();
eerb->buffer_page_count = eer_pages;
if (eerb->buffer_page_count < 1 ||
eerb->buffer_page_count > INT_MAX / PAGE_SIZE) {
@@ -532,6 +534,7 @@ static int dasd_eer_open(struct inode *inp, struct file *filp)
MESSAGE(KERN_WARNING, "can't open device since module "
"parameter eer_pages is smaller then 1 or"
" bigger then %d", (int)(INT_MAX / PAGE_SIZE));
+ unlock_kernel();
return -EINVAL;
}
eerb->buffersize = eerb->buffer_page_count * PAGE_SIZE;
@@ -539,12 +542,14 @@ static int dasd_eer_open(struct inode *inp, struct file *filp)
GFP_KERNEL);
if (!eerb->buffer) {
kfree(eerb);
+ unlock_kernel();
return -ENOMEM;
}
if (dasd_eer_allocate_buffer_pages(eerb->buffer,
eerb->buffer_page_count)) {
kfree(eerb->buffer);
kfree(eerb);
+ unlock_kernel();
return -ENOMEM;
}
filp->private_data = eerb;
@@ -552,6 +557,7 @@ static int dasd_eer_open(struct inode *inp, struct file *filp)
list_add(&eerb->list, &bufferlist);
spin_unlock_irqrestore(&bufferlock, flags);
+ unlock_kernel();
return nonseekable_open(inp,filp);
}
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c
index e136d10a0de..d18e6d2e0b4 100644
--- a/drivers/s390/char/fs3270.c
+++ b/drivers/s390/char/fs3270.c
@@ -14,6 +14,7 @@
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/types.h>
+#include <linux/smp_lock.h>
#include <asm/ccwdev.h>
#include <asm/cio.h>
@@ -421,6 +422,7 @@ fs3270_open(struct inode *inode, struct file *filp)
if (imajor(filp->f_path.dentry->d_inode) != IBM_FS3270_MAJOR)
return -ENODEV;
+ lock_kernel();
minor = iminor(filp->f_path.dentry->d_inode);
/* Check for minor 0 multiplexer. */
if (minor == 0) {
@@ -429,7 +431,8 @@ fs3270_open(struct inode *inode, struct file *filp)
tty = get_current_tty();
if (!tty || tty->driver->major != IBM_TTY3270_MAJOR) {
mutex_unlock(&tty_mutex);
- return -ENODEV;
+ rc = -ENODEV;
+ goto out;
}
minor = tty->index + RAW3270_FIRSTMINOR;
mutex_unlock(&tty_mutex);
@@ -438,19 +441,22 @@ fs3270_open(struct inode *inode, struct file *filp)
fp = (struct fs3270 *) raw3270_find_view(&fs3270_fn, minor);
if (!IS_ERR(fp)) {
raw3270_put_view(&fp->view);
- return -EBUSY;
+ rc = -EBUSY;
+ goto out;
}
/* Allocate fullscreen view structure. */
fp = fs3270_alloc_view();
- if (IS_ERR(fp))
- return PTR_ERR(fp);
+ if (IS_ERR(fp)) {
+ rc = PTR_ERR(fp);
+ goto out;
+ }
init_waitqueue_head(&fp->wait);
fp->fs_pid = get_pid(task_pid(current));
rc = raw3270_add_view(&fp->view, &fs3270_fn, minor);
if (rc) {
fs3270_free_view(&fp->view);
- return rc;
+ goto out;
}
/* Allocate idal-buffer. */
@@ -458,7 +464,8 @@ fs3270_open(struct inode *inode, struct file *filp)
if (IS_ERR(ib)) {
raw3270_put_view(&fp->view);
raw3270_del_view(&fp->view);
- return PTR_ERR(fp);
+ rc = PTR_ERR(fp);
+ goto out;
}
fp->rdbuf = ib;
@@ -466,9 +473,11 @@ fs3270_open(struct inode *inode, struct file *filp)
if (rc) {
raw3270_put_view(&fp->view);
raw3270_del_view(&fp->view);
- return rc;
+ goto out;
}
filp->private_data = fp;
+out:
+ unlock_kernel();
return 0;
}
diff --git a/drivers/s390/char/monreader.c b/drivers/s390/char/monreader.c
index f0e4c96afbf..35fd8dfcaaa 100644
--- a/drivers/s390/char/monreader.c
+++ b/drivers/s390/char/monreader.c
@@ -10,6 +10,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
+#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/kernel.h>
@@ -291,6 +292,7 @@ static int mon_open(struct inode *inode, struct file *filp)
/*
* only one user allowed
*/
+ lock_kernel();
rc = -EBUSY;
if (test_and_set_bit(MON_IN_USE, &mon_in_use))
goto out;
@@ -327,6 +329,7 @@ static int mon_open(struct inode *inode, struct file *filp)
goto out_path;
}
filp->private_data = monpriv;
+ unlock_kernel();
return nonseekable_open(inode, filp);
out_path:
@@ -336,6 +339,7 @@ out_priv:
out_use:
clear_bit(MON_IN_USE, &mon_in_use);
out:
+ unlock_kernel();
return rc;
}
diff --git a/drivers/s390/char/monwriter.c b/drivers/s390/char/monwriter.c
index a86c0534cd4..4d71aa8c1a7 100644
--- a/drivers/s390/char/monwriter.c
+++ b/drivers/s390/char/monwriter.c
@@ -12,6 +12,7 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/errno.h>
+#include <linux/smp_lock.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/miscdevice.h>
@@ -179,10 +180,12 @@ static int monwrite_open(struct inode *inode, struct file *filp)
monpriv = kzalloc(sizeof(struct mon_private), GFP_KERNEL);
if (!monpriv)
return -ENOMEM;
+ lock_kernel();
INIT_LIST_HEAD(&monpriv->list);
monpriv->hdr_to_read = sizeof(monpriv->hdr);
mutex_init(&monpriv->thread_mutex);
filp->private_data = monpriv;
+ unlock_kernel();
return nonseekable_open(inode, filp);
}
diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c
index ebe84067bae..687720b552d 100644
--- a/drivers/s390/char/tape_char.c
+++ b/drivers/s390/char/tape_char.c
@@ -14,6 +14,7 @@
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/mtio.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
@@ -289,21 +290,26 @@ tapechar_open (struct inode *inode, struct file *filp)
if (imajor(filp->f_path.dentry->d_inode) != tapechar_major)
return -ENODEV;
+ lock_kernel();
minor = iminor(filp->f_path.dentry->d_inode);
device = tape_get_device(minor / TAPE_MINORS_PER_DEV);
if (IS_ERR(device)) {
DBF_EVENT(3, "TCHAR:open: tape_get_device() failed\n");
- return PTR_ERR(device);
+ rc = PTR_ERR(device);
+ goto out;
}
rc = tape_open(device);
if (rc == 0) {
filp->private_data = device;
- return nonseekable_open(inode, filp);
+ rc = nonseekable_open(inode, filp);
}
- tape_put_device(device);
+ else
+ tape_put_device(device);
+out:
+ unlock_kernel();
return rc;
}
diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c
index 401ea84b305..09e7d9bf438 100644
--- a/drivers/s390/char/vmcp.c
+++ b/drivers/s390/char/vmcp.c
@@ -16,6 +16,7 @@
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
+#include <linux/smp_lock.h>
#include <asm/cpcmd.h>
#include <asm/debug.h>
#include <asm/uaccess.h>
@@ -39,11 +40,14 @@ static int vmcp_open(struct inode *inode, struct file *file)
session = kmalloc(sizeof(*session), GFP_KERNEL);
if (!session)
return -ENOMEM;
+
+ lock_kernel();
session->bufsize = PAGE_SIZE;
session->response = NULL;
session->resp_size = 0;
mutex_init(&session->mutex);
file->private_data = session;
+ unlock_kernel();
return nonseekable_open(inode, file);
}
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
index a246bc73ae6..c31faefa2b3 100644
--- a/drivers/s390/char/vmlogrdr.c
+++ b/drivers/s390/char/vmlogrdr.c
@@ -25,6 +25,7 @@
#include <linux/kmod.h>
#include <linux/cdev.h>
#include <linux/device.h>
+#include <linux/smp_lock.h>
#include <linux/string.h>
@@ -310,9 +311,11 @@ static int vmlogrdr_open (struct inode *inode, struct file *filp)
return -ENOSYS;
/* Besure this device hasn't already been opened */
+ lock_kernel();
spin_lock_bh(&logptr->priv_lock);
if (logptr->dev_in_use) {
spin_unlock_bh(&logptr->priv_lock);
+ unlock_kernel();
return -EBUSY;
}
logptr->dev_in_use = 1;
@@ -356,7 +359,9 @@ static int vmlogrdr_open (struct inode *inode, struct file *filp)
|| (logptr->iucv_path_severed));
if (logptr->iucv_path_severed)
goto out_record;
- return nonseekable_open(inode, filp);
+ ret = nonseekable_open(inode, filp);
+ unlock_kernel();
+ return ret;
out_record:
if (logptr->autorecording)
@@ -366,6 +371,7 @@ out_path:
logptr->path = NULL;
out_dev:
logptr->dev_in_use = 0;
+ unlock_kernel();
return -EIO;
}
diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c
index 49cba9effe8..0a9f1cccbe5 100644
--- a/drivers/s390/char/vmur.c
+++ b/drivers/s390/char/vmur.c
@@ -9,6 +9,7 @@
*/
#include <linux/cdev.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/cio.h>
@@ -669,7 +670,7 @@ static int ur_open(struct inode *inode, struct file *file)
if (accmode == O_RDWR)
return -EACCES;
-
+ lock_kernel();
/*
* We treat the minor number as the devno of the ur device
* to find in the driver tree.
@@ -677,8 +678,10 @@ static int ur_open(struct inode *inode, struct file *file)
devno = MINOR(file->f_dentry->d_inode->i_rdev);
urd = urdev_get_from_devno(devno);
- if (!urd)
- return -ENXIO;
+ if (!urd) {
+ rc = -ENXIO;
+ goto out;
+ }
spin_lock(&urd->open_lock);
while (urd->open_flag) {
@@ -721,6 +724,7 @@ static int ur_open(struct inode *inode, struct file *file)
goto fail_urfile_free;
urf->file_reclen = rc;
file->private_data = urf;
+ unlock_kernel();
return 0;
fail_urfile_free:
@@ -731,6 +735,8 @@ fail_unlock:
spin_unlock(&urd->open_lock);
fail_put:
urdev_put(urd);
+out:
+ unlock_kernel();
return rc;
}
diff --git a/drivers/s390/char/vmwatchdog.c b/drivers/s390/char/vmwatchdog.c
index 56b3eab019c..21a2a829bf4 100644
--- a/drivers/s390/char/vmwatchdog.c
+++ b/drivers/s390/char/vmwatchdog.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/watchdog.h>
+#include <linux/smp_lock.h>
#include <asm/ebcdic.h>
#include <asm/io.h>
@@ -121,11 +122,15 @@ static int __init vmwdt_probe(void)
static int vmwdt_open(struct inode *i, struct file *f)
{
int ret;
- if (test_and_set_bit(0, &vmwdt_is_open))
+ lock_kernel();
+ if (test_and_set_bit(0, &vmwdt_is_open)) {
+ unlock_kernel();
return -EBUSY;
+ }
ret = vmwdt_keepalive();
if (ret)
clear_bit(0, &vmwdt_is_open);
+ unlock_kernel();
return ret ? ret : nonseekable_open(i, f);
}
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index 8a4964f3584..cb22b97944b 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -34,6 +34,7 @@
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/compat.h>
+#include <linux/smp_lock.h>
#include <asm/atomic.h>
#include <asm/uaccess.h>
#include <linux/hw_random.h>
@@ -300,7 +301,9 @@ static ssize_t zcrypt_write(struct file *filp, const char __user *buf,
*/
static int zcrypt_open(struct inode *inode, struct file *filp)
{
+ lock_kernel();
atomic_inc(&zcrypt_open_count);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c
index 03c96605947..bba21e053a1 100644
--- a/drivers/sbus/char/bpp.c
+++ b/drivers/sbus/char/bpp.c
@@ -19,6 +19,7 @@
#include <linux/timer.h>
#include <linux/ioport.h>
#include <linux/major.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -429,6 +430,7 @@ static int bpp_open(struct inode *inode, struct file *f)
unsigned minor = iminor(inode);
int ret;
+ lock_kernel();
spin_lock(&bpp_open_lock);
ret = 0;
if (minor >= BPP_NO) {
@@ -444,6 +446,7 @@ static int bpp_open(struct inode *inode, struct file *f)
}
}
spin_unlock(&bpp_open_lock);
+ unlock_kernel();
return ret;
}
diff --git a/drivers/sbus/char/cpwatchdog.c b/drivers/sbus/char/cpwatchdog.c
index 23570341437..23abfdfb44f 100644
--- a/drivers/sbus/char/cpwatchdog.c
+++ b/drivers/sbus/char/cpwatchdog.c
@@ -279,6 +279,7 @@ static inline int wd_opt_timeout(void)
static int wd_open(struct inode *inode, struct file *f)
{
+ lock_kernel();
switch(iminor(inode))
{
case WD0_MINOR:
@@ -291,6 +292,7 @@ static int wd_open(struct inode *inode, struct file *f)
f->private_data = &wd_dev.watchdog[WD2_ID];
break;
default:
+ unlock_kernel();
return(-ENODEV);
}
@@ -304,11 +306,13 @@ static int wd_open(struct inode *inode, struct file *f)
(void *)wd_dev.regs)) {
printk("%s: Cannot register IRQ %d\n",
WD_OBPNAME, wd_dev.irq);
+ unlock_kernel();
return(-EBUSY);
}
wd_dev.initialized = 1;
}
+ unlock_kernel();
return(nonseekable_open(inode, f));
}
diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c
index 3279a1b6501..d8f5c0ca236 100644
--- a/drivers/sbus/char/display7seg.c
+++ b/drivers/sbus/char/display7seg.c
@@ -94,6 +94,7 @@ static int d7s_open(struct inode *inode, struct file *f)
{
if (D7S_MINOR != iminor(inode))
return -ENODEV;
+ cycle_kernel_lock();
atomic_inc(&d7s_users);
return 0;
}
diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c
index dadabef116b..a408402426f 100644
--- a/drivers/sbus/char/envctrl.c
+++ b/drivers/sbus/char/envctrl.c
@@ -27,6 +27,7 @@
#include <linux/miscdevice.h>
#include <linux/kmod.h>
#include <linux/reboot.h>
+#include <linux/smp_lock.h>
#include <asm/ebus.h>
#include <asm/uaccess.h>
@@ -694,6 +695,7 @@ envctrl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
static int
envctrl_open(struct inode *inode, struct file *file)
{
+ cycle_kernel_lock();
file->private_data = NULL;
return 0;
}
diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c
index 44e039865aa..7d95e151513 100644
--- a/drivers/sbus/char/flash.c
+++ b/drivers/sbus/char/flash.c
@@ -127,9 +127,13 @@ flash_read(struct file * file, char __user * buf,
static int
flash_open(struct inode *inode, struct file *file)
{
- if (test_and_set_bit(0, (void *)&flash.busy) != 0)
+ lock_kernel();
+ if (test_and_set_bit(0, (void *)&flash.busy) != 0) {
+ unlock_kernel();
return -EBUSY;
+ }
+ unlock_kernel();
return 0;
}
diff --git a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c
index 4b7079fdc10..2bec9ccc029 100644
--- a/drivers/sbus/char/jsflash.c
+++ b/drivers/sbus/char/jsflash.c
@@ -27,6 +27,7 @@
*/
#include <linux/module.h>
+#include <linux/smp_lock.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
@@ -417,11 +418,17 @@ static int jsf_mmap(struct file * file, struct vm_area_struct * vma)
static int jsf_open(struct inode * inode, struct file * filp)
{
-
- if (jsf0.base == 0) return -ENXIO;
- if (test_and_set_bit(0, (void *)&jsf0.busy) != 0)
+ lock_kernel();
+ if (jsf0.base == 0) {
+ unlock_kernel();
+ return -ENXIO;
+ }
+ if (test_and_set_bit(0, (void *)&jsf0.busy) != 0) {
+ unlock_kernel();
return -EBUSY;
+ }
+ unlock_kernel();
return 0; /* XXX What security? */
}
diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c
index fbfeb89a6f3..29dc735e1a2 100644
--- a/drivers/sbus/char/openprom.c
+++ b/drivers/sbus/char/openprom.c
@@ -33,6 +33,7 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <linux/string.h>
#include <linux/miscdevice.h>
#include <linux/init.h>
@@ -689,9 +690,11 @@ static int openprom_open(struct inode * inode, struct file * file)
if (!data)
return -ENOMEM;
+ lock_kernel();
data->current_node = of_find_node_by_path("/");
data->lastnode = data->current_node;
file->private_data = (void *) data;
+ unlock_kernel();
return 0;
}
diff --git a/drivers/sbus/char/riowatchdog.c b/drivers/sbus/char/riowatchdog.c
index a2fc6b8c133..88c0fc6395e 100644
--- a/drivers/sbus/char/riowatchdog.c
+++ b/drivers/sbus/char/riowatchdog.c
@@ -11,6 +11,7 @@
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
+#include <linux/smp_lock.h>
#include <asm/io.h>
#include <asm/ebus.h>
@@ -116,6 +117,7 @@ static void riowd_starttimer(void)
static int riowd_open(struct inode *inode, struct file *filp)
{
+ cycle_kernel_lock();
nonseekable_open(inode, filp);
return 0;
}
diff --git a/drivers/sbus/char/rtc.c b/drivers/sbus/char/rtc.c
index 18d18f1a114..b0429917154 100644
--- a/drivers/sbus/char/rtc.c
+++ b/drivers/sbus/char/rtc.c
@@ -12,6 +12,7 @@
*/
#include <linux/module.h>
+#include <linux/smp_lock.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
@@ -213,6 +214,7 @@ static int rtc_open(struct inode *inode, struct file *file)
{
int ret;
+ lock_kernel();
spin_lock_irq(&mostek_lock);
if (rtc_busy) {
ret = -EBUSY;
@@ -221,6 +223,7 @@ static int rtc_open(struct inode *inode, struct file *file)
ret = 0;
}
spin_unlock_irq(&mostek_lock);
+ unlock_kernel();
return ret;
}
diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c
index 383f32c1d34..513ba61ae96 100644
--- a/drivers/sbus/char/uctrl.c
+++ b/drivers/sbus/char/uctrl.c
@@ -9,6 +9,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
@@ -211,8 +212,10 @@ uctrl_ioctl(struct inode *inode, struct file *file,
static int
uctrl_open(struct inode *inode, struct file *file)
{
+ lock_kernel();
uctrl_get_event_status();
uctrl_get_external_status();
+ unlock_kernel();
return 0;
}
diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c
index d4f8fcded51..1f6cb8ae278 100644
--- a/drivers/sbus/char/vfc_dev.c
+++ b/drivers/sbus/char/vfc_dev.c
@@ -24,6 +24,7 @@
#include <linux/spinlock.h>
#include <linux/mutex.h>
#include <linux/mm.h>
+#include <linux/smp_lock.h>
#include <asm/openprom.h>
#include <asm/oplib.h>
@@ -178,14 +179,17 @@ static int vfc_open(struct inode *inode, struct file *file)
{
struct vfc_dev *dev;
+ lock_kernel();
spin_lock(&vfc_dev_lock);
dev = vfc_get_dev_ptr(iminor(inode));
if (dev == NULL) {
spin_unlock(&vfc_dev_lock);
+ unlock_kernel();
return -ENODEV;
}
if (dev->busy) {
spin_unlock(&vfc_dev_lock);
+ unlock_kernel();
return -EBUSY;
}
@@ -202,6 +206,7 @@ static int vfc_open(struct inode *inode, struct file *file)
vfc_captstat_reset(dev);
vfc_unlock_device(dev);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index 867f6fd5c2c..7045511f9ad 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -84,6 +84,7 @@
#include <linux/pci.h>
#include <linux/time.h>
#include <linux/mutex.h>
+#include <linux/smp_lock.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
@@ -862,11 +863,13 @@ out:
} /* End twa_chrdev_ioctl() */
/* This function handles open for the character device */
+/* NOTE that this function will race with remove. */
static int twa_chrdev_open(struct inode *inode, struct file *file)
{
unsigned int minor_number;
int retval = TW_IOCTL_ERROR_OS_ENODEV;
+ cycle_kernel_lock();
minor_number = iminor(inode);
if (minor_number >= twa_device_extension_count)
goto out;
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index 8c22329aa85..a0537f09aa2 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -198,6 +198,7 @@
#include <linux/module.h>
#include <linux/reboot.h>
+#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/moduleparam.h>
@@ -1027,10 +1028,12 @@ out:
} /* End tw_chrdev_ioctl() */
/* This function handles open for the character device */
+/* NOTE that this function races with remove. */
static int tw_chrdev_open(struct inode *inode, struct file *file)
{
unsigned int minor_number;
+ cycle_kernel_lock();
dprintk(KERN_WARNING "3w-xxxx: tw_ioctl_open()\n");
minor_number = iminor(inode);
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 1f7c83607f8..68c140e8267 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -38,6 +38,7 @@
#include <linux/moduleparam.h>
#include <linux/pci.h>
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/syscalls.h>
#include <linux/delay.h>
@@ -667,6 +668,7 @@ static int aac_cfg_open(struct inode *inode, struct file *file)
unsigned minor_number = iminor(inode);
int err = -ENODEV;
+ lock_kernel(); /* BKL pushdown: nothing else protects this list */
list_for_each_entry(aac, &aac_devices, entry) {
if (aac->id == minor_number) {
file->private_data = aac;
@@ -674,6 +676,7 @@ static int aac_cfg_open(struct inode *inode, struct file *file)
break;
}
}
+ unlock_kernel();
return err;
}
diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
index c4b938bc30d..aa2011b6468 100644
--- a/drivers/scsi/ch.c
+++ b/drivers/scsi/ch.c
@@ -22,6 +22,7 @@
#include <linux/chio.h> /* here are all the ioctls */
#include <linux/mutex.h>
#include <linux/idr.h>
+#include <linux/smp_lock.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
@@ -571,16 +572,19 @@ ch_open(struct inode *inode, struct file *file)
scsi_changer *ch;
int minor = iminor(inode);
+ lock_kernel();
spin_lock(&ch_index_lock);
ch = idr_find(&ch_index_idr, minor);
if (NULL == ch || scsi_device_get(ch->device)) {
spin_unlock(&ch_index_lock);
+ unlock_kernel();
return -ENXIO;
}
spin_unlock(&ch_index_lock);
file->private_data = ch;
+ unlock_kernel();
return 0;
}
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index 8508816f303..2bc30e32b67 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -49,6 +49,7 @@ MODULE_DESCRIPTION("Adaptec I2O RAID Driver");
#include <linux/kernel.h> /* for printk */
#include <linux/sched.h>
#include <linux/reboot.h>
+#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/dma-mapping.h>
@@ -1727,10 +1728,12 @@ static int adpt_open(struct inode *inode, struct file *file)
int minor;
adpt_hba* pHba;
+ lock_kernel();
//TODO check for root access
//
minor = iminor(inode);
if (minor >= hba_count) {
+ unlock_kernel();
return -ENXIO;
}
mutex_lock(&adpt_configuration_lock);
@@ -1741,6 +1744,7 @@ static int adpt_open(struct inode *inode, struct file *file)
}
if (pHba == NULL) {
mutex_unlock(&adpt_configuration_lock);
+ unlock_kernel();
return -ENXIO;
}
@@ -1751,6 +1755,7 @@ static int adpt_open(struct inode *inode, struct file *file)
pHba->in_use = 1;
mutex_unlock(&adpt_configuration_lock);
+ unlock_kernel();
return 0;
}
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 46771d4c81b..822d5214692 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -120,6 +120,7 @@
#include <linux/timer.h>
#include <linux/dma-mapping.h>
#include <linux/list.h>
+#include <linux/smp_lock.h>
#ifdef GDTH_RTC
#include <linux/mc146818rtc.h>
@@ -4019,10 +4020,12 @@ static int gdth_open(struct inode *inode, struct file *filep)
{
gdth_ha_str *ha;
+ lock_kernel();
list_for_each_entry(ha, &gdth_instances, list) {
if (!ha->sdev)
ha->sdev = scsi_get_host_dev(ha->shost);
}
+ unlock_kernel();
TRACE(("gdth_open()\n"));
return 0;
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 18551aaf5e0..28c9da7d4a5 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -46,6 +46,7 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
+#include <linux/smp_lock.h>
#include <scsi/scsicam.h>
#include "scsi.h"
@@ -3272,12 +3273,12 @@ mega_init_scb(adapter_t *adapter)
* @filep - unused
*
* Routines for the character/ioctl interface to the driver. Find out if this
- * is a valid open. If yes, increment the module use count so that it cannot
- * be unloaded.
+ * is a valid open.
*/
static int
megadev_open (struct inode *inode, struct file *filep)
{
+ cycle_kernel_lock();
/*
* Only allow superuser to access private ioctl interface
*/
diff --git a/drivers/scsi/megaraid/megaraid_mm.c b/drivers/scsi/megaraid/megaraid_mm.c
index 0ad215e27b8..ac3b280c2a7 100644
--- a/drivers/scsi/megaraid/megaraid_mm.c
+++ b/drivers/scsi/megaraid/megaraid_mm.c
@@ -15,6 +15,7 @@
* Common management module
*/
#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include "megaraid_mm.h"
@@ -96,6 +97,7 @@ mraid_mm_open(struct inode *inode, struct file *filep)
*/
if (!capable(CAP_SYS_ADMIN)) return (-EACCES);
+ cycle_kernel_lock();
return 0;
}
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index 7d84c8bbcf3..fc7ac158476 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -33,6 +33,7 @@
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
+#include <linux/smp_lock.h>
#include <linux/uio.h>
#include <asm/uaccess.h>
#include <linux/fs.h>
@@ -2863,6 +2864,7 @@ static void megasas_shutdown(struct pci_dev *pdev)
*/
static int megasas_mgmt_open(struct inode *inode, struct file *filep)
{
+ cycle_kernel_lock();
/*
* Allow only those users with admin rights
*/
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index 243d8becd30..1c79f9794f4 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -50,6 +50,7 @@ static const char * osst_version = "0.99.4";
#include <linux/moduleparam.h>
#include <linux/delay.h>
#include <linux/jiffies.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/dma.h>
#include <asm/system.h>
@@ -4359,7 +4360,7 @@ os_bypass:
/* Open the device */
-static int os_scsi_tape_open(struct inode * inode, struct file * filp)
+static int __os_scsi_tape_open(struct inode * inode, struct file * filp)
{
unsigned short flags;
int i, b_size, new_session = 0, retval = 0;
@@ -4725,6 +4726,18 @@ err_out:
return retval;
}
+/* BKL pushdown: spaghetti avoidance wrapper */
+static int os_scsi_tape_open(struct inode * inode, struct file * filp)
+{
+ int ret;
+
+ lock_kernel();
+ ret = __os_scsi_tape_open(inode, filp);
+ unlock_kernel();
+ return ret;
+}
+
+
/* Flush the tape buffer before close */
static int os_scsi_tape_flush(struct file * filp, fl_owner_t id)
diff --git a/drivers/scsi/scsi_tgt_if.c b/drivers/scsi/scsi_tgt_if.c
index d2557dbc2dc..0e9533f7aab 100644
--- a/drivers/scsi/scsi_tgt_if.c
+++ b/drivers/scsi/scsi_tgt_if.c
@@ -21,6 +21,7 @@
*/
#include <linux/miscdevice.h>
#include <linux/file.h>
+#include <linux/smp_lock.h>
#include <net/tcp.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
@@ -321,6 +322,7 @@ static int tgt_open(struct inode *inode, struct file *file)
{
tx_ring.tr_idx = rx_ring.tr_idx = 0;
+ cycle_kernel_lock();
return 0;
}
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index fe694f0ee19..fccd2e88d60 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -49,6 +49,7 @@ static int sg_version_num = 30534; /* 2 digits for each component */
#include <linux/delay.h>
#include <linux/scatterlist.h>
#include <linux/blktrace_api.h>
+#include <linux/smp_lock.h>
#include "scsi.h"
#include <scsi/scsi_dbg.h>
@@ -227,19 +228,26 @@ sg_open(struct inode *inode, struct file *filp)
int res;
int retval;
+ lock_kernel();
nonseekable_open(inode, filp);
SCSI_LOG_TIMEOUT(3, printk("sg_open: dev=%d, flags=0x%x\n", dev, flags));
sdp = sg_get_dev(dev);
- if ((!sdp) || (!sdp->device))
+ if ((!sdp) || (!sdp->device)) {
+ unlock_kernel();
return -ENXIO;
- if (sdp->detached)
+ }
+ if (sdp->detached) {
+ unlock_kernel();
return -ENODEV;
+ }
/* This driver's module count bumped by fops_get in <linux/fs.h> */
/* Prevent the device driver from vanishing while we sleep */
retval = scsi_device_get(sdp->device);
- if (retval)
+ if (retval) {
+ unlock_kernel();
return retval;
+ }
if (!((flags & O_NONBLOCK) ||
scsi_block_when_processing_errors(sdp->device))) {
@@ -295,10 +303,12 @@ sg_open(struct inode *inode, struct file *filp)
retval = -ENOMEM;
goto error_out;
}
+ unlock_kernel();
return 0;
error_out:
scsi_device_put(sdp->device);
+ unlock_kernel();
return retval;
}
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 6e5a5bb3131..4684cc716aa 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -38,6 +38,7 @@ static const char *verstr = "20080224";
#include <linux/cdev.h>
#include <linux/delay.h>
#include <linux/mutex.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/dma.h>
@@ -1113,7 +1114,7 @@ static int check_tape(struct scsi_tape *STp, struct file *filp)
}
- /* Open the device. Needs to be called with BKL only because of incrementing the SCSI host
+ /* Open the device. Needs to take the BKL only because of incrementing the SCSI host
module count. */
static int st_open(struct inode *inode, struct file *filp)
{
@@ -1123,6 +1124,7 @@ static int st_open(struct inode *inode, struct file *filp)
int dev = TAPE_NR(inode);
char *name;
+ lock_kernel();
/*
* We really want to do nonseekable_open(inode, filp); here, but some
* versions of tar incorrectly call lseek on tapes and bail out if that
@@ -1130,8 +1132,10 @@ static int st_open(struct inode *inode, struct file *filp)
*/
filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
- if (!(STp = scsi_tape_get(dev)))
+ if (!(STp = scsi_tape_get(dev))) {
+ unlock_kernel();
return -ENXIO;
+ }
write_lock(&st_dev_arr_lock);
filp->private_data = STp;
@@ -1140,6 +1144,7 @@ static int st_open(struct inode *inode, struct file *filp)
if (STp->in_use) {
write_unlock(&st_dev_arr_lock);
scsi_tape_put(STp);
+ unlock_kernel();
DEB( printk(ST_DEB_MSG "%s: Device already in use.\n", name); )
return (-EBUSY);
}
@@ -1188,12 +1193,14 @@ static int st_open(struct inode *inode, struct file *filp)
retval = (-EIO);
goto err_out;
}
+ unlock_kernel();
return 0;
err_out:
normalize_buffer(STp->buffer);
STp->in_use = 0;
scsi_tape_put(STp);
+ unlock_kernel();
return retval;
}
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
index f5b60c70389..ddbe1a5e970 100644
--- a/drivers/spi/spidev.c
+++ b/drivers/spi/spidev.c
@@ -30,6 +30,7 @@
#include <linux/errno.h>
#include <linux/mutex.h>
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <linux/spi/spi.h>
#include <linux/spi/spidev.h>
@@ -464,6 +465,7 @@ static int spidev_open(struct inode *inode, struct file *filp)
struct spidev_data *spidev;
int status = -ENXIO;
+ lock_kernel();
mutex_lock(&device_list_lock);
list_for_each_entry(spidev, &device_list, device_entry) {
@@ -489,6 +491,7 @@ static int spidev_open(struct inode *inode, struct file *filp)
pr_debug("spidev: nothing for minor %d\n", iminor(inode));
mutex_unlock(&device_list_lock);
+ unlock_kernel();
return status;
}
diff --git a/drivers/telephony/phonedev.c b/drivers/telephony/phonedev.c
index bcea8d9b718..4d74ba36c3a 100644
--- a/drivers/telephony/phonedev.c
+++ b/drivers/telephony/phonedev.c
@@ -23,6 +23,7 @@
#include <linux/errno.h>
#include <linux/phonedev.h>
#include <linux/init.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/system.h>
@@ -53,6 +54,7 @@ static int phone_open(struct inode *inode, struct file *file)
if (minor >= PHONE_NUM_DEVICES)
return -ENODEV;
+ lock_kernel();
mutex_lock(&phone_lock);
p = phone_device[minor];
if (p)
@@ -79,6 +81,7 @@ static int phone_open(struct inode *inode, struct file *file)
fops_put(old_fops);
end:
mutex_unlock(&phone_lock);
+ unlock_kernel();
return err;
}
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index 0a12e90ad41..5a7ca2e6094 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -297,12 +297,17 @@ static int uio_open(struct inode *inode, struct file *filep)
struct uio_listener *listener;
int ret = 0;
+ lock_kernel();
idev = idr_find(&uio_idr, iminor(inode));
- if (!idev)
- return -ENODEV;
+ if (!idev) {
+ ret = -ENODEV;
+ goto out;
+ }
- if (!try_module_get(idev->owner))
- return -ENODEV;
+ if (!try_module_get(idev->owner)) {
+ ret = -ENODEV;
+ goto out;
+ }
listener = kmalloc(sizeof(*listener), GFP_KERNEL);
if (!listener) {
@@ -319,7 +324,7 @@ static int uio_open(struct inode *inode, struct file *filep)
if (ret)
goto err_infoopen;
}
-
+ unlock_kernel();
return 0;
err_infoopen:
@@ -329,6 +334,8 @@ err_alloc_listener:
module_put(idev->owner);
+out:
+ unlock_kernel();
return ret;
}
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index de17738f3ac..9218cca2104 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -565,6 +565,7 @@ static int usbdev_open(struct inode *inode, struct file *file)
struct dev_state *ps;
int ret;
+ lock_kernel();
/* Protect against simultaneous removal or release */
mutex_lock(&usbfs_mutex);
@@ -611,6 +612,7 @@ static int usbdev_open(struct inode *inode, struct file *file)
if (ret)
kfree(ps);
mutex_unlock(&usbfs_mutex);
+ unlock_kernel();
return ret;
}
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c
index 8133c99c6c5..c6a95395e52 100644
--- a/drivers/usb/core/file.c
+++ b/drivers/usb/core/file.c
@@ -18,6 +18,7 @@
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/rwsem.h>
+#include <linux/smp_lock.h>
#include <linux/usb.h>
#include "usb.h"
@@ -33,6 +34,7 @@ static int usb_open(struct inode * inode, struct file * file)
int err = -ENODEV;
const struct file_operations *old_fops, *new_fops = NULL;
+ lock_kernel();
down_read(&minor_rwsem);
c = usb_minors[minor];
@@ -51,6 +53,7 @@ static int usb_open(struct inode * inode, struct file * file)
fops_put(old_fops);
done:
up_read(&minor_rwsem);
+ unlock_kernel();
return err;
}
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c
index 76be75e3ab8..ec8f2eb041c 100644
--- a/drivers/usb/gadget/printer.c
+++ b/drivers/usb/gadget/printer.c
@@ -462,6 +462,7 @@ printer_open(struct inode *inode, struct file *fd)
unsigned long flags;
int ret = -EBUSY;
+ lock_kernel();
dev = container_of(inode->i_cdev, struct printer_dev, printer_cdev);
spin_lock_irqsave(&dev->lock, flags);
@@ -477,7 +478,7 @@ printer_open(struct inode *inode, struct file *fd)
spin_unlock_irqrestore(&dev->lock, flags);
DBG(dev, "printer_open returned %x\n", ret);
-
+ unlock_kernel();
return ret;
}
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c
index 49145534e06..293a46247c3 100644
--- a/drivers/usb/mon/mon_bin.c
+++ b/drivers/usb/mon/mon_bin.c
@@ -15,6 +15,7 @@
#include <linux/poll.h>
#include <linux/compat.h>
#include <linux/mm.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
@@ -527,14 +528,17 @@ static int mon_bin_open(struct inode *inode, struct file *file)
size_t size;
int rc;
+ lock_kernel();
mutex_lock(&mon_lock);
if ((mbus = mon_bus_lookup(iminor(inode))) == NULL) {
mutex_unlock(&mon_lock);
+ unlock_kernel();
return -ENODEV;
}
if (mbus != &mon_bus0 && mbus->u_bus == NULL) {
printk(KERN_ERR TAG ": consistency error on open\n");
mutex_unlock(&mon_lock);
+ unlock_kernel();
return -ENODEV;
}
@@ -568,6 +572,7 @@ static int mon_bin_open(struct inode *inode, struct file *file)
file->private_data = rp;
mutex_unlock(&mon_lock);
+ unlock_kernel();
return 0;
err_allocbuff:
@@ -576,6 +581,7 @@ err_allocvec:
kfree(rp);
err_alloc:
mutex_unlock(&mon_lock);
+ unlock_kernel();
return rc;
}
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 776f7fcd2fb..33ebdb198da 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1326,20 +1326,27 @@ fb_open(struct inode *inode, struct file *file)
if (fbidx >= FB_MAX)
return -ENODEV;
+ lock_kernel();
#ifdef CONFIG_KMOD
if (!(info = registered_fb[fbidx]))
try_to_load(fbidx);
#endif /* CONFIG_KMOD */
- if (!(info = registered_fb[fbidx]))
- return -ENODEV;
- if (!try_module_get(info->fbops->owner))
- return -ENODEV;
+ if (!(info = registered_fb[fbidx])) {
+ res = -ENODEV;
+ goto out;
+ }
+ if (!try_module_get(info->fbops->owner)) {
+ res = -ENODEV;
+ goto out;
+ }
file->private_data = info;
if (info->fbops->fb_open) {
res = info->fbops->fb_open(info,1);
if (res)
module_put(info->fbops->owner);
}
+out:
+ unlock_kernel();
return res;
}
diff --git a/fs/char_dev.c b/fs/char_dev.c
index 68e510b8845..3cb7cda3d78 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -373,6 +373,8 @@ static int chrdev_open(struct inode *inode, struct file *filp)
return -ENXIO;
new = container_of(kobj, struct cdev, kobj);
spin_lock(&cdev_lock);
+ /* Check i_cdev again in case somebody beat us to it while
+ we dropped the lock. */
p = inode->i_cdev;
if (!p) {
inode->i_cdev = p = new;
@@ -392,11 +394,8 @@ static int chrdev_open(struct inode *inode, struct file *filp)
cdev_put(p);
return -ENXIO;
}
- if (filp->f_op->open) {
- lock_kernel();
+ if (filp->f_op->open)
ret = filp->f_op->open(inode,filp);
- unlock_kernel();
- }
if (ret)
cdev_put(p);
return ret;
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 86b4d5f405a..22857c639df 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -612,7 +612,7 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
if (retval < 0)
return (loff_t)retval;
}
- return remote_llseek(file, offset, origin);
+ return generic_file_llseek_unlocked(file, offset, origin);
}
struct file_system_type cifs_fs_type = {
diff --git a/fs/dlm/user.c b/fs/dlm/user.c
index ebbcf38fd33..f976f303c19 100644
--- a/fs/dlm/user.c
+++ b/fs/dlm/user.c
@@ -15,6 +15,7 @@
#include <linux/poll.h>
#include <linux/signal.h>
#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
#include <linux/dlm.h>
#include <linux/dlm_device.h>
@@ -618,13 +619,17 @@ static int device_open(struct inode *inode, struct file *file)
struct dlm_user_proc *proc;
struct dlm_ls *ls;
+ lock_kernel();
ls = dlm_find_lockspace_device(iminor(inode));
- if (!ls)
+ if (!ls) {
+ unlock_kernel();
return -ENOENT;
+ }
proc = kzalloc(sizeof(struct dlm_user_proc), GFP_KERNEL);
if (!proc) {
dlm_put_lockspace(ls);
+ unlock_kernel();
return -ENOMEM;
}
@@ -636,6 +641,7 @@ static int device_open(struct inode *inode, struct file *file)
spin_lock_init(&proc->locks_spin);
init_waitqueue_head(&proc->wait);
file->private_data = proc;
+ unlock_kernel();
return 0;
}
@@ -870,6 +876,7 @@ static unsigned int device_poll(struct file *file, poll_table *wait)
static int ctl_device_open(struct inode *inode, struct file *file)
{
+ cycle_kernel_lock();
file->private_data = NULL;
return 0;
}
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
index 2258b8f654a..24749bf0668 100644
--- a/fs/ecryptfs/file.c
+++ b/fs/ecryptfs/file.c
@@ -30,6 +30,7 @@
#include <linux/security.h>
#include <linux/compat.h>
#include <linux/fs_stack.h>
+#include <linux/smp_lock.h>
#include "ecryptfs_kernel.h"
/**
@@ -277,9 +278,11 @@ static int ecryptfs_fasync(int fd, struct file *file, int flag)
int rc = 0;
struct file *lower_file = NULL;
+ lock_kernel();
lower_file = ecryptfs_file_to_lower(file);
if (lower_file->f_op && lower_file->f_op->fasync)
rc = lower_file->f_op->fasync(fd, lower_file, flag);
+ unlock_kernel();
return rc;
}
diff --git a/fs/fat/cache.c b/fs/fat/cache.c
index fda25479af2..3a9ecac8d61 100644
--- a/fs/fat/cache.c
+++ b/fs/fat/cache.c
@@ -61,7 +61,7 @@ void fat_cache_destroy(void)
static inline struct fat_cache *fat_cache_alloc(struct inode *inode)
{
- return kmem_cache_alloc(fat_cache_cachep, GFP_KERNEL);
+ return kmem_cache_alloc(fat_cache_cachep, GFP_NOFS);
}
static inline void fat_cache_free(struct fat_cache *cache)
diff --git a/fs/fat/dir.c b/fs/fat/dir.c
index 486725ee99a..34541d06e62 100644
--- a/fs/fat/dir.c
+++ b/fs/fat/dir.c
@@ -472,7 +472,7 @@ static int __fat_readdir(struct inode *inode, struct file *filp, void *dirent,
loff_t cpos;
int ret = 0;
- lock_kernel();
+ lock_super(sb);
cpos = filp->f_pos;
/* Fake . and .. for the root directory. */
@@ -654,7 +654,7 @@ FillFailed:
if (unicode)
__putname(unicode);
out:
- unlock_kernel();
+ unlock_super(sb);
return ret;
}
diff --git a/fs/fat/file.c b/fs/fat/file.c
index 771326b8047..c672df4036e 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -11,7 +11,6 @@
#include <linux/mount.h>
#include <linux/time.h>
#include <linux/msdos_fs.h>
-#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
#include <linux/writeback.h>
#include <linux/backing-dev.h>
@@ -242,9 +241,7 @@ void fat_truncate(struct inode *inode)
nr_clusters = (inode->i_size + (cluster_size - 1)) >> sbi->cluster_bits;
- lock_kernel();
fat_free(inode, nr_clusters);
- unlock_kernel();
fat_flush_inodes(inode->i_sb, inode, NULL);
}
@@ -310,8 +307,6 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr)
int error = 0;
unsigned int ia_valid;
- lock_kernel();
-
/*
* Expand the file. Since inode_setattr() updates ->i_size
* before calling the ->truncate(), but FAT needs to fill the
@@ -366,7 +361,6 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr)
error = inode_setattr(inode, attr);
out:
- unlock_kernel();
return error;
}
EXPORT_SYMBOL_GPL(fat_setattr);
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 4e0a3dd9d67..46a4508ffd2 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -440,14 +440,13 @@ static void fat_delete_inode(struct inode *inode)
static void fat_clear_inode(struct inode *inode)
{
- struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
+ struct super_block *sb = inode->i_sb;
+ struct msdos_sb_info *sbi = MSDOS_SB(sb);
- lock_kernel();
spin_lock(&sbi->inode_hash_lock);
fat_cache_inval_inode(inode);
hlist_del_init(&MSDOS_I(inode)->i_fat_hash);
spin_unlock(&sbi->inode_hash_lock);
- unlock_kernel();
}
static void fat_write_super(struct super_block *sb)
@@ -485,7 +484,7 @@ static struct kmem_cache *fat_inode_cachep;
static struct inode *fat_alloc_inode(struct super_block *sb)
{
struct msdos_inode_info *ei;
- ei = kmem_cache_alloc(fat_inode_cachep, GFP_KERNEL);
+ ei = kmem_cache_alloc(fat_inode_cachep, GFP_NOFS);
if (!ei)
return NULL;
return &ei->vfs_inode;
@@ -567,7 +566,7 @@ retry:
if (inode->i_ino == MSDOS_ROOT_INO || !i_pos)
return 0;
- lock_kernel();
+ lock_super(sb);
bh = sb_bread(sb, i_pos >> sbi->dir_per_block_bits);
if (!bh) {
printk(KERN_ERR "FAT: unable to read inode block "
@@ -579,7 +578,7 @@ retry:
if (i_pos != MSDOS_I(inode)->i_pos) {
spin_unlock(&sbi->inode_hash_lock);
brelse(bh);
- unlock_kernel();
+ unlock_super(sb);
goto retry;
}
@@ -606,7 +605,7 @@ retry:
err = sync_dirty_buffer(bh);
brelse(bh);
out:
- unlock_kernel();
+ unlock_super(sb);
return err;
}
@@ -736,6 +735,7 @@ fat_encode_fh(struct dentry *de, __u32 *fh, int *lenp, int connectable)
static struct dentry *fat_get_parent(struct dentry *child)
{
+ struct super_block *sb = child->d_sb;
struct buffer_head *bh;
struct msdos_dir_entry *de;
loff_t i_pos;
@@ -743,14 +743,14 @@ static struct dentry *fat_get_parent(struct dentry *child)
struct inode *inode;
int err;
- lock_kernel();
+ lock_super(sb);
err = fat_get_dotdot_entry(child->d_inode, &bh, &de, &i_pos);
if (err) {
parent = ERR_PTR(err);
goto out;
}
- inode = fat_build_inode(child->d_sb, de, i_pos);
+ inode = fat_build_inode(sb, de, i_pos);
brelse(bh);
if (IS_ERR(inode)) {
parent = ERR_CAST(inode);
@@ -762,7 +762,7 @@ static struct dentry *fat_get_parent(struct dentry *child)
parent = ERR_PTR(-ENOMEM);
}
out:
- unlock_kernel();
+ unlock_super(sb);
return parent;
}
@@ -1172,6 +1172,12 @@ int fat_fill_super(struct super_block *sb, void *data, int silent,
long error;
char buf[50];
+ /*
+ * GFP_KERNEL is ok here, because while we do hold the
+ * supeblock lock, memory pressure can't call back into
+ * the filesystem, since we're only just about to mount
+ * it and have no inodes etc active!
+ */
sbi = kzalloc(sizeof(struct msdos_sb_info), GFP_KERNEL);
if (!sbi)
return -ENOMEM;
diff --git a/fs/fcntl.c b/fs/fcntl.c
index bfd776509a7..330a7d78259 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -12,7 +12,6 @@
#include <linux/fdtable.h>
#include <linux/capability.h>
#include <linux/dnotify.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/security.h>
@@ -227,7 +226,6 @@ static int setfl(int fd, struct file * filp, unsigned long arg)
if (error)
return error;
- lock_kernel();
if ((arg ^ filp->f_flags) & FASYNC) {
if (filp->f_op && filp->f_op->fasync) {
error = filp->f_op->fasync(fd, filp, (arg & FASYNC) != 0);
@@ -238,7 +236,6 @@ static int setfl(int fd, struct file * filp, unsigned long arg)
filp->f_flags = (arg & SETFL_MASK) | (filp->f_flags & ~SETFL_MASK);
out:
- unlock_kernel();
return error;
}
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c
index e1b7d525a06..24dd5945008 100644
--- a/fs/gfs2/ops_file.c
+++ b/fs/gfs2/ops_file.c
@@ -62,11 +62,11 @@ static loff_t gfs2_llseek(struct file *file, loff_t offset, int origin)
error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY,
&i_gh);
if (!error) {
- error = remote_llseek(file, offset, origin);
+ error = generic_file_llseek_unlocked(file, offset, origin);
gfs2_glock_dq_uninit(&i_gh);
}
} else
- error = remote_llseek(file, offset, origin);
+ error = generic_file_llseek_unlocked(file, offset, origin);
return error;
}
diff --git a/fs/msdos/namei.c b/fs/msdos/namei.c
index 05ff4f1d702..1f7f2956412 100644
--- a/fs/msdos/namei.c
+++ b/fs/msdos/namei.c
@@ -214,7 +214,7 @@ static struct dentry *msdos_lookup(struct inode *dir, struct dentry *dentry,
dentry->d_op = &msdos_dentry_operations;
- lock_kernel();
+ lock_super(sb);
res = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo);
if (res == -ENOENT)
goto add;
@@ -232,7 +232,7 @@ add:
if (dentry)
dentry->d_op = &msdos_dentry_operations;
out:
- unlock_kernel();
+ unlock_super(sb);
if (!res)
return dentry;
return ERR_PTR(res);
@@ -286,7 +286,7 @@ static int msdos_create(struct inode *dir, struct dentry *dentry, int mode,
unsigned char msdos_name[MSDOS_NAME];
int err, is_hid;
- lock_kernel();
+ lock_super(sb);
err = msdos_format_name(dentry->d_name.name, dentry->d_name.len,
msdos_name, &MSDOS_SB(sb)->options);
@@ -315,7 +315,7 @@ static int msdos_create(struct inode *dir, struct dentry *dentry, int mode,
d_instantiate(dentry, inode);
out:
- unlock_kernel();
+ unlock_super(sb);
if (!err)
err = fat_flush_inodes(sb, dir, inode);
return err;
@@ -324,11 +324,12 @@ out:
/***** Remove a directory */
static int msdos_rmdir(struct inode *dir, struct dentry *dentry)
{
+ struct super_block *sb = dir->i_sb;
struct inode *inode = dentry->d_inode;
struct fat_slot_info sinfo;
int err;
- lock_kernel();
+ lock_super(sb);
/*
* Check whether the directory is not in use, then check
* whether it is empty.
@@ -349,9 +350,9 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry)
inode->i_ctime = CURRENT_TIME_SEC;
fat_detach(inode);
out:
- unlock_kernel();
+ unlock_super(sb);
if (!err)
- err = fat_flush_inodes(inode->i_sb, dir, inode);
+ err = fat_flush_inodes(sb, dir, inode);
return err;
}
@@ -366,7 +367,7 @@ static int msdos_mkdir(struct inode *dir, struct dentry *dentry, int mode)
struct timespec ts;
int err, is_hid, cluster;
- lock_kernel();
+ lock_super(sb);
err = msdos_format_name(dentry->d_name.name, dentry->d_name.len,
msdos_name, &MSDOS_SB(sb)->options);
@@ -404,14 +405,14 @@ static int msdos_mkdir(struct inode *dir, struct dentry *dentry, int mode)
d_instantiate(dentry, inode);
- unlock_kernel();
+ unlock_super(sb);
fat_flush_inodes(sb, dir, inode);
return 0;
out_free:
fat_free_clusters(dir, cluster);
out:
- unlock_kernel();
+ unlock_super(sb);
return err;
}
@@ -419,10 +420,11 @@ out:
static int msdos_unlink(struct inode *dir, struct dentry *dentry)
{
struct inode *inode = dentry->d_inode;
+ struct super_block *sb= inode->i_sb;
struct fat_slot_info sinfo;
int err;
- lock_kernel();
+ lock_super(sb);
err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo);
if (err)
goto out;
@@ -434,9 +436,9 @@ static int msdos_unlink(struct inode *dir, struct dentry *dentry)
inode->i_ctime = CURRENT_TIME_SEC;
fat_detach(inode);
out:
- unlock_kernel();
+ unlock_super(sb);
if (!err)
- err = fat_flush_inodes(inode->i_sb, dir, inode);
+ err = fat_flush_inodes(sb, dir, inode);
return err;
}
@@ -618,10 +620,11 @@ error_inode:
static int msdos_rename(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry)
{
+ struct super_block *sb = old_dir->i_sb;
unsigned char old_msdos_name[MSDOS_NAME], new_msdos_name[MSDOS_NAME];
int err, is_hid;
- lock_kernel();
+ lock_super(sb);
err = msdos_format_name(old_dentry->d_name.name,
old_dentry->d_name.len, old_msdos_name,
@@ -640,9 +643,9 @@ static int msdos_rename(struct inode *old_dir, struct dentry *old_dentry,
err = do_msdos_rename(old_dir, old_msdos_name, old_dentry,
new_dir, new_msdos_name, new_dentry, is_hid);
out:
- unlock_kernel();
+ unlock_super(sb);
if (!err)
- err = fat_flush_inodes(old_dir->i_sb, old_dir, new_dir);
+ err = fat_flush_inodes(sb, old_dir, new_dir);
return err;
}
diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c
index 2b145de45b3..6a7d901f193 100644
--- a/fs/ncpfs/file.c
+++ b/fs/ncpfs/file.c
@@ -18,6 +18,7 @@
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include <linux/ncp_fs.h>
#include "ncplib_kernel.h"
@@ -281,9 +282,18 @@ static int ncp_release(struct inode *inode, struct file *file) {
return 0;
}
+static loff_t ncp_remote_llseek(struct file *file, loff_t offset, int origin)
+{
+ loff_t ret;
+ lock_kernel();
+ ret = generic_file_llseek_unlocked(file, offset, origin);
+ unlock_kernel();
+ return ret;
+}
+
const struct file_operations ncp_file_operations =
{
- .llseek = remote_llseek,
+ .llseek = ncp_remote_llseek,
.read = ncp_file_read,
.write = ncp_file_write,
.ioctl = ncp_ioctl,
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index d84a3d8f32a..4e98a56a177 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -170,6 +170,7 @@ force_reval:
static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin)
{
+ loff_t loff;
/* origin == SEEK_END => we must revalidate the cached file length */
if (origin == SEEK_END) {
struct inode *inode = filp->f_mapping->host;
@@ -177,7 +178,10 @@ static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin)
if (retval < 0)
return (loff_t)retval;
}
- return remote_llseek(filp, offset, origin);
+ lock_kernel(); /* BKL needed? */
+ loff = generic_file_llseek_unlocked(filp, offset, origin);
+ unlock_kernel();
+ return loff;
}
/*
diff --git a/fs/ocfs2/stack_user.c b/fs/ocfs2/stack_user.c
index c021280dd46..bd7e0f3acfc 100644
--- a/fs/ocfs2/stack_user.c
+++ b/fs/ocfs2/stack_user.c
@@ -21,6 +21,7 @@
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/mutex.h>
+#include <linux/smp_lock.h>
#include <linux/reboot.h>
#include <asm/uaccess.h>
@@ -619,10 +620,12 @@ static int ocfs2_control_open(struct inode *inode, struct file *file)
return -ENOMEM;
p->op_this_node = -1;
+ lock_kernel();
mutex_lock(&ocfs2_control_lock);
file->private_data = p;
list_add(&p->op_list, &ocfs2_control_private_list);
mutex_unlock(&ocfs2_control_lock);
+ unlock_kernel();
return 0;
}
diff --git a/fs/read_write.c b/fs/read_write.c
index f0d1240a5c6..9ba495d5a29 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -31,12 +31,12 @@ const struct file_operations generic_ro_fops = {
EXPORT_SYMBOL(generic_ro_fops);
-loff_t generic_file_llseek(struct file *file, loff_t offset, int origin)
+loff_t
+generic_file_llseek_unlocked(struct file *file, loff_t offset, int origin)
{
loff_t retval;
struct inode *inode = file->f_mapping->host;
- mutex_lock(&inode->i_mutex);
switch (origin) {
case SEEK_END:
offset += inode->i_size;
@@ -46,42 +46,26 @@ loff_t generic_file_llseek(struct file *file, loff_t offset, int origin)
}
retval = -EINVAL;
if (offset>=0 && offset<=inode->i_sb->s_maxbytes) {
+ /* Special lock needed here? */
if (offset != file->f_pos) {
file->f_pos = offset;
file->f_version = 0;
}
retval = offset;
}
- mutex_unlock(&inode->i_mutex);
return retval;
}
+EXPORT_SYMBOL(generic_file_llseek_unlocked);
-EXPORT_SYMBOL(generic_file_llseek);
-
-loff_t remote_llseek(struct file *file, loff_t offset, int origin)
+loff_t generic_file_llseek(struct file *file, loff_t offset, int origin)
{
- loff_t retval;
-
- lock_kernel();
- switch (origin) {
- case SEEK_END:
- offset += i_size_read(file->f_path.dentry->d_inode);
- break;
- case SEEK_CUR:
- offset += file->f_pos;
- }
- retval = -EINVAL;
- if (offset>=0 && offset<=file->f_path.dentry->d_inode->i_sb->s_maxbytes) {
- if (offset != file->f_pos) {
- file->f_pos = offset;
- file->f_version = 0;
- }
- retval = offset;
- }
- unlock_kernel();
- return retval;
+ loff_t n;
+ mutex_lock(&file->f_dentry->d_inode->i_mutex);
+ n = generic_file_llseek_unlocked(file, offset, origin);
+ mutex_unlock(&file->f_dentry->d_inode->i_mutex);
+ return n;
}
-EXPORT_SYMBOL(remote_llseek);
+EXPORT_SYMBOL(generic_file_llseek);
loff_t no_llseek(struct file *file, loff_t offset, int origin)
{
diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c
index efbe29af3d7..2294783320c 100644
--- a/fs/smbfs/file.c
+++ b/fs/smbfs/file.c
@@ -422,9 +422,18 @@ smb_file_permission(struct inode *inode, int mask, struct nameidata *nd)
return error;
}
+static loff_t smb_remote_llseek(struct file *file, loff_t offset, int origin)
+{
+ loff_t ret;
+ lock_kernel();
+ ret = generic_file_llseek_unlocked(file, offset, origin);
+ unlock_kernel();
+ return ret;
+}
+
const struct file_operations smb_file_operations =
{
- .llseek = remote_llseek,
+ .llseek = smb_remote_llseek,
.read = do_sync_read,
.aio_read = smb_file_aio_read,
.write = do_sync_write,
diff --git a/fs/vfat/namei.c b/fs/vfat/namei.c
index a3522727ea5..b546ba69be8 100644
--- a/fs/vfat/namei.c
+++ b/fs/vfat/namei.c
@@ -645,7 +645,7 @@ static int vfat_add_entry(struct inode *dir, struct qstr *qname, int is_dir,
if (len == 0)
return -ENOENT;
- slots = kmalloc(sizeof(*slots) * MSDOS_SLOTS, GFP_KERNEL);
+ slots = kmalloc(sizeof(*slots) * MSDOS_SLOTS, GFP_NOFS);
if (slots == NULL)
return -ENOMEM;
@@ -687,7 +687,7 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry,
struct dentry *alias;
int err, table;
- lock_kernel();
+ lock_super(sb);
table = (MSDOS_SB(sb)->options.name_check == 's') ? 2 : 0;
dentry->d_op = &vfat_dentry_ops[table];
@@ -699,7 +699,7 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry,
inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos);
brelse(sinfo.bh);
if (IS_ERR(inode)) {
- unlock_kernel();
+ unlock_super(sb);
return ERR_CAST(inode);
}
alias = d_find_alias(inode);
@@ -708,13 +708,13 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry,
dput(alias);
else {
iput(inode);
- unlock_kernel();
+ unlock_super(sb);
return alias;
}
}
error:
- unlock_kernel();
+ unlock_super(sb);
dentry->d_op = &vfat_dentry_ops[table];
dentry->d_time = dentry->d_parent->d_inode->i_version;
dentry = d_splice_alias(inode, dentry);
@@ -734,7 +734,7 @@ static int vfat_create(struct inode *dir, struct dentry *dentry, int mode,
struct timespec ts;
int err;
- lock_kernel();
+ lock_super(sb);
ts = CURRENT_TIME_SEC;
err = vfat_add_entry(dir, &dentry->d_name, 0, 0, &ts, &sinfo);
@@ -755,17 +755,18 @@ static int vfat_create(struct inode *dir, struct dentry *dentry, int mode,
dentry->d_time = dentry->d_parent->d_inode->i_version;
d_instantiate(dentry, inode);
out:
- unlock_kernel();
+ unlock_super(sb);
return err;
}
static int vfat_rmdir(struct inode *dir, struct dentry *dentry)
{
struct inode *inode = dentry->d_inode;
+ struct super_block *sb = dir->i_sb;
struct fat_slot_info sinfo;
int err;
- lock_kernel();
+ lock_super(sb);
err = fat_dir_empty(inode);
if (err)
@@ -783,7 +784,7 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry)
inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
fat_detach(inode);
out:
- unlock_kernel();
+ unlock_super(sb);
return err;
}
@@ -791,10 +792,11 @@ out:
static int vfat_unlink(struct inode *dir, struct dentry *dentry)
{
struct inode *inode = dentry->d_inode;
+ struct super_block *sb = dir->i_sb;
struct fat_slot_info sinfo;
int err;
- lock_kernel();
+ lock_super(sb);
err = vfat_find(dir, &dentry->d_name, &sinfo);
if (err)
@@ -807,7 +809,7 @@ static int vfat_unlink(struct inode *dir, struct dentry *dentry)
inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
fat_detach(inode);
out:
- unlock_kernel();
+ unlock_super(sb);
return err;
}
@@ -820,7 +822,7 @@ static int vfat_mkdir(struct inode *dir, struct dentry *dentry, int mode)
struct timespec ts;
int err, cluster;
- lock_kernel();
+ lock_super(sb);
ts = CURRENT_TIME_SEC;
cluster = fat_alloc_new_dir(dir, &ts);
@@ -849,13 +851,13 @@ static int vfat_mkdir(struct inode *dir, struct dentry *dentry, int mode)
dentry->d_time = dentry->d_parent->d_inode->i_version;
d_instantiate(dentry, inode);
- unlock_kernel();
+ unlock_super(sb);
return 0;
out_free:
fat_free_clusters(dir, cluster);
out:
- unlock_kernel();
+ unlock_super(sb);
return err;
}
@@ -869,11 +871,12 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
struct timespec ts;
loff_t dotdot_i_pos, new_i_pos;
int err, is_dir, update_dotdot, corrupt = 0;
+ struct super_block *sb = old_dir->i_sb;
old_sinfo.bh = sinfo.bh = dotdot_bh = NULL;
old_inode = old_dentry->d_inode;
new_inode = new_dentry->d_inode;
- lock_kernel();
+ lock_super(sb);
err = vfat_find(old_dir, &old_dentry->d_name, &old_sinfo);
if (err)
goto out;
@@ -951,7 +954,7 @@ out:
brelse(sinfo.bh);
brelse(dotdot_bh);
brelse(old_sinfo.bh);
- unlock_kernel();
+ unlock_super(sb);
return err;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index d8e2762ed14..faac13e2cc5 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1870,7 +1870,8 @@ extern void
file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping);
extern loff_t no_llseek(struct file *file, loff_t offset, int origin);
extern loff_t generic_file_llseek(struct file *file, loff_t offset, int origin);
-extern loff_t remote_llseek(struct file *file, loff_t offset, int origin);
+extern loff_t generic_file_llseek_unlocked(struct file *file, loff_t offset,
+ int origin);
extern int generic_file_open(struct inode * inode, struct file * filp);
extern int nonseekable_open(struct inode * inode, struct file * filp);
diff --git a/include/linux/smp_lock.h b/include/linux/smp_lock.h
index aab3a4cff4e..813be59bf34 100644
--- a/include/linux/smp_lock.h
+++ b/include/linux/smp_lock.h
@@ -27,11 +27,24 @@ static inline int reacquire_kernel_lock(struct task_struct *task)
extern void __lockfunc lock_kernel(void) __acquires(kernel_lock);
extern void __lockfunc unlock_kernel(void) __releases(kernel_lock);
+/*
+ * Various legacy drivers don't really need the BKL in a specific
+ * function, but they *do* need to know that the BKL became available.
+ * This function just avoids wrapping a bunch of lock/unlock pairs
+ * around code which doesn't really need it.
+ */
+static inline void cycle_kernel_lock(void)
+{
+ lock_kernel();
+ unlock_kernel();
+}
+
#else
#define lock_kernel() do { } while(0)
#define unlock_kernel() do { } while(0)
#define release_kernel_lock(task) do { } while(0)
+#define cycle_kernel_lock() do { } while(0)
#define reacquire_kernel_lock(task) 0
#define kernel_locked() 1
diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c
index 0afe32be4c8..8cb75702638 100644
--- a/kernel/pm_qos_params.c
+++ b/kernel/pm_qos_params.c
@@ -29,6 +29,7 @@
#include <linux/pm_qos_params.h>
#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/time.h>
@@ -358,15 +359,19 @@ static int pm_qos_power_open(struct inode *inode, struct file *filp)
int ret;
long pm_qos_class;
+ lock_kernel();
pm_qos_class = find_pm_qos_object_by_minor(iminor(inode));
if (pm_qos_class >= 0) {
filp->private_data = (void *)pm_qos_class;
sprintf(name, "process_%d", current->pid);
ret = pm_qos_add_requirement(pm_qos_class, name,
PM_QOS_DEFAULT_VALUE);
- if (ret >= 0)
+ if (ret >= 0) {
+ unlock_kernel();
return 0;
+ }
}
+ unlock_kernel();
return -EPERM;
}
diff --git a/net/irda/irnet/irnet.h b/net/irda/irnet/irnet.h
index b001c361ad3..bccf4d0059f 100644
--- a/net/irda/irnet/irnet.h
+++ b/net/irda/irnet/irnet.h
@@ -241,6 +241,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/smp_lock.h>
#include <linux/skbuff.h>
#include <linux/tty.h>
#include <linux/proc_fs.h>
diff --git a/net/irda/irnet/irnet_ppp.c b/net/irda/irnet/irnet_ppp.c
index e0eab5927c4..e84a70dd346 100644
--- a/net/irda/irnet/irnet_ppp.c
+++ b/net/irda/irnet/irnet_ppp.c
@@ -479,6 +479,7 @@ dev_irnet_open(struct inode * inode,
ap = kzalloc(sizeof(*ap), GFP_KERNEL);
DABORT(ap == NULL, -ENOMEM, FS_ERROR, "Can't allocate struct irnet...\n");
+ lock_kernel();
/* initialize the irnet structure */
ap->file = file;
@@ -500,6 +501,7 @@ dev_irnet_open(struct inode * inode,
{
DERROR(FS_ERROR, "Can't setup IrDA link...\n");
kfree(ap);
+ unlock_kernel();
return err;
}
@@ -510,6 +512,7 @@ dev_irnet_open(struct inode * inode,
file->private_data = ap;
DEXIT(FS_TRACE, " - ap=0x%p\n", ap);
+ unlock_kernel();
return 0;
}
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 61f5d425b63..c49b9d9e303 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -22,6 +22,7 @@
#include <linux/mm.h>
#include <linux/file.h>
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <linux/time.h>
#include <linux/pm_qos_params.h>
#include <linux/uio.h>
@@ -3249,14 +3250,17 @@ static int snd_pcm_fasync(int fd, struct file * file, int on)
struct snd_pcm_file * pcm_file;
struct snd_pcm_substream *substream;
struct snd_pcm_runtime *runtime;
- int err;
+ int err = -ENXIO;
+ lock_kernel();
pcm_file = file->private_data;
substream = pcm_file->substream;
- snd_assert(substream != NULL, return -ENXIO);
+ snd_assert(substream != NULL, goto out);
runtime = substream->runtime;
err = fasync_helper(fd, file, on, &runtime->fasync);
+out:
+ unlock_kernel();
if (err < 0)
return err;
return 0;
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 09a94953745..1003ae375d4 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -21,6 +21,7 @@
#include <linux/init.h>
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <linux/time.h>
#include <linux/device.h>
#include <linux/moduleparam.h>
@@ -121,7 +122,7 @@ void *snd_lookup_minor_data(unsigned int minor, int type)
EXPORT_SYMBOL(snd_lookup_minor_data);
-static int snd_open(struct inode *inode, struct file *file)
+static int __snd_open(struct inode *inode, struct file *file)
{
unsigned int minor = iminor(inode);
struct snd_minor *mptr = NULL;
@@ -163,6 +164,18 @@ static int snd_open(struct inode *inode, struct file *file)
return err;
}
+
+/* BKL pushdown: nasty #ifdef avoidance wrapper */
+static int snd_open(struct inode *inode, struct file *file)
+{
+ int ret;
+
+ lock_kernel();
+ ret = __snd_open(inode, file);
+ unlock_kernel();
+ return ret;
+}
+
static const struct file_operations snd_fops =
{
.owner = THIS_MODULE,
diff --git a/sound/sound_core.c b/sound/sound_core.c
index 46daca17550..dcfc1d5ce63 100644
--- a/sound/sound_core.c
+++ b/sound/sound_core.c
@@ -37,6 +37,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
+#include <linux/smp_lock.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/fs.h>
@@ -464,6 +465,8 @@ int soundcore_open(struct inode *inode, struct file *file)
struct sound_unit *s;
const struct file_operations *new_fops = NULL;
+ lock_kernel ();
+
chain=unit&0x0F;
if(chain==4 || chain==5) /* dsp/audio/dsp16 */
{
@@ -511,9 +514,11 @@ int soundcore_open(struct inode *inode, struct file *file)
file->f_op = fops_get(old_fops);
}
fops_put(old_fops);
+ unlock_kernel();
return err;
}
spin_unlock(&sound_loader_lock);
+ unlock_kernel();
return -ENODEV;
}