diff options
68 files changed, 669 insertions, 312 deletions
diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c index f6c1c5fd075d..fa1eceed0d23 100644 --- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c +++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c @@ -30,7 +30,6 @@ #include <linux/miscdevice.h> #include <linux/utsname.h> #include <linux/cpumask.h> -#include <linux/smp_lock.h> #include <linux/nodemask.h> #include <linux/smp.h> #include <linux/mutex.h> @@ -682,8 +681,7 @@ static int sn_hwperf_map_err(int hwperf_err) /* * ioctl for "sn_hwperf" misc device */ -static int -sn_hwperf_ioctl(struct inode *in, struct file *fp, u32 op, unsigned long arg) +static long sn_hwperf_ioctl(struct file *fp, u32 op, unsigned long arg) { struct sn_hwperf_ioctl_args a; struct cpuinfo_ia64 *cdata; @@ -699,8 +697,6 @@ sn_hwperf_ioctl(struct inode *in, struct file *fp, u32 op, unsigned long arg) int i; int j; - unlock_kernel(); - /* only user requests are allowed here */ if ((op & SN_HWPERF_OP_MASK) < 10) { r = -EINVAL; @@ -859,12 +855,11 @@ sn_hwperf_ioctl(struct inode *in, struct file *fp, u32 op, unsigned long arg) error: vfree(p); - lock_kernel(); return r; } static const struct file_operations sn_hwperf_fops = { - .ioctl = sn_hwperf_ioctl, + .unlocked_ioctl = sn_hwperf_ioctl, }; static struct miscdevice sn_hwperf_dev = { diff --git a/arch/um/drivers/harddog_kern.c b/arch/um/drivers/harddog_kern.c index d332503fa1be..cfcac1ff4cf2 100644 --- a/arch/um/drivers/harddog_kern.c +++ b/arch/um/drivers/harddog_kern.c @@ -124,8 +124,8 @@ static ssize_t harddog_write(struct file *file, const char __user *data, size_t return 0; } -static int harddog_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static int harddog_ioctl_unlocked(struct file *file, + unsigned int cmd, unsigned long arg) { void __user *argp= (void __user *)arg; static struct watchdog_info ident = { @@ -148,10 +148,22 @@ static int harddog_ioctl(struct inode *inode, struct file *file, } } +static long harddog_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + long ret; + + lock_kernel(); + ret = harddog_ioctl_unlocked(file, cmd, arg); + unlock_kernel(); + + return ret; +} + static const struct file_operations harddog_fops = { .owner = THIS_MODULE, .write = harddog_write, - .ioctl = harddog_ioctl, + .unlocked_ioctl = harddog_ioctl, .open = harddog_open, .release = harddog_release, }; diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c index 368219cc2366..ae42695c3597 100644 --- a/arch/um/drivers/hostaudio_kern.c +++ b/arch/um/drivers/hostaudio_kern.c @@ -136,7 +136,7 @@ static unsigned int hostaudio_poll(struct file *file, return mask; } -static int hostaudio_ioctl(struct inode *inode, struct file *file, +static long hostaudio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct hostaudio_state *state = file->private_data; @@ -223,7 +223,7 @@ static int hostaudio_release(struct inode *inode, struct file *file) /* /dev/mixer file operations */ -static int hostmixer_ioctl_mixdev(struct inode *inode, struct file *file, +static long hostmixer_ioctl_mixdev(struct file *file, unsigned int cmd, unsigned long arg) { struct hostmixer_state *state = file->private_data; @@ -289,7 +289,7 @@ static const struct file_operations hostaudio_fops = { .read = hostaudio_read, .write = hostaudio_write, .poll = hostaudio_poll, - .ioctl = hostaudio_ioctl, + .unlocked_ioctl = hostaudio_ioctl, .mmap = NULL, .open = hostaudio_open, .release = hostaudio_release, @@ -298,7 +298,7 @@ static const struct file_operations hostaudio_fops = { static const struct file_operations hostmixer_fops = { .owner = THIS_MODULE, .llseek = no_llseek, - .ioctl = hostmixer_ioctl_mixdev, + .unlocked_ioctl = hostmixer_ioctl_mixdev, .open = hostmixer_open_mixdev, .release = hostmixer_release, }; diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c index d22f9e5c0eac..7158393b6793 100644 --- a/arch/um/drivers/mmapper_kern.c +++ b/arch/um/drivers/mmapper_kern.c @@ -46,8 +46,7 @@ static ssize_t mmapper_write(struct file *file, const char __user *buf, return count; } -static int mmapper_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long mmapper_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { return -ENOIOCTLCMD; } @@ -90,7 +89,7 @@ static const struct file_operations mmapper_fops = { .owner = THIS_MODULE, .read = mmapper_read, .write = mmapper_write, - .ioctl = mmapper_ioctl, + .unlocked_ioctl = mmapper_ioctl, .mmap = mmapper_mmap, .open = mmapper_open, .release = mmapper_release, diff --git a/drivers/char/apm-emulation.c b/drivers/char/apm-emulation.c index 4f568cb9af3f..033e1505fca9 100644 --- a/drivers/char/apm-emulation.c +++ b/drivers/char/apm-emulation.c @@ -265,8 +265,8 @@ static unsigned int apm_poll(struct file *fp, poll_table * wait) * Only when everyone who has opened /dev/apm_bios with write permission * has acknowledge does the actual suspend happen. */ -static int -apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) +static long +apm_ioctl(struct file *filp, u_int cmd, u_long arg) { struct apm_user *as = filp->private_data; int err = -EINVAL; @@ -274,6 +274,7 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) if (!as->suser || !as->writer) return -EPERM; + lock_kernel(); switch (cmd) { case APM_IOC_SUSPEND: mutex_lock(&state_lock); @@ -334,6 +335,7 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) mutex_unlock(&state_lock); break; } + unlock_kernel(); return err; } @@ -397,7 +399,7 @@ static const struct file_operations apm_bios_fops = { .owner = THIS_MODULE, .read = apm_read, .poll = apm_poll, - .ioctl = apm_ioctl, + .unlocked_ioctl = apm_ioctl, .open = apm_open, .release = apm_release, }; diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c index a7424bf7eacf..63313a33ba5f 100644 --- a/drivers/char/applicom.c +++ b/drivers/char/applicom.c @@ -26,6 +26,7 @@ #include <linux/sched.h> #include <linux/slab.h> #include <linux/errno.h> +#include <linux/smp_lock.h> #include <linux/miscdevice.h> #include <linux/pci.h> #include <linux/wait.h> @@ -106,8 +107,7 @@ static unsigned int DeviceErrorCount; /* number of device error */ static ssize_t ac_read (struct file *, char __user *, size_t, loff_t *); static ssize_t ac_write (struct file *, const char __user *, size_t, loff_t *); -static int ac_ioctl(struct inode *, struct file *, unsigned int, - unsigned long); +static long ac_ioctl(struct file *, unsigned int, unsigned long); static irqreturn_t ac_interrupt(int, void *); static const struct file_operations ac_fops = { @@ -115,7 +115,7 @@ static const struct file_operations ac_fops = { .llseek = no_llseek, .read = ac_read, .write = ac_write, - .ioctl = ac_ioctl, + .unlocked_ioctl = ac_ioctl, }; static struct miscdevice ac_miscdev = { @@ -689,7 +689,7 @@ static irqreturn_t ac_interrupt(int vec, void *dev_instance) -static int ac_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +static long ac_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { /* @ ADG ou ATO selon le cas */ int i; @@ -711,7 +711,8 @@ static int ac_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un kfree(adgl); return -EFAULT; } - + + lock_kernel(); IndexCard = adgl->num_card-1; if(cmd != 6 && ((IndexCard >= MAX_BOARD) || !apbs[IndexCard].RamIO)) { @@ -721,6 +722,7 @@ static int ac_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un warncount--; } kfree(adgl); + unlock_kernel(); return -EINVAL; } @@ -838,6 +840,7 @@ static int ac_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un } Dummy = readb(apbs[IndexCard].RamIO + VERS); kfree(adgl); + unlock_kernel(); return 0; } diff --git a/drivers/char/ds1620.c b/drivers/char/ds1620.c index 61f0146e215d..dbee8688f75c 100644 --- a/drivers/char/ds1620.c +++ b/drivers/char/ds1620.c @@ -232,7 +232,7 @@ ds1620_read(struct file *file, char __user *buf, size_t count, loff_t *ptr) } static int -ds1620_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +ds1620_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct therm therm; union { @@ -316,6 +316,18 @@ ds1620_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned return 0; } +static long +ds1620_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = ds1620_ioctl(file, cmd, arg); + unlock_kernel(); + + return ret; +} + #ifdef THERM_USE_PROC static int proc_therm_ds1620_read(char *buf, char **start, off_t offset, @@ -344,7 +356,7 @@ static const struct file_operations ds1620_fops = { .owner = THIS_MODULE, .open = ds1620_open, .read = ds1620_read, - .ioctl = ds1620_ioctl, + .unlocked_ioctl = ds1620_unlocked_ioctl, }; static struct miscdevice ds1620_miscdev = { diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c index 045c930e6320..e3859d4eaead 100644 --- a/drivers/char/dtlk.c +++ b/drivers/char/dtlk.c @@ -93,8 +93,8 @@ static ssize_t dtlk_write(struct file *, const char __user *, static unsigned int dtlk_poll(struct file *, poll_table *); static int dtlk_open(struct inode *, struct file *); static int dtlk_release(struct inode *, struct file *); -static int dtlk_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg); +static long dtlk_ioctl(struct file *file, + unsigned int cmd, unsigned long arg); static const struct file_operations dtlk_fops = { @@ -102,7 +102,7 @@ static const struct file_operations dtlk_fops = .read = dtlk_read, .write = dtlk_write, .poll = dtlk_poll, - .ioctl = dtlk_ioctl, + .unlocked_ioctl = dtlk_ioctl, .open = dtlk_open, .release = dtlk_release, }; @@ -263,10 +263,9 @@ static void dtlk_timer_tick(unsigned long data) wake_up_interruptible(&dtlk_process_list); } -static int dtlk_ioctl(struct inode *inode, - struct file *file, - unsigned int cmd, - unsigned long arg) +static long dtlk_ioctl(struct file *file, + unsigned int cmd, + unsigned long arg) { char __user *argp = (char __user *)arg; struct dtlk_settings *sp; @@ -276,7 +275,9 @@ static int dtlk_ioctl(struct inode *inode, switch (cmd) { case DTLK_INTERROGATE: + lock_kernel(); sp = dtlk_interrogate(); + unlock_kernel(); if (copy_to_user(argp, sp, sizeof(struct dtlk_settings))) return -EINVAL; return 0; diff --git a/drivers/char/generic_nvram.c b/drivers/char/generic_nvram.c index fda4181b5e67..82b5a88a82d7 100644 --- a/drivers/char/generic_nvram.c +++ b/drivers/char/generic_nvram.c @@ -19,6 +19,7 @@ #include <linux/miscdevice.h> #include <linux/fcntl.h> #include <linux/init.h> +#include <linux/smp_lock.h> #include <asm/uaccess.h> #include <asm/nvram.h> #ifdef CONFIG_PPC_PMAC @@ -84,8 +85,7 @@ static ssize_t write_nvram(struct file *file, const char __user *buf, return p - buf; } -static int nvram_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static int nvram_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { switch(cmd) { #ifdef CONFIG_PPC_PMAC @@ -116,12 +116,23 @@ static int nvram_ioctl(struct inode *inode, struct file *file, return 0; } +static long nvram_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = nvram_ioctl(file, cmd, arg); + unlock_kernel(); + + return ret; +} + const struct file_operations nvram_fops = { .owner = THIS_MODULE, .llseek = nvram_llseek, .read = read_nvram, .write = write_nvram, - .ioctl = nvram_ioctl, + .unlocked_ioctl = nvram_unlocked_ioctl, }; static struct miscdevice nvram_dev = { diff --git a/drivers/char/genrtc.c b/drivers/char/genrtc.c index 31e7c91c2d9d..b6c2cc167c11 100644 --- a/drivers/char/genrtc.c +++ b/drivers/char/genrtc.c @@ -262,7 +262,7 @@ static inline int gen_set_rtc_irq_bit(unsigned char bit) #endif } -static int gen_rtc_ioctl(struct inode *inode, struct file *file, +static int gen_rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct rtc_time wtime; @@ -332,6 +332,18 @@ static int gen_rtc_ioctl(struct inode *inode, struct file *file, return -EINVAL; } +static long gen_rtc_unlocked_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = gen_rtc_ioctl(file, cmd, arg); + unlock_kernel(); + + return ret; +} + /* * We enforce only one user at a time here with the open/close. * Also clear the previous interrupt data on an open, and clean @@ -482,7 +494,7 @@ static const struct file_operations gen_rtc_fops = { .read = gen_rtc_read, .poll = gen_rtc_poll, #endif - .ioctl = gen_rtc_ioctl, + .unlocked_ioctl = gen_rtc_unlocked_ioctl, .open = gen_rtc_open, .release = gen_rtc_release, }; diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index 9ded667625ac..a0a1829d3198 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c @@ -431,14 +431,18 @@ static int hpet_release(struct inode *inode, struct file *file) static int hpet_ioctl_common(struct hpet_dev *, int, unsigned long, int); -static int -hpet_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg) +static long hpet_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) { struct hpet_dev *devp; + int ret; devp = file->private_data; - return hpet_ioctl_common(devp, cmd, arg, 0); + lock_kernel(); + ret = hpet_ioctl_common(devp, cmd, arg, 0); + unlock_kernel(); + + return ret; } static int hpet_ioctl_ieon(struct hpet_dev *devp) @@ -654,7 +658,7 @@ static const struct file_operations hpet_fops = { .llseek = no_llseek, .read = hpet_read, .poll = hpet_poll, - .ioctl = hpet_ioctl, + .unlocked_ioctl = hpet_ioctl, .open = hpet_open, .release = hpet_release, .fasync = hpet_fasync, diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index 65545de3dbf4..d8ec92a38980 100644 --- a/drivers/char/ipmi/ipmi_devintf.c +++ b/drivers/char/ipmi/ipmi_devintf.c @@ -228,8 +228,7 @@ static int handle_send_req(ipmi_user_t user, return rv; } -static int ipmi_ioctl(struct inode *inode, - struct file *file, +static int ipmi_ioctl(struct file *file, unsigned int cmd, unsigned long data) { @@ -630,6 +629,23 @@ static int ipmi_ioctl(struct inode *inode, return rv; } +/* + * Note: it doesn't make sense to take the BKL here but + * not in compat_ipmi_ioctl. -arnd + */ +static long ipmi_unlocked_ioctl(struct file *file, + unsigned int cmd, + unsigned long data) +{ + int ret; + + lock_kernel(); + ret = ipmi_ioctl(file, cmd, data); + unlock_kernel(); + + return ret; +} + #ifdef CONFIG_COMPAT /* @@ -802,7 +818,7 @@ static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd, if (copy_to_user(precv64, &recv64, sizeof(recv64))) return -EFAULT; - rc = ipmi_ioctl(filep->f_path.dentry->d_inode, filep, + rc = ipmi_ioctl(filep, ((cmd == COMPAT_IPMICTL_RECEIVE_MSG) ? IPMICTL_RECEIVE_MSG : IPMICTL_RECEIVE_MSG_TRUNC), @@ -819,14 +835,14 @@ static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd, return rc; } default: - return ipmi_ioctl(filep->f_path.dentry->d_inode, filep, cmd, arg); + return ipmi_ioctl(filep, cmd, arg); } } #endif static const struct file_operations ipmi_fops = { .owner = THIS_MODULE, - .ioctl = ipmi_ioctl, + .unlocked_ioctl = ipmi_unlocked_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = compat_ipmi_ioctl, #endif diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index a4d57e31f713..82bcdb262a3a 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c @@ -659,7 +659,7 @@ static struct watchdog_info ident = { .identity = "IPMI" }; -static int ipmi_ioctl(struct inode *inode, struct file *file, +static int ipmi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; @@ -730,6 +730,19 @@ static int ipmi_ioctl(struct inode *inode, struct file *file, } } +static long ipmi_unlocked_ioctl(struct file *file, + unsigned int cmd, + unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = ipmi_ioctl(file, cmd, arg); + unlock_kernel(); + + return ret; +} + static ssize_t ipmi_write(struct file *file, const char __user *buf, size_t len, @@ -880,7 +893,7 @@ static const struct file_operations ipmi_wdog_fops = { .read = ipmi_read, .poll = ipmi_poll, .write = ipmi_write, - .ioctl = ipmi_ioctl, + .unlocked_ioctl = ipmi_unlocked_ioctl, .open = ipmi_open, .release = ipmi_close, .fasync = ipmi_fasync, diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c index 47e8f7b0e4c1..66d2917b003f 100644 --- a/drivers/char/nvram.c +++ b/drivers/char/nvram.c @@ -296,8 +296,8 @@ checksum_err: return -EIO; } -static int nvram_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long nvram_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) { int i; @@ -308,6 +308,7 @@ static int nvram_ioctl(struct inode *inode, struct file *file, if (!capable(CAP_SYS_ADMIN)) return -EACCES; + lock_kernel(); spin_lock_irq(&rtc_lock); for (i = 0; i < NVRAM_BYTES; ++i) @@ -315,6 +316,7 @@ static int nvram_ioctl(struct inode *inode, struct file *file, __nvram_set_checksum(); spin_unlock_irq(&rtc_lock); + unlock_kernel(); return 0; case NVRAM_SETCKS: @@ -323,9 +325,11 @@ static int nvram_ioctl(struct inode *inode, struct file *file, if (!capable(CAP_SYS_ADMIN)) return -EACCES; + lock_kernel(); spin_lock_irq(&rtc_lock); __nvram_set_checksum(); spin_unlock_irq(&rtc_lock); + unlock_kernel(); return 0; default: @@ -422,7 +426,7 @@ static const struct file_operations nvram_fops = { .llseek = nvram_llseek, .read = nvram_read, .write = nvram_write, - .ioctl = nvram_ioctl, + .unlocked_ioctl = nvram_ioctl, .open = nvram_open, .release = nvram_release, }; diff --git a/drivers/char/nwflash.c b/drivers/char/nwflash.c index f80810901db6..043a1c7b86be 100644 --- a/drivers/char/nwflash.c +++ b/drivers/char/nwflash.c @@ -94,8 +94,9 @@ static int get_flash_id(void) return c2; } -static int flash_ioctl(struct inode *inodep, struct file *filep, unsigned int cmd, unsigned long arg) +static long flash_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) { + lock_kernel(); switch (cmd) { case CMD_WRITE_DISABLE: gbWriteBase64Enable = 0; @@ -113,8 +114,10 @@ static int flash_ioctl(struct inode *inodep, struct file *filep, unsigned int cm default: gbWriteBase64Enable = 0; gbWriteEnable = 0; + unlock_kernel(); return -EINVAL; } + unlock_kernel(); return 0; } @@ -631,7 +634,7 @@ static const struct file_operations flash_fops = .llseek = flash_llseek, .read = flash_read, .write = flash_write, - .ioctl = flash_ioctl, + .unlocked_ioctl = flash_ioctl, }; static struct miscdevice flash_miscdev = diff --git a/drivers/char/raw.c b/drivers/char/raw.c index 8756ab0daa8b..b38942f6bf31 100644 --- a/drivers/char/raw.c +++ b/drivers/char/raw.c @@ -121,13 +121,17 @@ static int raw_release(struct inode *inode, struct file *filp) /* * Forward ioctls to the underlying block device. */ -static int -raw_ioctl(struct inode *inode, struct file *filp, - unsigned int command, unsigned long arg) +static long +raw_ioctl(struct file *filp, unsigned int command, unsigned long arg) { struct block_device *bdev = filp->private_data; + int ret; + + lock_kernel(); + ret = blkdev_ioctl(bdev, 0, command, arg); + unlock_kernel(); - return blkdev_ioctl(bdev, 0, command, arg); + return ret; } static void bind_device(struct raw_config_request *rq) @@ -141,13 +145,14 @@ static void bind_device(struct raw_config_request *rq) * Deal with ioctls against the raw-device control interface, to bind * and unbind other raw devices. */ -static int raw_ctl_ioctl(struct inode *inode, struct file *filp, - unsigned int command, unsigned long arg) +static long raw_ctl_ioctl(struct file *filp, unsigned int command, + unsigned long arg) { struct raw_config_request rq; struct raw_device_data *rawdev; int err = 0; + lock_kernel(); switch (command) { case RAW_SETBIND: case RAW_GETBIND: @@ -240,25 +245,26 @@ static int raw_ctl_ioctl(struct inode *inode, struct file *filp, break; } out: + unlock_kernel(); return err; } static const struct file_operations raw_fops = { - .read = do_sync_read, - .aio_read = generic_file_aio_read, - .write = do_sync_write, - .aio_write = blkdev_aio_write, - .fsync = blkdev_fsync, - .open = raw_open, - .release= raw_release, - .ioctl = raw_ioctl, - .owner = THIS_MODULE, + .read = do_sync_read, + .aio_read = generic_file_aio_read, + .write = do_sync_write, + .aio_write = blkdev_aio_write, + .fsync = blkdev_fsync, + .open = raw_open, + .release = raw_release, + .unlocked_ioctl = raw_ioctl, + .owner = THIS_MODULE, }; static const struct file_operations raw_ctl_fops = { - .ioctl = raw_ctl_ioctl, - .open = raw_open, - .owner = THIS_MODULE, + .unlocked_ioctl = raw_ctl_ioctl, + .open = raw_open, + .owner = THIS_MODULE, }; static struct cdev raw_cdev; diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c index 0627f7a5b9b8..b7ca2a9676cf 100644 --- a/drivers/hwmon/fschmd.c +++ b/drivers/hwmon/fschmd.c @@ -38,6 +38,7 @@ #include <linux/i2c.h> #include <linux/hwmon.h> #include <linux/hwmon-sysfs.h> +#include <linux/smp_lock.h> #include <linux/err.h> #include <linux/mutex.h> #include <linux/sysfs.h> @@ -847,8 +848,7 @@ static ssize_t watchdog_write(struct file *filp, const char __user *buf, return count; } -static int watchdog_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +static long watchdog_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | @@ -858,6 +858,7 @@ static int watchdog_ioctl(struct inode *inode, struct file *filp, int i, ret = 0; struct fschmd_data *data = filp->private_data; + lock_kernel(); switch (cmd) { case WDIOC_GETSUPPORT: ident.firmware_version = data->revision; @@ -914,7 +915,7 @@ static int watchdog_ioctl(struct inode *inode, struct file *filp, default: ret = -ENOTTY; } - + unlock_kernel(); return ret; } @@ -924,7 +925,7 @@ static const struct file_operations watchdog_fops = { .open = watchdog_open, .release = watchdog_release, .write = watchdog_write, - .ioctl = watchdog_ioctl, + .unlocked_ioctl = watchdog_ioctl, }; diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index 612807d97155..697202e27891 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c @@ -35,6 +35,7 @@ #include <linux/slab.h> #include <linux/i2c.h> #include <linux/hwmon.h> +#include <linux/smp_lock.h> #include <linux/hwmon-vid.h> #include <linux/hwmon-sysfs.h> #include <linux/err.h> @@ -1319,8 +1320,8 @@ static ssize_t watchdog_write(struct file *filp, const char __user *buf, return count; } -static int watchdog_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +static long watchdog_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) { static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | @@ -1332,6 +1333,7 @@ static int watchdog_ioctl(struct inode *inode, struct file *filp, int val, ret = 0; struct w83793_data *data = filp->private_data; + lock_kernel(); switch (cmd) { case WDIOC_GETSUPPORT: if (!nowayout) @@ -1385,7 +1387,7 @@ static int watchdog_ioctl(struct inode *inode, struct file *filp, default: ret = -ENOTTY; } - + unlock_kernel(); return ret; } @@ -1395,7 +1397,7 @@ static const struct file_operations watchdog_fops = { .open = watchdog_open, .release = watchdog_close, .write = watchdog_write, - .ioctl = watchdog_ioctl, + .unlocked_ioctl = watchdog_ioctl, }; /* diff --git a/drivers/input/misc/hp_sdc_rtc.c b/drivers/input/misc/hp_sdc_rtc.c index ad730e15afc0..e00a1cc79c0a 100644 --- a/drivers/input/misc/hp_sdc_rtc.c +++ b/drivers/input/misc/hp_sdc_rtc.c @@ -43,6 +43,7 @@ #include <linux/proc_fs.h> #include <linux/poll.h> #include <linux/rtc.h> +#include <linux/smp_lock.h> #include <linux/semaphore.h> MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>"); @@ -64,8 +65,8 @@ static DECLARE_WAIT_QUEUE_HEAD(hp_sdc_rtc_wait); static ssize_t hp_sdc_rtc_read(struct file *file, char __user *buf, size_t count, loff_t *ppos); -static int hp_sdc_rtc_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg); +static long hp_sdc_rtc_unlocked_ioctl(struct file *file, + unsigned int cmd, unsigned long arg); static unsigned int hp_sdc_rtc_poll(struct file *file, poll_table *wait); @@ -512,7 +513,7 @@ static int hp_sdc_rtc_read_proc(char *page, char **start, off_t off, return len; } -static int hp_sdc_rtc_ioctl(struct inode *inode, struct file *file, +static int hp_sdc_rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { #if 1 @@ -659,14 +660,27 @@ static int hp_sdc_rtc_ioctl(struct inode *inode, struct file *file, #endif } +static long hp_sdc_rtc_unlocked_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = hp_sdc_rtc_ioctl(file, cmd, arg); + unlock_kernel(); + + return ret; +} + + static const struct file_operations hp_sdc_rtc_fops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .read = hp_sdc_rtc_read, - .poll = hp_sdc_rtc_poll, - .ioctl = hp_sdc_rtc_ioctl, - .open = hp_sdc_rtc_open, - .fasync = hp_sdc_rtc_fasync, + .owner = THIS_MODULE, + .llseek = no_llseek, + .read = hp_sdc_rtc_read, + .poll = hp_sdc_rtc_poll, + .unlocked_ioctl = hp_sdc_rtc_ioctl, + .open = hp_sdc_rtc_open, + .fasync = hp_sdc_rtc_fasync, }; static struct miscdevice hp_sdc_rtc_dev = { diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index ee5837522f5a..0cabe31f26df 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -787,8 +787,7 @@ capi_poll(struct file *file, poll_table * wait) } static int -capi_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +capi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct capidev *cdev = file->private_data; capi_ioctl_struct data; @@ -981,6 +980,18 @@ register_out: } } +static long +capi_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = capi_ioctl(file, cmd, arg); + unlock_kernel(); + + return ret; +} + static int capi_open(struct inode *inode, struct file *file) { struct capidev *cdev; @@ -1026,7 +1037,7 @@ static const struct file_operations capi_fops = .read = capi_read, .write = capi_write, .poll = capi_poll, - .ioctl = capi_ioctl, + .unlocked_ioctl = capi_unlocked_ioctl, .open = capi_open, .release = capi_release, }; diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c index 70044ee4b228..a44cdb492ea9 100644 --- a/drivers/isdn/i4l/isdn_common.c +++ b/drivers/isdn/i4l/isdn_common.c @@ -1272,9 +1272,9 @@ isdn_poll(struct file *file, poll_table * wait) static int -isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) +isdn_ioctl(struct file *file, uint cmd, ulong arg) { - uint minor = iminor(inode); + uint minor = iminor(file->f_path.dentry->d_inode); isdn_ctrl c; int drvidx; int chidx; @@ -1722,6 +1722,18 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) #undef cfg } +static long +isdn_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = isdn_ioctl(file, cmd, arg); + unlock_kernel(); + + return ret; +} + /* * Open the device code. */ @@ -1838,7 +1850,7 @@ static const struct file_operations isdn_fops = .read = isdn_read, .write = isdn_write, .poll = isdn_poll, - .ioctl = isdn_ioctl, + .unlocked_ioctl = isdn_unlocked_ioctl, .open = isdn_open, .release = isdn_close, }; diff --git a/drivers/isdn/mISDN/timerdev.c b/drivers/isdn/mISDN/timerdev.c index 8785004e85e0..c3243c913ec0 100644 --- a/drivers/isdn/mISDN/timerdev.c +++ b/drivers/isdn/mISDN/timerdev.c @@ -24,6 +24,7 @@ #include <linux/miscdevice.h> #include <linux/module.h> #include <linux/mISDNif.h> +#include <linux/smp_lock.h> #include "core.h" static u_int *debug; @@ -215,9 +216,8 @@ unlock: return ret; } -static int -mISDN_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, - unsigned long arg) +static long +mISDN_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) { struct mISDNtimerdev *dev = filep->private_data; int id, tout, ret = 0; @@ -226,6 +226,7 @@ mISDN_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, if (*debug & DEBUG_TIMER) printk(KERN_DEBUG "%s(%p, %x, %lx)\n", __func__, filep, cmd, arg); + lock_kernel(); switch (cmd) { case IMADDTIMER: if (get_user(tout, (int __user *)arg)) { @@ -257,13 +258,14 @@ mISDN_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, default: ret = -EINVAL; } + unlock_kernel(); return ret; } static const struct file_operations mISDN_fops = { .read = mISDN_read, .poll = mISDN_poll, - .ioctl = mISDN_ioctl, + .unlocked_ioctl = mISDN_ioctl, .open = mISDN_open, .release = mISDN_close, }; diff --git a/drivers/macintosh/nvram.c b/drivers/macintosh/nvram.c index c876349c32de..a271c8218d82 100644 --- a/drivers/macintosh/nvram.c +++ b/drivers/macintosh/nvram.c @@ -100,7 +100,7 @@ const struct file_operations nvram_fops = { .llseek = nvram_llseek, .read = read_nvram, .write = write_nvram, - .ioctl = nvram_ioctl, + .unlocked_ioctl = nvram_ioctl, }; static struct miscdevice nvram_dev = { diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index 42764849eb78..3d4fc0f7b00b 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -2273,8 +2273,7 @@ static int register_pmu_pm_ops(void) device_initcall(register_pmu_pm_ops); #endif -static int -pmu_ioctl(struct inode * inode, struct file *filp, +static int pmu_ioctl(struct file *filp, u_int cmd, u_long arg) { __u32 __user *argp = (__u32 __user *)arg; @@ -2337,11 +2336,23 @@ pmu_ioctl(struct inode * inode, struct file *filp, return error; } +static long pmu_unlocked_ioctl(struct file *filp, + u_int cmd, u_long arg) +{ + int ret; + + lock_kernel(); + ret = pmu_ioctl(filp, cmd, arg); + unlock_kernel(); + + return ret; +} + static const struct file_operations pmu_device_fops = { .read = pmu_read, .write = pmu_write, .poll = pmu_fpoll, - .ioctl = pmu_ioctl, + .unlocked_ioctl = pmu_unlocked_ioctl, .open = pmu_open, .release = pmu_release, }; diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c index 9ddc57909d49..425862ffb285 100644 --- a/drivers/media/dvb/dvb-core/dmxdev.c +++ b/drivers/media/dvb/dvb-core/dmxdev.c @@ -25,6 +25,7 @@ #include <linux/slab.h> #include <linux/vmalloc.h> #include <linux/module.h> +#include <linux/smp_lock.h> #include <linux/poll.h> #include <linux/ioctl.h> #include <linux/wait.h> @@ -963,7 +964,7 @@ dvb_demux_read(struct file *file, char __user *buf, size_t count, return ret; } -static int dvb_demux_do_ioctl(struct inode *inode, struct file *file, +static int dvb_demux_do_ioctl(struct file *file, unsigned int cmd, void *parg) { struct dmxdev_filter *dmxdevfilter = file->private_data; @@ -1084,10 +1085,16 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file, return ret; } -static int dvb_demux_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long dvb_demux_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) { - return dvb_usercopy(inode, file, cmd, arg, dvb_demux_do_ioctl); + int ret; + + lock_kernel(); + ret = dvb_usercopy(file, cmd, arg, dvb_demux_do_ioctl); + unlock_kernel(); + + return ret; } static unsigned int dvb_demux_poll(struct file *file, poll_table *wait) @@ -1139,7 +1146,7 @@ static int dvb_demux_release(struct inode *inode, struct file *file) static const struct file_operations dvb_demux_fops = { .owner = THIS_MODULE, .read = dvb_demux_read, - .ioctl = dvb_demux_ioctl, + .unlocked_ioctl = dvb_demux_ioctl, .open = dvb_demux_open, .release = dvb_demux_release, .poll = dvb_demux_poll, @@ -1152,7 +1159,7 @@ static struct dvb_device dvbdev_demux = { .fops = &dvb_demux_fops }; -static int dvb_dvr_do_ioctl(struct inode *inode, struct file *file, +static int dvb_dvr_do_ioctl(struct file *file, unsigned int cmd, void *parg) { struct dvb_device *dvbdev = file->private_data; @@ -1176,10 +1183,16 @@ static int dvb_dvr_do_ioctl(struct inode *inode, struct file *file, return ret; } -static int dvb_dvr_ioctl(struct inode *inode, struct file *file, +static long dvb_dvr_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - return dvb_usercopy(inode, file, cmd, arg, dvb_dvr_do_ioctl); + int ret; + + lock_kernel(); + ret = dvb_usercopy(file, cmd, arg, dvb_dvr_do_ioctl); + unlock_kernel(); + + return ret; } static unsigned int dvb_dvr_poll(struct file *file, poll_table *wait) @@ -1208,7 +1221,7 @@ static const struct file_operations dvb_dvr_fops = { .owner = THIS_MODULE, .read = dvb_dvr_read, .write = dvb_dvr_write, - .ioctl = dvb_dvr_ioctl, + .unlocked_ioctl = dvb_dvr_ioctl, .open = dvb_dvr_open, .release = dvb_dvr_release, .poll = dvb_dvr_poll, diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c index cb22da53bfb0..ef259a0718ac 100644 --- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c @@ -36,6 +36,7 @@ #include <linux/delay.h> #include <linux/spinlock.h> #include <linux/sched.h> +#include <linux/smp_lock.h> #include <linux/kthread.h> #include "dvb_ca_en50221.h" @@ -1181,7 +1182,7 @@ static int dvb_ca_en50221_thread(void *data) * * @return 0 on success, <0 on error. */ -static int dvb_ca_en50221_io_do_ioctl(struct inode *inode, struct file *file, +static int dvb_ca_en50221_io_do_ioctl(struct file *file, unsigned int cmd, void *parg) { struct dvb_device *dvbdev = file->private_data; @@ -1255,10 +1256,16 @@ static int dvb_ca_en50221_io_do_ioctl(struct inode *inode, struct file *file, * * @return 0 on success, <0 on error. */ -static int dvb_ca_en50221_io_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long dvb_ca_en50221_io_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) { - return dvb_usercopy(inode, file, cmd, arg, dvb_ca_en50221_io_do_ioctl); + int ret; + + lock_kernel(); + ret = dvb_usercopy(file, cmd, arg, dvb_ca_en50221_io_do_ioctl); + unlock_kernel(); + + return ret; } @@ -1611,7 +1618,7 @@ static const struct file_operations dvb_ca_fops = { .owner = THIS_MODULE, .read = dvb_ca_en50221_io_read, .write = dvb_ca_en50221_io_write, - .ioctl = dvb_ca_en50221_io_ioctl, + .unlocked_ioctl = dvb_ca_en50221_io_ioctl, .open = dvb_ca_en50221_io_open, .release = dvb_ca_en50221_io_release, .poll = dvb_ca_en50221_io_poll, diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 6932def4d266..44ae89ecef94 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -36,6 +36,7 @@ #include <linux/list.h> #include <linux/freezer.h> #include <linux/jiffies.h> +#include <linux/smp_lock.h> #include <linux/kthread.h> #include <asm/processor.h> @@ -1195,14 +1196,14 @@ static void dtv_property_cache_submit(struct dvb_frontend *fe) } } -static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file, +static int dvb_frontend_ioctl_legacy(struct file *file, unsigned int cmd, void *parg); -static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, +static int dvb_frontend_ioctl_properties(struct file *file, unsigned int cmd, void *parg); static int dtv_property_process_get(struct dvb_frontend *fe, struct dtv_property *tvp, - struct inode *inode, struct file *file) + struct file *file) { int r = 0; @@ -1335,7 +1336,6 @@ static int dtv_property_process_get(struct dvb_frontend *fe, static int dtv_property_process_set(struct dvb_frontend *fe, struct dtv_property *tvp, - struct inode *inode, struct file *file) { int r = 0; @@ -1366,7 +1366,7 @@ static int dtv_property_process_set(struct dvb_frontend *fe, dprintk("%s() Finalised property cache\n", __func__); dtv_property_cache_submit(fe); - r |= dvb_frontend_ioctl_legacy(inode, file, FE_SET_FRONTEND, + r |= dvb_frontend_ioctl_legacy(file, FE_SET_FRONTEND, &fepriv->parameters); break; case DTV_FREQUENCY: @@ -1398,12 +1398,12 @@ static int dtv_property_process_set(struct dvb_frontend *fe, break; case DTV_VOLTAGE: fe->dtv_property_cache.voltage = tvp->u.data; - r = dvb_frontend_ioctl_legacy(inode, file, FE_SET_VOLTAGE, + r = dvb_frontend_ioctl_legacy(file, FE_SET_VOLTAGE, (void *)fe->dtv_property_cache.voltage); break; case DTV_TONE: fe->dtv_property_cache.sectone = tvp->u.data; - r = dvb_frontend_ioctl_legacy(inode, file, FE_SET_TONE, + r = dvb_frontend_ioctl_legacy(file, FE_SET_TONE, (void *)fe->dtv_property_cache.sectone); break; case DTV_CODE_RATE_HP: @@ -1487,7 +1487,7 @@ static int dtv_property_process_set(struct dvb_frontend *fe, return r; } -static int dvb_frontend_ioctl(struct inode *inode, struct file *file, +static int dvb_frontend_ioctl(struct file *file, unsigned int cmd, void *parg) { struct dvb_device *dvbdev = file->private_data; @@ -1509,17 +1509,17 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, return -ERESTARTSYS; if ((cmd == FE_SET_PROPERTY) || (cmd == FE_GET_PROPERTY)) - err = dvb_frontend_ioctl_properties(inode, file, cmd, parg); + err = dvb_frontend_ioctl_properties(file, cmd, parg); else { fe->dtv_property_cache.state = DTV_UNDEFINED; - err = dvb_frontend_ioctl_legacy(inode, file, cmd, parg); + err = dvb_frontend_ioctl_legacy(file, cmd, parg); } up(&fepriv->sem); return err; } -static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, +static int dvb_frontend_ioctl_properties(struct file *file, unsigned int cmd, void *parg) { struct dvb_device *dvbdev = file->private_data; @@ -1555,7 +1555,7 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, } for (i = 0; i < tvps->num; i++) { - (tvp + i)->result = dtv_property_process_set(fe, tvp + i, inode, file); + (tvp + i)->result = dtv_property_process_set(fe, tvp + i, file); err |= (tvp + i)->result; } @@ -1587,7 +1587,7 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, } for (i = 0; i < tvps->num; i++) { - (tvp + i)->result = dtv_property_process_get(fe, tvp + i, inode, file); + (tvp + i)->result = dtv_property_process_get(fe, tvp + i, file); err |= (tvp + i)->result; } @@ -1604,7 +1604,7 @@ out: return err; } -static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file, +static int dvb_frontend_ioctl_legacy(struct file *file, unsigned int cmd, void *parg) { struct dvb_device *dvbdev = file->private_data; @@ -2031,7 +2031,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file) static const struct file_operations dvb_frontend_fops = { .owner = THIS_MODULE, - .ioctl = dvb_generic_ioctl, + .unlocked_ioctl = dvb_generic_ioctl, .poll = dvb_frontend_poll, .open = dvb_frontend_open, .release = dvb_frontend_release diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index cccea412088b..f6dac2bb0ac6 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c @@ -59,6 +59,7 @@ #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/dvb/net.h> +#include <linux/smp_lock.h> #include <linux/uio.h> #include <asm/uaccess.h> #include <linux/crc32.h> @@ -1329,7 +1330,7 @@ static int dvb_net_remove_if(struct dvb_net *dvbnet, unsigned long num) return 0; } -static int dvb_net_do_ioctl(struct inode *inode, struct file *file, +static int dvb_net_do_ioctl(struct file *file, unsigned int cmd, void *parg) { struct dvb_device *dvbdev = file->private_data; @@ -1431,10 +1432,16 @@ static int dvb_net_do_ioctl(struct inode *inode, struct file *file, return 0; } -static int dvb_net_ioctl(struct inode *inode, struct file *file, +static long dvb_net_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - return dvb_usercopy(inode, file, cmd, arg, dvb_net_do_ioctl); + int ret; + + lock_kernel(); + ret = dvb_usercopy(file, cmd, arg, dvb_net_do_ioctl); + unlock_kernel(); + + return ret; } static int dvb_net_close(struct inode *inode, struct file *file) @@ -1455,7 +1462,7 @@ static int dvb_net_close(struct inode *inode, struct file *file) static const struct file_operations dvb_net_fops = { .owner = THIS_MODULE, - .ioctl = dvb_net_ioctl, + .unlocked_ioctl = dvb_net_ioctl, .open = dvb_generic_open, .release = dvb_net_close, }; diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c index 94159b90f733..b915c39d782f 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.c +++ b/drivers/media/dvb/dvb-core/dvbdev.c @@ -154,10 +154,11 @@ int dvb_generic_release(struct inode *inode, struct file *file) EXPORT_SYMBOL(dvb_generic_release); -int dvb_generic_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +long dvb_generic_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) { struct dvb_device *dvbdev = file->private_data; + int ret; if (!dvbdev) return -ENODEV; @@ -165,7 +166,11 @@ int dvb_generic_ioctl(struct inode *inode, struct file *file, if (!dvbdev->kernel_ioctl) return -EINVAL; - return dvb_usercopy (inode, file, cmd, arg, dvbdev->kernel_ioctl); + lock_kernel(); + ret = dvb_usercopy(file, cmd, arg, dvbdev->kernel_ioctl); + unlock_kernel(); + + return ret; } EXPORT_SYMBOL(dvb_generic_ioctl); @@ -377,9 +382,9 @@ EXPORT_SYMBOL(dvb_unregister_adapter); define this as video_usercopy(). this will introduce a dependecy to the v4l "videodev.o" module, which is unnecessary for some cards (ie. the budget dvb-cards don't need the v4l module...) */ -int dvb_usercopy(struct inode *inode, struct file *file, +int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg, - int (*func)(struct inode *inode, struct file *file, + int (*func)(struct file *file, unsigned int cmd, void *arg)) { char sbuf[128]; @@ -416,7 +421,7 @@ int dvb_usercopy(struct inode *inode, struct file *file, } /* call driver */ - if ((err = func(inode, file, cmd, parg)) == -ENOIOCTLCMD) + if ((err = func(file, cmd, parg)) == -ENOIOCTLCMD) err = -EINVAL; if (err < 0) diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h index f7b499d4a3c0..fcc6ae98745e 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.h +++ b/drivers/media/dvb/dvb-core/dvbdev.h @@ -116,8 +116,7 @@ struct dvb_device { wait_queue_head_t wait_queue; /* don't really need those !? -- FIXME: use video_usercopy */ - int (*kernel_ioctl)(struct inode *inode, struct file *file, - unsigned int cmd, void *arg); + int (*kernel_ioctl)(struct file *file, unsigned int cmd, void *arg); void *priv; }; @@ -138,17 +137,15 @@ extern void dvb_unregister_device (struct dvb_device *dvbdev); extern int dvb_generic_open (struct inode *inode, struct file *file); extern int dvb_generic_release (struct inode *inode, struct file *file); -extern int dvb_generic_ioctl (struct inode *inode, struct file *file, +extern long dvb_generic_ioctl (struct file *file, unsigned int cmd, unsigned long arg); /* we don't mess with video_usercopy() any more, we simply define out own dvb_usercopy(), which will hopefully become generic_usercopy() someday... */ -extern int dvb_usercopy(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg, - int (*func)(struct inode *inode, struct file *file, - unsigned int cmd, void *arg)); +extern int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg, + int (*func)(struct file *file, unsigned int cmd, void *arg)); /** generic DVB attach function. */ #ifdef CONFIG_MEDIA_ATTACH diff --git a/drivers/media/dvb/firewire/firedtv-ci.c b/drivers/media/dvb/firewire/firedtv-ci.c index 853e04b7cb36..d3c2cf60de76 100644 --- a/drivers/media/dvb/firewire/firedtv-ci.c +++ b/drivers/media/dvb/firewire/firedtv-ci.c @@ -175,8 +175,7 @@ static int fdtv_ca_send_msg(struct firedtv *fdtv, void *arg) return err; } -static int fdtv_ca_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *arg) +static int fdtv_ca_ioctl(struct file *file, unsigned int cmd, void *arg) { struct dvb_device *dvbdev = file->private_data; struct firedtv *fdtv = dvbdev->priv; @@ -217,7 +216,7 @@ static unsigned int fdtv_ca_io_poll(struct file *file, poll_table *wait) static const struct file_operations fdtv_ca_fops = { .owner = THIS_MODULE, - .ioctl = dvb_generic_ioctl, + .unlocked_ioctl = dvb_generic_ioctl, .open = dvb_generic_open, .release = dvb_generic_release, .poll = fdtv_ca_io_poll, diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index 38915591c6e5..a6be529eec5c 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c @@ -708,7 +708,7 @@ static void gpioirq(unsigned long cookie) #ifdef CONFIG_DVB_AV7110_OSD -static int dvb_osd_ioctl(struct inode *inode, struct file *file, +static int dvb_osd_ioctl(struct file *file, unsigned int cmd, void *parg) { struct dvb_device *dvbdev = file->private_data; @@ -727,7 +727,7 @@ static int dvb_osd_ioctl(struct inode *inode, struct file *file, static const struct file_operations dvb_osd_fops = { .owner = THIS_MODULE, - .ioctl = dvb_generic_ioctl, + .unlocked_ioctl = dvb_generic_ioctl, .open = dvb_generic_open, .release = dvb_generic_release, }; diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c index 53884814161c..13efba942dac 100644 --- a/drivers/media/dvb/ttpci/av7110_av.c +++ b/drivers/media/dvb/ttpci/av7110_av.c @@ -1089,7 +1089,7 @@ static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len } -static int dvb_video_ioctl(struct inode *inode, struct file *file, +static int dvb_video_ioctl(struct file *file, unsigned int cmd, void *parg) { struct dvb_device *dvbdev = file->private_data; @@ -1297,7 +1297,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, return ret; } -static int dvb_audio_ioctl(struct inode *inode, struct file *file, +static int dvb_audio_ioctl(struct file *file, unsigned int cmd, void *parg) { struct dvb_device *dvbdev = file->private_data; @@ -1517,7 +1517,7 @@ static int dvb_audio_release(struct inode *inode, struct file *file) static const struct file_operations dvb_video_fops = { .owner = THIS_MODULE, .write = dvb_video_write, - .ioctl = dvb_generic_ioctl, + .unlocked_ioctl = dvb_generic_ioctl, .open = dvb_video_open, .release = dvb_video_release, .poll = dvb_video_poll, @@ -1535,7 +1535,7 @@ static struct dvb_device dvbdev_video = { static const struct file_operations dvb_audio_fops = { .owner = THIS_MODULE, .write = dvb_audio_write, - .ioctl = dvb_generic_ioctl, + .unlocked_ioctl = dvb_generic_ioctl, .open = dvb_audio_open, .release = dvb_audio_release, .poll = dvb_audio_poll, diff --git a/drivers/media/dvb/ttpci/av7110_ca.c b/drivers/media/dvb/ttpci/av7110_ca.c index ac7779c45c5b..4eba35a018e3 100644 --- a/drivers/media/dvb/ttpci/av7110_ca.c +++ b/drivers/media/dvb/ttpci/av7110_ca.c @@ -248,8 +248,7 @@ static unsigned int dvb_ca_poll (struct file *file, poll_table *wait) return mask; } -static int dvb_ca_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *parg) +static int dvb_ca_ioctl(struct file *file, unsigned int cmd, void *parg) { struct dvb_device *dvbdev = file->private_data; struct av7110 *av7110 = dvbdev->priv; @@ -350,7 +349,7 @@ static const struct file_operations dvb_ca_fops = { .owner = THIS_MODULE, .read = dvb_ca_read, .write = dvb_ca_write, - .ioctl = dvb_generic_ioctl, + .unlocked_ioctl = dvb_generic_ioctl, .open = dvb_ca_open, .release = dvb_generic_release, .poll = dvb_ca_poll, diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 8bb5e4a66328..000d65ea55a4 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -468,8 +468,7 @@ static int mtd_do_readoob(struct mtd_info *mtd, uint64_t start, return ret; } -static int mtd_ioctl(struct inode *inode, struct file *file, - u_int cmd, u_long arg) +static int mtd_ioctl(struct file *file, u_int cmd, u_long arg) { struct mtd_file_info *mfi = file->private_data; struct mtd_info *mtd = mfi->mtd; @@ -840,6 +839,17 @@ static int mtd_ioctl(struct inode *inode, struct file *file, return ret; } /* memory_ioctl */ +static long mtd_unlocked_ioctl(struct file *file, u_int cmd, u_long arg) +{ + int ret; + + lock_kernel(); + ret = mtd_ioctl(file, cmd, arg); + unlock_kernel(); + + return ret; +} + #ifdef CONFIG_COMPAT struct mtd_oob_buf32 { @@ -854,7 +864,6 @@ struct mtd_oob_buf32 { static long mtd_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - struct inode *inode = file->f_path.dentry->d_inode; struct mtd_file_info *mfi = file->private_data; struct mtd_info *mtd = mfi->mtd; void __user *argp = compat_ptr(arg); @@ -892,7 +901,7 @@ static long mtd_compat_ioctl(struct file *file, unsigned int cmd, break; } default: - ret = mtd_ioctl(inode, file, cmd, (unsigned long)argp); + ret = mtd_ioctl(file, cmd, (unsigned long)argp); } unlock_kernel(); @@ -960,7 +969,7 @@ static const struct file_operations mtd_fops = { .llseek = mtd_lseek, .read = mtd_read, .write = mtd_write, - .ioctl = mtd_ioctl, + .unlocked_ioctl = mtd_unlocked_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = mtd_compat_ioctl, #endif diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c index ef0c5f133691..d007a2a03830 100644 --- a/drivers/pcmcia/pcmcia_ioctl.c +++ b/drivers/pcmcia/pcmcia_ioctl.c @@ -813,8 +813,7 @@ static u_int ds_poll(struct file *file, poll_table *wait) /*====================================================================*/ -static int ds_ioctl(struct inode *inode, struct file *file, - u_int cmd, u_long arg) +static int ds_ioctl(struct file *file, u_int cmd, u_long arg) { struct pcmcia_socket *s; void __user *uarg = (char __user *)arg; @@ -1021,13 +1020,25 @@ free_out: return err; } /* ds_ioctl */ +static long ds_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = ds_ioctl(file, cmd, arg); + unlock_kernel(); + + return ret; +} + + /*====================================================================*/ static const struct file_operations ds_fops = { .owner = THIS_MODULE, .open = ds_open, .release = ds_release, - .ioctl = ds_ioctl, + .unlocked_ioctl = ds_unlocked_ioctl, .read = ds_read, .write = ds_write, .poll = ds_poll, diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 60fe266f0f49..038095d99976 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -623,7 +623,7 @@ static ssize_t wdt_read(struct file *file, char __user *buf, * according to their available features. We only actually usefully support * querying capabilities and current status. */ -static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, +static int wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int new_margin, rv; @@ -676,6 +676,18 @@ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, return -ENOTTY; } +static long wdt_unlocked_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = wdt_ioctl(file, cmd, arg); + unlock_kernel(); + + return ret; +} + /** * wdt_open: * @inode: inode of device @@ -736,7 +748,7 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, static const struct file_operations wdt_fops = { .owner = THIS_MODULE, .read = wdt_read, - .ioctl = wdt_ioctl, + .unlocked_ioctl = wdt_unlocked_ioctl, .write = wdt_write, .open = wdt_open, .release = wdt_release, diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c index fc2f676e984d..d53e62ab09da 100644 --- a/drivers/sbus/char/openprom.c +++ b/drivers/sbus/char/openprom.c @@ -298,9 +298,9 @@ static int opromgetbootargs(void __user *argp, struct openpromio *op, int bufsiz /* * SunOS and Solaris /dev/openprom ioctl calls. */ -static int openprom_sunos_ioctl(struct inode * inode, struct file * file, - unsigned int cmd, unsigned long arg, - struct device_node *dp) +static long openprom_sunos_ioctl(struct file * file, + unsigned int cmd, unsigned long arg, + struct device_node *dp) { DATA *data = file->private_data; struct openpromio *opp = NULL; @@ -316,6 +316,8 @@ static int openprom_sunos_ioctl(struct inode * inode, struct file * file, if (bufsize < 0) return bufsize; + lock_kernel(); + switch (cmd) { case OPROMGETOPT: case OPROMGETPROP: @@ -365,6 +367,8 @@ static int openprom_sunos_ioctl(struct inode * inode, struct file * file, } kfree(opp); + unlock_kernel(); + return error; } @@ -547,13 +551,14 @@ static int opiocgetnext(unsigned int cmd, void __user *argp) return 0; } -static int openprom_bsd_ioctl(struct inode * inode, struct file * file, +static int openprom_bsd_ioctl(struct file * file, unsigned int cmd, unsigned long arg) { DATA *data = (DATA *) file->private_data; void __user *argp = (void __user *)arg; int err; + lock_kernel(); switch (cmd) { case OPIOCGET: err = opiocget(argp, data); @@ -570,10 +575,10 @@ static int openprom_bsd_ioctl(struct inode * inode, struct file * file, case OPIOCGETOPTNODE: BUILD_BUG_ON(sizeof(phandle) != sizeof(int)); + err = 0; if (copy_to_user(argp, &options_node->phandle, sizeof(phandle))) - return -EFAULT; - - return 0; + err = -EFAULT; + break; case OPIOCGETNEXT: case OPIOCGETCHILD: @@ -581,9 +586,10 @@ static int openprom_bsd_ioctl(struct inode * inode, struct file * file, break; default: - return -EINVAL; - + err = -EINVAL; + break; }; + unlock_kernel(); return err; } @@ -592,8 +598,8 @@ static int openprom_bsd_ioctl(struct inode * inode, struct file * file, /* * Handoff control to the correct ioctl handler. */ -static int openprom_ioctl(struct inode * inode, struct file * file, - unsigned int cmd, unsigned long arg) +static long openprom_ioctl(struct file * file, + unsigned int cmd, unsigned long arg) { DATA *data = (DATA *) file->private_data; @@ -602,14 +608,14 @@ static int openprom_ioctl(struct inode * inode, struct file * file, case OPROMNXTOPT: if ((file->f_mode & FMODE_READ) == 0) return -EPERM; - return openprom_sunos_ioctl(inode, file, cmd, arg, + return openprom_sunos_ioctl(file, cmd, arg, options_node); case OPROMSETOPT: case OPROMSETOPT2: if ((file->f_mode & FMODE_WRITE) == 0) return -EPERM; - return openprom_sunos_ioctl(inode, file, cmd, arg, + return openprom_sunos_ioctl(file, cmd, arg, options_node); case OPROMNEXT: @@ -618,7 +624,7 @@ static int openprom_ioctl(struct inode * inode, struct file * file, case OPROMNXTPROP: if ((file->f_mode & FMODE_READ) == 0) return -EPERM; - return openprom_sunos_ioctl(inode, file, cmd, arg, + return openprom_sunos_ioctl(file, cmd, arg, data->current_node); case OPROMU2P: @@ -630,7 +636,7 @@ static int openprom_ioctl(struct inode * inode, struct file * file, case OPROMPATH2NODE: if ((file->f_mode & FMODE_READ) == 0) return -EPERM; - return openprom_sunos_ioctl(inode, file, cmd, arg, NULL); + return openprom_sunos_ioctl(file, cmd, arg, NULL); case OPIOCGET: case OPIOCNEXTPROP: @@ -639,12 +645,12 @@ static int openprom_ioctl(struct inode * inode, struct file * file, case OPIOCGETCHILD: if ((file->f_mode & FMODE_READ) == 0) return -EBADF; - return openprom_bsd_ioctl(inode,file,cmd,arg); + return openprom_bsd_ioctl(file,cmd,arg); case OPIOCSET: if ((file->f_mode & FMODE_WRITE) == 0) return -EBADF; - return openprom_bsd_ioctl(inode,file,cmd,arg); + return openprom_bsd_ioctl(file,cmd,arg); default: return -EINVAL; @@ -676,7 +682,7 @@ static long openprom_compat_ioctl(struct file *file, unsigned int cmd, case OPROMSETCUR: case OPROMPCI2NODE: case OPROMPATH2NODE: - rval = openprom_ioctl(file->f_path.dentry->d_inode, file, cmd, arg); + rval = openprom_ioctl(file, cmd, arg); break; } @@ -709,7 +715,7 @@ static int openprom_release(struct inode * inode, struct file * file) static const struct file_operations openprom_fops = { .owner = THIS_MODULE, .llseek = no_llseek, - .ioctl = openprom_ioctl, + .unlocked_ioctl = openprom_ioctl, .compat_ioctl = openprom_compat_ioctl, .open = openprom_open, .release = openprom_release, diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index 1bb774becf25..e20b7bdd4c78 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c @@ -125,7 +125,7 @@ static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_H static int twa_aen_read_queue(TW_Device_Extension *tw_dev, int request_id); static char *twa_aen_severity_lookup(unsigned char severity_code); static void twa_aen_sync_time(TW_Device_Extension *tw_dev, int request_id); -static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); +static long twa_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg); static int twa_chrdev_open(struct inode *inode, struct file *file); static int twa_fill_sense(TW_Device_Extension *tw_dev, int request_id, int copy_sense, int print_host); static void twa_free_request_id(TW_Device_Extension *tw_dev,int request_id); @@ -220,7 +220,7 @@ static struct device_attribute *twa_host_attrs[] = { /* File operations struct for character device */ static const struct file_operations twa_fops = { .owner = THIS_MODULE, - .ioctl = twa_chrdev_ioctl, + .unlocked_ioctl = twa_chrdev_ioctl, .open = twa_chrdev_open, .release = NULL }; @@ -637,8 +637,9 @@ out: } /* End twa_check_srl() */ /* This function handles ioctl for the character device */ -static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +static long twa_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { + struct inode *inode = file->f_path.dentry->d_inode; long timeout; unsigned long *cpu_addr, data_buffer_length_adjusted = 0, flags = 0; dma_addr_t dma_handle; @@ -657,6 +658,8 @@ static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int int retval = TW_IOCTL_ERROR_OS_EFAULT; void __user *argp = (void __user *)arg; + lock_kernel(); + /* Only let one of these through at a time */ if (mutex_lock_interruptible(&tw_dev->ioctl_lock)) { retval = TW_IOCTL_ERROR_OS_EINTR; @@ -876,6 +879,7 @@ out3: out2: mutex_unlock(&tw_dev->ioctl_lock); out: + unlock_kernel(); return retval; } /* End twa_chrdev_ioctl() */ diff --git a/drivers/scsi/3w-sas.c b/drivers/scsi/3w-sas.c index d38000db9237..f481e734aad4 100644 --- a/drivers/scsi/3w-sas.c +++ b/drivers/scsi/3w-sas.c @@ -750,19 +750,22 @@ static void twl_load_sgl(TW_Device_Extension *tw_dev, TW_Command_Full *full_comm /* This function handles ioctl for the character device This interface is used by smartmontools open source software */ -static int twl_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +static long twl_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { long timeout; unsigned long *cpu_addr, data_buffer_length_adjusted = 0, flags = 0; dma_addr_t dma_handle; int request_id = 0; TW_Ioctl_Driver_Command driver_command; + struct inode *inode = file->f_dentry->d_inode; TW_Ioctl_Buf_Apache *tw_ioctl; TW_Command_Full *full_command_packet; TW_Device_Extension *tw_dev = twl_device_extension_list[iminor(inode)]; int retval = -EFAULT; void __user *argp = (void __user *)arg; + lock_kernel(); + /* Only let one of these through at a time */ if (mutex_lock_interruptible(&tw_dev->ioctl_lock)) { retval = -EINTR; @@ -858,6 +861,7 @@ out3: out2: mutex_unlock(&tw_dev->ioctl_lock); out: + unlock_kernel(); return retval; } /* End twl_chrdev_ioctl() */ @@ -884,7 +888,7 @@ out: /* File operations struct for character device */ static const struct file_operations twl_fops = { .owner = THIS_MODULE, - .ioctl = twl_chrdev_ioctl, + .unlocked_ioctl = twl_chrdev_ioctl, .open = twl_chrdev_open, .release = NULL }; diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c index d119a614bf7d..30d735ad35b5 100644 --- a/drivers/scsi/3w-xxxx.c +++ b/drivers/scsi/3w-xxxx.c @@ -881,7 +881,7 @@ static int tw_allocate_memory(TW_Device_Extension *tw_dev, int size, int which) } /* End tw_allocate_memory() */ /* This function handles ioctl for the character device */ -static int tw_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +static long tw_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int request_id; dma_addr_t dma_handle; @@ -889,6 +889,7 @@ static int tw_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int unsigned long flags; unsigned int data_buffer_length = 0; unsigned long data_buffer_length_adjusted = 0; + struct inode *inode = file->f_dentry->d_inode; unsigned long *cpu_addr; long timeout; TW_New_Ioctl *tw_ioctl; @@ -899,9 +900,12 @@ static int tw_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl()\n"); + lock_kernel(); /* Only let one of these through at a time */ - if (mutex_lock_interruptible(&tw_dev->ioctl_lock)) + if (mutex_lock_interruptible(&tw_dev->ioctl_lock)) { + unlock_kernel(); return -EINTR; + } /* First copy down the buffer length */ if (copy_from_user(&data_buffer_length, argp, sizeof(unsigned int))) @@ -1030,6 +1034,7 @@ out2: dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, cpu_addr, dma_handle); out: mutex_unlock(&tw_dev->ioctl_lock); + unlock_kernel(); return retval; } /* End tw_chrdev_ioctl() */ @@ -1052,7 +1057,7 @@ static int tw_chrdev_open(struct inode *inode, struct file *file) /* File operations struct for character device */ static const struct file_operations tw_fops = { .owner = THIS_MODULE, - .ioctl = tw_chrdev_ioctl, + .unlocked_ioctl = tw_chrdev_ioctl, .open = tw_chrdev_open, .release = NULL }; diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index e9373a2d14fa..33898b61fdb5 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -705,12 +705,17 @@ static int aac_cfg_open(struct inode *inode, struct file *file) * Bugs: Needs to handle hot plugging */ -static int aac_cfg_ioctl(struct inode *inode, struct file *file, +static long aac_cfg_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { + int ret; if (!capable(CAP_SYS_RAWIO)) return -EPERM; - return aac_do_ioctl(file->private_data, cmd, (void __user *)arg); + lock_kernel(); + ret = aac_do_ioctl(file->private_data, cmd, (void __user *)arg); + unlock_kernel(); + + return ret; } #ifdef CONFIG_COMPAT @@ -1029,7 +1034,7 @@ ssize_t aac_get_serial_number(struct device *device, char *buf) static const struct file_operations aac_cfg_fops = { .owner = THIS_MODULE, - .ioctl = aac_cfg_ioctl, + .unlocked_ioctl = aac_cfg_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = aac_compat_cfg_ioctl, #endif diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c index 0435d044c9da..b0c576f84b28 100644 --- a/drivers/scsi/dpt_i2o.c +++ b/drivers/scsi/dpt_i2o.c @@ -114,12 +114,13 @@ static int hba_count = 0; static struct class *adpt_sysfs_class; +static long adpt_unlocked_ioctl(struct file *, unsigned int, unsigned long); #ifdef CONFIG_COMPAT static long compat_adpt_ioctl(struct file *, unsigned int, unsigned long); #endif static const struct file_operations adpt_fops = { - .ioctl = adpt_ioctl, + .unlocked_ioctl = adpt_unlocked_ioctl, .open = adpt_open, .release = adpt_close, #ifdef CONFIG_COMPAT @@ -2069,8 +2070,7 @@ static int adpt_system_info(void __user *buffer) return 0; } -static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd, - ulong arg) +static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) { int minor; int error = 0; @@ -2153,6 +2153,20 @@ static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd, return error; } +static long adpt_unlocked_ioctl(struct file *file, uint cmd, ulong arg) +{ + struct inode *inode; + long ret; + + inode = file->f_dentry->d_inode; + + lock_kernel(); + ret = adpt_ioctl(inode, file, cmd, arg); + unlock_kernel(); + + return ret; +} + #ifdef CONFIG_COMPAT static long compat_adpt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index a765fe7a55c3..f672d6213eea 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -180,8 +180,8 @@ static const char *gdth_ctr_name(gdth_ha_str *ha); static int gdth_open(struct inode *inode, struct file *filep); static int gdth_close(struct inode *inode, struct file *filep); -static int gdth_ioctl(struct inode *inode, struct file *filep, - unsigned int cmd, unsigned long arg); +static long gdth_unlocked_ioctl(struct file *filep, unsigned int cmd, + unsigned long arg); static void gdth_flush(gdth_ha_str *ha); static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *)); @@ -369,7 +369,7 @@ MODULE_LICENSE("GPL"); /* ioctl interface */ static const struct file_operations gdth_fops = { - .ioctl = gdth_ioctl, + .unlocked_ioctl = gdth_unlocked_ioctl, .open = gdth_open, .release = gdth_close, }; @@ -4462,8 +4462,7 @@ free_fail: return rc; } -static int gdth_ioctl(struct inode *inode, struct file *filep, - unsigned int cmd, unsigned long arg) +static int gdth_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) { gdth_ha_str *ha; Scsi_Cmnd *scp; @@ -4611,6 +4610,17 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, return 0; } +static long gdth_unlocked_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = gdth_ioctl(file, cmd, arg); + unlock_kernel(); + + return ret; +} /* flush routine */ static void gdth_flush(gdth_ha_str *ha) diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index 4bf7edca9e69..0b6e3228610a 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -91,12 +91,15 @@ static struct proc_dir_entry *mega_proc_dir_entry; /* For controller re-ordering */ static struct mega_hbas mega_hbas[MAX_CONTROLLERS]; +static long +megadev_unlocked_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); + /* * The File Operations structure for the serial/ioctl interface of the driver */ static const struct file_operations megadev_fops = { .owner = THIS_MODULE, - .ioctl = megadev_ioctl, + .unlocked_ioctl = megadev_unlocked_ioctl, .open = megadev_open, }; @@ -3302,8 +3305,7 @@ megadev_open (struct inode *inode, struct file *filep) * controller. */ static int -megadev_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, - unsigned long arg) +megadev_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) { adapter_t *adapter; nitioctl_t uioc; @@ -3694,6 +3696,18 @@ freemem_and_return: return 0; } +static long +megadev_unlocked_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = megadev_ioctl(filep, cmd, arg); + unlock_kernel(); + + return ret; +} + /** * mega_m_to_n() * @arg - user address diff --git a/drivers/scsi/megaraid.h b/drivers/scsi/megaraid.h index d310f49d077e..2b4a048cadf1 100644 --- a/drivers/scsi/megaraid.h +++ b/drivers/scsi/megaraid.h @@ -1013,8 +1013,7 @@ static void mega_8_to_40ld (mraid_inquiry *inquiry, mega_inquiry3 *enquiry3, mega_product_info *); static int megadev_open (struct inode *, struct file *); -static int megadev_ioctl (struct inode *, struct file *, unsigned int, - unsigned long); +static int megadev_ioctl (struct file *, unsigned int, unsigned long); static int mega_m_to_n(void __user *, nitioctl_t *); static int mega_n_to_m(void __user *, megacmd_t *); diff --git a/drivers/scsi/megaraid/megaraid_mm.c b/drivers/scsi/megaraid/megaraid_mm.c index 36e0b7d05c1d..41f82f76d884 100644 --- a/drivers/scsi/megaraid/megaraid_mm.c +++ b/drivers/scsi/megaraid/megaraid_mm.c @@ -22,7 +22,7 @@ // Entry points for char node driver static int mraid_mm_open(struct inode *, struct file *); -static int mraid_mm_ioctl(struct inode *, struct file *, uint, unsigned long); +static long mraid_mm_unlocked_ioctl(struct file *, uint, unsigned long); // routines to convert to and from the old the format @@ -70,7 +70,7 @@ static wait_queue_head_t wait_q; static const struct file_operations lsi_fops = { .open = mraid_mm_open, - .ioctl = mraid_mm_ioctl, + .unlocked_ioctl = mraid_mm_unlocked_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = mraid_mm_compat_ioctl, #endif @@ -110,8 +110,7 @@ mraid_mm_open(struct inode *inode, struct file *filep) * @arg : user ioctl packet */ static int -mraid_mm_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, - unsigned long arg) +mraid_mm_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) { uioc_t *kioc; char signature[EXT_IOCTL_SIGN_SZ] = {0}; @@ -218,6 +217,19 @@ mraid_mm_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, return rval; } +static long +mraid_mm_unlocked_ioctl(struct file *filep, unsigned int cmd, + unsigned long arg) +{ + int err; + + /* inconsistant: mraid_mm_compat_ioctl doesn't take the BKL */ + lock_kernel(); + err = mraid_mm_ioctl(filep, cmd, arg); + unlock_kernel(); + + return err; +} /** * mraid_mm_get_adapter - Returns corresponding adapters for the mimd packet @@ -1225,7 +1237,7 @@ mraid_mm_compat_ioctl(struct file *filep, unsigned int cmd, { int err; - err = mraid_mm_ioctl(NULL, filep, cmd, arg); + err = mraid_mm_ioctl(filep, cmd, arg); return err; } diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c index b219118f8bd6..8dbf1c3afb7b 100644 --- a/drivers/scsi/osst.c +++ b/drivers/scsi/osst.c @@ -4932,7 +4932,7 @@ static int os_scsi_tape_close(struct inode * inode, struct file * filp) /* The ioctl command */ -static int osst_ioctl(struct inode * inode,struct file * file, +static long osst_ioctl(struct file * file, unsigned int cmd_in, unsigned long arg) { int i, cmd_nr, cmd_type, blk, retval = 0; @@ -4943,8 +4943,11 @@ static int osst_ioctl(struct inode * inode,struct file * file, char * name = tape_name(STp); void __user * p = (void __user *)arg; - if (mutex_lock_interruptible(&STp->lock)) + lock_kernel(); + if (mutex_lock_interruptible(&STp->lock)) { + unlock_kernel(); return -ERESTARTSYS; + } #if DEBUG if (debugging && !STp->in_use) { @@ -5256,12 +5259,15 @@ static int osst_ioctl(struct inode * inode,struct file * file, mutex_unlock(&STp->lock); - return scsi_ioctl(STp->device, cmd_in, p); + retval = scsi_ioctl(STp->device, cmd_in, p); + unlock_kernel(); + return retval; out: if (SRpnt) osst_release_request(SRpnt); mutex_unlock(&STp->lock); + unlock_kernel(); return retval; } @@ -5613,7 +5619,7 @@ static const struct file_operations osst_fops = { .owner = THIS_MODULE, .read = osst_read, .write = osst_write, - .ioctl = osst_ioctl, + .unlocked_ioctl = osst_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = osst_compat_ioctl, #endif diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index dee1c96288d4..ef752b248c4d 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -758,8 +758,7 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp, } static int -sg_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd_in, unsigned long arg) +sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) { void __user *p = (void __user *)arg; int __user *ip = p; @@ -1078,6 +1077,18 @@ sg_ioctl(struct inode *inode, struct file *filp, } } +static long +sg_unlocked_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = sg_ioctl(filp, cmd_in, arg); + unlock_kernel(); + + return ret; +} + #ifdef CONFIG_COMPAT static long sg_compat_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) { @@ -1322,7 +1333,7 @@ static const struct file_operations sg_fops = { .read = sg_read, .write = sg_write, .poll = sg_poll, - .ioctl = sg_ioctl, + .unlocked_ioctl = sg_unlocked_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = sg_compat_ioctl, #endif diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index e7fa3644ba6a..61c76b13f0f1 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c @@ -954,8 +954,7 @@ static int mon_bin_queued(struct mon_reader_bin *rp) /* */ -static int mon_bin_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static int mon_bin_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct mon_reader_bin *rp = file->private_data; // struct mon_bus* mbus = rp->r.m_bus; @@ -1095,6 +1094,19 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file, return ret; } +static long mon_bin_unlocked_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = mon_bin_ioctl(file, cmd, arg); + unlock_kernel(); + + return ret; +} + + #ifdef CONFIG_COMPAT static long mon_bin_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) @@ -1148,14 +1160,13 @@ static long mon_bin_compat_ioctl(struct file *file, return 0; case MON_IOCG_STATS: - return mon_bin_ioctl(NULL, file, cmd, - (unsigned long) compat_ptr(arg)); + return mon_bin_ioctl(file, cmd, (unsigned long) compat_ptr(arg)); case MON_IOCQ_URB_LEN: case MON_IOCQ_RING_SIZE: case MON_IOCT_RING_SIZE: case MON_IOCH_MFLUSH: - return mon_bin_ioctl(NULL, file, cmd, arg); + return mon_bin_ioctl(file, cmd, arg); default: ; @@ -1239,7 +1250,7 @@ static const struct file_operations mon_fops_binary = { .read = mon_bin_read, /* .write = mon_text_write, */ .poll = mon_bin_poll, - .ioctl = mon_bin_ioctl, + .unlocked_ioctl = mon_bin_unlocked_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = mon_bin_compat_ioctl, #endif diff --git a/drivers/usb/mon/mon_stat.c b/drivers/usb/mon/mon_stat.c index 1becdc3837e6..8ec94f15a738 100644 --- a/drivers/usb/mon/mon_stat.c +++ b/drivers/usb/mon/mon_stat.c @@ -11,6 +11,7 @@ #include <linux/slab.h> #include <linux/usb.h> #include <linux/fs.h> +#include <linux/smp_lock.h> #include <asm/uaccess.h> #include "usb_mon.h" @@ -63,6 +64,6 @@ const struct file_operations mon_fops_stat = { .read = mon_stat_read, /* .write = mon_stat_write, */ /* .poll = mon_stat_poll, */ - /* .ioctl = mon_stat_ioctl, */ + /* .unlocked_ioctl = mon_stat_ioctl, */ .release = mon_stat_release, }; diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index e8e5e63ac950..db4117ed7803 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c @@ -18,13 +18,14 @@ #include <linux/slab.h> #include <linux/param.h> #include <linux/time.h> +#include <linux/smp_lock.h> #include "autofs_i.h" static int autofs4_dir_symlink(struct inode *,struct dentry *,const char *); static int autofs4_dir_unlink(struct inode *,struct dentry *); static int autofs4_dir_rmdir(struct inode *,struct dentry *); static int autofs4_dir_mkdir(struct inode *,struct dentry *,int); -static int autofs4_root_ioctl(struct inode *, struct file *,unsigned int,unsigned long); +static long autofs4_root_ioctl(struct file *,unsigned int,unsigned long); static int autofs4_dir_open(struct inode *inode, struct file *file); static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct nameidata *); static void *autofs4_follow_link(struct dentry *, struct nameidata *); @@ -38,7 +39,7 @@ const struct file_operations autofs4_root_operations = { .read = generic_read_dir, .readdir = dcache_readdir, .llseek = dcache_dir_lseek, - .ioctl = autofs4_root_ioctl, + .unlocked_ioctl = autofs4_root_ioctl, }; const struct file_operations autofs4_dir_operations = { @@ -902,8 +903,8 @@ int is_autofs4_dentry(struct dentry *dentry) * ioctl()'s on the root directory is the chief method for the daemon to * generate kernel reactions */ -static int autofs4_root_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +static int autofs4_root_ioctl_unlocked(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { struct autofs_sb_info *sbi = autofs4_sbi(inode->i_sb); void __user *p = (void __user *)arg; @@ -947,3 +948,16 @@ static int autofs4_root_ioctl(struct inode *inode, struct file *filp, return -ENOSYS; } } + +static long autofs4_root_ioctl(struct file *filp, + unsigned int cmd, unsigned long arg) +{ + long ret; + struct inode *inode = filp->f_dentry->d_inode; + + lock_kernel(); + ret = autofs4_root_ioctl_unlocked(inode, filp, cmd, arg); + unlock_kernel(); + + return ret; +} diff --git a/fs/coda/pioctl.c b/fs/coda/pioctl.c index 773f2ce9aa06..ca25d96d45c9 100644 --- a/fs/coda/pioctl.c +++ b/fs/coda/pioctl.c @@ -1,6 +1,6 @@ /* * Pioctl operations for Coda. - * Original version: (C) 1996 Peter Braam + * Original version: (C) 1996 Peter Braam * Rewritten for Linux 2.1: (C) 1997 Carnegie Mellon University * * Carnegie Mellon encourages users of this code to contribute improvements @@ -23,21 +23,22 @@ #include <linux/coda_fs_i.h> #include <linux/coda_psdev.h> +#include <linux/smp_lock.h> + /* pioctl ops */ static int coda_ioctl_permission(struct inode *inode, int mask); -static int coda_pioctl(struct inode * inode, struct file * filp, - unsigned int cmd, unsigned long user_data); +static long coda_pioctl(struct file *filp, unsigned int cmd, + unsigned long user_data); /* exported from this file */ -const struct inode_operations coda_ioctl_inode_operations = -{ +const struct inode_operations coda_ioctl_inode_operations = { .permission = coda_ioctl_permission, .setattr = coda_setattr, }; const struct file_operations coda_ioctl_operations = { .owner = THIS_MODULE, - .ioctl = coda_pioctl, + .unlocked_ioctl = coda_pioctl, }; /* the coda pioctl inode ops */ @@ -46,48 +47,53 @@ static int coda_ioctl_permission(struct inode *inode, int mask) return (mask & MAY_EXEC) ? -EACCES : 0; } -static int coda_pioctl(struct inode * inode, struct file * filp, - unsigned int cmd, unsigned long user_data) +static long coda_pioctl(struct file *filp, unsigned int cmd, + unsigned long user_data) { struct path path; - int error; + int error; struct PioctlData data; - struct inode *target_inode = NULL; - struct coda_inode_info *cnp; + struct inode *inode = filp->f_dentry->d_inode; + struct inode *target_inode = NULL; + struct coda_inode_info *cnp; - /* get the Pioctl data arguments from user space */ - if (copy_from_user(&data, (void __user *)user_data, sizeof(data))) { - return -EINVAL; - } - - /* - * Look up the pathname. Note that the pathname is in - * user memory, and namei takes care of this - */ - if (data.follow) { - error = user_path(data.path, &path); - } else { - error = user_lpath(data.path, &path); + lock_kernel(); + + /* get the Pioctl data arguments from user space */ + if (copy_from_user(&data, (void __user *)user_data, sizeof(data))) { + error = -EINVAL; + goto out; } - - if ( error ) { - return error; - } else { + + /* + * Look up the pathname. Note that the pathname is in + * user memory, and namei takes care of this + */ + if (data.follow) + error = user_path(data.path, &path); + else + error = user_lpath(data.path, &path); + + if (error) + goto out; + else target_inode = path.dentry->d_inode; - } - + /* return if it is not a Coda inode */ - if ( target_inode->i_sb != inode->i_sb ) { + if (target_inode->i_sb != inode->i_sb) { path_put(&path); - return -EINVAL; + error = -EINVAL; + goto out; } /* now proceed to make the upcall */ - cnp = ITOC(target_inode); + cnp = ITOC(target_inode); error = venus_pioctl(inode->i_sb, &(cnp->c_fid), cmd, &data); path_put(&path); - return error; -} +out: + unlock_kernel(); + return error; +} diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c index be4392ca2098..66b9cf79c5ba 100644 --- a/fs/coda/psdev.c +++ b/fs/coda/psdev.c @@ -73,8 +73,7 @@ static unsigned int coda_psdev_poll(struct file *file, poll_table * wait) return mask; } -static int coda_psdev_ioctl(struct inode * inode, struct file * filp, - unsigned int cmd, unsigned long arg) +static long coda_psdev_ioctl(struct file * filp, unsigned int cmd, unsigned long arg) { unsigned int data; @@ -344,7 +343,7 @@ static const struct file_operations coda_psdev_fops = { .read = coda_psdev_read, .write = coda_psdev_write, .poll = coda_psdev_poll, - .ioctl = coda_psdev_ioctl, + .unlocked_ioctl = coda_psdev_ioctl, .open = coda_psdev_open, .release = coda_psdev_release, }; diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index 5f4023678251..764fd1bdca88 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c @@ -494,7 +494,7 @@ const struct inode_operations hfsplus_dir_inode_operations = { const struct file_operations hfsplus_dir_operations = { .read = generic_read_dir, .readdir = hfsplus_readdir, - .ioctl = hfsplus_ioctl, + .unlocked_ioctl = hfsplus_ioctl, .llseek = generic_file_llseek, .release = hfsplus_dir_release, }; diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index 5c10d803d9df..6505c30ad965 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h @@ -337,8 +337,7 @@ struct inode *hfsplus_new_inode(struct super_block *, int); void hfsplus_delete_inode(struct inode *); /* ioctl.c */ -int hfsplus_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg); +long hfsplus_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); int hfsplus_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags); ssize_t hfsplus_getxattr(struct dentry *dentry, const char *name, diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index 1bcf597c0562..9bbb82924a22 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c @@ -285,7 +285,7 @@ static const struct file_operations hfsplus_file_operations = { .fsync = file_fsync, .open = hfsplus_file_open, .release = hfsplus_file_release, - .ioctl = hfsplus_ioctl, + .unlocked_ioctl = hfsplus_ioctl, }; struct inode *hfsplus_new_inode(struct super_block *sb, int mode) diff --git a/fs/hfsplus/ioctl.c b/fs/hfsplus/ioctl.c index f457d2ca51ab..ac405f099026 100644 --- a/fs/hfsplus/ioctl.c +++ b/fs/hfsplus/ioctl.c @@ -17,14 +17,16 @@ #include <linux/mount.h> #include <linux/sched.h> #include <linux/xattr.h> +#include <linux/smp_lock.h> #include <asm/uaccess.h> #include "hfsplus_fs.h" -int hfsplus_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) +long hfsplus_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { + struct inode *inode = filp->f_path.dentry->d_inode; unsigned int flags; + lock_kernel(); switch (cmd) { case HFSPLUS_IOC_EXT2_GETFLAGS: flags = 0; @@ -38,8 +40,10 @@ int hfsplus_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, case HFSPLUS_IOC_EXT2_SETFLAGS: { int err = 0; err = mnt_want_write(filp->f_path.mnt); - if (err) + if (err) { + unlock_kernel(); return err; + } if (!is_owner_or_cap(inode)) { err = -EACCES; @@ -85,9 +89,11 @@ int hfsplus_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, mark_inode_dirty(inode); setflags_out: mnt_drop_write(filp->f_path.mnt); + unlock_kernel(); return err; } default: + unlock_kernel(); return -ENOTTY; } } diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index 7edfcd4d5e52..92dde6f8d893 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c @@ -51,7 +51,7 @@ const struct file_operations ncp_dir_operations = { .read = generic_read_dir, .readdir = ncp_readdir, - .ioctl = ncp_ioctl, + .unlocked_ioctl = ncp_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = ncp_compat_ioctl, #endif diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c index 1daabb90e0a5..b93870892892 100644 --- a/fs/ncpfs/file.c +++ b/fs/ncpfs/file.c @@ -295,7 +295,7 @@ const struct file_operations ncp_file_operations = .llseek = ncp_remote_llseek, .read = ncp_file_read, .write = ncp_file_write, - .ioctl = ncp_ioctl, + .unlocked_ioctl = ncp_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = ncp_compat_ioctl, #endif diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c index 60a5e2864ea8..023c03d02070 100644 --- a/fs/ncpfs/ioctl.c +++ b/fs/ncpfs/ioctl.c @@ -20,6 +20,7 @@ #include <linux/smp_lock.h> #include <linux/vmalloc.h> #include <linux/sched.h> +#include <linux/smp_lock.h> #include <linux/ncp_fs.h> @@ -261,9 +262,9 @@ ncp_get_charsets(struct ncp_server* server, struct ncp_nls_ioctl __user *arg) } #endif /* CONFIG_NCPFS_NLS */ -static int __ncp_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +static long __ncp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { + struct inode *inode = filp->f_dentry->d_inode; struct ncp_server *server = NCP_SERVER(inode); int result; struct ncp_ioctl_request request; @@ -841,11 +842,11 @@ static int ncp_ioctl_need_write(unsigned int cmd) } } -int ncp_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +long ncp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { - int ret; + long ret; + lock_kernel(); if (ncp_ioctl_need_write(cmd)) { /* * inside the ioctl(), any failures which @@ -853,24 +854,28 @@ int ncp_ioctl(struct inode *inode, struct file *filp, * -EACCESS, so it seems consistent to keep * that here. */ - if (mnt_want_write(filp->f_path.mnt)) - return -EACCES; + if (mnt_want_write(filp->f_path.mnt)) { + ret = -EACCES; + goto out; + } } - ret = __ncp_ioctl(inode, filp, cmd, arg); + ret = __ncp_ioctl(filp, cmd, arg); if (ncp_ioctl_need_write(cmd)) mnt_drop_write(filp->f_path.mnt); + +out: + unlock_kernel(); return ret; } #ifdef CONFIG_COMPAT long ncp_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - struct inode *inode = file->f_path.dentry->d_inode; - int ret; + long ret; lock_kernel(); arg = (unsigned long) compat_ptr(arg); - ret = ncp_ioctl(inode, file, cmd, arg); + ret = ncp_ioctl(file, cmd, arg); unlock_kernel(); return ret; } diff --git a/fs/smbfs/dir.c b/fs/smbfs/dir.c index 3e4803b4427e..6c978428892d 100644 --- a/fs/smbfs/dir.c +++ b/fs/smbfs/dir.c @@ -39,7 +39,7 @@ const struct file_operations smb_dir_operations = { .read = generic_read_dir, .readdir = smb_readdir, - .ioctl = smb_ioctl, + .unlocked_ioctl = smb_ioctl, .open = smb_dir_open, }; diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c index dbf6548bbf06..84ecf0e43f91 100644 --- a/fs/smbfs/file.c +++ b/fs/smbfs/file.c @@ -437,7 +437,7 @@ const struct file_operations smb_file_operations = .aio_read = smb_file_aio_read, .write = do_sync_write, .aio_write = smb_file_aio_write, - .ioctl = smb_ioctl, + .unlocked_ioctl = smb_ioctl, .mmap = smb_file_mmap, .open = smb_file_open, .release = smb_file_release, diff --git a/fs/smbfs/ioctl.c b/fs/smbfs/ioctl.c index dbae1f8ea26f..07215312ad39 100644 --- a/fs/smbfs/ioctl.c +++ b/fs/smbfs/ioctl.c @@ -13,6 +13,7 @@ #include <linux/time.h> #include <linux/mm.h> #include <linux/highuid.h> +#include <linux/smp_lock.h> #include <linux/net.h> #include <linux/smb_fs.h> @@ -22,14 +23,14 @@ #include "proto.h" -int -smb_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +long +smb_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { - struct smb_sb_info *server = server_from_inode(inode); + struct smb_sb_info *server = server_from_inode(filp->f_path.dentry->d_inode); struct smb_conn_opt opt; int result = -EINVAL; + lock_kernel(); switch (cmd) { uid16_t uid16; uid_t uid32; @@ -62,6 +63,7 @@ smb_ioctl(struct inode *inode, struct file *filp, default: break; } + unlock_kernel(); return result; } diff --git a/fs/smbfs/proto.h b/fs/smbfs/proto.h index 03f456c1b7d4..05939a6f43e6 100644 --- a/fs/smbfs/proto.h +++ b/fs/smbfs/proto.h @@ -67,7 +67,7 @@ extern const struct address_space_operations smb_file_aops; extern const struct file_operations smb_file_operations; extern const struct inode_operations smb_file_inode_operations; /* ioctl.c */ -extern int smb_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); +extern long smb_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); /* smbiod.c */ extern void smbiod_wake_up(void); extern int smbiod_register_server(struct smb_sb_info *server); diff --git a/include/linux/ncp_fs.h b/include/linux/ncp_fs.h index 30b06c893944..4522aed00906 100644 --- a/include/linux/ncp_fs.h +++ b/include/linux/ncp_fs.h @@ -210,7 +210,7 @@ int ncp_date_dos2unix(__le16 time, __le16 date); void ncp_date_unix2dos(int unix_date, __le16 * time, __le16 * date); /* linux/fs/ncpfs/ioctl.c */ -int ncp_ioctl(struct inode *, struct file *, unsigned int, unsigned long); +long ncp_ioctl(struct file *, unsigned int, unsigned long); long ncp_compat_ioctl(struct file *, unsigned int, unsigned long); /* linux/fs/ncpfs/sock.c */ diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index c2173ebdb33c..58de76c8540c 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c @@ -34,6 +34,7 @@ #include <linux/sunrpc/cache.h> #include <linux/sunrpc/stats.h> #include <linux/sunrpc/rpc_pipe_fs.h> +#include <linux/smp_lock.h> #define RPCDBG_FACILITY RPCDBG_CACHE @@ -1545,12 +1546,18 @@ static unsigned int cache_poll_pipefs(struct file *filp, poll_table *wait) return cache_poll(filp, wait, cd); } -static int cache_ioctl_pipefs(struct inode *inode, struct file *filp, +static long cache_ioctl_pipefs(struct file *filp, unsigned int cmd, unsigned long arg) { + struct inode *inode = filp->f_dentry->d_inode; struct cache_detail *cd = RPC_I(inode)->private; + long ret; - return cache_ioctl(inode, filp, cmd, arg, cd); + lock_kernel(); + ret = cache_ioctl(inode, filp, cmd, arg, cd); + unlock_kernel(); + + return ret; } static int cache_open_pipefs(struct inode *inode, struct file *filp) @@ -1573,7 +1580,7 @@ const struct file_operations cache_file_operations_pipefs = { .read = cache_read_pipefs, .write = cache_write_pipefs, .poll = cache_poll_pipefs, - .ioctl = cache_ioctl_pipefs, /* for FIONREAD */ + .unlocked_ioctl = cache_ioctl_pipefs, /* for FIONREAD */ .open = cache_open_pipefs, .release = cache_release_pipefs, }; diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 20e30c6f8355..95ccbcf45d3e 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c @@ -27,6 +27,7 @@ #include <linux/workqueue.h> #include <linux/sunrpc/rpc_pipe_fs.h> #include <linux/sunrpc/cache.h> +#include <linux/smp_lock.h> static struct vfsmount *rpc_mount __read_mostly; static int rpc_mount_count; @@ -309,8 +310,7 @@ rpc_pipe_poll(struct file *filp, struct poll_table_struct *wait) } static int -rpc_pipe_ioctl(struct inode *ino, struct file *filp, - unsigned int cmd, unsigned long arg) +rpc_pipe_ioctl_unlocked(struct file *filp, unsigned int cmd, unsigned long arg) { struct rpc_inode *rpci = RPC_I(filp->f_path.dentry->d_inode); int len; @@ -331,13 +331,25 @@ rpc_pipe_ioctl(struct inode *ino, struct file *filp, } } +static long +rpc_pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + long ret; + + lock_kernel(); + ret = rpc_pipe_ioctl_unlocked(filp, cmd, arg); + unlock_kernel(); + + return ret; +} + static const struct file_operations rpc_pipe_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .read = rpc_pipe_read, .write = rpc_pipe_write, .poll = rpc_pipe_poll, - .ioctl = rpc_pipe_ioctl, + .unlocked_ioctl = rpc_pipe_ioctl, .open = rpc_pipe_open, .release = rpc_pipe_release, }; |