From 75bd2ef1457998791cfc89cd59927574488fc22a Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 09:09:23 -0600 Subject: [PATCH 001/146] bsg: cdev lock_kernel() pushdown Push the cdev lock_kernel call into bsg_open(). Signed-off-by: Jonathan Corbet --- block/bsg.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/block/bsg.c b/block/bsg.c index f0b7cd343216..dbe3ffd505ca 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -834,7 +835,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); From 0c401df37ef9f45f35390a5574e24cbf3f916acf Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 09:10:18 -0600 Subject: [PATCH 002/146] cris: cdev lock_kernel() pushdown Push the cdev lock_kernel() call into cris drivers. Signed-off-by: Jonathan Corbet --- arch/cris/arch-v10/drivers/gpio.c | 3 ++ arch/cris/arch-v10/drivers/sync_serial.c | 34 ++++++++++++++--------- arch/cris/arch-v32/drivers/mach-a3/gpio.c | 4 +++ arch/cris/arch-v32/drivers/mach-fs/gpio.c | 5 +++- arch/cris/arch-v32/drivers/sync_serial.c | 33 +++++++++++++--------- 5 files changed, 52 insertions(+), 27 deletions(-) diff --git a/arch/cris/arch-v10/drivers/gpio.c b/arch/cris/arch-v10/drivers/gpio.c index 68a998bd1069..86048e697eb5 100644 --- a/arch/cris/arch-v10/drivers/gpio.c +++ b/arch/cris/arch-v10/drivers/gpio.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -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/sync_serial.c b/arch/cris/arch-v10/drivers/sync_serial.c index 069546e342c5..91fea623c7c9 100644 --- a/arch/cris/arch-v10/drivers/sync_serial.c +++ b/arch/cris/arch-v10/drivers/sync_serial.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -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/mach-a3/gpio.c b/arch/cris/arch-v32/drivers/mach-a3/gpio.c index de107dad9f4f..ef98608e5067 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 #include #include +#include #include #include @@ -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 7863fd4efc2b..fe1fde893887 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 #include #include +#include #include #include @@ -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 47c377df6fb3..d2a0fbf5341f 100644 --- a/arch/cris/arch-v32/drivers/sync_serial.c +++ b/arch/cris/arch-v32/drivers/sync_serial.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -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) From 7558da942e51933b5e6aa5e851d4da1df0cd6752 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 09:10:50 -0600 Subject: [PATCH 003/146] mips: cdev lock_kernel() pushdown Push the cdev lock_kernel() call into MIPS-specific drivers. Signed-off-by: Jonathan Corbet --- arch/mips/kernel/rtlx.c | 7 ++++++- arch/mips/kernel/vpe.c | 12 +++++++++--- arch/mips/sibyte/common/sb_tbprof.c | 25 ++++++++++++++++++------- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c index b88f1c18ff4d..b55641961232 100644 --- a/arch/mips/kernel/rtlx.c +++ b/arch/mips/kernel/rtlx.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -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 2794501ff302..972b2d2b8401 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -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 63b444eaf01e..28b012ab8dcb 100644 --- a/arch/mips/sibyte/common/sb_tbprof.c +++ b/arch/mips/sibyte/common/sb_tbprof.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -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) From 1fa984b583a809423ddb1d88fa46484071f85f80 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 09:11:26 -0600 Subject: [PATCH 004/146] sh: cdev lock_kernel() pushdown Push the cdev lock_kernel() call down into the sh gio driver. Signed-off-by: Jonathan Corbet --- arch/sh/boards/landisk/gio.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/arch/sh/boards/landisk/gio.c b/arch/sh/boards/landisk/gio.c index 17025080db35..0c15b0a50b99 100644 --- a/arch/sh/boards/landisk/gio.c +++ b/arch/sh/boards/landisk/gio.c @@ -14,6 +14,7 @@ */ #include #include +#include #include #include #include @@ -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) From 5119e92efc733d730b34f9605a5ae61fdc4bf649 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 09:12:01 -0600 Subject: [PATCH 005/146] x86: cdev lock_kernel() pushdown Push the cdev lock_kernel() call down into the x86 msr and cpuid drivers. Signed-off-by: Jonathan Corbet --- arch/x86/kernel/cpuid.c | 23 ++++++++++++++++------- arch/x86/kernel/msr.c | 16 ++++++++++++---- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c index daff52a62248..71f1c2654bec 100644 --- a/arch/x86/kernel/cpuid.c +++ b/arch/x86/kernel/cpuid.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -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); + unsigned int cpu; + struct cpuinfo_x86 *c; + int ret = 0; + + lock_kernel(); - if (cpu >= NR_CPUS || !cpu_online(cpu)) - return -ENXIO; /* No such CPU */ + 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/msr.c b/arch/x86/kernel/msr.c index 1f3abe048e93..a153b3905f60 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 */ + 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)) - return -EIO; /* MSR not supported */ - + ret = -EIO; /* MSR not supported */ +out: + unlock_kernel(); return 0; } From 3db633ee352bfe20d4a2b0c3c8a46ce31a6c7149 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 09:21:02 -0600 Subject: [PATCH 006/146] i2c: cdev lock_kernel() pushdown Signed-off-by: Jonathan Corbet --- drivers/i2c/i2c-dev.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index d34c14c81c29..006a5857256a 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c @@ -34,6 +34,7 @@ #include #include #include +#include #include 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) From 0911810755fc9f15659cc3cb43912633b90027a0 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 09:21:33 -0600 Subject: [PATCH 007/146] cosa: cdev lock_kernel() pushdown Signed-off-by: Jonathan Corbet --- drivers/net/wan/cosa.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c index b0fce1387eaf..5827324e9d9f 100644 --- a/drivers/net/wan/cosa.c +++ b/drivers/net/wan/cosa.c @@ -92,6 +92,7 @@ #include #include #include +#include #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<= cosa->nchannels) - return -ENODEV; + & ((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) From 0bec0bba7a507bdaf07312fcabdc00b5576abb32 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 09:25:03 -0600 Subject: [PATCH 008/146] pcmcia: cdev lock_kernel() pushdown Signed-off-by: Jonathan Corbet --- drivers/pcmcia/pcmcia_ioctl.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c index 5f186abca108..138396ef5be9 100644 --- a/drivers/pcmcia/pcmcia_ioctl.c +++ b/drivers/pcmcia/pcmcia_ioctl.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #define IN_CARD_SERVICES @@ -397,20 +398,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; @@ -419,7 +427,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; @@ -441,7 +450,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 */ /*====================================================================*/ From 51a776fa7a7997e726d4a478eda0854c6f9143bd Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 09:38:18 -0600 Subject: [PATCH 009/146] rtc: cdev lock_kernel() pushdown Signed-off-by: Jonathan Corbet --- drivers/rtc/rtc-dev.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index 90dfa0df747a..0114a78b7cbb 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c @@ -13,6 +13,7 @@ #include #include +#include #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; } From 764a4a8e54cdd6efc5928f876aa9e35778f22377 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 10:01:17 -0600 Subject: [PATCH 010/146] drivers/s390: cdev lock_kernel() pushdown Signed-off-by: Jonathan Corbet --- drivers/s390/char/fs3270.c | 23 ++++++++++++++++------- drivers/s390/char/tape_char.c | 12 +++++++++--- drivers/s390/char/vmlogrdr.c | 8 +++++++- drivers/s390/char/vmur.c | 12 +++++++++--- 4 files changed, 41 insertions(+), 14 deletions(-) diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c index ef36f2132aa4..b5ecd59676c4 100644 --- a/drivers/s390/char/fs3270.c +++ b/drivers/s390/char/fs3270.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -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/tape_char.c b/drivers/s390/char/tape_char.c index ebe84067bae9..687720b552d1 100644 --- a/drivers/s390/char/tape_char.c +++ b/drivers/s390/char/tape_char.c @@ -14,6 +14,7 @@ #include #include #include +#include #include @@ -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/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index e8487347e4d4..d101328a2980 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c @@ -25,6 +25,7 @@ #include #include #include +#include #include @@ -319,9 +320,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; @@ -365,7 +368,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) @@ -375,6 +380,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 83ae9a852f00..61549987ed70 100644 --- a/drivers/s390/char/vmur.c +++ b/drivers/s390/char/vmur.c @@ -9,6 +9,7 @@ */ #include +#include #include #include @@ -668,7 +669,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. @@ -676,8 +677,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) { @@ -720,6 +723,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: @@ -730,6 +734,8 @@ fail_unlock: spin_unlock(&urd->open_lock); fail_put: urdev_put(urd); +out: + unlock_kernel(); return rc; } From 579174a55f491edeaccb8f5d3dc7ad69a17f5423 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 10:03:09 -0600 Subject: [PATCH 011/146] AoE: cdev lock_kernel() pushdown Signed-off-by: Jonathan Corbet --- drivers/block/aoe/aoechr.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c index e8e60e7a2e70..d1de68a31920 100644 --- a/drivers/block/aoe/aoechr.c +++ b/drivers/block/aoe/aoechr.c @@ -7,6 +7,7 @@ #include #include #include +#include #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; } From ea2959a2972410f15155a015df74ce77ac79f8b8 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 10:07:56 -0600 Subject: [PATCH 012/146] paride: cdev lock_kernel() pushdown Signed-off-by: Jonathan Corbet --- drivers/block/paride/pg.c | 22 ++++++++++++++++------ drivers/block/paride/pt.c | 8 +++++++- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c index ab86e23ddc69..9d92636350e5 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 #include #include /* current, TASK_* */ +#include #include #include @@ -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 8b9549ab4a4e..314333db16ee 100644 --- a/drivers/block/paride/pt.c +++ b/drivers/block/paride/pt.c @@ -146,6 +146,7 @@ static int (*drives[4])[6] = {&drive0, &drive1, &drive2, &drive3}; #include #include #include /* current, TASK_*, schedule_timeout() */ +#include #include @@ -650,8 +651,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 +682,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; } From 6071239ef1947914892601e36785c7b1cf8b7dd4 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 10:10:37 -0600 Subject: [PATCH 013/146] mtdchar: cdev lock_kernel() pushdown Signed-off-by: Jonathan Corbet --- drivers/mtd/mtdchar.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 5d3ac512ce16..129d429cd2da 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -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 */ /*====================================================================*/ From 72b67048f5dac18fd6494e3d3bff7e54840e8761 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 10:15:38 -0600 Subject: [PATCH 014/146] UBI: cdev lock_kernel() pushdown Signed-off-by: Jonathan Corbet --- drivers/mtd/ubi/cdev.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 9d6aae5449b6..89193ba9451e 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -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); From 702e57d9ef7002f8d362faa6ddebc59e6d43fa05 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 10:25:44 -0600 Subject: [PATCH 015/146] HID: cdev lock_kernel() pushdown Signed-off-by: Jonathan Corbet --- drivers/hid/hidraw.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index 1ca6f4635eeb..2fde6c63f47d 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c @@ -30,6 +30,7 @@ #include #include #include +#include #include @@ -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; } From 2edbf8537edc62c9b0ef75e7025d01e8b6a48707 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 10:37:16 -0600 Subject: [PATCH 016/146] Input: cdev lock_kernel() pushdown Signed-off-by: Jonathan Corbet --- drivers/input/input.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/input/input.c b/drivers/input/input.c index 27006fc18305..408df0bd6be5 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -21,6 +21,7 @@ #include #include #include +#include MODULE_AUTHOR("Vojtech Pavlik "); 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; } From fbc8a81d66bbbce3f0b4d5752f8bc8bb3c1fc439 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 10:39:37 -0600 Subject: [PATCH 017/146] UIO: cdev lock_kernel() pushdown Signed-off-by: Jonathan Corbet --- drivers/uio/uio.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index 55cc7b80422a..1a0415e77a30 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; } From ecc38983f6c83f371fefb5a69a72e358fc7b1218 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 10:46:49 -0600 Subject: [PATCH 018/146] ipmi: cdev lock_kernel() pushdown Signed-off-by: Jonathan Corbet --- drivers/char/ipmi/ipmi_devintf.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index 0246a2b8ce48..c816656d6bfb 100644 --- a/drivers/char/ipmi/ipmi_devintf.c +++ b/drivers/char/ipmi/ipmi_devintf.c @@ -43,6 +43,7 @@ #include #include #include +#include struct ipmi_file_private { @@ -121,6 +122,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 +131,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 +146,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) From 1f439647a4072ec64bb2e4b9290cd7be6aee8328 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 11:04:19 -0600 Subject: [PATCH 019/146] mem: cdev lock_kernel() pushdown It's really hard to tell if this is necessary - lots of weird magic happens by way of map_devmem() Signed-off-by: Jonathan Corbet --- drivers/char/mem.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 934ffafedaea..070e22e8ea9e 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -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 = { From 309c4551c0fa0897d5343c36cbfbfa39f1f41b88 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 11:07:52 -0600 Subject: [PATCH 020/146] misc: cdev lock_kernel() pushdown misc_open() looks fine, but who knows what all of the misc drivers are doing in their open() functions? Signed-off-by: Jonathan Corbet --- drivers/char/misc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/char/misc.c b/drivers/char/misc.c index eaace0db0ff4..6e1563c3d30a 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c @@ -49,6 +49,7 @@ #include #include #include +#include /* * 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; } From 2d863e92ec1b1deb8167d7f5266f754f258e876a Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 11:16:21 -0600 Subject: [PATCH 021/146] viotape: cdev lock_kernel pushdown () Signed-off-by: Jonathan Corbet --- drivers/char/viotape.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index 58aad63831f4..af03d2709300 100644 --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -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; } From 12ead6b098b65dd21d3ed4fcccf20025dbe86cc2 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 11:24:23 -0600 Subject: [PATCH 022/146] mbcs: cdev lock_kernel() pushdown This driver would appear to have no internal locking at all. Signed-off-by: Jonathan Corbet --- drivers/char/mbcs.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/char/mbcs.c b/drivers/char/mbcs.c index f4716ad7348a..acd8e9ed474a 100644 --- a/drivers/char/mbcs.c +++ b/drivers/char/mbcs.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -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; } From abedd296e97a5d943e76999de97253f1b62a4846 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 11:29:38 -0600 Subject: [PATCH 023/146] lp: cdev lock_kernel() pushdown Signed-off-by: Jonathan Corbet --- drivers/char/lp.c | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/drivers/char/lp.c b/drivers/char/lp.c index 60ac642752be..71abb4c33aa2 100644 --- a/drivers/char/lp.c +++ b/drivers/char/lp.c @@ -126,6 +126,7 @@ #include #include #include +#include #include #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) From 70ffa16e604bab22b12bf72cb7796f1dd01ec335 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 11:34:16 -0600 Subject: [PATCH 024/146] drm: cdev lock_kernel() pushdown Signed-off-by: Jonathan Corbet --- drivers/char/drm/drm_fops.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c index 68f0da801ed8..7a25726f07f7 100644 --- a/drivers/char/drm/drm_fops.c +++ b/drivers/char/drm/drm_fops.c @@ -37,6 +37,7 @@ #include "drmP.h" #include "drm_sarea.h" #include +#include 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; } From 16750c2f32e3fd879fce787a13900f11633ef9af Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 11:58:31 -0600 Subject: [PATCH 025/146] phonedev: cdev lock_kernel() pushdown phone_open() looks OK, but I don't trust the subsidiary drivers (and ixj in particular). Signed-off-by: Jonathan Corbet --- drivers/telephony/phonedev.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/telephony/phonedev.c b/drivers/telephony/phonedev.c index bcea8d9b718c..4d74ba36c3a1 100644 --- a/drivers/telephony/phonedev.c +++ b/drivers/telephony/phonedev.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -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; } From 04f4ac9d1bb8a9103609ce8e927f8e98826ce339 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 12:01:56 -0600 Subject: [PATCH 026/146] ide-tape: cdev lock_kernel() pushdown ->release() already has explicit lock_kernel() calls... Signed-off-by: Jonathan Corbet --- drivers/ide/ide-tape.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 1e1f26331a24..a3d228302d20 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; } From eb09d3d4ee09b25876db549b6d5221610216e105 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 12:22:06 -0600 Subject: [PATCH 027/146] sg: cdev lock_kernel() pushdown Signed-off-by: Jonathan Corbet --- drivers/scsi/sg.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index c9d7f721b9e2..4284625ed035 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 #include #include +#include #include "scsi.h" #include @@ -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 */ /* 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; } From 647d87bd1b9e7ff24f89b7d4e38c75d756018caa Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 12:23:19 -0600 Subject: [PATCH 028/146] osst: cdev lock_kernel() pushdown. Signed-off-by: Jonathan Corbet --- drivers/scsi/osst.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c index 31f7aec44d90..24ad89a649ce 100644 --- a/drivers/scsi/osst.c +++ b/drivers/scsi/osst.c @@ -50,6 +50,7 @@ static const char * osst_version = "0.99.4"; #include #include #include +#include #include #include #include @@ -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) From d4514d1bed1c7157bcff4c81307a9e0374df257a Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 16:01:47 -0600 Subject: [PATCH 029/146] aacraid: cdev lock_kernel() pushdown Signed-off-by: Jonathan Corbet --- drivers/scsi/aacraid/linit.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 1f7c83607f84..68c140e82673 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -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; } From b3369c68bf9d61062585f3ebc1286220191c0f84 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 16:08:15 -0600 Subject: [PATCH 030/146] st: cdev lock_kernel() pushdown Signed-off-by: Jonathan Corbet --- drivers/scsi/st.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index e8db66ad0bde..e93544dd81bf 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -38,6 +38,7 @@ static const char *verstr = "20080224"; #include #include #include +#include #include #include @@ -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; } From 46787b481be00d5443d385480d12470728406cf4 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 16:09:48 -0600 Subject: [PATCH 031/146] gdth: cdev lock_kernel() pushdown Signed-off-by: Jonathan Corbet --- drivers/scsi/gdth.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index 46771d4c81bd..822d5214692b 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -120,6 +120,7 @@ #include #include #include +#include #ifdef GDTH_RTC #include @@ -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; From 1bcaa0bd6fd5b510dd9f1ba2da114d3f1253af61 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 16:16:28 -0600 Subject: [PATCH 032/146] isdn: cdev lock_kernel() pushdown Signed-off-by: Jonathan Corbet --- drivers/isdn/i4l/isdn_common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c index 0f3c66de69bc..5158c606ff5b 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; } From 20613f24bcd1cbfb08e64f0bb00c44481313b448 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 16:24:25 -0600 Subject: [PATCH 033/146] usbcore: cdev lock_kernel() pushdown usb_open() is protected by a down_read(&minor_rwsem), but I'm not sure I trust it to protect everything including subsidiary open() functions. Signed-off-by: Jonathan Corbet --- drivers/usb/core/file.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index 8133c99c6c5c..c6a95395e52a 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #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; } From 5794e1b14bcd9817c5fa27d3254996f0d9551296 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 16:26:57 -0600 Subject: [PATCH 034/146] dvb: cdev lock_kernel() pushdown Signed-off-by: Jonathan Corbet --- drivers/media/dvb/dvb-core/dvbdev.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c index 8b56d929f7fd..e208a60c048a 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.c +++ b/drivers/media/dvb/dvb-core/dvbdev.c @@ -32,6 +32,7 @@ #include #include #include +#include #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; } From fc7f687a6878e19f7ce58cb8a65659cd2730b586 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 16:30:36 -0600 Subject: [PATCH 035/146] fbmem: cdev lock_kernel() pushdown Signed-off-by: Jonathan Corbet --- drivers/video/fbmem.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 776f7fcd2fbf..33ebdb198daf 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; } From 78a3c3d7c6b89085610edfe86f7790144afc737e Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 16:39:03 -0600 Subject: [PATCH 036/146] sound: cdev lock_kernel() pushdown Signed-off-by: Jonathan Corbet --- sound/core/sound.c | 15 ++++++++++++++- sound/sound_core.c | 5 +++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/sound/core/sound.c b/sound/core/sound.c index 812f91b3de5b..65b66fa6f97e 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -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 46daca175502..dcfc1d5ce631 100644 --- a/sound/sound_core.c +++ b/sound/sound_core.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -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; } From c43ef17450dce8cbf50f97497a1949ff8f484e88 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 15 May 2008 16:44:14 -0600 Subject: [PATCH 037/146] snsc: cdev lock_kernel() pushdown Signed-off-by: Jonathan Corbet --- drivers/char/snsc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c index 8fe099a41065..0b799ac1b049 100644 --- a/drivers/char/snsc.c +++ b/drivers/char/snsc.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -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; } From 39d95b9d857ad9ed335dd1a2d6c6de1f1ee69ce1 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Fri, 16 May 2008 09:10:50 -0600 Subject: [PATCH 038/146] tty: cdev lock_kernel() pushdown Parts of the serial code actually BUG() if we don't do this. --- drivers/char/tty_io.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index e94bee032314..fd182f2e4a6c 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 /** From d21c95c569c462da20d491b75d0a45bd70ddc1bf Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Fri, 16 May 2008 13:40:30 -0600 Subject: [PATCH 039/146] Add "no BKL needed" comments to several drivers This documents the fact that somebody looked at the relevant open() functions and concluded that, due to their trivial nature, no locking was needed. Signed-off-by: Jonathan Corbet --- arch/cris/arch-v10/drivers/eeprom.c | 2 +- arch/cris/arch-v32/drivers/cryptocop.c | 2 +- drivers/char/cs5535_gpio.c | 2 ++ drivers/char/dtlk.c | 2 ++ drivers/char/pc8736x_gpio.c | 1 + drivers/char/ppdev.c | 1 + drivers/char/scx200_gpio.c | 1 + drivers/char/tb0219.c | 1 + drivers/char/vr41xx_giu.c | 2 ++ drivers/infiniband/core/ucm.c | 1 + drivers/infiniband/hw/ipath/ipath_file_ops.c | 1 + drivers/net/ppp_generic.c | 1 + drivers/scsi/3w-9xxx.c | 2 ++ drivers/scsi/3w-xxxx.c | 2 ++ drivers/scsi/megaraid.c | 5 +++-- drivers/scsi/megaraid/megaraid_sas.c | 1 + 16 files changed, 23 insertions(+), 4 deletions(-) diff --git a/arch/cris/arch-v10/drivers/eeprom.c b/arch/cris/arch-v10/drivers/eeprom.c index f1cac9dc75b8..40c6fe4c06f4 100644 --- a/arch/cris/arch-v10/drivers/eeprom.c +++ b/arch/cris/arch-v10/drivers/eeprom.c @@ -375,7 +375,7 @@ int __init eeprom_init(void) } /* Opens the device. */ - +/* BKL not needed: no global resources accessed */ static int eeprom_open(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 9fb58202be99..c17204289575 100644 --- a/arch/cris/arch-v32/drivers/cryptocop.c +++ b/arch/cris/arch-v32/drivers/cryptocop.c @@ -2302,7 +2302,7 @@ static int cryptocop_job_setup(struct cryptocop_prio_job **pj, struct cryptocop_ return 0; } - +/* No BKL needed here - no global resources accessed */ static int cryptocop_open(struct inode *inode, struct file *filp) { int p = iminor(inode); diff --git a/drivers/char/cs5535_gpio.c b/drivers/char/cs5535_gpio.c index c0a4a0bb509e..628e3d3249d2 100644 --- a/drivers/char/cs5535_gpio.c +++ b/drivers/char/cs5535_gpio.c @@ -153,6 +153,8 @@ static ssize_t cs5535_gpio_read(struct file *file, char __user *buf, return count; } +/* No BKL needed here - "mask" is the only global resource used + here and it's a boot-time parameter */ static int cs5535_gpio_open(struct inode *inode, struct file *file) { u32 m = iminor(inode); diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c index abde6ddefe69..433388c60235 100644 --- a/drivers/char/dtlk.c +++ b/drivers/char/dtlk.c @@ -288,6 +288,8 @@ static int dtlk_ioctl(struct inode *inode, } } +/* No BKL needed here; "dtlk_busy" is the only global resource, + and it is not ever set by anybody (test is broken) */ static int dtlk_open(struct inode *inode, struct file *file) { TRACE_TEXT("(dtlk_open"); diff --git a/drivers/char/pc8736x_gpio.c b/drivers/char/pc8736x_gpio.c index ecfaf180e5bd..8715dc9f4a53 100644 --- a/drivers/char/pc8736x_gpio.c +++ b/drivers/char/pc8736x_gpio.c @@ -212,6 +212,7 @@ static struct nsc_gpio_ops pc8736x_gpio_ops = { .gpio_current = pc8736x_gpio_current }; +/* No BKL needed here; no global resources accessed */ static int pc8736x_gpio_open(struct inode *inode, struct file *file) { unsigned m = iminor(inode); diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c index 3aab837d9480..ce1987574888 100644 --- a/drivers/char/ppdev.c +++ b/drivers/char/ppdev.c @@ -633,6 +633,7 @@ static int pp_ioctl(struct inode *inode, struct file *file, return 0; } +/* No BKL needed here: only local resources used */ static int pp_open (struct inode * inode, struct file * file) { unsigned int minor = iminor(inode); diff --git a/drivers/char/scx200_gpio.c b/drivers/char/scx200_gpio.c index 99e5272e3c53..be2c623a9862 100644 --- a/drivers/char/scx200_gpio.c +++ b/drivers/char/scx200_gpio.c @@ -46,6 +46,7 @@ struct nsc_gpio_ops scx200_gpio_ops = { }; EXPORT_SYMBOL_GPL(scx200_gpio_ops); +/* No BKL needed here: no global resources used */ static int scx200_gpio_open(struct inode *inode, struct file *file) { unsigned m = iminor(inode); diff --git a/drivers/char/tb0219.c b/drivers/char/tb0219.c index 4c431cb7cf1b..db8c2ca2ce4c 100644 --- a/drivers/char/tb0219.c +++ b/drivers/char/tb0219.c @@ -232,6 +232,7 @@ static ssize_t tanbac_tb0219_write(struct file *file, const char __user *data, return i; } +/* No BKL needed here; no global resources accessed */ static int tanbac_tb0219_open(struct inode *inode, struct file *file) { unsigned int minor; diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c index e5ed09192be8..412937fdb958 100644 --- a/drivers/char/vr41xx_giu.c +++ b/drivers/char/vr41xx_giu.c @@ -543,6 +543,8 @@ static ssize_t gpio_write(struct file *file, const char __user *data, return i; } +/* No BKL needed here; only global (giu_nr_pins) is only set + at probe time */ static int gpio_open(struct inode *inode, struct file *file) { unsigned int pin; diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c index d7a6881b571d..3e6a8ff6d76c 100644 --- a/drivers/infiniband/core/ucm.c +++ b/drivers/infiniband/core/ucm.c @@ -1155,6 +1155,7 @@ static unsigned int ib_ucm_poll(struct file *filp, return mask; } +/* No BKL needed here: no global resources used */ static int ib_ucm_open(struct inode *inode, struct file *filp) { struct ib_ucm_file *file; diff --git a/drivers/infiniband/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c index b472b15637f0..e80cfbd4f3fd 100644 --- a/drivers/infiniband/hw/ipath/ipath_file_ops.c +++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c @@ -1812,6 +1812,7 @@ done: return ret; } +/* No BKL needed here */ static int ipath_open(struct inode *in, struct file *fp) { /* The real work is performed later in ipath_assign_port() */ diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 1f4ca2b54a73..dc8505062da7 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -351,6 +351,7 @@ static const int npindex_to_ethertype[NUM_NP] = { * Open instances of /dev/ppp can be in one of three states: * unattached, attached to a ppp unit, or attached to a ppp channel. */ +/* No BKL needed here */ static int ppp_open(struct inode *inode, struct file *file) { /* diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index b31faeccb9cd..2239d16fb9b5 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c @@ -862,6 +862,8 @@ out: } /* End twa_chrdev_ioctl() */ /* This function handles open for the character device */ +/* NOTE that this function will race with remove; adding BKL + will not help. */ static int twa_chrdev_open(struct inode *inode, struct file *file) { unsigned int minor_number; diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c index 8c22329aa85e..bbff029536ea 100644 --- a/drivers/scsi/3w-xxxx.c +++ b/drivers/scsi/3w-xxxx.c @@ -1027,6 +1027,8 @@ out: } /* End tw_chrdev_ioctl() */ /* This function handles open for the character device */ +/* NOTE that this function races with remove - adding BKL + won't help */ static int tw_chrdev_open(struct inode *inode, struct file *file) { unsigned int minor_number; diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index 18551aaf5e09..c9aa2c45a699 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -3272,8 +3272,9 @@ 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. + * + * No BKL needed here. */ static int megadev_open (struct inode *inode, struct file *filep) diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index 7d84c8bbcf3f..81374b7c555c 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c @@ -2860,6 +2860,7 @@ static void megasas_shutdown(struct pci_dev *pdev) /** * megasas_mgmt_open - char node "open" entry point + * No BKL is needed here. */ static int megasas_mgmt_open(struct inode *inode, struct file *filep) { From 609f9e92b570f390a457a81effe0af6b758dc582 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Fri, 16 May 2008 13:46:14 -0600 Subject: [PATCH 040/146] spidev: BKL pushdown Add the BKL to spidev_open(), even though the existing locking looks adequate. Signed-off-by: Jonathan Corbet --- drivers/spi/spidev.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index b3518ca9f04e..ab2b769c83ca 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -393,6 +394,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) { @@ -418,6 +420,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; } From f97259e35de1f99ba0ac19383408e247fd763cf0 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Fri, 16 May 2008 13:47:50 -0600 Subject: [PATCH 041/146] vcs: BKL pushdown Add explicit BKL to vcs_open(). Signed-off-by: Jonathan Corbet --- drivers/char/vc_screen.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c index 83aeedda200c..eebfad2777d2 100644 --- a/drivers/char/vc_screen.c +++ b/drivers/char/vc_screen.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -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 = { From f4943db14f5071ecbf7ca76722e59a2fd22bda4d Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Fri, 16 May 2008 13:50:20 -0600 Subject: [PATCH 042/146] xilinx icap: BKL pushdown Add explicit lock_kernel() calls to hwicap_open() even though the existing locking looks adequate. Signed-off-by: Jonathan Corbet --- drivers/char/xilinx_hwicap/xilinx_hwicap.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c index 3edf1fc12963..1e1b81e57cdc 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c @@ -85,6 +85,7 @@ #include #include #include +#include #include #include #include @@ -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; } From b8c71d7ae2a7f723d171d9175212b6d0a727655d Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Fri, 16 May 2008 13:53:00 -0600 Subject: [PATCH 043/146] tlckl: BKL pushdown Put explicit lock_kernel calls into tlclk_open() Signed-off-by: Jonathan Corbet --- drivers/char/tlclk.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c index 35e58030d296..8f2284be68e1 100644 --- a/drivers/char/tlclk.c +++ b/drivers/char/tlclk.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -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) From c0bed680f0ca603864375ed5f9fed4296a53aa62 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Fri, 16 May 2008 13:54:46 -0600 Subject: [PATCH 044/146] raw: BKL pushdown Put explicit lock_kernel() calls into raw_open(), even though the existing locking looks adequate. Signed-off-by: Jonathan Corbet --- drivers/char/raw.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/char/raw.c b/drivers/char/raw.c index bbfa0e241cba..505fcbe884a4 100644 --- a/drivers/char/raw.c +++ b/drivers/char/raw.c @@ -19,6 +19,7 @@ #include #include #include +#include #include @@ -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: From 65f37b790bd7ba15413838579470296a709c45e6 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Fri, 16 May 2008 13:57:31 -0600 Subject: [PATCH 045/146] dsp56k: BKL pushdown Put explicit lock_kernel calls into dsp56k_open(). [Stupid missing label error fixed] Signed-off-by: Jonathan Corbet --- drivers/char/dsp56k.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c index a69c65283260..7bf7485377e6 100644 --- a/drivers/char/dsp56k.c +++ b/drivers/char/dsp56k.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -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) From 057e7c7ff9f91a36a761588c53826bd6a710aeba Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Fri, 16 May 2008 14:01:12 -0600 Subject: [PATCH 046/146] infiniband: more BKL pushdown Be extra-cautious and protect the remaining open() functions. Signed-off-by: Jonathan Corbet --- drivers/infiniband/core/user_mad.c | 7 ++++++- drivers/infiniband/core/uverbs_main.c | 9 +++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index 3aa2db54eae4..1fc17940a765 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c @@ -47,6 +47,7 @@ #include #include #include +#include #include @@ -783,14 +784,17 @@ static int ib_umad_open(struct inode *inode, struct file *filp) struct ib_umad_file *file; int ret = 0; + lock_kernel(); spin_lock(&port_lock); port = umad_port[iminor(inode) - IB_UMAD_MINOR_BASE]; if (port) kref_get(&port->umad_dev->ref); spin_unlock(&port_lock); - if (!port) + if (!port) { + unlock_kernel(); return -ENXIO; + } mutex_lock(&port->file_mutex); @@ -819,6 +823,7 @@ static int ib_umad_open(struct inode *inode, struct file *filp) out: mutex_unlock(&port->file_mutex); + unlock_kernel(); return ret; } diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index cc1afa28c181..8ede1e475ce6 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -45,6 +45,7 @@ #include #include #include +#include #include @@ -616,14 +617,17 @@ static int ib_uverbs_open(struct inode *inode, struct file *filp) struct ib_uverbs_file *file; int ret; + lock_kernel(); spin_lock(&map_lock); dev = dev_table[iminor(inode) - IB_UVERBS_BASE_MINOR]; if (dev) kref_get(&dev->ref); spin_unlock(&map_lock); - if (!dev) + if (!dev) { + unlock_kernel(); return -ENXIO; + } if (!try_module_get(dev->ib_dev->owner)) { ret = -ENODEV; @@ -644,6 +648,7 @@ static int ib_uverbs_open(struct inode *inode, struct file *filp) filp->private_data = file; + unlock_kernel(); return 0; err_module: @@ -651,7 +656,7 @@ err_module: err: kref_put(&dev->ref, ib_uverbs_release_dev); - + unlock_kernel(); return ret; } From 4541b5ec9f631a143cdea862d07ddfc3cdac36f2 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Fri, 16 May 2008 14:03:05 -0600 Subject: [PATCH 047/146] phantom: BKL pushdown Add explicit lock_kernel calls to phantom_open(). Signed-off-by: Jonathan Corbet --- drivers/misc/phantom.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c index 71d1c84e2fa8..186162470090 100644 --- a/drivers/misc/phantom.c +++ b/drivers/misc/phantom.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -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; } From 5e9829ad38c24aa71252e643836e7cedcb1c83d7 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Fri, 16 May 2008 14:06:45 -0600 Subject: [PATCH 048/146] bpp: bkl pushdown Put explicit lock_kernel() calls into bpp_open(). It has locking, but I'm not convinced it won't race with ioctl(). Signed-off-by: Jonathan Corbet --- drivers/sbus/char/bpp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c index b87037ec9805..c1c091a00575 100644 --- a/drivers/sbus/char/bpp.c +++ b/drivers/sbus/char/bpp.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -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; } From 9aaf20cbf5b7cccd45495326cba0b35b2884e6b3 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Fri, 16 May 2008 14:08:58 -0600 Subject: [PATCH 049/146] videopix: BKL pushdown Add explicit lock_kernel() calls to vfc_open(). Signed-off-by: Jonathan Corbet --- drivers/sbus/char/vfc_dev.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c index d4f8fcded51d..1f6cb8ae2784 100644 --- a/drivers/sbus/char/vfc_dev.c +++ b/drivers/sbus/char/vfc_dev.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -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; } From dea3f665d6fa263a9870a54e9f8cfd146016f140 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Fri, 16 May 2008 14:11:09 -0600 Subject: [PATCH 050/146] dpt_i20: BKL pushdown Add lock_kernel() calls to adpt_open() Signed-off-by: Jonathan Corbet --- drivers/scsi/dpt_i2o.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c index 8508816f303d..2bc30e32b67a 100644 --- a/drivers/scsi/dpt_i2o.c +++ b/drivers/scsi/dpt_i2o.c @@ -49,6 +49,7 @@ MODULE_DESCRIPTION("Adaptec I2O RAID Driver"); #include /* for printk */ #include #include +#include #include #include @@ -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; } From b0061a0ec4d10a69309d0371a01e8b99387009ef Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Fri, 16 May 2008 14:12:52 -0600 Subject: [PATCH 051/146] changer: BKL pushdown Add lock_kernel() calls to ch_open(), though the existing locking looks adequate. Signed-off-by: Jonathan Corbet --- drivers/scsi/ch.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c index 75c84d7b9ce8..8e821be380f4 100644 --- a/drivers/scsi/ch.c +++ b/drivers/scsi/ch.c @@ -22,6 +22,7 @@ #include /* here are all the ioctls */ #include #include +#include #include #include @@ -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; } From a237f3bbaab28bb780201f15f6003cf3d2e81024 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Fri, 16 May 2008 14:15:33 -0600 Subject: [PATCH 052/146] CAPI: BKL pushdown Put explicit lock_kernel() calls into capi_open() Signed-off-by: Jonathan Corbet --- drivers/isdn/capi/capi.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 6ca0bb949ad3..2095153582f1 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #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 From 3462032d66703ef7721329b44fe2dac4aaef475d Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Fri, 16 May 2008 14:17:33 -0600 Subject: [PATCH 053/146] divamnt: BKL pushdown Put explicit lock_kernel() calls into maint_open(). Signed-off-by: Jonathan Corbet --- drivers/isdn/hardware/eicon/divamnt.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/isdn/hardware/eicon/divamnt.c b/drivers/isdn/hardware/eicon/divamnt.c index c90928974249..1e85f743214e 100644 --- a/drivers/isdn/hardware/eicon/divamnt.c +++ b/drivers/isdn/hardware/eicon/divamnt.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #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) From 26ce4f0684ef4b96d0244ac58b89ec282d5b980c Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Fri, 16 May 2008 14:19:56 -0600 Subject: [PATCH 054/146] adb: BKL pushdown Put explicit lock_kernel() calls in adb_open(). The fact that adb_release() already has them suggests this is necessary. Signed-off-by: Jonathan Corbet --- drivers/macintosh/adb.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c index dbaad39020a1..40c70ba62bf0 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) From b2f2ba01b2a4356e92231669f7e3dcee37ac2fca Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Fri, 16 May 2008 14:21:30 -0600 Subject: [PATCH 055/146] printer gadget: BKL pushdown Add explicit lock_kernel() calls to printer_open() Signed-off-by: Jonathan Corbet --- drivers/usb/gadget/printer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 76be75e3ab8f..ec8f2eb041ca 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; } From 1af46fd72d6c18c1d96ce7f3491b841055e9dcfd Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Fri, 16 May 2008 14:23:31 -0600 Subject: [PATCH 056/146] USB Monitor: BKL pushdown Add explicit lock_kernel() calls to mon_bin_open() Signed-off-by: Jonathan Corbet --- drivers/usb/mon/mon_bin.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index 49145534e06e..293a46247c3b 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c @@ -15,6 +15,7 @@ #include #include #include +#include #include @@ -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; } From b5b4aa67da65aeb58718e0a39158b293873ac572 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Fri, 16 May 2008 14:25:20 -0600 Subject: [PATCH 057/146] usbdev: BKL pushdown Add explicit lock_kernel() calls to usbdev_open() Signed-off-by: Jonathan Corbet --- drivers/usb/core/devio.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index de17738f3acb..9218cca21043 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; } From 6606470dd1d628878383c96d10b52a77986ddac7 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Fri, 16 May 2008 14:28:31 -0600 Subject: [PATCH 058/146] videodev: BKL pushdown Put explicit lock_kernel() calls into videodev_open(). That function itself seems OK, but one never knows about all the open() functions provided by underlying video drivers. Signed-off-by: Jonathan Corbet --- drivers/media/video/videodev.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index 31e8af0ba278..e5679c28163f 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -496,6 +497,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) { @@ -505,6 +507,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; } } @@ -518,6 +521,7 @@ static int video_open(struct inode *inode, struct file *file) } fops_put(old_fops); mutex_unlock(&videodev_lock); + unlock_kernel(); return err; } From 0b2806768899dba5967bcd4a3b93eaed9a1dc4f3 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Sun, 18 May 2008 14:27:41 -0600 Subject: [PATCH 059/146] Add cycle_kernel_lock() A number of driver functions are so obviously trivial that they do not need the big kernel lock - at least not overtly. It turns out that the acquisition of the BKL in driver open() functions can perform a sort of poor-hacker's serialization function, delaying the open operation until the driver is certain to have completed its initialization. Add a simple cycle_kernel_lock() function for these cases to make it clear that there is no need to *hold* the BKL, just to be sure that we can acquire it. Signed-off-by: Jonathan Corbet --- include/linux/smp_lock.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/include/linux/smp_lock.h b/include/linux/smp_lock.h index aab3a4cff4e1..813be59bf345 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 From f2b9857eee17797541b845782ade4d7a9d50f843 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Sun, 18 May 2008 15:32:43 -0600 Subject: [PATCH 060/146] Add a bunch of cycle_kernel_lock() calls All of the open() functions which don't need the BKL on their face may still depend on its acquisition to serialize opens against driver initialization. So make those functions acquire then release the BKL to be on the safe side. Signed-off-by: Jonathan Corbet --- arch/cris/arch-v10/drivers/eeprom.c | 4 +-- arch/cris/arch-v10/drivers/i2c.c | 2 ++ arch/cris/arch-v32/drivers/cryptocop.c | 3 +- arch/cris/arch-v32/drivers/i2c.c | 2 ++ drivers/char/cs5535_gpio.c | 4 +-- drivers/char/dtlk.c | 5 +-- drivers/char/ip2/ip2main.c | 34 ++------------------ drivers/char/pc8736x_gpio.c | 3 +- drivers/char/ppdev.c | 3 +- drivers/char/scx200_gpio.c | 3 +- drivers/char/tb0219.c | 3 +- drivers/char/vr41xx_giu.c | 4 +-- drivers/infiniband/core/ucm.c | 3 +- drivers/infiniband/hw/ipath/ipath_file_ops.c | 3 +- drivers/isdn/hardware/eicon/divasi.c | 2 ++ drivers/isdn/hardware/eicon/divasmain.c | 2 ++ drivers/net/ppp_generic.c | 3 +- drivers/scsi/3w-9xxx.c | 5 +-- drivers/scsi/3w-xxxx.c | 5 +-- drivers/scsi/megaraid.c | 4 +-- drivers/scsi/megaraid/megaraid_sas.c | 3 +- 21 files changed, 45 insertions(+), 55 deletions(-) diff --git a/arch/cris/arch-v10/drivers/eeprom.c b/arch/cris/arch-v10/drivers/eeprom.c index 40c6fe4c06f4..1f2ae909d3e6 100644 --- a/arch/cris/arch-v10/drivers/eeprom.c +++ b/arch/cris/arch-v10/drivers/eeprom.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include "i2c.h" @@ -375,10 +376,9 @@ int __init eeprom_init(void) } /* Opens the device. */ -/* BKL not needed: no global resources accessed */ 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/i2c.c b/arch/cris/arch-v10/drivers/i2c.c index d6d22067d0c8..2797e67ce4f4 100644 --- a/arch/cris/arch-v10/drivers/i2c.c +++ b/arch/cris/arch-v10/drivers/i2c.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -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-v32/drivers/cryptocop.c b/arch/cris/arch-v32/drivers/cryptocop.c index c17204289575..67c61ea86813 100644 --- a/arch/cris/arch-v32/drivers/cryptocop.c +++ b/arch/cris/arch-v32/drivers/cryptocop.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -2302,11 +2303,11 @@ static int cryptocop_job_setup(struct cryptocop_prio_job **pj, struct cryptocop_ return 0; } -/* No BKL needed here - no global resources accessed */ 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 c2fb7a5c1396..179e7b804331 100644 --- a/arch/cris/arch-v32/drivers/i2c.c +++ b/arch/cris/arch-v32/drivers/i2c.c @@ -33,6 +33,7 @@ #include #include #include +#include #include @@ -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/drivers/char/cs5535_gpio.c b/drivers/char/cs5535_gpio.c index 628e3d3249d2..04ba906b4880 100644 --- a/drivers/char/cs5535_gpio.c +++ b/drivers/char/cs5535_gpio.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -153,12 +154,11 @@ static ssize_t cs5535_gpio_read(struct file *file, char __user *buf, return count; } -/* No BKL needed here - "mask" is the only global resource used - here and it's a boot-time parameter */ 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/dtlk.c b/drivers/char/dtlk.c index 433388c60235..6b900b297cc6 100644 --- a/drivers/char/dtlk.c +++ b/drivers/char/dtlk.c @@ -56,6 +56,7 @@ #include /* for -EBUSY */ #include /* for request_region */ #include /* for loops_per_jiffy */ +#include /* cycle_kernel_lock() */ #include /* for inb_p, outb_p, inb, outb, etc. */ #include /* for get_user, etc. */ #include /* for wait_queue */ @@ -288,12 +289,12 @@ static int dtlk_ioctl(struct inode *inode, } } -/* No BKL needed here; "dtlk_busy" is the only global resource, - and it is not ever set by anybody (test is broken) */ +/* 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/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index 70957acaa960..a978c57b6b2b 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c @@ -98,6 +98,7 @@ #include #include #include +#include #include #include @@ -2931,42 +2932,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/pc8736x_gpio.c b/drivers/char/pc8736x_gpio.c index 8715dc9f4a53..b930de50407a 100644 --- a/drivers/char/pc8736x_gpio.c +++ b/drivers/char/pc8736x_gpio.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #define DEVNAME "pc8736x_gpio" @@ -212,12 +213,12 @@ static struct nsc_gpio_ops pc8736x_gpio_ops = { .gpio_current = pc8736x_gpio_current }; -/* No BKL needed here; no global resources accessed */ 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 ce1987574888..f6e6acadd9a0 100644 --- a/drivers/char/ppdev.c +++ b/drivers/char/ppdev.c @@ -66,6 +66,7 @@ #include #include #include +#include #include #define PP_VERSION "ppdev: user-space parallel port driver" @@ -633,12 +634,12 @@ static int pp_ioctl(struct inode *inode, struct file *file, return 0; } -/* No BKL needed here: only local resources used */ 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/scx200_gpio.c b/drivers/char/scx200_gpio.c index be2c623a9862..1d9100561c8a 100644 --- a/drivers/char/scx200_gpio.c +++ b/drivers/char/scx200_gpio.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -46,12 +47,12 @@ struct nsc_gpio_ops scx200_gpio_ops = { }; EXPORT_SYMBOL_GPL(scx200_gpio_ops); -/* No BKL needed here: no global resources used */ 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/tb0219.c b/drivers/char/tb0219.c index db8c2ca2ce4c..6062b62800fd 100644 --- a/drivers/char/tb0219.c +++ b/drivers/char/tb0219.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -232,11 +233,11 @@ static ssize_t tanbac_tb0219_write(struct file *file, const char __user *data, return i; } -/* No BKL needed here; no global resources accessed */ 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/vr41xx_giu.c b/drivers/char/vr41xx_giu.c index 412937fdb958..ffe9b4e3072e 100644 --- a/drivers/char/vr41xx_giu.c +++ b/drivers/char/vr41xx_giu.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -543,12 +544,11 @@ static ssize_t gpio_write(struct file *file, const char __user *data, return i; } -/* No BKL needed here; only global (giu_nr_pins) is only set - at probe time */ 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/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c index 3e6a8ff6d76c..b25675faaaf5 100644 --- a/drivers/infiniband/core/ucm.c +++ b/drivers/infiniband/core/ucm.c @@ -45,6 +45,7 @@ #include #include #include +#include #include @@ -1155,11 +1156,11 @@ static unsigned int ib_ucm_poll(struct file *filp, return mask; } -/* No BKL needed here: no global resources used */ 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/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c index e80cfbd4f3fd..35f301c88b57 100644 --- a/drivers/infiniband/hw/ipath/ipath_file_ops.c +++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include "ipath_kernel.h" @@ -1812,10 +1813,10 @@ done: return ret; } -/* No BKL needed here */ 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/isdn/hardware/eicon/divasi.c b/drivers/isdn/hardware/eicon/divasi.c index 78f141e77466..f4969fe0a055 100644 --- a/drivers/isdn/hardware/eicon/divasi.c +++ b/drivers/isdn/hardware/eicon/divasi.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #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 5fcbdccd7a53..65c95019a9ae 100644 --- a/drivers/isdn/hardware/eicon/divasmain.c +++ b/drivers/isdn/hardware/eicon/divasmain.c @@ -21,6 +21,7 @@ #include #include #include +#include #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/net/ppp_generic.c b/drivers/net/ppp_generic.c index dc8505062da7..83625fdff3dd 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -351,9 +352,9 @@ static const int npindex_to_ethertype[NUM_NP] = { * Open instances of /dev/ppp can be in one of three states: * unattached, attached to a ppp unit, or attached to a ppp channel. */ -/* No BKL needed here */ 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/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index 2239d16fb9b5..eaa805df5b00 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c @@ -84,6 +84,7 @@ #include #include #include +#include #include #include #include @@ -862,13 +863,13 @@ out: } /* End twa_chrdev_ioctl() */ /* This function handles open for the character device */ -/* NOTE that this function will race with remove; adding BKL - will not help. */ +/* 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 bbff029536ea..a0537f09aa21 100644 --- a/drivers/scsi/3w-xxxx.c +++ b/drivers/scsi/3w-xxxx.c @@ -198,6 +198,7 @@ #include #include +#include #include #include #include @@ -1027,12 +1028,12 @@ out: } /* End tw_chrdev_ioctl() */ /* This function handles open for the character device */ -/* NOTE that this function races with remove - adding BKL - won't help */ +/* 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/megaraid.c b/drivers/scsi/megaraid.c index c9aa2c45a699..28c9da7d4a5c 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include "scsi.h" @@ -3273,12 +3274,11 @@ mega_init_scb(adapter_t *adapter) * * Routines for the character/ioctl interface to the driver. Find out if this * is a valid open. - * - * No BKL needed here. */ 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_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index 81374b7c555c..fc7ac158476c 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -2860,10 +2861,10 @@ static void megasas_shutdown(struct pci_dev *pdev) /** * megasas_mgmt_open - char node "open" entry point - * No BKL is needed here. */ static int megasas_mgmt_open(struct inode *inode, struct file *filep) { + cycle_kernel_lock(); /* * Allow only those users with admin rights */ From a30427d92d0bc152b833088e4a305bbeb1a0c162 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Sun, 18 May 2008 15:39:11 -0600 Subject: [PATCH 061/146] Add a comment in chrdev_open() I stared at this code for a while and almost deleted it before understanding crept into my slow brain. Hopefully this makes life easier for the next person to happen on it. Signed-off-by: Jonathan Corbet --- fs/char_dev.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/char_dev.c b/fs/char_dev.c index 68e510b88457..a54d69369b2f 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; From 9514dff918b947ae43b66517dc90d0e05548bd6a Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Sun, 18 May 2008 15:40:00 -0600 Subject: [PATCH 062/146] Remove the lock_kernel() call from chrdev_open() All in-kernel char device open() functions now either have their own lock_kernel() calls or clearly do not need one. Signed-off-by: Jonathan Corbet --- fs/char_dev.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/fs/char_dev.c b/fs/char_dev.c index a54d69369b2f..3cb7cda3d780 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c @@ -394,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; From 5ca6a93d802a9d110127556e5d3ed032fd273e03 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 19 May 2008 16:06:52 +1000 Subject: [PATCH 063/146] bkl-removal viotape fixup Signed-off-by: Stephen Rothwell Signed-off-by: Jonathan Corbet --- drivers/char/viotape.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index af03d2709300..a171d894b7e7 100644 --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c @@ -688,7 +688,7 @@ static int viotap_open(struct inode *inode, struct file *file) if (op == NULL) return -ENOMEM; - lock_kernel() + lock_kernel(); get_dev_info(file->f_path.dentry->d_inode, &devi); /* Note: We currently only support one mode! */ From 8f5934278d1d86590244c2791b28f77d67466007 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 19 May 2008 19:53:01 -0700 Subject: [PATCH 064/146] Replace BKL with superblock lock in fat/msdos/vfat This replaces the use of the BKL in the FAT family of filesystems with the existing superblock lock instead. The code already appears to do mostly proper locking with its own private spinlocks (and mutexes), but while the BKL could possibly have been dropped entirely, converting it to use the superblock lock (which is just a regular mutex) is the conservative thing to do. As a per-filesystem mutex, it not only won't have any of the possible latency issues related to the BKL, but the lock is obviously private to the particular filesystem instance and will thus not cause problems for entirely unrelated users like the BKL can. Signed-off-by: Linus Torvalds Cc: OGAWA Hirofumi Signed-off-by: Jonathan Corbet --- fs/fat/cache.c | 2 +- fs/fat/dir.c | 4 ++-- fs/fat/file.c | 12 +++++++----- fs/fat/inode.c | 26 ++++++++++++++++---------- fs/msdos/namei.c | 35 +++++++++++++++++++---------------- fs/vfat/namei.c | 35 +++++++++++++++++++---------------- 6 files changed, 64 insertions(+), 50 deletions(-) diff --git a/fs/fat/cache.c b/fs/fat/cache.c index fda25479af26..3a9ecac8d61f 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 486725ee99ae..34541d06e626 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 27cc1164ec36..7059928fb351 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c @@ -229,7 +229,8 @@ static int fat_free(struct inode *inode, int skip) void fat_truncate(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); const unsigned int cluster_size = sbi->cluster_size; int nr_clusters; @@ -242,9 +243,9 @@ void fat_truncate(struct inode *inode) nr_clusters = (inode->i_size + (cluster_size - 1)) >> sbi->cluster_bits; - lock_kernel(); + lock_super(sb); fat_free(inode, nr_clusters); - unlock_kernel(); + unlock_super(sb); fat_flush_inodes(inode->i_sb, inode, NULL); } @@ -297,12 +298,13 @@ static int fat_allow_set_time(struct msdos_sb_info *sbi, struct inode *inode) int fat_setattr(struct dentry *dentry, struct iattr *attr) { + struct super_block *sb = dentry->d_sb; struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb); struct inode *inode = dentry->d_inode; int mask, error = 0; unsigned int ia_valid; - lock_kernel(); + lock_super(sb); /* * Expand the file. Since inode_setattr() updates ->i_size @@ -356,7 +358,7 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr) mask = sbi->options.fs_fmask; inode->i_mode &= S_IFMT | (S_IRWXUGO & ~mask); out: - unlock_kernel(); + unlock_super(sb); return error; } EXPORT_SYMBOL_GPL(fat_setattr); diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 4e0a3dd9d677..46a4508ffd2e 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/msdos/namei.c b/fs/msdos/namei.c index 05ff4f1d7026..1f7f2956412a 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/vfat/namei.c b/fs/vfat/namei.c index a3522727ea5b..b546ba69be82 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; From a076230134f3083a58cef99e48b127818ef01e7a Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:15:30 +0200 Subject: [PATCH 065/146] agp-frontend: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/char/agp/frontend.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c index 857b26227d87..963eff28fa00 100644 --- a/drivers/char/agp/frontend.c +++ b/drivers/char/agp/frontend.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #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; } From b82829943c470e59cfd3ee84d8ed6ae5d5e1a55b Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:15:32 +0200 Subject: [PATCH 066/146] ans-lcd: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/macintosh/ans-lcd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/macintosh/ans-lcd.c b/drivers/macintosh/ans-lcd.c index 73c50bc02095..6a8221893256 100644 --- a/drivers/macintosh/ans-lcd.c +++ b/drivers/macintosh/ans-lcd.c @@ -3,6 +3,7 @@ */ #include +#include #include #include #include @@ -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; } From 2861ead38b8a376888c3f63b9c8e45d4cee02117 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:15:33 +0200 Subject: [PATCH 067/146] apm-emulation: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/char/apm-emulation.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/char/apm-emulation.c b/drivers/char/apm-emulation.c index cdd876dbb2b0..da8a1658a273 100644 --- a/drivers/char/apm-emulation.c +++ b/drivers/char/apm-emulation.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -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; } From 864fe51671c9e44fb9d02765623daac9acc26a8b Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:15:34 +0200 Subject: [PATCH 068/146] apm_32: BKL pushdown Signed-off-by: Arnd Bergmann --- arch/x86/kernel/apm_32.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c index bf9290e29013..82222366477f 100644 --- a/arch/x86/kernel/apm_32.c +++ b/arch/x86/kernel/apm_32.c @@ -204,6 +204,7 @@ #include #include +#include #include #include #include @@ -1544,10 +1545,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; @@ -1569,6 +1572,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; } From 52e7c5e08201e20ddbe93cb1977869c38072bc2f Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:15:36 +0200 Subject: [PATCH 069/146] basler-excite: BKL pushdown Signed-off-by: Arnd Bergmann --- arch/mips/basler/excite/excite_iodev.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/mips/basler/excite/excite_iodev.c b/arch/mips/basler/excite/excite_iodev.c index 476d20e08d0e..a1e3526b4a94 100644 --- a/arch/mips/basler/excite/excite_iodev.c +++ b/arch/mips/basler/excite/excite_iodev.c @@ -26,6 +26,7 @@ #include #include #include +#include #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) From 9a8bd2f76cb78fd730337f1b3b9cbef101ce2dad Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:15:37 +0200 Subject: [PATCH 070/146] bf561-coreb: BKL pushdown Signed-off-by: Arnd Bergmann --- arch/blackfin/mach-bf561/coreb.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/blackfin/mach-bf561/coreb.c b/arch/blackfin/mach-bf561/coreb.c index 1b44e9e6dc3b..852647801a01 100644 --- a/arch/blackfin/mach-bf561/coreb.c +++ b/arch/blackfin/mach-bf561/coreb.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -196,6 +197,7 @@ static loff_t coreb_lseek(struct file *file, loff_t offset, int origin) static int coreb_open(struct inode *inode, struct file *file) { + lock_kernel(); spin_lock_irq(&coreb_lock); if (coreb_status & COREB_IS_OPEN) @@ -204,10 +206,12 @@ static int coreb_open(struct inode *inode, struct file *file) coreb_status |= COREB_IS_OPEN; spin_unlock_irq(&coreb_lock); + unlock_kernel(); return 0; out_busy: spin_unlock_irq(&coreb_lock); + unlock_kernel(); return -EBUSY; } From 986837badea28a8d32864ced7cbc2fb80b9f7c91 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:15:38 +0200 Subject: [PATCH 071/146] block-dasd_eer: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/s390/block/dasd_eer.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c index 6e53ab606e97..29da4413ad43 100644 --- a/drivers/s390/block/dasd_eer.c +++ b/drivers/s390/block/dasd_eer.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -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); } From 8324af6dddac11f9f7e9df8b784f6949ddb61b5d Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:15:40 +0200 Subject: [PATCH 072/146] bluetooth-vhci: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/bluetooth/hci_vhci.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c index 0638730a4a19..7734bc9af3ca 100644 --- a/drivers/bluetooth/hci_vhci.c +++ b/drivers/bluetooth/hci_vhci.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -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); } From 556889a4ae89d5f2adf98cac58ecf9326b0d0297 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:15:41 +0200 Subject: [PATCH 073/146] briq_panel: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/char/briq_panel.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/char/briq_panel.c b/drivers/char/briq_panel.c index b6f2639f903d..d8cff909001c 100644 --- a/drivers/char/briq_panel.c +++ b/drivers/char/briq_panel.c @@ -6,6 +6,7 @@ #include +#include #include #include #include @@ -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; } From 122bc5eaf81a3870f6cc00d2e5e97f32f92e636b Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:15:42 +0200 Subject: [PATCH 074/146] bvme6000-rtc: BKL pushdown Signed-off-by: Arnd Bergmann --- arch/m68k/bvme6000/rtc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/m68k/bvme6000/rtc.c b/arch/m68k/bvme6000/rtc.c index a812d03879f8..e8ac3f7d72df 100644 --- a/arch/m68k/bvme6000/rtc.c +++ b/arch/m68k/bvme6000/rtc.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -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; } From b05c9e6cd939b6f79be17e9b6a23ca15a219dec2 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:15:43 +0200 Subject: [PATCH 075/146] cpwatchdog: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/sbus/char/cpwatchdog.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/sbus/char/cpwatchdog.c b/drivers/sbus/char/cpwatchdog.c index 235703414370..23abfdfb44f1 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)); } From 135fe10f9fb9fba981f60c5526e37900f52c9705 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:15:45 +0200 Subject: [PATCH 076/146] crypto-prng: BKL pushdown Signed-off-by: Arnd Bergmann --- arch/s390/crypto/prng.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/s390/crypto/prng.c b/arch/s390/crypto/prng.c index 0cfefddd8375..c238ee4aa038 100644 --- a/arch/s390/crypto/prng.c +++ b/arch/s390/crypto/prng.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -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); } From e73322ceefb2a777dc0ef369a2504bf5c42b8c52 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:15:46 +0200 Subject: [PATCH 077/146] crypto-zcrypt_api: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/s390/crypto/zcrypt_api.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index 4d36e805a234..e41c2fa86d8b 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -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; } From 009228dfb641ca7e4315ab0d0d55465747331025 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:15:47 +0200 Subject: [PATCH 078/146] display7seg: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/sbus/char/display7seg.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c index 3279a1b6501d..d8f5c0ca236d 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; } From 514bcc66d4072a221a8dfd341a4006385a441918 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:15:48 +0200 Subject: [PATCH 079/146] dlm-user: BKL pushdown Signed-off-by: Arnd Bergmann --- fs/dlm/user.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/fs/dlm/user.c b/fs/dlm/user.c index ebbcf38fd33b..f976f303c196 100644 --- a/fs/dlm/user.c +++ b/fs/dlm/user.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -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; } From 7ccef46320ecd52c4d20c8aad592599df76bb7a1 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:15:49 +0200 Subject: [PATCH 080/146] ds1286: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/char/ds1286.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/char/ds1286.c b/drivers/char/ds1286.c index ea35ab2c9909..fb584938c9c3 100644 --- a/drivers/char/ds1286.c +++ b/drivers/char/ds1286.c @@ -27,6 +27,7 @@ * option) any later version. */ #include +#include #include #include #include @@ -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; } From 080c2226474fa3060fadce9a2341004f477aadb3 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:15:50 +0200 Subject: [PATCH 081/146] ds1620: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/char/ds1620.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/char/ds1620.c b/drivers/char/ds1620.c index 334ad5bbe6b6..34275c6f1da2 100644 --- a/drivers/char/ds1620.c +++ b/drivers/char/ds1620.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -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, }; From 89c7de08c5fc059c4f6231571416d9bc0bbc91d4 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:15:52 +0200 Subject: [PATCH 082/146] efirtc: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/char/efirtc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/char/efirtc.c b/drivers/char/efirtc.c index 49233f589874..d57ca3e4e534 100644 --- a/drivers/char/efirtc.c +++ b/drivers/char/efirtc.c @@ -28,6 +28,7 @@ */ +#include #include #include #include @@ -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; } From 1d17bf0c08569e7aefd27df0179065fb955588c4 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:15:53 +0200 Subject: [PATCH 083/146] envctrl: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/sbus/char/envctrl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c index dadabef116b6..a408402426f8 100644 --- a/drivers/sbus/char/envctrl.c +++ b/drivers/sbus/char/envctrl.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -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; } From 78abb6ac919cee123e632d833a42d0312ccb2b0d Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:15:54 +0200 Subject: [PATCH 084/146] flash: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/sbus/char/flash.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c index 44e039865aa9..7d95e151513a 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; } From 742a2fe31bf311d065a2bbacc2b363103b351300 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:15:55 +0200 Subject: [PATCH 085/146] genrtc: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/char/genrtc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/char/genrtc.c b/drivers/char/genrtc.c index 69f0a2993af0..aac0985a572b 100644 --- a/drivers/char/genrtc.c +++ b/drivers/char/genrtc.c @@ -51,6 +51,7 @@ #include #include #include +#include #include #include @@ -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; } From 4a7e79a7deab9718d51dc8d3ee938bd0eb789b7b Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:15:57 +0200 Subject: [PATCH 086/146] hdpu_cpustate: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/misc/hdpuftrs/hdpu_cpustate.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/misc/hdpuftrs/hdpu_cpustate.c b/drivers/misc/hdpuftrs/hdpu_cpustate.c index ff51ab67231c..176fe4e09d3f 100644 --- a/drivers/misc/hdpuftrs/hdpu_cpustate.c +++ b/drivers/misc/hdpuftrs/hdpu_cpustate.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -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) From 986f8b8ccf4806c1e95528a6f157998113fb4f41 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:15:58 +0200 Subject: [PATCH 087/146] hp_sdc_rtc: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/input/misc/hp_sdc_rtc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/input/misc/hp_sdc_rtc.c b/drivers/input/misc/hp_sdc_rtc.c index 45e5d05b01de..49d8abfe38fe 100644 --- a/drivers/input/misc/hp_sdc_rtc.c +++ b/drivers/input/misc/hp_sdc_rtc.c @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -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; } From 48b81880519274d2a8b3e9919a47d91d05a1c964 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:15:59 +0200 Subject: [PATCH 088/146] hpet: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/char/hpet.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index e7fb0bca3667..fb0a85a1eb36 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -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; } From a9c4e8f74ba26f10cf78fed7c5b863ea50988856 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:00 +0200 Subject: [PATCH 089/146] hw-random: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/char/hw_random/core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c index 662d60e44e9a..e5d583c84e4f 100644 --- a/drivers/char/hw_random/core.c +++ b/drivers/char/hw_random/core.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -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; } From 6b0ee363b294c3724224909dcb0b80f7dac3dfd6 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:02 +0200 Subject: [PATCH 090/146] infiniband-ucma: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/infiniband/core/ucma.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index ca4cf3a511ab..195f97302fe5 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -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; } From b0e54f7c477ad24fa0d49baed942c5a5909c748b Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:03 +0200 Subject: [PATCH 091/146] ip27-rtc: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/char/ip27-rtc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/char/ip27-rtc.c b/drivers/char/ip27-rtc.c index 86e6538a77b0..ec9d0443d92c 100644 --- a/drivers/char/ip27-rtc.c +++ b/drivers/char/ip27-rtc.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -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; } From af96f0103d332be92c42a44accf731da667ecc03 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:04 +0200 Subject: [PATCH 092/146] ipmi-watchdog: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/char/ipmi/ipmi_watchdog.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index 1b9a87047817..357d99b9d0e5 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -819,6 +820,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. From cddf63d99d0d145f18b293c3d0de4af7dab2a922 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:06 +0200 Subject: [PATCH 093/146] irnet_ppp: BKL pushdown Signed-off-by: Arnd Bergmann --- net/irda/irnet/irnet.h | 1 + net/irda/irnet/irnet_ppp.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/net/irda/irnet/irnet.h b/net/irda/irnet/irnet.h index b001c361ad30..bccf4d0059f0 100644 --- a/net/irda/irnet/irnet.h +++ b/net/irda/irnet/irnet.h @@ -241,6 +241,7 @@ #include #include +#include #include #include #include diff --git a/net/irda/irnet/irnet_ppp.c b/net/irda/irnet/irnet_ppp.c index e0eab5927c4f..e84a70dd346b 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; } From 28fbbf491368c9491461ca492e13862da1b49180 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:08 +0200 Subject: [PATCH 094/146] jsflash: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/sbus/char/jsflash.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c index 4b7079fdc10c..2bec9ccc0293 100644 --- a/drivers/sbus/char/jsflash.c +++ b/drivers/sbus/char/jsflash.c @@ -27,6 +27,7 @@ */ #include +#include #include #include #include @@ -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? */ } From 600bf8140c22e473ef0806ae45214aaaf53e0da3 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:10 +0200 Subject: [PATCH 095/146] lcd: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/char/lcd.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/char/lcd.c b/drivers/char/lcd.c index 4fe9206f84de..1c29b20e4f4c 100644 --- a/drivers/char/lcd.c +++ b/drivers/char/lcd.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -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 From b9bde77a6a4f76b767d4363a5f74127528426159 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:11 +0200 Subject: [PATCH 096/146] macintosh-smu: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/macintosh/smu.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c index 77ad192962c5..b82fcd210bf3 100644 --- a/drivers/macintosh/smu.c +++ b/drivers/macintosh/smu.c @@ -19,6 +19,7 @@ * the userland interface */ +#include #include #include #include @@ -1083,10 +1084,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; } From cad84238056babf4e4e6b0de183238224aab8177 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:12 +0200 Subject: [PATCH 097/146] media-radio-miropcm20-rds: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/media/radio/miropcm20-rds.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/media/radio/miropcm20-rds.c b/drivers/media/radio/miropcm20-rds.c index 06dfed9ef4c7..3e840f74d45c 100644 --- a/drivers/media/radio/miropcm20-rds.c +++ b/drivers/media/radio/miropcm20-rds.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -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; } From f18f81daba25d29541e46972a7ff4d65162ff167 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:13 +0200 Subject: [PATCH 098/146] megaraid: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/scsi/megaraid/megaraid_mm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/scsi/megaraid/megaraid_mm.c b/drivers/scsi/megaraid/megaraid_mm.c index 0ad215e27b83..ac3b280c2a72 100644 --- a/drivers/scsi/megaraid/megaraid_mm.c +++ b/drivers/scsi/megaraid/megaraid_mm.c @@ -15,6 +15,7 @@ * Common management module */ #include +#include #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; } From b78032a7e52995b42d231d0064358eef16c9a8cc Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:14 +0200 Subject: [PATCH 099/146] message-i2o-i2o_config: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/message/i2o/i2o_config.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c index c0fb77dc19bb..95b4c108585c 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; } From 77149367dade50af8370420265bd4f818cde8afd Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:16 +0200 Subject: [PATCH 100/146] microcode: BKL pushdown Signed-off-by: Arnd Bergmann --- arch/x86/kernel/microcode.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/kernel/microcode.c b/arch/x86/kernel/microcode.c index 69729e38b78a..9f0a994eef9b 100644 --- a/arch/x86/kernel/microcode.c +++ b/arch/x86/kernel/microcode.c @@ -75,6 +75,7 @@ #include #include #include +#include #include #include #include @@ -422,6 +423,7 @@ out: static int microcode_open (struct inode *unused1, struct file *unused2) { + cycle_kernel_lock(); return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; } From 6ce46a435a3ac9e706d09a3075cbc60ed72d37db Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:17 +0200 Subject: [PATCH 101/146] monreader: BKL pushdown [jmc: added ] Signed-off-by: Arnd Bergmann Signed-off-by: Jonathan Corbet --- drivers/s390/char/monreader.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/s390/char/monreader.c b/drivers/s390/char/monreader.c index 1e1f50655bbf..dc4710e64e0c 100644 --- a/drivers/s390/char/monreader.c +++ b/drivers/s390/char/monreader.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -340,6 +341,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; @@ -377,6 +379,7 @@ static int mon_open(struct inode *inode, struct file *filp) } P_INFO("open, established connection to *MONITOR service\n\n"); filp->private_data = monpriv; + unlock_kernel(); return nonseekable_open(inode, filp); out_path: @@ -386,6 +389,7 @@ out_priv: out_use: clear_bit(MON_IN_USE, &mon_in_use); out: + unlock_kernel(); return rc; } From dca67e9d3db27b090259b696e1166615f40099e2 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:18 +0200 Subject: [PATCH 102/146] monwriter: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/s390/char/monwriter.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/s390/char/monwriter.c b/drivers/s390/char/monwriter.c index a86c0534cd49..4d71aa8c1a79 100644 --- a/drivers/s390/char/monwriter.c +++ b/drivers/s390/char/monwriter.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -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); } From f9c8154f367d471f1af56742fe8534f8458adb98 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:20 +0200 Subject: [PATCH 103/146] mousedev: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/input/mousedev.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index b989748598ae..8137e50ded87 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -14,6 +14,7 @@ #define MOUSEDEV_MIX 31 #include +#include #include #include #include @@ -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; } From e3e8e59dcd63621e3ade03083c17b6363a8e2dc8 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:22 +0200 Subject: [PATCH 104/146] mvme16x-rtc: BKL pushdown Signed-off-by: Arnd Bergmann --- arch/m68k/mvme16x/rtc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/m68k/mvme16x/rtc.c b/arch/m68k/mvme16x/rtc.c index e341387787ab..432a9f13b2ed 100644 --- a/arch/m68k/mvme16x/rtc.c +++ b/arch/m68k/mvme16x/rtc.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -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; } From db41bc9c4dfeed656dfd63d26883f81abc4005df Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:23 +0200 Subject: [PATCH 105/146] mwave-mwavedd: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/char/mwave/mwavedd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/char/mwave/mwavedd.c b/drivers/char/mwave/mwavedd.c index 8d14823b0514..50243fcd87e8 100644 --- a/drivers/char/mwave/mwavedd.c +++ b/drivers/char/mwave/mwavedd.c @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #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; } From fd3e05b6c82ebee06f888482975172028e89382d Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:24 +0200 Subject: [PATCH 106/146] net-tun: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/net/tun.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 0ce07a339c7e..ce5af2aa8843 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -797,6 +798,7 @@ static int tun_chr_fasync(int fd, struct file *file, int on) 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; From 930ab4e532623795f934467c452a8c71be2c30fe Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:26 +0200 Subject: [PATCH 107/146] nvram: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/char/nvram.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c index 98dec380af49..197cd7a0c332 100644 --- a/drivers/char/nvram.c +++ b/drivers/char/nvram.c @@ -107,6 +107,7 @@ #include #include #include +#include #include #include @@ -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; } From b7fdf9fdd6457c9ed02099fe82bab92b0b3e291b Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:28 +0200 Subject: [PATCH 108/146] ocfs2-stack_user: BKL pushdown Signed-off-by: Arnd Bergmann --- fs/ocfs2/stack_user.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/ocfs2/stack_user.c b/fs/ocfs2/stack_user.c index b503772cd0ec..cd120011104d 100644 --- a/fs/ocfs2/stack_user.c +++ b/fs/ocfs2/stack_user.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -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; } From 7bcc3209be82d69361a944c57caeb548b35c7f04 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:29 +0200 Subject: [PATCH 109/146] openprom: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/sbus/char/openprom.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c index fbfeb89a6f32..29dc735e1a20 100644 --- a/drivers/sbus/char/openprom.c +++ b/drivers/sbus/char/openprom.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -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; } From 6044c319d11051f3462dafd0e7a900ef121d7bc7 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:30 +0200 Subject: [PATCH 110/146] parisc-eisa_eeprom: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/parisc/eisa_eeprom.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/parisc/eisa_eeprom.c b/drivers/parisc/eisa_eeprom.c index 86e9c84a965e..5ac207932fd7 100644 --- a/drivers/parisc/eisa_eeprom.c +++ b/drivers/parisc/eisa_eeprom.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -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; From b691750098f830b748540cd955f5ac56545bab25 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:31 +0200 Subject: [PATCH 111/146] parisc-kernel-perf: BKL pushdown Signed-off-by: Arnd Bergmann --- arch/parisc/kernel/perf.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/parisc/kernel/perf.c b/arch/parisc/kernel/perf.c index 89d6d5ad44b5..f696f57faa15 100644 --- a/arch/parisc/kernel/perf.c +++ b/arch/parisc/kernel/perf.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -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; } From db26e64dc3f0d51c4db1a625c248a81f7850eee9 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:33 +0200 Subject: [PATCH 112/146] pm_qos_params: BKL pushdown [jmc: added ] Signed-off-by: Arnd Bergmann Signed-off-by: Jonathan Corbet --- kernel/pm_qos_params.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c index 0afe32be4c85..8cb757026386 100644 --- a/kernel/pm_qos_params.c +++ b/kernel/pm_qos_params.c @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -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; } From f29b889edef0c3ab98732c84247c790a1583cb94 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:35 +0200 Subject: [PATCH 113/146] riowatchdog: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/sbus/char/riowatchdog.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/sbus/char/riowatchdog.c b/drivers/sbus/char/riowatchdog.c index a2fc6b8c1334..88c0fc6395e1 100644 --- a/drivers/sbus/char/riowatchdog.c +++ b/drivers/sbus/char/riowatchdog.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -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; } From 4333deee6b7a5a82afb9e700e76cb46e68fde68d Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:37 +0200 Subject: [PATCH 114/146] rtc: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/char/rtc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index 5f80a9dff573..10f06a6bfeb5 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c @@ -73,6 +73,7 @@ #include #include #include +#include #include #include #include @@ -733,6 +734,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) @@ -742,10 +744,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; } From 41012735352e72b8a3f95521817dcad1b2986636 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:39 +0200 Subject: [PATCH 115/146] rtc-rtc-m41t80: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/rtc/rtc-m41t80.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index a3e0880b38fb..0a19c06019be 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -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; From 5ab0854dd77a520abe7c3b9c7770972fd3e61e90 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:40 +0200 Subject: [PATCH 116/146] sbus-rtc: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/sbus/char/rtc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/sbus/char/rtc.c b/drivers/sbus/char/rtc.c index 18d18f1a114e..b0429917154d 100644 --- a/drivers/sbus/char/rtc.c +++ b/drivers/sbus/char/rtc.c @@ -12,6 +12,7 @@ */ #include +#include #include #include #include @@ -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; } From 556e4b0b69d6e45e6b4e61390ef5aebce3ea432d Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:42 +0200 Subject: [PATCH 117/146] scsi-tgt: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/scsi/scsi_tgt_if.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/scsi/scsi_tgt_if.c b/drivers/scsi/scsi_tgt_if.c index d2557dbc2dc1..0e9533f7aabc 100644 --- a/drivers/scsi/scsi_tgt_if.c +++ b/drivers/scsi/scsi_tgt_if.c @@ -21,6 +21,7 @@ */ #include #include +#include #include #include #include @@ -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; } From 9edca64b724db74373f0c9ef7cb044a5f221a4a3 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:43 +0200 Subject: [PATCH 118/146] serio: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/input/serio/serio_raw.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c index 0403622ae267..c9397c8ee97e 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include @@ -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; } From 0410e689b19b6ca010a6a44abfa820968ae15733 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:45 +0200 Subject: [PATCH 119/146] sony-laptop: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/misc/sony-laptop.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c index 00e48e2a9c11..60775be22822 100644 --- a/drivers/misc/sony-laptop.c +++ b/drivers/misc/sony-laptop.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -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; } From f8f2c79d594463427f7114cedb1555110d547d89 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:46 +0200 Subject: [PATCH 120/146] sonypi: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/char/sonypi.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index 58533de59027..85e0eb76eeab 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -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; } From ee30d64e42ee1384a81d241b3962d3c1e6174992 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:48 +0200 Subject: [PATCH 121/146] sparc-apc: BKL pushdown Signed-off-by: Arnd Bergmann --- arch/sparc/kernel/apc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/sparc/kernel/apc.c b/arch/sparc/kernel/apc.c index d06a405ca718..6707422c9847 100644 --- a/arch/sparc/kernel/apc.c +++ b/arch/sparc/kernel/apc.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -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; } From 09de36137c3794786bc75682c0e1ce45182c1772 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:50 +0200 Subject: [PATCH 122/146] sparc64-rtc: BKL pushdown Signed-off-by: Arnd Bergmann --- arch/sparc64/kernel/time.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index e5d238970c7e..bedc4c159b1c 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -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; } From 25368ca579905efe7f7dda43c252eb7b371de98c Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:51 +0200 Subject: [PATCH 123/146] tpm-tpm: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/char/tpm/tpm.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index a5d8bcb40000..e1fc193d9396 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -26,6 +26,7 @@ #include #include #include +#include #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); From f138e4814a9c28bc44d967a8effdd977ac00fc6e Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:52 +0200 Subject: [PATCH 124/146] uctrl: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/sbus/char/uctrl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c index 383f32c1d347..513ba61ae966 100644 --- a/drivers/sbus/char/uctrl.c +++ b/drivers/sbus/char/uctrl.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -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; } From 8702965848ed4bee27486a3e3d2ae34ebba6dd83 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:53 +0200 Subject: [PATCH 125/146] uinput: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/input/misc/uinput.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index a56ad4ba8fe2..2bcfa0b35061 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -37,6 +37,7 @@ #include #include #include +#include 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; } From 78dccb46ddc2ff460c8b4d5ec0886964bd4b59e5 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:54 +0200 Subject: [PATCH 126/146] uml-harddog: BKL pushdown Signed-off-by: Arnd Bergmann --- arch/um/drivers/harddog_kern.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/um/drivers/harddog_kern.c b/arch/um/drivers/harddog_kern.c index a9ad4bd6d953..d332503fa1be 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; } From bd6859fe836491d20ea6e57fee93e0e08ee69443 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:56 +0200 Subject: [PATCH 127/146] uml-mmapper: BKL pushdown Signed-off-by: Arnd Bergmann --- arch/um/drivers/mmapper_kern.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c index 67b2f55a602f..eb240323c40a 100644 --- a/arch/um/drivers/mmapper_kern.c +++ b/arch/um/drivers/mmapper_kern.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "mem_user.h" @@ -77,6 +78,7 @@ out: static int mmapper_open(struct inode *inode, struct file *file) { + cycle_kernel_lock(); return 0; } From 7eb500d1a0408c37d0c0360f066f8b7701835d68 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:57 +0200 Subject: [PATCH 128/146] uml-random: BKL pushdown Signed-off-by: Arnd Bergmann --- arch/um/drivers/random.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c index 4949044773ba..6eabb7022a2d 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 +#include #include #include #include @@ -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; From ffe83733b88655b643e9d4ad0dda5ef9584d5926 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:58 +0200 Subject: [PATCH 129/146] via-pmu: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/macintosh/via-pmu.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index d6365a9f0637..d524dc245a2c 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -18,6 +18,7 @@ * */ #include +#include #include #include #include @@ -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; } From 6c111d886317513605c459cbe8d1970fab732c90 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:16:59 +0200 Subject: [PATCH 130/146] vmcp: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/s390/char/vmcp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c index 2f419b0ea628..bf3dc6e0e33a 100644 --- a/drivers/s390/char/vmcp.c +++ b/drivers/s390/char/vmcp.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -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); } From 3e0420f066c632e135939ccf218ae793e02dccd7 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:17:01 +0200 Subject: [PATCH 131/146] vmwatchdog: BKL pushdown Signed-off-by: Arnd Bergmann --- drivers/s390/char/vmwatchdog.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/s390/char/vmwatchdog.c b/drivers/s390/char/vmwatchdog.c index 19f8389291b6..ee80e936d514 100644 --- a/drivers/s390/char/vmwatchdog.c +++ b/drivers/s390/char/vmwatchdog.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -131,11 +132,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); } From 38c4c97c62a30aef276663c1128a2051a25ead7d Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 20 May 2008 19:17:02 +0200 Subject: [PATCH 132/146] x86-mce: BKL pushdown Signed-off-by: Arnd Bergmann --- arch/x86/kernel/cpu/mcheck/mce_64.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c index e07e8c068ae0..4ef151633e8b 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_64.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -527,10 +528,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; } @@ -539,6 +542,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); } From 9c20616c385ebeaa30257ef5d35e8f346db4ee32 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 29 May 2008 17:14:05 -0600 Subject: [PATCH 133/146] Make FAT users happier by not deadlocking The FAT BKL removal patch can cause deadlocks. It turns out that the new lock_super() calls are unneeded, remove them (as directed by Linus). Reported-by: "Tony Luck" Signed-off-by: Jonathan Corbet --- fs/fat/file.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/fs/fat/file.c b/fs/fat/file.c index 7059928fb351..bdf91e97397d 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -229,8 +228,7 @@ static int fat_free(struct inode *inode, int skip) void fat_truncate(struct inode *inode) { - struct super_block *sb = inode->i_sb; - struct msdos_sb_info *sbi = MSDOS_SB(sb); + struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); const unsigned int cluster_size = sbi->cluster_size; int nr_clusters; @@ -243,9 +241,7 @@ void fat_truncate(struct inode *inode) nr_clusters = (inode->i_size + (cluster_size - 1)) >> sbi->cluster_bits; - lock_super(sb); fat_free(inode, nr_clusters); - unlock_super(sb); fat_flush_inodes(inode->i_sb, inode, NULL); } @@ -298,14 +294,11 @@ static int fat_allow_set_time(struct msdos_sb_info *sbi, struct inode *inode) int fat_setattr(struct dentry *dentry, struct iattr *attr) { - struct super_block *sb = dentry->d_sb; struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb); struct inode *inode = dentry->d_inode; int mask, error = 0; unsigned int ia_valid; - lock_super(sb); - /* * Expand the file. Since inode_setattr() updates ->i_size * before calling the ->truncate(), but FAT needs to fill the @@ -358,7 +351,6 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr) mask = sbi->options.fs_fmask; inode->i_mode &= S_IFMT | (S_IRWXUGO & ~mask); out: - unlock_super(sb); return error; } EXPORT_SYMBOL_GPL(fat_setattr); From 9465efc9e96135a2cec8154c0c766fa59984a298 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Fri, 27 Jun 2008 11:05:24 +0200 Subject: [PATCH 134/146] Remove BKL from remote_llseek v2 - Replace remote_llseek with generic_file_llseek_unlocked (to force compilation failures in all users) - Change all users to either use generic_file_llseek_unlocked directly or take the BKL around. I changed the file systems who don't use the BKL for anything (CIFS, GFS) to call it directly. NCPFS and SMBFS and NFS take the BKL, but explicitely in their own source now. I moved them all over in a single patch to avoid unbisectable sections. Open problem: 32bit kernels can corrupt fpos because its modification is not atomic, but they can do that anyways because there's other paths who modify it without BKL. Do we need a special lock for the pos/f_version = 0 checks? Trond says the NFS BKL is likely not needed, but keep it for now until his full audit. v2: Use generic_file_llseek_unlocked instead of remote_llseek_unlocked and factor duplicated code (suggested by hch) Cc: Trond.Myklebust@netapp.com Cc: swhiteho@redhat.com Cc: sfrench@samba.org Cc: vandrove@vc.cvut.cz Signed-off-by: Andi Kleen Signed-off-by: Andi Kleen Signed-off-by: Jonathan Corbet --- fs/cifs/cifsfs.c | 2 +- fs/gfs2/ops_file.c | 4 ++-- fs/ncpfs/file.c | 12 +++++++++++- fs/nfs/file.c | 6 +++++- fs/read_write.c | 38 +++++++++++--------------------------- fs/smbfs/file.c | 11 ++++++++++- include/linux/fs.h | 3 ++- 7 files changed, 42 insertions(+), 34 deletions(-) diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 427a7c695896..aeff0fe5b6b9 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -581,7 +581,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/gfs2/ops_file.c b/fs/gfs2/ops_file.c index e1b7d525a066..24dd59450088 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/ncpfs/file.c b/fs/ncpfs/file.c index 2b145de45b39..6a7d901f1936 100644 --- a/fs/ncpfs/file.c +++ b/fs/ncpfs/file.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #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 3536b01164f9..a34eb78989f5 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/read_write.c b/fs/read_write.c index f0d1240a5c69..9ba495d5a29b 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 efbe29af3d7a..2294783320cb 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/include/linux/fs.h b/include/linux/fs.h index f413085f748e..b158e5161bca 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1871,7 +1871,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); From b7e3e1fbf69d1b6abfd337460ea17d7230e3a6e5 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 19 Jun 2008 15:41:11 -0600 Subject: [PATCH 135/146] mpt: fasync BKL pushdown It looks like this driver really needs the BKL here. Signed-off-by: Jonathan Corbet --- drivers/message/fusion/mptctl.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index e630b50966ec..c5946560c4e2 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 From 743115ee05f09f356d86763316acf627a7f5a6b3 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 19 Jun 2008 15:44:57 -0600 Subject: [PATCH 136/146] i2o: fasync BKL pushdown This driver appears to really need the BKL to protect open_files. Signed-off-by: Jonathan Corbet --- drivers/message/i2o/i2o_config.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c index 95b4c108585c..4238de98d4a6 100644 --- a/drivers/message/i2o/i2o_config.c +++ b/drivers/message/i2o/i2o_config.c @@ -1084,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) From 9d319522576ce0b2fd023a965445f9c3739ee6f1 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 19 Jun 2008 15:50:37 -0600 Subject: [PATCH 137/146] tun: fasync BKL pushdown Signed-off-by: Jonathan Corbet --- drivers/net/tun.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/net/tun.c b/drivers/net/tun.c index ce5af2aa8843..4c0c5972a489 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -782,18 +782,21 @@ 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) From 5d1e3230f4b4a93c6561b0fb5a99bb1eb02227ed Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 19 Jun 2008 16:04:53 -0600 Subject: [PATCH 138/146] tty_io: fasync BKL pushdown Signed-off-by: Jonathan Corbet --- drivers/char/tty_io.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index fd182f2e4a6c..eda27899372c 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -2909,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; @@ -2935,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; } /** From dbfb2df7e9fbd6e5ab8cd9b94b27767fe311fa0d Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 19 Jun 2008 16:07:51 -0600 Subject: [PATCH 139/146] Bluetooth VHCI: fasync BKL pushdown Signed-off-by: Jonathan Corbet --- drivers/bluetooth/hci_vhci.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c index 7734bc9af3ca..d97700aa54a9 100644 --- a/drivers/bluetooth/hci_vhci.c +++ b/drivers/bluetooth/hci_vhci.c @@ -318,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 = { From dda6445e219b5d1fd67e9426ce8d23f8fbfaaf66 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 19 Jun 2008 16:18:25 -0600 Subject: [PATCH 140/146] ecryptfs: fasync BKL pushdown Signed-off-by: Jonathan Corbet --- fs/ecryptfs/file.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index 2258b8f654a6..24749bf0668f 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c @@ -30,6 +30,7 @@ #include #include #include +#include #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; } From 70b028b7ea94f1b36c61f3ee1c921cc3a87812e6 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Mon, 23 Jun 2008 17:00:14 -0600 Subject: [PATCH 141/146] ipmi: fasync BKL pushdown This driver really needs it to avoid races against open() Signed-off-by: Jonathan Corbet --- drivers/char/ipmi/ipmi_devintf.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index c816656d6bfb..c11a40483459 100644 --- a/drivers/char/ipmi/ipmi_devintf.c +++ b/drivers/char/ipmi/ipmi_devintf.c @@ -101,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); } From 2db9f0a35a4e4ad7cee756a4e0dabb7c1c8b6c72 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Mon, 23 Jun 2008 17:40:43 -0600 Subject: [PATCH 142/146] snd/PCM: fasync BKL pushdown Chances are this is unneeded, but the code is twisty enough that it is hard to tell. Signed-off-by: Jonathan Corbet --- sound/core/pcm_native.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 61f5d425b630..c49b9d9e303c 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -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; From a238b790d5f99c7832f9b73ac8847025815b85f7 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Fri, 20 Jun 2008 09:12:01 -0600 Subject: [PATCH 143/146] Call fasync() functions without the BKL lock_kernel() calls have been pushed down into code which needs it, so there is no need to take the BKL at this level anymore. This work inspired and aided by Andi Kleen's unlocked_fasync() patches. Acked-by: Andi Kleen Signed-off-by: Jonathan Corbet --- fs/fcntl.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/fs/fcntl.c b/fs/fcntl.c index bfd776509a72..330a7d782591 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -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; } From 57debddaa1d247ed147209b22b5d40bd97526c33 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Mon, 30 Jun 2008 16:45:15 -0600 Subject: [PATCH 144/146] bf561-coreb: BKL unneeded for open() According to Mike Frysinger: http://permalink.gmane.org/gmane.linux.kernel/699279 open() does not need the BKL, so take it back out. --- arch/blackfin/mach-bf561/coreb.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/arch/blackfin/mach-bf561/coreb.c b/arch/blackfin/mach-bf561/coreb.c index 852647801a01..8598098c0840 100644 --- a/arch/blackfin/mach-bf561/coreb.c +++ b/arch/blackfin/mach-bf561/coreb.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include @@ -195,9 +194,9 @@ 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) { - lock_kernel(); spin_lock_irq(&coreb_lock); if (coreb_status & COREB_IS_OPEN) @@ -206,12 +205,10 @@ static int coreb_open(struct inode *inode, struct file *file) coreb_status |= COREB_IS_OPEN; spin_unlock_irq(&coreb_lock); - unlock_kernel(); return 0; out_busy: spin_unlock_irq(&coreb_lock); - unlock_kernel(); return -EBUSY; } From 5b2d281acb04a29fcdc76ced5ca6099565a0747f Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Fri, 27 Jun 2008 14:43:20 -0700 Subject: [PATCH 145/146] IB/uverbs: BKL is not needed for ib_uverbs_open() Remove explicit lock_kernel() calls and document why the code is safe. Signed-off-by: Roland Dreier Signed-off-by: Jonathan Corbet --- drivers/infiniband/core/uverbs_main.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 8ede1e475ce6..fdfcf7910d9a 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -45,7 +45,6 @@ #include #include #include -#include #include @@ -611,23 +610,32 @@ 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; struct ib_uverbs_file *file; int ret; - lock_kernel(); spin_lock(&map_lock); dev = dev_table[iminor(inode) - IB_UVERBS_BASE_MINOR]; if (dev) kref_get(&dev->ref); spin_unlock(&map_lock); - if (!dev) { - unlock_kernel(); + if (!dev) return -ENXIO; - } if (!try_module_get(dev->ib_dev->owner)) { ret = -ENODEV; @@ -648,7 +656,6 @@ static int ib_uverbs_open(struct inode *inode, struct file *filp) filp->private_data = file; - unlock_kernel(); return 0; err_module: @@ -656,7 +663,6 @@ err_module: err: kref_put(&dev->ref, ib_uverbs_release_dev); - unlock_kernel(); return ret; } From feae1ef116ed381625d3731c5ae4f4ebcb3fa302 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Fri, 11 Jul 2008 13:54:40 -0700 Subject: [PATCH 146/146] IB/umad: BKL is not needed for ib_umad_open() Remove explicit lock_kernel() calls and document why the code is safe. Signed-off-by: Roland Dreier Signed-off-by: Jonathan Corbet --- drivers/infiniband/core/user_mad.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index 1fc17940a765..ef6dd825fee9 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c @@ -47,7 +47,6 @@ #include #include #include -#include #include @@ -778,23 +777,33 @@ 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; struct ib_umad_file *file; int ret = 0; - lock_kernel(); spin_lock(&port_lock); port = umad_port[iminor(inode) - IB_UMAD_MINOR_BASE]; if (port) kref_get(&port->umad_dev->ref); spin_unlock(&port_lock); - if (!port) { - unlock_kernel(); + if (!port) return -ENXIO; - } mutex_lock(&port->file_mutex); @@ -823,7 +832,6 @@ static int ib_umad_open(struct inode *inode, struct file *filp) out: mutex_unlock(&port->file_mutex); - unlock_kernel(); return ret; }