Push BKL into chrdev opens
Subsystems (22)
RFC 1/1 Push BKL into chrdev opens
This patch adds the BKL to each character device's open() function. The BKL will remain in chrdev_open() until the module unload races are fixed, but this makes it unnecessary there for any other reason.
I'm reasonably confident that I found all of the character devices' open()s if the device used register_chrdev or devfs_register_chrdev. I _think_ this covers them all. I'm also reasonably confident that I added all of the #includes correctly this time. It is hard to say if it compiles or not because half the kernel doesn't compile right now anyway :(
I'm posting this to give any of the driver writers a chance to scream before I send it elsewhere. However, before you scream too loudly, remember, I didn't _add_ the BKL to your driver. It was already being held there, you just may not have known it. Adding it explicitly to your driver changes nothing but semantics. If you _know_ that you don't need it, I'll make sure not to touch your driver in the patch that I ultimately submit. If you would like some pamphlets, magazines, or videos on how to remove the BKL from your driver, I can provide those too.
I'll also update Documentation/filesystems/Locking somewhat like this:
-instances of ->open() - will be called without the BKL.
+instances of ->open() - will be called without the BKL. BKL has been +pushed into each chardev ->open(), so module races are all that is +keeping BKL in chrdev_open()
Patch attached against the latest Linus BK tree. I'll hopefully have it in a public BK tree soon, ripe for pulling.
Signature · 2 lines
Dave Hansen [email protected]
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas:
# ChangeSet 1.548 -> 1.550
# drivers/video/fbmem.c 1.24 -> 1.25
# drivers/sbus/audio/audio.c 1.9 -> 1.10
# arch/i386/kernel/cpuid.c 1.9 -> 1.10 # arch/cris/drivers/gpio.c 1.6 -> 1.8 # drivers/block/acsi_slm.c 1.4 -> 1.5
# drivers/usb/misc/tiglusb.c 1.7 -> 1.8
# drivers/char/lp.c 1.19 -> 1.20
# arch/m68k/atari/joystick.c 1.4 -> 1.5
# drivers/net/wan/cosa.c 1.9 -> 1.11
# drivers/sbus/char/bpp.c 1.5 -> 1.6
# arch/m68k/bvme6000/rtc.c 1.5 -> 1.6
# drivers/char/raw.c 1.18 -> 1.20
# drivers/char/istallion.c 1.10 -> 1.11
# drivers/telephony/phonedev.c 1.4 -> 1.6
# arch/cris/drivers/i2c.c 1.3 -> 1.4
# drivers/net/wan/hdlc_ppp.c 1.2 -> 1.3
# arch/cris/drivers/sync_serial.c 1.4 -> 1.6
# drivers/media/video/videodev.c 1.13 -> 1.14
# sound/core/sound.c 1.6 -> 1.8
# drivers/char/drm/radeon_drv.c 1.4 -> 1.5
# drivers/ide/ide-tape.c 1.53 -> 1.54
# arch/x86_64/kernel/msr.c 1.3 -> 1.4
# drivers/char/stallion.c 1.10 -> 1.11
# drivers/ieee1394/ieee1394_core.c 1.15 -> 1.17
# arch/x86_64/kernel/cpuid.c 1.3 -> 1.4
# drivers/block/paride/pt.c 1.10 -> 1.12
# drivers/scsi/dpt_i2o.c 1.13 -> 1.14
# drivers/char/vc_screen.c 1.5 -> 1.6
# fs/intermezzo/psdev.c 1.8 -> 1.10
# arch/sparc64/solaris/socksys.c 1.7 -> 1.8
# drivers/isdn/i4l/isdn_common.c 1.21 -> 1.23
# drivers/ieee1394/pcilynx.c 1.19 -> 1.21
# drivers/atm/atmdev_init.c 1.4 -> 1.5
# arch/cris/drivers/eeprom.c 1.6 -> 1.7
# drivers/mtd/mtdblock.c 1.20 -> 1.21
# drivers/char/ftape/zftape/zftape-init.c 1.8 -> 1.10
# net/netlink/netlink_dev.c 1.7 -> 1.8
# drivers/char/dtlk.c 1.8 -> 1.9
# arch/i386/kernel/msr.c 1.9 -> 1.10
# sound/sound_core.c 1.10 -> 1.12
# drivers/s390/char/tapechar.c 1.7 -> 1.9
# drivers/char/ppdev.c 1.13 -> 1.14 # drivers/scsi/sg.c 1.18 -> 1.19 # drivers/scsi/osst.c 1.15 -> 1.18
# drivers/mtd/mtdblock_ro.c 1.14 -> 1.15
# drivers/char/tpqic02.c 1.13 -> 1.14
# drivers/macintosh/adb.c 1.9 -> 1.10
# drivers/char/dsp56k.c 1.9 -> 1.10
# drivers/input/input.c 1.11 -> 1.13
# drivers/sbus/char/vfc_dev.c 1.6 -> 1.7
# drivers/char/tty_io.c 1.35 -> 1.36
# drivers/s390/char/tubfs.c 1.5 -> 1.8
# drivers/md/lvm.c 1.29 -> 1.30
# drivers/scsi/st.c 1.20 -> 1.21
# drivers/mtd/mtdchar.c 1.8 -> 1.9
# drivers/sbus/char/sunkbd.c 1.6 -> 1.7
# drivers/pcmcia/ds.c 1.13 -> 1.14
# drivers/sgi/char/shmiq.c 1.6 -> 1.7
# drivers/i2c/i2c-dev.c 1.11 -> 1.13
# drivers/char/drm/drm_stub.h 1.3 -> 1.5
# drivers/block/paride/pg.c 1.10 -> 1.12
# drivers/isdn/divert/divert_procfs.c 1.9 -> 1.10
# drivers/macintosh/rtc.c 1.7 -> 1.8
# drivers/net/ppp_generic.c 1.12 -> 1.13
# drivers/isdn/capi/capi.c 1.33 -> 1.34
# drivers/usb/core/file.c 1.3 -> 1.5
# drivers/char/ip2main.c 1.12 -> 1.15
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/07/30 [email protected] 1.543.1.1
# 1/2 should cover all devices which use register_chrdev directly
# next one will cover devfs_register_chrdev
#
# chrdev_open() hold the BKL around all calls to the character drivers'
# open functions. # # This patch shifts that call into the individual open()s. The BKL will # remain in chrdev_open() until the module unload races are fixed, but # this makes it unnecessary for any other reason. # # -------------------------------------------- # 02/07/30 [email protected] 1.543.1.2 # part 2/2 # # BKL push into character devices' open() functions # # This changeset should cover all of the character devices which use # the devfs register function. Combined with the previous patch, it # should now be safe for the _drivers_ if the BKL is gone from # chrdev_open(). But, this can't be done yet because of module # load/unload races. # -------------------------------------------- # 02/07/30 [email protected] 1.543.1.3 # lock/unlock_kernel() need to have smp_lock.h # -------------------------------------------- # 02/07/30 [email protected] 1.543.1.4 # Fix a few little problems with returning before unlocking # -------------------------------------------- # 02/07/30 [email protected] 1.549 # Merge bk://linus.bkbits.net/linux-2.5 # into nighthawk.sr71.net:/home/dave/lse/linux/2.5/bk/linux-2.5 # -------------------------------------------- # 02/07/31 [email protected] 1.550 # Push the BKL into a few more open() functions that were missed in t # he last couple of patches # # Fix a few includes # # Fix a few rtc drivers so they don't need the BKL at all # -------------------------------------------- # diff -Nru a/arch/cris/drivers/eeprom.c b/arch/cris/drivers/eeprom.c --- a/arch/cris/drivers/eeprom.c Wed Jul 31 10:25:53 2002 +++ b/arch/cris/drivers/eeprom.c Wed Jul 31 10:25:53 2002 @@ -424,20 +424,31 @@
static int eeprom_open(struct inode * inode, struct file * file) {
+ int ret = -EFAULT;
+ lock_kernel();
if(MINOR(inode->i_rdev) != EEPROM_MINOR_NR)
- return -ENXIO;
+ {
+ ret = -ENXIO;
+ goto out;
+ }
if(MAJOR(inode->i_rdev) != EEPROM_MAJOR_NR)
- return -ENXIO;
+ {
+ ret = -ENXIO;
+ goto out;
+ }
if( eeprom.size > 0 )
{
/* OK */
- return 0;
+ ret = 0;
+ goto out;}
+out:
/* No EEprom found */
- return -EFAULT; + unlock_kernel(); + return ret;
}
/* Changes the current file position. */
arch/cris/drivers/gpio.c +15 -5
@@ -69,6 +69,7 @@#include <linux/string.h> #include <linux/poll.h> #include <linux/init.h> +#include <linux/smp_lock.h> #include <asm/etraxgpio.h> #include <asm/svinto.h>
@@ -217,16 +218,23 @@ gpio_open(struct inode *inode, struct file *filp) { struct gpio_private *priv; +int ret =0 ;int p =minor (inode->i_rdev); + +lock_kernel (); -if (p >=NUM_PORTS && p !=LEDS ) -return -EINVAL ; +if (p >=NUM_PORTS && p !=LEDS ) { + ret = -EINVAL ; + goto out; + } priv = (struct gpio_private *)kmalloc (sizeof (struct gpio_private ),GFP_KERNEL ); -if (!priv) -return -ENOMEM ; +if (!priv) { + ret = -ENOMEM ; + goto out; + } priv->minor = p;
@@ -250,7 +258,9 @@ filp->private_data = (void *)priv; -return 0 ; +out: +unlock_kernel (); +return ret; } static int
arch/cris/drivers/i2c.c +1 -0
@@ -58,6 +58,7 @@#include <linux/string.h> #include <linux/init.h> #include <linux/config.h> +#include <linux/smp_lock.h> #include <asm/etraxi2c.h>
arch/cris/drivers/sync_serial.c +13 -3
@@ -22,6 +22,7 @@#include <linux/interrupt.h> #include <linux/init.h> #include <linux/timer.h> +#include <linux/smp_lock.h> #include <asm/irq.h> #include <asm/io.h> #include <asm/svinto.h>
@@ -338,20 +339,29 @@static int sync_serial_open (struct inode *inode,struct file *file) {int dev =MINOR (inode->i_rdev); +int ret =0 ; + +lock_kernel (); +DEBUG (printk ("Open sync serial port %d\n" , dev));if (dev <0 || dev >=NUMBER_OF_PORTS || !ports[dev].enabled) {DEBUG (printk ("Invalid minor %d\n" , dev)); -return -ENODEV ; + ret = -ENODEV ; + goto out; }if (ports[dev].busy) {DEBUG (printk ("Device is busy.. \n" )); -return -EBUSY ; + ret = -EBUSY ; + goto out; } ports[dev].busy =1 ; -return 0 ; + +out: +unlock_kernel (); +return ret; }static int sync_serial_release (struct inode *inode,struct file *file)
arch/i386/kernel/cpuid.c +8 -4
@@ -133,13 +133,17 @@ {int cpu =minor (file->f_dentry->d_inode->i_rdev);struct cpuinfo_x86 *c = &(cpu_data)[cpu]; +int ret =0 ; + +lock_kernel ();if ( !(cpu_online_map & (1UL << cpu)) ) -return -ENXIO ;/* No such CPU */ -if ( c->cpuid_level <0 ) -return -EIO ;/* CPUID not supported */ + ret = -ENXIO ;/* No such CPU */ +else if ( c->cpuid_level <0 ) + ret = -EIO ;/* CPUID not supported */ -return 0 ; +unlock_kernel (); +return ret; }/*
arch/i386/kernel/msr.c +9 -5
@@ -233,13 +233,17 @@ {int cpu =minor (file->f_dentry->d_inode->i_rdev);struct cpuinfo_x86 *c = &(cpu_data)[cpu]; +int ret =0 ; + +lock_kernel ();if ( !(cpu_online_map & (1UL << cpu)) ) -return -ENXIO ;/* No such CPU */ -if ( !cpu_has (c,X86_FEATURE_MSR ) ) -return -EIO ;/* MSR not supported */ - -return 0 ; + ret = -ENXIO ;/* No such CPU */ +else if ( !cpu_has (c,X86_FEATURE_MSR ) ) + ret = -EIO ;/* MSR not supported */ + +unlock_kernel (); +return ret; }/*
arch/m68k/atari/joystick.c +14 -5
@@ -72,15 +72,24 @@static int open_joystick (struct inode *inode,struct file *file) {int minor =DEVICE_NR (inode->i_rdev); +int ret =0 ; -if (!DIGITAL_JOY (inode->i_rdev) || minor >1 ) -return -ENODEV ; -if (joystick[minor].active) -return -EBUSY ; +lock_kernel (); + +if (!DIGITAL_JOY (inode->i_rdev) || minor >1 ) { + ret = -ENODEV ; + goto out; + } +if (joystick[minor].active) { + ret = -EBUSY ; + goto out; + } joystick[minor].active =1 ; joystick[minor].ready =0 ;ikbd_joystick_event_on (); -return 0 ; +out: +unlock_kernel (); +return ret; } static ssize_t write_joystick(struct file *file, const char *buffer,
arch/m68k/bvme6000/rtc.c +2 -5
@@ -141,18 +141,15 @@static int rtc_open (struct inode *inode,struct file *file) { -if (rtc_status) +if (test_and_set_bit (0 ,&rtc_status))return -EBUSY ; - rtc_status =1 ;return 0 ; }static int rtc_release (struct inode *inode,struct file *file) { -lock_kernel (); - rtc_status =0 ; -unlock_kernel (); +clear_bit (0 ,&rtc_status);return 0 ; }
arch/sparc64/solaris/socksys.c +10 -2
@@ -67,6 +67,8 @@int (*sys_socket)(int ,int ,int ) = (int (*)(int ,int ,int ))SUNOS (97 );struct sol_socket_struct * sock; + +lock_kernel (); family = ((minor (inode->i_rdev) >>4 ) &0xf );switch (family) {
@@ -89,8 +91,10 @@ } fd =sys_socket (family, type, protocol); -if (fd <0 ) +if (fd <0 ) { +unlock_kernel ();return fd; + }/* * N.B. The following operations are not legal! *
@@ -107,7 +111,10 @@ filp->f_op = &socksys_file_ops; sock = (struct sol_socket_struct *)mykmalloc (sizeof (struct sol_socket_struct ),GFP_KERNEL ); -if (!sock)return -ENOMEM ; +if (!sock) { +unlock_kernel (); +return -ENOMEM ; + }SOLDD (("sock=%016lx(%016lx)\n" , sock, filp)); sock->magic =SOLARIS_SOCKET_MAGIC ; sock->modcount =0 ;
@@ -119,6 +126,7 @@sys_close (fd);dput (dentry); +unlock_kernel ();return 0 ; }
arch/x86_64/kernel/cpuid.c +7 -3
@@ -133,12 +133,16 @@ {int cpu =minor (file->f_dentry->d_inode->i_rdev);struct cpuinfo_x86 *c = &(cpu_data)[cpu]; +int ret =0 ; + +lock_kernel ();if ( !(cpu_online_map & (1UL << cpu)) ) -return -ENXIO ;/* No such CPU */ -if ( c->cpuid_level <0 ) -return -EIO ;/* CPUID not supported */ + ret = -ENXIO ;/* No such CPU */ +else if ( c->cpuid_level <0 ) + ret = -EIO ;/* CPUID not supported */ +unlock_kernel ();return 0 ; }
arch/x86_64/kernel/msr.c +8 -4
@@ -234,13 +234,17 @@ {int cpu =minor (file->f_dentry->d_inode->i_rdev);struct cpuinfo_x86 *c = &(cpu_data)[cpu]; - +int ret =0 ; + +lock_kernel (); +if ( !(cpu_online_map & (1UL << cpu)) ) -return -ENXIO ;/* No such CPU */ + ret = -ENXIO ;/* No such CPU */ if ( !cpu_has (c,X86_FEATURE_MSR ) ) -return -EIO ;/* MSR not supported */ + ret = -EIO ;/* MSR not supported */ -return 0 ; +unlock_kernel (); +return ret; }/*
drivers/atm/atmdev_init.c +1 -0
@@ -5,6 +5,7 @@#include <linux/config.h> #include <linux/init.h> +#include <linux/smp_lock.h> #ifdef CONFIG_ATM_ZATM
drivers/block/acsi_slm.c +4 -0
@@ -774,12 +774,14 @@ device =MINOR (inode->i_rdev);if (device >= N_SLM_Printers)return ( -ENXIO ); +lock_kernel (); sip = &slm_info[device];if (file->f_mode &2 ) {/* open for writing is exclusive */ if ( !atomic_dec_and_test (&sip->wr_ok) ) {atomic_inc (&sip->wr_ok); +unlock_kernel ();return ( -EBUSY ); } }
@@ -787,10 +789,12 @@/* open for reading is exclusive */ if ( !atomic_dec_and_test (&sip->rd_ok) ) {atomic_inc (&sip->rd_ok); +unlock_kernel ();return ( -EBUSY ); } } +unlock_kernel ();return (0 ); }
drivers/block/paride/pg.c +10 -1
@@ -169,6 +169,7 @@#include <linux/slab.h> #include <linux/mtio.h> #include <linux/pg.h> +#include <linux/smp_lock.h> #include <asm/uaccess.h>
@@ -506,9 +507,15 @@ {int unit =DEVICE_NR (inode->i_rdev); -if ((unit >=PG_UNITS ) || (!PG .present))return -ENODEV ; +lock_kernel (); + +if ((unit >=PG_UNITS ) || (!PG .present)) { +unlock_kernel (); +return -ENODEV ; + }if (test_and_set_bit (0 , &PG .access) ) { +unlock_kernel ();return -EBUSY ; }
@@ -524,9 +531,11 @@if (PG .bufptr ==NULL ) {clear_bit (0 , &PG .access ) ;printk ("%s: buffer allocation failed\n" ,PG .name); +unlock_kernel ();return -ENOMEM ; } +unlock_kernel ();return 0 ; }
drivers/block/paride/pt.c +13 -3
@@ -147,6 +147,7 @@#include <linux/delay.h> #include <linux/slab.h> #include <linux/mtio.h> +#include <linux/smp_lock.h> #include <asm/uaccess.h>
@@ -625,22 +626,29 @@ {int unit =DEVICE_NR (inode->i_rdev); -if ((unit >=PT_UNITS ) || (!PT .present))return -ENODEV ; - + lock_kernel() + +if ((unit >=PT_UNITS ) || (!PT .present)) { +unlock_kernel (); +return -ENODEV ; + }if ( !atomic_dec_and_test (&PT .available) ) {atomic_inc ( &PT .available ); -return -EBUSY ; +unlock_kernel (); + eturn -EBUSY ; }pt_identify (unit);if (!PT .flags &PT_MEDIA ) {atomic_inc ( &PT .available ); +unlock_kernel ();return -ENODEV ; }if ((!PT .flags &PT_WRITE_OK ) && (file ->f_mode &2 )) {atomic_inc ( &PT .available ); +unlock_kernel ();return -EROFS ; }
@@ -651,9 +659,11 @@if (PT .bufptr ==NULL ) {atomic_inc ( &PT .available );printk ("%s: buffer allocation failed\n" ,PT .name); +unlock_kernel ();return -ENOMEM ; } +unlock_kernel ();return 0 ; }
drivers/char/drm/drm_stub.h +7 -1
@@ -53,7 +53,11 @@int err = -ENODEV ;struct file_operations *old_fops; -if (!DRM (stub_list) || !DRM (stub_list)[minor].fops)return -ENODEV ; +lock_kernel (); + +if (!DRM (stub_list) || !DRM (stub_list)[minor].fops) + goto out; + old_fops = filp->f_op; filp->f_op =fops_get (DRM (stub_list)[minor].fops);if (filp->f_op->open && (err = filp->f_op->open (inode, filp))) {
@@ -62,6 +66,8 @@ }fops_put (old_fops); +out: +unlock_kernel ();return err; }
drivers/char/drm/radeon_drv.c +0 -1
@@ -112,5 +112,4 @@#include "drm_memory.h" #include "drm_proc.h" #include "drm_vm.h" -#include "drm_stub.h" #include "drm_scatter.h"
drivers/char/dsp56k.c +7 -1
@@ -443,12 +443,16 @@ {int dev =minor (inode->i_rdev) &0x0f ; +lock_kernel (); +switch (dev) {case DSP56K_DEV_56001 : -if (test_and_set_bit (0 , &dsp56k.in_use)) +if (test_and_set_bit (0 , &dsp56k.in_use)) { +unlock_kernel ();return -EBUSY ; + } dsp56k.timeout =TIMEOUT ; dsp56k.maxio =MAXIO ;
@@ -464,9 +468,11 @@break ;default : +unlock_kernel ();return -ENODEV ; } +unlock_kernel ();return 0 ; }
drivers/char/dtlk.c +8 -4
@@ -302,17 +302,21 @@static int dtlk_open (struct inode *inode,struct file *file) { +int ret =0 ;TRACE_TEXT ("(dtlk_open" ); +lock_kernel (); +switch (minor (inode->i_rdev)) {case DTLK_MINOR :if (dtlk_busy) -return -EBUSY ; -return 0 ; - + ret = -EBUSY ; +break ;default : -return -ENXIO ; + ret = -ENXIO ; } +unlock_kernel (); +return ret; }static int dtlk_release (struct inode *inode,struct file *file)
drivers/char/ftape/zftape/zftape-init.c +6 -0
@@ -112,14 +112,18 @@int result;TRACE_FUN (ft_t_flow); +lock_kernel (); +TRACE (ft_t_flow,"called for minor %d" ,minor (ino->i_rdev));if (test_and_set_bit (0 ,&busy_flag) ) { +unlock_kernel ();TRACE_ABORT (-EBUSY , ft_t_warn,"failed: already busy" ); }if ((minor (ino->i_rdev) & ~(ZFT_MINOR_OP_MASK |FTAPE_NO_REWIND )) >FTAPE_SEL_D ) {clear_bit (0 ,&busy_flag); +unlock_kernel ();TRACE_ABORT (-ENXIO , ft_t_err,"failed: illegal unit nr" ); } orig_sigmask = current->blocked;
@@ -128,6 +132,7 @@if (result <0 ) { current->blocked = orig_sigmask;/* restore mask */ clear_bit (0 ,&busy_flag); +unlock_kernel ();TRACE_ABORT (result, ft_t_err,"_ftape_open failed" ); }else {/* Mask signals that will disturb proper operation of the
@@ -135,6 +140,7 @@*/ current->blocked = orig_sigmask;sigaddsetmask (¤t->blocked, _DO_BLOCK); +unlock_kernel (); TRACE_EXIT 0; } }
drivers/char/ip2main.c +17 -1
@@ -94,6 +94,7 @@#include <linux/module.h> #include <linux/signal.h> #include <linux/sched.h> +#include <linux/smp_lock.h> #ifdef CONFIG_DEVFS_FS #include <linux/devfs_fs_kernel.h> #endif
@@ -1589,11 +1590,15 @@wait_queue_t wait;int rc =0 ;int do_clocal =0 ; -i2ChanStrPtr pCh = DevTable[minor (tty->device)]; +i2ChanStrPtr pCh; + +lock_kernel (); + pCh = DevTable[minor (tty->device)];ip2trace (minor (tty->device),ITRC_OPEN ,ITRC_ENTER ,0 );if ( pCh ==NULL ) { +unlock_kernel ();return -ENODEV ; }/* Setup pointer links in device and tty structures */
@@ -1629,6 +1634,7 @@if (tty_hung_up_p (pFile) ) {set_current_state (TASK_RUNNING );remove_wait_queue (&pCh->close_wait, &wait); +unlock_kernel ();return ( pCh->flags &ASYNC_HUP_NOTIFY ) ? -EAGAIN : -ERESTARTSYS ; } }
@@ -1643,16 +1649,19 @@*/ if ( tty->driver.subtype ==SERIAL_TYPE_CALLOUT ) {if ( pCh->flags &ASYNC_NORMAL_ACTIVE ) { +unlock_kernel ();return -EBUSY ; }if ( ( pCh->flags &ASYNC_CALLOUT_ACTIVE ) && ( pCh->flags &ASYNC_SESSION_LOCKOUT ) && ( pCh->session != current->session ) ) { +unlock_kernel ();return -EBUSY ; }if ( ( pCh->flags &ASYNC_CALLOUT_ACTIVE ) && ( pCh->flags &ASYNC_PGRP_LOCKOUT ) && ( pCh->pgrp != current->pgrp ) ) { +unlock_kernel ();return -EBUSY ; } pCh->flags |=ASYNC_CALLOUT_ACTIVE ;
@@ -1663,6 +1672,7 @@*/ if ( (pFile->f_flags &O_NONBLOCK ) || (tty->flags & (1 <<TTY_IO_ERROR ) )) {if ( pCh->flags &ASYNC_CALLOUT_ACTIVE ) { +unlock_kernel ();return -EBUSY ; } pCh->flags |=ASYNC_NORMAL_ACTIVE ;
@@ -1701,6 +1711,7 @@if (tty_hung_up_p (pFile) ) {set_current_state (TASK_RUNNING );remove_wait_queue (&pCh->open_wait, &wait); +unlock_kernel ();return ( pCh->flags &ASYNC_HUP_NOTIFY ) ? -EBUSY : -ERESTARTSYS ; } if ( !(pCh->flags & ASYNC_CALLOUT_ACTIVE) &&
@@ -1734,6 +1745,7 @@ip2trace (CHANN ,ITRC_OPEN ,4 ,0 );if (rc !=0 ) { +unlock_kernel ();return rc; } pCh->flags |=ASYNC_NORMAL_ACTIVE ;
@@ -1771,6 +1783,7 @@ip2trace (CHANN ,ITRC_OPEN ,ITRC_RETURN ,0 ); +unlock_kernel ();return 0 ; }
@@ -3285,6 +3298,8 @@i2eBordStrPtr pB;i2ChanStrPtr pCh; +lock_kernel (); +#ifdef IP2DEBUG_IPL printk (KERN_DEBUG "IP2IPL: open\n" );#endif
@@ -3317,6 +3332,7 @@case 3 :break ; } +unlock_kernel ();return 0 ; }/******************************************************************************/
drivers/char/istallion.c +22 -18
@@ -1022,6 +1022,8 @@/*****************************************************************************/ +#define returnout (x) ret=x;goto out; +static int stli_open (struct tty_struct *tty,struct file *filp) {stlibrd_t *brdp;
@@ -1037,21 +1039,21 @@ minordev =minor (tty->device); brdnr =MINOR2BRD (minordev);if (brdnr >= stli_nrbrds) -return (-ENODEV ); +returnout (-ENODEV ); brdp = stli_brds[brdnr];if (brdp == (stlibrd_t *)NULL ) -return (-ENODEV ); +returnout (-ENODEV );if ((brdp->state &BST_STARTED ) ==0 ) -return (-ENODEV ); +returnout (-ENODEV ); portnr =MINOR2PORT (minordev);if ((portnr <0 ) || (portnr > brdp->nrports)) -return (-ENODEV ); +returnout (-ENODEV ); portp = brdp->ports[portnr];if (portp == (stliport_t *)NULL ) -return (-ENODEV ); +returnout (-ENODEV );if (portp->devnr <1 ) -return (-ENODEV ); +returnout (-ENODEV );MOD_INC_USE_COUNT ;
@@ -1064,8 +1066,8 @@if (portp->flags &ASYNC_CLOSING ) {interruptible_sleep_on (&portp->close_wait);if (portp->flags &ASYNC_HUP_NOTIFY ) -return (-EAGAIN ); -return (-ERESTARTSYS ); +returnout (-EAGAIN ); +returnout (-ERESTARTSYS ); }/*
@@ -1080,7 +1082,7 @@while (test_bit (ST_INITIALIZING , &portp->state)) {if (signal_pending (current)) -return (-ERESTARTSYS ); +returnout (-ERESTARTSYS );interruptible_sleep_on (&portp->raw_wait); }
@@ -1093,7 +1095,7 @@clear_bit (ST_INITIALIZING , &portp->state);wake_up_interruptible (&portp->raw_wait);if (rc <0 ) -return (rc); +returnout (rc); }/*
@@ -1105,8 +1107,8 @@if (portp->flags &ASYNC_CLOSING ) {interruptible_sleep_on (&portp->close_wait);if (portp->flags &ASYNC_HUP_NOTIFY ) -return (-EAGAIN ); -return (-ERESTARTSYS ); +returnout (-EAGAIN ); +returnout (-ERESTARTSYS ); }/*
@@ -1116,23 +1118,23 @@*/ if (tty->driver.subtype ==STL_DRVTYPCALLOUT ) {if (portp->flags &ASYNC_NORMAL_ACTIVE ) -return (-EBUSY ); +returnout (-EBUSY );if (portp->flags &ASYNC_CALLOUT_ACTIVE ) {if ((portp->flags &ASYNC_SESSION_LOCKOUT ) && (portp->session != current->session)) -return (-EBUSY ); +returnout (-EBUSY );if ((portp->flags &ASYNC_PGRP_LOCKOUT ) && (portp->pgrp != current->pgrp)) -return (-EBUSY ); +returnout (-EBUSY ); } portp->flags |=ASYNC_CALLOUT_ACTIVE ; }else {if (filp->f_flags &O_NONBLOCK ) {if (portp->flags &ASYNC_CALLOUT_ACTIVE ) -return (-EBUSY ); +returnout (-EBUSY ); }else {if ((rc =stli_waitcarrier (brdp, portp, filp)) !=0 ) -return (rc); +returnout (rc); } portp->flags |=ASYNC_NORMAL_ACTIVE ; }
@@ -1147,7 +1149,9 @@ portp->session = current->session; portp->pgrp = current->pgrp; -return (0 ); +out: +unlock_kernel (); +return 0 ; }/*****************************************************************************/
drivers/char/lp.c +14 -6
@@ -486,7 +486,7 @@static int lp_open (struct inode * inode,struct file * file) {unsigned int minor =minor (inode->i_rdev); - +int ret =0 ;if (minor >=LP_NO )return -ENXIO ;if ((LP_F (minor) &LP_EXIST ) ==0 )
@@ -494,6 +494,8 @@if (test_and_set_bit (LP_BUSY_BIT_POS , &LP_F (minor)))return -EBUSY ; +lock_kernel (); +/* 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
@@ -507,21 +509,25 @@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 = (char *)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]);
@@ -537,7 +543,9 @@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)
drivers/char/ppdev.c +4 -0
@@ -644,6 +644,8 @@if (!pp)return -ENOMEM ; +lock_kernel (); + pp->state.mode =IEEE1284_MODE_COMPAT ; pp->state.phase =init_phase (pp->state.mode); pp->flags =0 ;
@@ -657,6 +659,8 @@*/ pp->pdev =NULL ; file->private_data = pp; + +unlock_kernel ();return 0 ; }
drivers/char/raw.c +5 -0
@@ -15,6 +15,7 @@#include <linux/module.h> #include <linux/raw.h> #include <linux/capability.h> +#include <linux/smp_lock.h> #include <asm/uaccess.h>
@@ -39,8 +40,11 @@struct block_device *bdev;int err; +lock_kernel (); +if (minor ==0 ) {/* It is the control device */ filp->f_op = &raw_ctl_fops; +unlock_kernel ();return 0 ; }
@@ -60,6 +64,7 @@ } }up (&raw_mutex); +unlock_kernel ();return err; }
drivers/char/stallion.c +62 -23
138 lines not on this page · raw message
drivers/char/tpqic02.c +2 -1
@@ -2178,8 +2178,9 @@static int qic02_tape_open_no_use_count (struct inode *,struct file *);int open_error; - +lock_kernel (); open_error =qic02_tape_open_no_use_count (inode, filp); +unlock_kernel ();return open_error; }
drivers/char/tty_io.c +22 -11
@@ -1286,13 +1286,17 @@unsigned short saved_flags;char buf[64 ]; +lock_kernel (); + saved_flags = filp->f_flags; retry_open: noctty = filp->f_flags &O_NOCTTY ; device = inode->i_rdev;if (IS_TTY_DEV (device)) { -if (!current->tty) -return -ENXIO ; +if (!current->tty) { + retval = -ENXIO ; + goto out; + } device = current->tty->device; filp->f_flags |=O_NONBLOCK ;/* Don't let /dev/tty block */ /* noctty = 1; */
@@ -1308,8 +1312,10 @@struct console *c = console_drivers;while (c && !c->device) c = c->next; -if (!c) -return -ENODEV ; +if (!c) { + retval = -ENODEV ; + goto out; + } device = c->device (c); filp->f_flags |=O_NONBLOCK ;/* Don't let /dev/console block */ noctty =1 ;
@@ -1333,7 +1339,8 @@if (!init_dev (device, &tty)) goto ptmx_found;/* ok! */ } } -return -EIO ;/* no free ptys */ + retval = -EIO ;/* no free ptys */ + goto out; ptmx_found:set_bit (TTY_PTY_LOCK , &tty->flags);/* LOCK THE SLAVE */ minor -= driver->minor_start;
@@ -1345,14 +1352,15 @@#else /* CONFIG_UNIX_98_PTYS */ -return -ENODEV ; + retval = -ENODEV ; + goto out;#endif /* CONFIG_UNIX_98_PTYS */ } retval =init_dev (device, &tty); -if (retval) -return retval; +if (retval) + goto out;#ifdef CONFIG_UNIX98_PTYS init_dev_done:
@@ -1383,9 +1391,9 @@release_dev (filp);if (retval != -ERESTARTSYS ) -return retval; + goto out;if (signal_pending (current)) -return retval; + goto out;schedule ();/* * Need to reset f_op in case a hangup happened.
@@ -1417,7 +1425,10 @@ nr_warns++; } } -return 0 ; + retval =0 ; +out: +unlock_kernel (); +return retval; }static int tty_release (struct inode * inode,struct file * filp)
drivers/char/vc_screen.c +5 -1
@@ -458,8 +458,12 @@ vcs_open(struct inode *inode, struct file *filp) { unsigned int currcons = minor(inode->i_rdev) & 127; -if (currcons && !vc_cons_allocated (currcons-1 )) +lock_kernel (); +if (currcons && !vc_cons_allocated (currcons-1 )) { +unlock_kernel ();return -ENXIO ; + } +unlock_kernel ();return 0 ; }
drivers/i2c/i2c-dev.c +13 -4
@@ -36,6 +36,7 @@#include <linux/fs.h> #include <linux/slab.h> #include <linux/version.h> +#include <linux/smp_lock.h> #if LINUX_KERNEL_VERSION >=KERNEL_VERSION (2 ,4 ,0 )#include <linux/smp_lock.h> #endif /* LINUX_KERNEL_VERSION >= KERNEL_VERSION(2,4,0) */
@@ -383,19 +384,24 @@ {unsigned int minor =minor (inode->i_rdev);struct i2c_client *client; +int ret =0 ; +lock_kernel ();if ((minor >=I2CDEV_ADAPS_MAX ) || ! (i2cdev_adaps[minor])) {#ifdef DEBUG printk (KERN_DEBUG "i2c-dev.o: Trying to open unattached adapter i2c-%d\n" , minor);#endif -return -ENODEV ; + ret = -ENODEV ; + goto out; }/* Note that we here allocate a client for later use, but we will *not* register this client! Yes, this is safe. No, it is not very clean. */ -if (! (client =kmalloc (sizeof (struct i2c_client ),GFP_KERNEL ))) -return -ENOMEM ; +if (! (client =kmalloc (sizeof (struct i2c_client ),GFP_KERNEL ))) { + ret = -ENOMEM ; + goto out; + }memcpy (client,&i2cdev_client_template,sizeof (struct i2c_client )); client->adapter = i2cdev_adaps[minor]; file->private_data = client;
@@ -409,7 +415,10 @@#ifdef DEBUG printk (KERN_DEBUG "i2c-dev.o: opened i2c-%d\n" ,minor);#endif -return 0 ; + +out: +unlock_kernel (); +return ret; }static int i2cdev_release (struct inode *inode,struct file *file)
drivers/ide/ide-tape.c +16 -6
@@ -4866,17 +4866,24 @@idetape_tape_t *tape;struct atapi_packet_command pc;unsigned int minor=minor (inode->i_rdev); +int ret =0 ; + +lock_kernel ();#if IDETAPE_DEBUG_LOG printk (KERN_INFO "ide-tape: Reached idetape_chrdev_open\n" );#endif -if ((drive =get_drive_ptr (inode->i_rdev)) ==NULL ) -return -ENXIO ; +if ((drive =get_drive_ptr (inode->i_rdev)) ==NULL ) { + ret = -ENXIO ; + goto out; + } tape = drive->driver_data; -if (test_and_set_bit (IDETAPE_BUSY , &tape->flags)) -return -EBUSY ; +if (test_and_set_bit (IDETAPE_BUSY , &tape->flags)) { + ret = -EBUSY ; + goto out; + }MOD_INC_USE_COUNT ;if (!tape->onstream) {idetape_read_position (drive);
@@ -4896,7 +4903,8 @@clear_bit (IDETAPE_BUSY , &tape->flags);printk (KERN_ERR "ide-tape: %s: drive not ready\n" , tape->name);MOD_DEC_USE_COUNT ; -return -EBUSY ; + ret = -EBUSY ; + goto out; }idetape_read_position (drive);MOD_DEC_USE_COUNT ;
@@ -4915,7 +4923,9 @@ tape->max_frames = tape->cur_frames = tape->req_buffer_fill =0 ;idetape_restart_speed_control (drive); tape->restart_speed_control_req =0 ; -return 0 ; +out: +unlock_kernel (); +return ret; }static void idetape_write_release (struct inode *inode)
drivers/ieee1394/ieee1394_core.c +6 -1
@@ -19,6 +19,8 @@#include <linux/interrupt.h> #include <linux/module.h> #include <linux/proc_fs.h> +#include <linux/smp_lock.h> +#include <asm/bitops.h> #include <asm/byteorder.h> #include <asm/semaphore.h>
@@ -870,6 +872,8 @@int blocknum;int retval = -ENODEV ; +lock_kernel (); +/* Maintaining correct module reference counts is tricky here!
@@ -950,7 +954,7 @@the module from unloading while the file is open, and will be dropped by the VFS when the file is released. */ - +unlock_kernel ();return 0 ; }
@@ -960,6 +964,7 @@function returns. */ file->f_op = &ieee1394_chardev_ops; +unlock_kernel ();return retval;#undef INCREF
drivers/ieee1394/pcilynx.c +27 -11
@@ -30,6 +30,8 @@#include <linux/pci.h> #include <linux/fs.h> #include <linux/poll.h> +#include <linux/smp_lock.h> +#include <asm/byteorder.h> #include <asm/atomic.h> #include <asm/io.h>
@@ -717,32 +719,44 @@int cid =minor (inode->i_rdev);enum { t_rom, t_aux, t_ram } type;struct memdata *md; - +int ret =0 ; + +lock_kernel (); +if (cid <PCILYNX_MINOR_AUX_START ) {/* just for completeness */ -return -ENXIO ; + ret = -ENXIO ; + goto out; }else if (cid <PCILYNX_MINOR_ROM_START ) { cid -=PCILYNX_MINOR_AUX_START ; -if (cid >= num_of_cards || !cards[cid].aux_port) -return -ENXIO ; +if (cid >= num_of_cards || !cards[cid].aux_port) { + ret = -ENXIO ; + goto out; + } type = t_aux; }else if (cid <PCILYNX_MINOR_RAM_START ) { cid -=PCILYNX_MINOR_ROM_START ; -if (cid >= num_of_cards || !cards[cid].local_rom) -return -ENXIO ; +if (cid >= num_of_cards || !cards[cid].local_rom) { + ret = -ENXIO ; + goto out; + } type = t_rom; }else {/* WARNING: Know what you are doing when opening RAM. * It is currently used inside the driver! */ cid -=PCILYNX_MINOR_RAM_START ; -if (cid >= num_of_cards || !cards[cid].local_ram) -return -ENXIO ; +if (cid >= num_of_cards || !cards[cid].local_ram) { + ret = -ENXIO ; + goto out; + } type = t_ram; } md = (struct memdata *)kmalloc (sizeof (struct memdata ),SLAB_KERNEL ); -if (md ==NULL ) -return -ENOMEM ; +if (md ==NULL ) { + ret = -ENOMEM ; + goto out; + } md->lynx = &cards[cid]; md->cid = cid;
@@ -763,7 +777,9 @@ file->private_data = md; -return 0 ; +out: +unlock_kernel (); +return ret; }static int mem_release (struct inode *inode,struct file *file)
drivers/input/input.c +13 -3
@@ -219,12 +219,16 @@int input_open_device (struct input_handle *handle) { +int ret =0 ; +lock_kernel (); +if (handle->dev->pm_dev)pm_access (handle->dev->pm_dev); handle->open++;if (handle->dev->open) -return handle->dev->open (handle->dev); -return 0 ; + ret = handle->dev->open (handle->dev); +unlock_kernel (); +return ret; }int input_flush_device (struct input_handle * handle,struct file * file)
@@ -636,9 +640,13 @@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))) +if (!handler || !(new_fops =fops_get (handler->fops))) { +unlock_kernel ();return -ENODEV ; + }/* * That's _really_ odd. Usually NULL ->open means "nothing special",
@@ -646,6 +654,7 @@*/ if (!new_fops->open) {fops_put (new_fops); +unlock_kernel ();return -ENODEV ; } old_fops = file->f_op;
@@ -658,6 +667,7 @@ file->f_op =fops_get (old_fops); }fops_put (old_fops); +unlock_kernel ();return err; }
drivers/isdn/capi/capi.c +8 -5
@@ -934,13 +934,16 @@static int capi_open (struct inode *inode,struct file *file) { +int ret =0 ; +lock_kernel (); +if (file->private_data) -return -EEXIST ; + ret = -EEXIST ; +else if ((file->private_data =capidev_alloc ()) ==0 ) + ret = -ENOMEM ; -if ((file->private_data =capidev_alloc ()) ==0 ) -return -ENOMEM ; - -return 0 ; +unlock_kernel (); +return ret; } static int
drivers/isdn/divert/divert_procfs.c +2 -0
@@ -135,6 +135,7 @@ {unsigned long flags; +lock_kernel ();spin_lock_irqsave ( &divert_info_lock, flags ); if_used++;if (divert_info_head)
@@ -143,6 +144,7 @@ (struct divert_info **) filep->private_data = &divert_info_head;spin_unlock_irqrestore ( &divert_info_lock, flags );/* start_divert(); */ +unlock_kernel ();return (0 ); }/* isdn_divert_open */
drivers/isdn/i4l/isdn_common.c +11 -1
@@ -970,12 +970,15 @@if (!p)return -ENOMEM ; +lock_kernel (); + p->next = (char *) dev->infochain; p->private = (char *) &(filep->private_data); dev->infochain = p;/* At opening we allow a single update */ filep->private_data = (char *)1 ; +unlock_kernel ();return 0 ; }
@@ -1146,11 +1149,15 @@uint minor =minor (ino->i_rdev);int drvidx; +lock_kernel (); drvidx =isdn_minor2drv (minor -ISDN_MINOR_CTRL ); -if (drvidx <0 ) +if (drvidx <0 ) { +unlock_kernel ();return -ENODEV ; + }isdn_lock_drivers (); +unlock_kernel ();return 0 ; }
@@ -1686,6 +1693,8 @@int err = -ENODEV ;struct file_operations *old_fops, *new_fops =NULL ; +lock_kernel (); +if (minor >=ISDN_MINOR_CTRL && minor <=ISDN_MINOR_CTRLMAX ) new_fops =fops_get (&isdn_ctrl_fops);#ifdef CONFIG_ISDN_PPP
@@ -1711,6 +1720,7 @@fops_put (old_fops); out: +unlock_kernel ();return err; }
drivers/macintosh/adb.c +12 -4
@@ -641,12 +641,18 @@static int adb_open (struct inode *inode,struct file *file) {struct adbdev_state *state; +int ret =0 ; -if (minor (inode->i_rdev) >0 || adb_controller ==NULL ) -return -ENXIO ; +lock_kernel (); +if (minor (inode->i_rdev) >0 || adb_controller ==NULL ) { + ret = -ENXIO ; + goto out; + } state =kmalloc (sizeof (struct adbdev_state ),GFP_KERNEL ); -if (state ==0 ) +if (state ==0 ) {return -ENOMEM ; + goto out; + } file->private_data = state;spin_lock_init (&state->lock);atomic_set (&state->n_pending,0 );
@@ -654,7 +660,9 @@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)
drivers/macintosh/rtc.c +2 -4
@@ -97,11 +97,9 @@static int rtc_open (struct inode *inode,struct file *file) { -if (rtc_busy) +if (test_and_set_bit (0 ,&rtc_busy))return -EBUSY ; - rtc_busy =1 ; -MOD_INC_USE_COUNT ;return 0 ;
@@ -110,7 +108,7 @@static int rtc_release (struct inode *inode,struct file *file) {MOD_DEC_USE_COUNT ; - rtc_busy =0 ; +clear_bit (0 ,&rtc_busy);return 0 ; }
drivers/md/lvm.c +14 -3
@@ -513,15 +513,24 @@static int lvm_chr_open (struct inode *inode,struct file *file) {unsigned int minor =minor (inode->i_rdev); +int ret =0 ; + +lock_kernel ();P_DEV ("chr_open MINOR: %d VG#: %d mode: %s%s lock: %d\n" , minor,VG_CHR (minor),MODE_TO_STR (file->f_mode), lock);/* super user validation */ -if (!capable (CAP_SYS_ADMIN ))return -EACCES ; +if (!capable (CAP_SYS_ADMIN )) { + ret = -EACCES ; + goto out; + }/* Group special file open */ -if (VG_CHR (minor) >MAX_VG )return -ENXIO ; +if (VG_CHR (minor) >MAX_VG ) { + ret = -ENXIO ; + goto out; + }spin_lock (&lvm_lock);if (lock == current->pid)
@@ -532,7 +541,9 @@MOD_INC_USE_COUNT ; -return 0 ; +out: +unlock_kernel (); +return ret; }/* lvm_chr_open() */
drivers/media/video/videodev.c +3 -0
@@ -79,6 +79,7 @@if (minor>=VIDEO_NUM_DEVICES )return -ENODEV ; +lock_kernel ();down (&videodev_lock); vfl=video_device[minor];if (vfl==NULL ) {
@@ -91,6 +92,7 @@ vfl=video_device[minor];if (vfl==NULL ) {up (&videodev_lock); +unlock_kernel ();return -ENODEV ; } }
@@ -104,6 +106,7 @@ }fops_put (old_fops);up (&videodev_lock); +unlock_kernel ();return err; }
drivers/mtd/mtdblock.c +12 -2
@@ -12,6 +12,7 @@#include <linux/kernel.h> #include <linux/slab.h> #include <linux/buffer_head.h> +#include <linux/smp_lock.h> #include <linux/mtd/mtd.h> #include <linux/mtd/compatmac.h>
@@ -274,11 +275,16 @@if (dev >=MAX_MTD_DEVICES )return -EINVAL ; +lock_kernel (); + mtd =get_mtd_device (NULL , dev); -if (!mtd) +if (!mtd) { +unlock_kernel ();return -ENODEV ; + }if (MTD_ABSENT == mtd->type) {put_mtd_device (mtd); +unlock_kernel ();return -ENODEV ; }
@@ -288,6 +294,7 @@if (mtdblks[dev]) { mtdblks[dev]->count++;spin_unlock (&mtdblks_lock); +unlock_kernel ();return 0 ; }
@@ -301,6 +308,7 @@ mtdblk =kmalloc (sizeof (struct mtdblk_dev ),GFP_KERNEL );if (!mtdblk) {put_mtd_device (mtd); +unlock_kernel ();return -ENOMEM ; }memset (mtdblk,0 ,sizeof (*mtdblk));
@@ -316,6 +324,7 @@if (!mtdblk->cache_data) {put_mtd_device (mtdblk->mtd);kfree (mtdblk); +unlock_kernel ();return -ENOMEM ; } }
@@ -331,6 +340,7 @@put_mtd_device (mtdblk->mtd);vfree (mtdblk->cache_data);kfree (mtdblk); +unlock_kernel ();return 0 ; }
@@ -339,9 +349,9 @@set_device_ro (inode->i_rdev, !(mtdblk->mtd->flags &MTD_WRITEABLE ));spin_unlock (&mtdblks_lock); +unlock_kernel ();DEBUG (MTD_DEBUG_LEVEL1 ,"ok\n" ); -return 0 ; }
drivers/mtd/mtdblock_ro.c +11 -4
@@ -12,6 +12,7 @@#include <linux/module.h> #include <linux/types.h> +#include <linux/smp_lock.h> #include <linux/mtd/mtd.h> #include <linux/mtd/compatmac.h>
@@ -43,26 +44,32 @@struct mtd_info *mtd =NULL ;int dev; +int ret=0 ;DEBUG (1 ,"mtdblock_open\n" );if (inode ==0 )return -EINVAL ; +lock_kernel (); dev =minor (inode->i_rdev); mtd =get_mtd_device (NULL , dev); -if (!mtd) -return -EINVAL ; +if (!mtd) { + ret = -EINVAL ; + goto out; + }if (MTD_ABSENT == mtd->type) {put_mtd_device (mtd); -return -EINVAL ; + ret = -EINVAL ; + goto out; } mtd_sizes[dev] = mtd->size>>9 ;DEBUG (1 ,"ok\n" ); - +out: +unlock_kernel ();return 0 ; }
drivers/mtd/mtdchar.c +22 -9
@@ -67,24 +67,34 @@int minor =minor (inode->i_rdev);int devnum = minor >>1 ;struct mtd_info *mtd; +int ret =0 ; + +lock_kernel ();DEBUG (MTD_DEBUG_LEVEL0 ,"MTD_open\n" ); -if (devnum >=MAX_MTD_DEVICES ) -return -ENODEV ; +if (devnum >=MAX_MTD_DEVICES ) { + ret = -ENODEV ; + goto out; + }/* You can't open the RO devices RW */ -if ((file->f_mode &2 ) && (minor &1 )) -return -EACCES ; +if ((file->f_mode &2 ) && (minor &1 )) { + ret = -EACCES ; + goto out; + } mtd =get_mtd_device (NULL , devnum); -if (!mtd) -return -ENODEV ; +if (!mtd) { + ret = -ENODEV ; + goto out; + }if (MTD_ABSENT == mtd->type) {put_mtd_device (mtd); -return -ENODEV ; + ret = -ENODEV ; + goto out; } file->private_data = mtd;
@@ -92,10 +102,13 @@/* 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; } -return 0 ; +out: +unlock_kernel (); +return ret; }/* mtd_open */ /*====================================================================*/
drivers/net/ppp_generic.c +5 -2
@@ -339,12 +339,15 @@*/ static int ppp_open (struct inode *inode,struct file *file) { +int ret=0 ;/* * This could (should?) be enforced by the permissions on /dev/ppp. */ +lock_kernel ();if (!capable (CAP_NET_ADMIN )) -return -EPERM ; -return 0 ; + ret = -EPERM ; +unlock_kernel (); +return ret; }static int ppp_release (struct inode *inode,struct file *file)
drivers/net/wan/cosa.c +25 -10
@@ -611,19 +611,22 @@static int cosa_sppp_open (struct net_device *d) {struct channel_data *chan = d->priv; -int err, flags; +int err=0 , flags; +lock_kernel ();if (!(chan->cosa->firmware_status &COSA_FW_START )) {printk (KERN_NOTICE "%s: start the firmware first (status %d)\n" , chan->cosa->name, chan->cosa->firmware_status); -return -EPERM ; + err = -EPERM ; + goto out; }spin_lock_irqsave (&chan->cosa->lock, flags);if (chan->usage !=0 ) {printk (KERN_WARNING "%s: sppp_open called with usage count %d\n" , chan->name, chan->usage);spin_unlock_irqrestore (&chan->cosa->lock, flags); -return -EBUSY ; + err = -EBUSY ; + goto out; } chan->setup_rx = sppp_setup_rx; chan->tx_done = sppp_tx_done;
@@ -641,12 +644,14 @@MOD_DEC_USE_COUNT ;spin_unlock_irqrestore (&chan->cosa->lock, flags); -return err; + goto out; }netif_start_queue (d);cosa_enable_rx (chan); -return 0 ; +out: +unlock_kernel (); +return err; }static int cosa_sppp_tx (struct sk_buff *skb,struct net_device *dev)
@@ -932,15 +937,22 @@struct channel_data *chan;unsigned long flags;int n; +int ret =0 ; + +lock_kernel ();if ((n=minor (file->f_dentry->d_inode->i_rdev)>>CARD_MINOR_BITS ) - >= nr_cards) -return -ENODEV ; + >= nr_cards) { + ret = -ENODEV ; + goto out; + } cosa = cosa_cards+n;if ((n=minor (file->f_dentry->d_inode->i_rdev) - & ((1 <<CARD_MINOR_BITS )-1 )) >= cosa->nchannels) -return -ENODEV ; + & ((1 <<CARD_MINOR_BITS )-1 )) >= cosa->nchannels) { + ret = -ENODEV ; + goto out; + } chan = cosa->chan + n; file->private_data = chan;
@@ -949,7 +961,8 @@if (chan->usage <0 ) {/* in netdev mode */ spin_unlock_irqrestore (&cosa->lock, flags); -return -EBUSY ; + ret = -EBUSY ; + goto out; } cosa->usage++; chan->usage++;
@@ -958,6 +971,8 @@ chan->setup_rx = chrdev_setup_rx; chan->rx_done = chrdev_rx_done;spin_unlock_irqrestore (&cosa->lock, flags); +out: +unlock_kernel ();return 0 ; }
drivers/net/wan/hdlc_ppp.c +5 -2
@@ -25,6 +25,7 @@#include <linux/lapb.h> #include <linux/rtnetlink.h> #include <linux/hdlc.h> +#include <linux/smp_lock.h> static int ppp_open (hdlc_device *hdlc)
@@ -33,6 +34,8 @@void *old_ioctl;int result; +lock_kernel (); + dev->priv = &hdlc->state.ppp.syncppp_ptr; hdlc->state.ppp.syncppp_ptr = &hdlc->state.ppp.pppdev; hdlc->state.ppp.pppdev.dev = dev;
@@ -47,10 +50,10 @@ result =sppp_open (dev);if (result) {sppp_detach (dev); -return result; } -return 0 ; +unlock_kernel (); +return result; }
drivers/pcmcia/ds.c +18 -6
@@ -561,20 +561,30 @@socket_t i =minor (inode->i_rdev);socket_info_t *s;user_info_t *user; +int ret =0 ; + +lock_kernel ();DEBUG (0 ,"ds_open(socket %d)\n" , i); -if ((i >= sockets) || (sockets ==0 )) -return -ENODEV ; +if ((i >= sockets) || (sockets ==0 )) { + ret = -ENODEV ; + goto out; + } s = &socket_table[i];if ((file->f_flags &O_ACCMODE ) !=O_RDONLY ) { -if (s->state &SOCKET_BUSY ) -return -EBUSY ; +if (s->state &SOCKET_BUSY ) { + ret = -EBUSY ; + goto out; + }else s->state |=SOCKET_BUSY ; } user =kmalloc (sizeof (user_info_t),GFP_KERNEL ); -if (!user)return -ENOMEM ; +if (!user) { + ret = -ENOMEM ; + goto out; + } user->event_tail = user->event_head =0 ; user->next = s->user; user->user_magic =USER_MAGIC ;
@@ -583,7 +593,9 @@if (s->state &SOCKET_PRESENT )queue_event (user,CS_EVENT_CARD_INSERTION ); -return 0 ; +out: +unlock_kernel (); +return ret; }/* ds_open */ /*====================================================================*/
drivers/s390/char/tapechar.c +5 -0
@@ -18,6 +18,7 @@#include <linux/version.h> #include <linux/types.h> #include <linux/proc_fs.h> +#include <linux/smp_lock.h> #include <asm/s390dyn.h> #include <linux/mtio.h> #include <asm/uaccess.h>
@@ -556,6 +557,8 @@int rc =0 ;long lockflags; +lock_kernel (); +MOD_INC_USE_COUNT ;tape_sprintf_event (tape_dbf_area,6 ,"c:open: %x\n" ,td->first_minor);
@@ -592,6 +595,8 @@if (td!=NULL )tape_put_device (td); } + +unlock_kernel ();return rc; }
drivers/s390/char/tubfs.c +14 -7
@@ -10,6 +10,7 @@* Author: Richard Hitt */ #include "tubio.h" +#include <linux/smp_lock.h> int fs3270_major =-1 ;/* init to impossible -1 */
@@ -115,23 +116,26 @@ } } -/* -* fs3270_open -*/ static int fs3270_open (struct inode *ip,struct file *fp) {tub_t *tubp;long flags; +int ret =0 ; + +lock_kernel ();/* See INODE2TUB(ip) for handling of "/dev/3270/tub" */ -if ((tubp =INODE2TUB (ip)) ==NULL ) -return -ENOENT ; +if ((tubp =INODE2TUB (ip)) ==NULL ) { + ret = -ENOENT ; + goto out; + }TUBLOCK (tubp->irq, flags);if (tubp->mode ==TBM_FS || tubp->mode ==TBM_FSLN ) {TUBUNLOCK (tubp->irq, flags); -return -EBUSY ; + ret = -EBUSY ; + goto out; }tub_inc_use_count ();
@@ -142,7 +146,10 @@ tubp->fs_pid = current->pid; tubp->fsopen =1 ;TUBUNLOCK (tubp->irq, flags); -return 0 ; + +out: +unlock_kernel (); +return ret; }/*
drivers/sbus/audio/audio.c +31 -17
93 lines not on this page · raw message
drivers/sbus/char/bpp.c +2 -1
@@ -442,6 +442,7 @@unsigned minor =MINOR (inode->i_rdev);int ret; +lock_kernel ();spin_lock (&bpp_open_lock); ret =0 ;if (minor >=BPP_NO ) {
@@ -457,7 +458,7 @@ } }spin_unlock (&bpp_open_lock); - +unlock_kernel ();return ret; }
drivers/sbus/char/sunkbd.c +2 -1
@@ -1514,6 +1514,7 @@static int kbd_open (struct inode *i,struct file *f) { +lock_kernel ();spin_lock_irq (&kbd_queue_lock); kbd_active++;
@@ -1526,7 +1527,7 @@ out:spin_unlock_irq (&kbd_queue_lock); - +unlock_kernel ();return 0 ; }
drivers/sbus/char/vfc_dev.c +4 -0
@@ -188,14 +188,17 @@ {struct vfc_dev *dev; +lock_kernel ();spin_lock (&vfc_dev_lock); dev =vfc_get_dev_ptr (MINOR (inode->i_rdev));if (dev ==NULL ) {spin_unlock (&vfc_dev_lock); +unlock_kernel ();return -ENODEV ; }if (dev->busy) {spin_unlock (&vfc_dev_lock); +unlock_kernel ();return -EBUSY ; }
@@ -212,6 +215,7 @@vfc_captstat_reset (dev);vfc_unlock_device (dev); +unlock_kernel ();return 0 ; }
drivers/scsi/dpt_i2o.c +7 -1
@@ -1556,10 +1556,13 @@int minor;adpt_hba * pHba; +lock_kernel (); +//TODO check for root access // minor =minor (inode->i_rdev);if (minor >= hba_count) { +unlock_kernel ();return -ENXIO ; }down (&adpt_configuration_lock);
@@ -1570,17 +1573,20 @@ }if (pHba ==NULL ) {up (&adpt_configuration_lock); +unlock_kernel ();return -ENXIO ; }// if(pHba->in_use){ -// up(&adpt_configuration_lock); +// up(&adpt_configuration_lock); +// unlock_kernel(); // return -EBUSY; // } pHba->in_use =1 ;up (&adpt_configuration_lock); +unlock_kernel ();return 0 ; }
drivers/scsi/osst.c +19 -8
@@ -46,6 +46,7 @@#include <linux/spinlock.h> #include <linux/vmalloc.h> #include <linux/version.h> +#include <linux/smp_lock.h> #include <asm/uaccess.h> #include <asm/dma.h> #include <asm/system.h>
@@ -4162,18 +4163,24 @@int dev =TAPE_NR (inode->i_rdev);int mode =TAPE_MODE (inode->i_rdev); -if (dev >= osst_template.dev_max || (STp = os_scsi_tapes[dev]) ==NULL || !STp->device) -return (-ENXIO ); +lock_kernel (); + +if (dev >= osst_template.dev_max || (STp = os_scsi_tapes[dev]) ==NULL || !STp->device) { + retval = (-ENXIO ); + goto out; + }if ( !scsi_block_when_processing_errors (STp->device) ) { -return -ENXIO ; + retval = -ENXIO ; + goto out; }if (STp->in_use) {#if DEBUG printk (OSST_DEB_MSG "osst%d:D: Device already in use.\n" , dev);#endif -return (-EBUSY ); + retval = (-EBUSY ); + goto out; } STp->in_use =1 ; STp->rew_at_close = (minor (inode->i_rdev) &0x80 ) ==0 ;
@@ -4346,7 +4353,8 @@ STp->buffer->buffer_blocks =OS_DATA_SIZE / STp->block_size; STp->fast_open = TRUE;scsi_release_request (SRpnt); -return 0 ; + retval =0 ; + goto out; }#if DEBUG if (i != STp->first_frame_position)
@@ -4430,7 +4438,8 @@ STp->ps[0 ].drv_file = STp->ps[0 ].drv_block = (-1 ); STp->partition = STp->new_partition =0 ; STp->door_locked =ST_UNLOCKED ; -return 0 ; + retval =0 ; + goto out; }osst_configure_onstream (STp, &SRpnt);
@@ -4509,7 +4518,8 @@scsi_release_request (SRpnt); SRpnt =NULL ; -return 0 ; + retval =0 ; + goto out; err_out:if (SRpnt !=NULL )
@@ -4526,7 +4536,8 @@__MOD_DEC_USE_COUNT (STp->device->host->hostt->module);if (osst_template.module)__MOD_DEC_USE_COUNT (osst_template.module); - +out: +unlock_kernel ();return retval; }
drivers/scsi/sg.c +14 -5
@@ -268,12 +268,18 @@int res;int retval = -EBUSY ; +lock_kernel (); +SCSI_LOG_TIMEOUT (3 ,printk ("sg_open: dev=%d, flags=0x%x\n" , dev, flags)); sdp =sg_get_dev (dev); -if ((! sdp) || (! sdp->device)) -return -ENXIO ; -if (sdp->detached) -return -ENODEV ; +if ((! sdp) || (! sdp->device)) { + retval = -ENXIO ; + goto out; + } +if (sdp->detached) { + retval = -ENODEV ; + goto out; + }/* This driver's module count bumped by fops_get in <linux/fs.h> */ /* Prevent the device driver from vanishing while we sleep */
@@ -329,12 +335,15 @@ retval = -ENOMEM ; goto error_out; } -return 0 ; + retval =0 ; + goto out; error_out: sdp->device->access_count--;if ((! sdp->detached) && sdp->device->host->hostt->module)__MOD_DEC_USE_COUNT (sdp->device->host->hostt->module); +out: +unlock_kernel ();return retval; }
drivers/scsi/st.c +6 -0
@@ -909,16 +909,20 @@ST_partstat *STps;int dev =TAPE_NR (inode->i_rdev); +lock_kernel (); +write_lock (&st_dev_arr_lock);if (dev >= st_template.dev_max || scsi_tapes ==NULL || ((STp = scsi_tapes[dev]) ==NULL )) {write_unlock (&st_dev_arr_lock); +unlock_kernel ();return (-ENXIO ); }if (STp->in_use) {write_unlock (&st_dev_arr_lock); DEB( printk(ST_DEB_MSG "st%d: Device already in use.\n", dev); ) +unlock_kernel ();return (-EBUSY ); } STp->in_use =1 ;
@@ -962,6 +966,7 @@ retval = (-EIO ); goto err_out; } +unlock_kernel ();return 0 ; err_out:
@@ -970,6 +975,7 @@ STp->device->access_count--;if (STp->device->host->hostt->module)__MOD_DEC_USE_COUNT (STp->device->host->hostt->module); +unlock_kernel ();return retval; }
drivers/sgi/char/shmiq.c +16 -6
@@ -386,25 +386,35 @@ shmiq_qcntl_open (struct inode *inode, struct file *filp) { int minor = MINOR (inode->i_rdev); +int ret =0 ; -if (minor ==0 ) -return 0 ; +lock_kernel (); + +if (minor ==0 ) { + ret =0 ; + goto out; + } minor--; -if (minor >MAX_SHMI_QUEUES ) -return -EINVAL ; +if (minor >MAX_SHMI_QUEUES ) { + ret = -EINVAL ; + goto out; + }spin_lock ( &shmiqs [minor].shmiq_lock );if (shmiqs [minor].opened) {spin_unlock ( &shmiqs [minor].shmiq_lock ); -return -EBUSY ; + goto out; + ret = -EBUSY ; } shmiqs [minor].opened =1 ; shmiqs [minor].shmiq_vaddr =0 ;spin_unlock ( &shmiqs [minor].shmiq_lock ); -return 0 ; +out: +unlock_kernel (); +return ret; } static int
drivers/telephony/phonedev.c +9 -2
@@ -19,6 +19,7 @@#include <linux/types.h> #include <linux/kernel.h> #include <linux/fs.h> +#include <linux/smp_lock.h> #include <linux/mm.h> #include <linux/string.h> #include <linux/errno.h>
@@ -51,8 +52,12 @@struct phone_device *p;struct file_operations *old_fops, *new_fops =NULL ; -if (minor >=PHONE_NUM_DEVICES ) -return -ENODEV ; +lock_kernel (); + +if (minor >=PHONE_NUM_DEVICES ) { + err = -ENODEV ; + goto out; + }down (&phone_lock); p = phone_device[minor];
@@ -83,6 +88,8 @@fops_put (old_fops); end:up (&phone_lock); +out: +unlock_kernel ();return err; }
drivers/usb/core/file.c +5 -0
@@ -19,6 +19,7 @@#include <linux/module.h> #include <linux/devfs_fs_kernel.h> #include <linux/spinlock.h> +#include <linux/smp_lock.h> #include <linux/errno.h> #ifdef CONFIG_USB_DEBUG
@@ -42,11 +43,14 @@int err = -ENODEV ;struct file_operations *old_fops, *new_fops =NULL ; +lock_kernel (); +spin_lock (&minor_lock); c = usb_minors[minor];if (!c || !(new_fops =fops_get (c))) {spin_unlock (&minor_lock); +lock_kernel ();return err; }spin_unlock (&minor_lock);
@@ -61,6 +65,7 @@ file->f_op =fops_get (old_fops); }fops_put (old_fops); +unlock_kernel ();return err; }
drivers/usb/misc/tiglusb.c +13 -5
@@ -106,31 +106,38 @@ {int devnum =minor (inode->i_rdev);ptiglusb_t s; +int ret =0 ;if (devnum <TIUSB_MINOR || devnum >= (TIUSB_MINOR +MAXTIGL ))return -EIO ; +lock_kernel (); + s = &tiglusb[devnum -TIUSB_MINOR ];if (down_interruptible (&s->mutex)) { -return -ERESTARTSYS ; + ret = -ERESTARTSYS ; + goto out; }while (!s->dev || s->opened) {up (&s->mutex);if (filp->f_flags &O_NONBLOCK ) { -return -EBUSY ; + ret = -EBUSY ; + goto out; }schedule_timeout (HZ /2 );if (signal_pending (current)) { -return -EAGAIN ; + ret = -EAGAIN ; + goto out; }if (down_interruptible (&s->mutex)) { -return -ERESTARTSYS ; + ret = -ERESTARTSYS ; + goto out; } }
@@ -139,7 +146,8 @@ filp->f_pos =0 ; filp->private_data = s; - +out: +unlock_kernel ();return 0 ; }
drivers/video/fbmem.c +8 -2
@@ -689,12 +689,16 @@struct fb_info *info;int res =0 ; +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 (!(info = registered_fb[fbidx])) { + res = -ENODEV ; + goto out; + }if (info->fbops->owner)__MOD_INC_USE_COUNT (info->fbops->owner);if (info->fbops->fb_open) {
@@ -702,6 +706,8 @@if (res && info->fbops->owner)__MOD_DEC_USE_COUNT (info->fbops->owner); } +out: +unlock_kernel ();return res; }
fs/intermezzo/psdev.c +6 -0
@@ -35,6 +35,7 @@#include <linux/time.h> #include <linux/lp.h> #include <linux/slab.h> +#include <linux/smp_lock.h> #include <asm/ioctls.h> #include <linux/ioport.h> #include <linux/fcntl.h>
@@ -1229,11 +1230,14 @@struct upc_comm *upccom;ENTRY ; +lock_kernel (); +if ( ! (upccom =presto_psdev_f2u (file)) ) {kdev_t dev = file->f_dentry->d_inode->i_rdev;printk ("InterMezzo: %s, bad device %s\n" , __FUNCTION__,kdevname (dev));EXIT ; +unlock_kernel ();return -EINVAL ; }
@@ -1241,6 +1245,8 @@CDEBUG (D_PSDEV ,"Psdev_open: uc_pid: %d, caller: %d, flags: %d\n" , upccom->uc_pid, current->pid, file->f_flags); + +unlock_kernel ();EXIT ;return 0 ;
net/netlink/netlink_dev.c +17 -8
@@ -105,28 +105,37 @@struct sockaddr_nl nladdr;int err; -if (minor>=MAX_LINKS ) -return -ENODEV ; -if (test_and_set_bit (minor, &open_map)) -return -EBUSY ; +lock_kernel (); + +if (minor>=MAX_LINKS ) { + err = -ENODEV ; + goto out; + } +if (test_and_set_bit (minor, &open_map)) { + err = -EBUSY ; + goto out; + } err =sock_create (PF_NETLINK ,SOCK_RAW , minor, &sock);if (err <0 ) - goto out; + goto clearout;memset (&nladdr,0 ,sizeof (nladdr)); nladdr.nl_family =AF_NETLINK ; nladdr.nl_groups = ~0 ;if ((err = sock->ops->bind (sock, (struct sockaddr *)&nladdr,sizeof (nladdr))) <0 ) {sock_release (sock); - goto out; + goto clearout; } netlink_user[minor] = sock; -return 0 ; + err =0 ; + goto out; -out: +clearout:clear_bit (minor, &open_map); +out: +unlock_kernel ();return err; }
sound/core/sound.c +8 -1
@@ -30,6 +30,7 @@#include <sound/control.h> #include <sound/initval.h> #include <linux/kmod.h> +#include <linux/smp_lock.h> #ifdef CONFIG_DEVFS_FS #include <linux/devfs_fs_kernel.h> #endif
@@ -123,12 +124,15 @@struct file_operations *old_fops;int err =0 ; +lock_kernel (); +if (dev !=SNDRV_MINOR_SEQUENCER ) {if (snd_cards[card] ==NULL ) {#ifdef CONFIG_KMOD snd_request_card (card); if (snd_cards[card] == NULL)#endif +unlock_kernel ();return -ENODEV ; } }else {
@@ -137,8 +141,10 @@snd_request_other (minor);#endif } -if (mptr ==NULL && (mptr =snd_minor_search (minor)) ==NULL ) +if (mptr ==NULL && (mptr =snd_minor_search (minor)) ==NULL ) { +unlock_kernel ();return -ENODEV ; + } old_fops = file->f_op; file->f_op =fops_get (mptr->f_ops);if (file->f_op->open)
@@ -148,6 +154,7 @@ file->f_op =fops_get (old_fops); }fops_put (old_fops); +unlock_kernel ();return err; }
sound/sound_core.c +5 -0
@@ -44,6 +44,7 @@#include <linux/sound.h> #include <linux/major.h> #include <linux/kmod.h> +#include <linux/smp_lock.h> #include <linux/devfs_fs_kernel.h> #define SOUND_STEP 16
@@ -485,6 +486,8 @@struct sound_unit *s;struct file_operations *new_fops =NULL ; +lock_kernel (); + chain=unit&0x0F ;if (chain==4 || chain==5 )/* dsp/audio/dsp16 */ {
@@ -536,9 +539,11 @@ file->f_op =fops_get (old_fops); }fops_put (old_fops); +unlock_kernel ();return err; }spin_unlock (&sound_loader_lock); +unlock_kernel ();return -ENODEV ; }
Quoted 1 line · Dave Hansen
This patch adds the BKL to each character device's
open()function. The BKL will remain inchrdev_open()until the module unload races are fixed, but this makes it unnecessary there for any other reason.
Greg KH noticed that I'd touched USB, and wondered about the places where get/put_fops were used to make sure the driver gets called directly the next time, instead of going through the subsystem. I don't believe that the BKL is needed in the devices in this case, only in the subsystem itself.
During inode init (init_special_inode) f_op is set to def_chr_fops, which contains chrdev_open First open of char device file:
if (f->f_op && f->f_op->open) {
error = f->f_op->open(inode,f);
}The ->open() call goes to chrdev_open USB is determined to handle the device BKL is grabbed in chrdev_open
generic USB ->open() called (usb_open()) driver ->open() is calledf_op is replaced with the driver's f_op struct. BKL is released
Subsequent calls:
if (f->f_op && f->f_op->open) {
error = f->f_op->open(inode,f);
}->open() goes directly to driver. No BKL grabbed after first call. The drivers were only protected during the first call, not during subsequent ones. The addition of the BKL to usb_open() alone duplicates this behavior. Adding BKL to individual devices in cases like this is not required.
The tree is available for pulling from:
http://linux-bkl.bkbits.net/linux-2.5-bkl
Signature · 2 lines
Dave Hansen [email protected]
Quoted 3 lines · Dave Hansen
This patch adds the BKL to each character device's
open()function. The BKL will remain inchrdev_open()until the module unload races are fixed, but this makes it unnecessary there for any other reason.
[...]
Quoted 13 lines
diff -Nru
a/drivers/char/istallion.cb/drivers/char/istallion.cdrivers/char/istallion.c +2
-0@@ -1022,6 +1022,8 @@/*****************************************************************************/ +#define returnout (x) ret=x;goto out; +static int stli_open (struct tty_struct *tty,struct file *filp) {stlibrd_t *brdp;
drivers/char/istallion.c line 1042
Quoted 5 lines
drivers/char/istallion.c +1
-1@@ -1037,21 +1039,21 @@ minordev =minor (tty->device); brdnr =MINOR2BRD (minordev);if (brdnr >= stli_nrbrds) -return (-ENODEV ); +returnout (-ENODEV );
Hi Dave,
The returnout macro is incredibly ugly. It is also broken. (The "goto out" is on the same level as the if and is executed regardless of the if condition.)
-Kevin
Signature · 4 lines
------------------------------------------------------------------------ | Kevin O'Connor "BTW, IMHO we need a FAQ for | | [email protected] 'IMHO', 'FAQ', 'BTW', etc. !" | ------------------------------------------------------------------------
Quoted 3 lines · Kevin O'Connor
The returnout macro is incredibly ugly. It is also broken. (The "goto out" is on the same level as the if and is executed regardless of the if condition.)
You are very, very right. Ugh. I made this during a 10-second moment of weakness when I wondered if we should have a macro to do this.
Cleanup attached.
Signature · 2 lines
Dave Hansen [email protected]
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas:
# ChangeSet 1.545 -> 1.546
# drivers/char/istallion.c 1.13 -> 1.14
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/08/02 [email protected] 1.546
# fix ugliness # -------------------------------------------- # diff -Nru a/drivers/char/istallion.c b/drivers/char/istallion.c --- a/drivers/char/istallion.c Fri Aug 2 11:42:09 2002 +++ b/drivers/char/istallion.c Fri Aug 2 11:42:09 2002 @@ -1022,8 +1022,6 @@
/*****************************************************************************/
-#define returnout(x) ret=x;goto out;
-
static int stli_open(struct tty_struct *tty, struct file *filp) {
stlibrd_t *brdp;
@@ -1038,23 +1036,34 @@
minordev = minor(tty->device);
brdnr = MINOR2BRD(minordev);
- if (brdnr >= stli_nrbrds)
- returnout(-ENODEV);
+ if (brdnr >= stli_nrbrds) {
+ ret = -ENODEV;
+ goto out;
+ }
brdp = stli_brds[brdnr];
- if (brdp == (stlibrd_t *) NULL)
- returnout(-ENODEV);
- if ((brdp->state & BST_STARTED) == 0)
- returnout(-ENODEV);
+ if (brdp == (stlibrd_t *) NULL) {
+ ret = -ENODEV;
+ goto out;
+ }
+ if ((brdp->state & BST_STARTED) == 0) {
+ ret = -ENODEV;
+ goto out;
+ }
portnr = MINOR2PORT(minordev);
- if ((portnr < 0) || (portnr > brdp->nrports))
- returnout(-ENODEV);
+ if ((portnr < 0) || (portnr > brdp->nrports)) {
+ ret = -ENODEV;
+ goto out;
+ }
portp = brdp->ports[portnr];
- if (portp == (stliport_t *) NULL)
- returnout(-ENODEV);
- if (portp->devnr < 1)
- returnout(-ENODEV);
-
+ if (portp == (stliport_t *) NULL) {
+ ret = -ENODEV;
+ goto out;
+ }
+ if (portp->devnr < 1) {
+ ret =-ENODEV;
+ goto out;
+ }
MOD_INC_USE_COUNT;
/*
@@ -1065,9 +1074,12 @@
*/
if (portp->flags & ASYNC_CLOSING) {
interruptible_sleep_on(&portp->close_wait);
- if (portp->flags & ASYNC_HUP_NOTIFY)
- returnout(-EAGAIN);
- returnout(-ERESTARTSYS);
+ if (portp->flags & ASYNC_HUP_NOTIFY) {
+ ret = -EAGAIN;
+ goto out;
+ }
+ ret = -ERESTARTSYS;
+ goto out;
}
/*
@@ -1081,8 +1093,10 @@
portp->refcount++;
while (test_bit(ST_INITIALIZING, &portp->state)) {
- if (signal_pending(current))
- returnout(-ERESTARTSYS);
+ if (signal_pending(current)) {
+ ret = -ERESTARTSYS;
+ goto out;
+ }
interruptible_sleep_on(&portp->raw_wait);
}
@@ -1094,8 +1108,10 @@
}
clear_bit(ST_INITIALIZING, &portp->state); wake_up_interruptible(&portp->raw_wait);
- if (rc < 0)
- returnout(rc);
+ if (rc < 0) {
+ ret = rc;
+ goto out;
+ }
}
/*
@@ -1106,9 +1122,12 @@
*/
if (portp->flags & ASYNC_CLOSING) {
interruptible_sleep_on(&portp->close_wait);
- if (portp->flags & ASYNC_HUP_NOTIFY)
- returnout(-EAGAIN);
- returnout(-ERESTARTSYS);
+ if (portp->flags & ASYNC_HUP_NOTIFY) {
+ ret = -EAGAIN;
+ goto out;
+ }
+ ret = -ERESTARTSYS;
+ goto out;
}
/*
@@ -1117,24 +1136,34 @@
* then also we might have to wait for carrier.
*/
if (tty->driver.subtype == STL_DRVTYPCALLOUT) {
- if (portp->flags & ASYNC_NORMAL_ACTIVE)
- returnout(-EBUSY);
+ if (portp->flags & ASYNC_NORMAL_ACTIVE) {
+ ret = -EBUSY;
+ goto out;
+ }
if (portp->flags & ASYNC_CALLOUT_ACTIVE) {
if ((portp->flags & ASYNC_SESSION_LOCKOUT) &&
- (portp->session != current->session))
- returnout(-EBUSY);
+ (portp->session != current->session)) {
+ ret = -EBUSY;
+ goto out;
+ }
if ((portp->flags & ASYNC_PGRP_LOCKOUT) &&
- (portp->pgrp != current->pgrp))
- returnout(-EBUSY);
+ (portp->pgrp != current->pgrp)) {
+ ret = -EBUSY);
+ goto out;
+ }
}
portp->flags |= ASYNC_CALLOUT_ACTIVE;
} else {
if (filp->f_flags & O_NONBLOCK) {
- if (portp->flags & ASYNC_CALLOUT_ACTIVE)
- returnout(-EBUSY);
+ if (portp->flags & ASYNC_CALLOUT_ACTIVE) {
+ ret = -EBUSY;
+ goto out;
+ }
} else {
- if ((rc = stli_waitcarrier(brdp, portp, filp)) != 0)
- returnout(rc);
+ if ((rc = stli_waitcarrier(brdp, portp, filp)) != 0) {
+ ret = rc;
+ goto out;
+ }
}
portp->flags |= ASYNC_NORMAL_ACTIVE;
}
@@ -1151,7 +1180,7 @@
portp->pgrp = current->pgrp;
out:
unlock_kernel();
- return 0;
+ return ret;
}
/*****************************************************************************/