diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2010-04-15 14:02:56 +1000 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2010-04-15 14:02:56 +1000 |
commit | 9eb91f8b24d50eaad2534aef99aa19520305483d (patch) | |
tree | 496348ee60c5802951a7aa4fe3bd13a9ac5aa7fd | |
parent | 6b2fce1ab75a8ae81f2b48409b41c3faead8ab6a (diff) | |
parent | d48af88be21a0f1e3217cda95e820aed88ae0bcb (diff) |
Merge remote branch 'bkl-procfs/bkl/procfs'
-rw-r--r-- | drivers/char/i8k.c | 53 | ||||
-rw-r--r-- | drivers/isdn/divert/divert_procfs.c | 90 | ||||
-rw-r--r-- | fs/proc/base.c | 10 | ||||
-rw-r--r-- | fs/proc/inode.c | 4 | ||||
-rw-r--r-- | fs/proc/kcore.c | 1 | ||||
-rw-r--r-- | fs/proc/kmsg.c | 1 | ||||
-rw-r--r-- | fs/proc/vmcore.c | 1 | ||||
-rw-r--r-- | net/sunrpc/cache.c | 18 |
8 files changed, 122 insertions, 56 deletions
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c index fc8cf7ac7f2b..85f8893ca08a 100644 --- a/drivers/char/i8k.c +++ b/drivers/char/i8k.c @@ -23,6 +23,7 @@ #include <linux/seq_file.h> #include <linux/dmi.h> #include <linux/capability.h> +#include <linux/smp_lock.h> #include <asm/uaccess.h> #include <asm/io.h> @@ -82,8 +83,7 @@ module_param(fan_mult, int, 0); MODULE_PARM_DESC(fan_mult, "Factor to multiply fan speed with"); static int i8k_open_fs(struct inode *inode, struct file *file); -static int i8k_ioctl(struct inode *, struct file *, unsigned int, - unsigned long); +static long i8k_ioctl(struct file *, unsigned int, unsigned long); static const struct file_operations i8k_fops = { .owner = THIS_MODULE, @@ -91,7 +91,7 @@ static const struct file_operations i8k_fops = { .read = seq_read, .llseek = seq_lseek, .release = single_release, - .ioctl = i8k_ioctl, + .unlocked_ioctl = i8k_ioctl, }; struct smm_regs { @@ -307,8 +307,7 @@ static int i8k_get_dell_signature(int req_fn) return regs.eax == 1145651527 && regs.edx == 1145392204 ? 0 : -1; } -static int i8k_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, - unsigned long arg) +static long i8k_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) { int val = 0; int speed; @@ -318,6 +317,9 @@ static int i8k_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, if (!argp) return -EINVAL; + /* Pushed down from procfs ioctl handler */ + lock_kernel(); + switch (cmd) { case I8K_BIOS_VERSION: val = i8k_get_bios_version(); @@ -341,57 +343,78 @@ static int i8k_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, break; case I8K_GET_SPEED: - if (copy_from_user(&val, argp, sizeof(int))) + if (copy_from_user(&val, argp, sizeof(int))) { + unlock_kernel(); return -EFAULT; + } val = i8k_get_fan_speed(val); break; case I8K_GET_FAN: - if (copy_from_user(&val, argp, sizeof(int))) + if (copy_from_user(&val, argp, sizeof(int))) { + unlock_kernel(); return -EFAULT; + } val = i8k_get_fan_status(val); break; case I8K_SET_FAN: - if (restricted && !capable(CAP_SYS_ADMIN)) + if (restricted && !capable(CAP_SYS_ADMIN)) { + unlock_kernel(); return -EPERM; + } - if (copy_from_user(&val, argp, sizeof(int))) + if (copy_from_user(&val, argp, sizeof(int))) { + unlock_kernel(); return -EFAULT; + } - if (copy_from_user(&speed, argp + 1, sizeof(int))) + if (copy_from_user(&speed, argp + 1, sizeof(int))) { + unlock_kernel(); return -EFAULT; + } val = i8k_set_fan(val, speed); break; default: + unlock_kernel(); return -EINVAL; } - if (val < 0) - return val; + if (val < 0) { + unlock_kernel(); + return -val; + } switch (cmd) { case I8K_BIOS_VERSION: - if (copy_to_user(argp, &val, 4)) + if (copy_to_user(argp, &val, 4)) { + unlock_kernel(); return -EFAULT; + } break; case I8K_MACHINE_ID: - if (copy_to_user(argp, buff, 16)) + if (copy_to_user(argp, buff, 16)) { + unlock_kernel(); return -EFAULT; + } break; default: - if (copy_to_user(argp, &val, sizeof(int))) + if (copy_to_user(argp, &val, sizeof(int))) { + unlock_kernel(); return -EFAULT; + } break; } + unlock_kernel(); + return 0; } diff --git a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c index 9f49d9065791..ec595cf4ce6b 100644 --- a/drivers/isdn/divert/divert_procfs.c +++ b/drivers/isdn/divert/divert_procfs.c @@ -20,6 +20,7 @@ #include <linux/sched.h> #include <linux/isdnif.h> #include <net/net_namespace.h> +#include <linux/smp_lock.h> #include "isdn_divert.h" @@ -177,18 +178,20 @@ isdn_divert_close(struct inode *ino, struct file *filep) /*********/ /* IOCTL */ /*********/ -static int -isdn_divert_ioctl(struct inode *inode, struct file *file, - uint cmd, ulong arg) +static long isdn_divert_ioctl(struct file *file, uint cmd, ulong arg) { divert_ioctl dioctl; - int i; unsigned long flags; divert_rule *rulep; char *cp; - if (copy_from_user(&dioctl, (void __user *) arg, sizeof(dioctl))) + /* Pushed down from procfs ioctl handler */ + lock_kernel(); + + if (copy_from_user(&dioctl, (void __user *) arg, sizeof(dioctl))) { + unlock_kernel(); return -EFAULT; + } switch (cmd) { case IIOCGETVER: @@ -196,65 +199,84 @@ isdn_divert_ioctl(struct inode *inode, struct file *file, break; case IIOCGETDRV: - if ((dioctl.getid.drvid = divert_if.name_to_drv(dioctl.getid.drvnam)) < 0) - return (-EINVAL); + if ((dioctl.getid.drvid = divert_if.name_to_drv(dioctl.getid.drvnam)) < 0) { + unlock_kernel(); + return -EINVAL; + } break; case IIOCGETNAM: cp = divert_if.drv_to_name(dioctl.getid.drvid); - if (!cp) - return (-EINVAL); - if (!*cp) - return (-EINVAL); + if (!cp || !*cp) { + unlock_kernel(); + return -EINVAL; + } strcpy(dioctl.getid.drvnam, cp); break; case IIOCGETRULE: - if (!(rulep = getruleptr(dioctl.getsetrule.ruleidx))) - return (-EINVAL); + if (!(rulep = getruleptr(dioctl.getsetrule.ruleidx))) { + unlock_kernel(); + return -EINVAL; + } dioctl.getsetrule.rule = *rulep; /* copy data */ break; case IIOCMODRULE: - if (!(rulep = getruleptr(dioctl.getsetrule.ruleidx))) - return (-EINVAL); - spin_lock_irqsave(&divert_lock, flags); + if (!(rulep = getruleptr(dioctl.getsetrule.ruleidx))) { + unlock_kernel(); + return -EINVAL; + } + spin_lock_irqsave(&divert_lock, flags); *rulep = dioctl.getsetrule.rule; /* copy data */ spin_unlock_irqrestore(&divert_lock, flags); - return (0); /* no copy required */ - break; + + unlock_kernel(); + return 0; /* no copy required */ case IIOCINSRULE: - return (insertrule(dioctl.getsetrule.ruleidx, &dioctl.getsetrule.rule)); - break; + unlock_kernel(); + return insertrule(dioctl.getsetrule.ruleidx, &dioctl.getsetrule.rule); case IIOCDELRULE: - return (deleterule(dioctl.getsetrule.ruleidx)); - break; + unlock_kernel(); + return deleterule(dioctl.getsetrule.ruleidx); case IIOCDODFACT: - return (deflect_extern_action(dioctl.fwd_ctrl.subcmd, - dioctl.fwd_ctrl.callid, - dioctl.fwd_ctrl.to_nr)); + unlock_kernel(); + return deflect_extern_action(dioctl.fwd_ctrl.subcmd, + dioctl.fwd_ctrl.callid, + dioctl.fwd_ctrl.to_nr); case IIOCDOCFACT: case IIOCDOCFDIS: - case IIOCDOCFINT: - if (!divert_if.drv_to_name(dioctl.cf_ctrl.drvid)) - return (-EINVAL); /* invalid driver */ - if ((i = cf_command(dioctl.cf_ctrl.drvid, + case IIOCDOCFINT: { + long err; + + if (!divert_if.drv_to_name(dioctl.cf_ctrl.drvid)) { + unlock_kernel(); + return -EINVAL; /* invalid driver */ + } + err = cf_command(dioctl.cf_ctrl.drvid, (cmd == IIOCDOCFACT) ? 1 : (cmd == IIOCDOCFDIS) ? 0 : 2, dioctl.cf_ctrl.cfproc, dioctl.cf_ctrl.msn, dioctl.cf_ctrl.service, dioctl.cf_ctrl.fwd_nr, - &dioctl.cf_ctrl.procid))) - return (i); + &dioctl.cf_ctrl.procid); + if (err) { + unlock_kernel(); + return err; + } break; + } default: - return (-EINVAL); - } /* switch cmd */ + unlock_kernel(); + return -EINVAL; + } + + unlock_kernel(); return copy_to_user((void __user *)arg, &dioctl, sizeof(dioctl)) ? -EFAULT : 0; } /* isdn_divert_ioctl */ @@ -265,7 +287,7 @@ static const struct file_operations isdn_fops = .read = isdn_divert_read, .write = isdn_divert_write, .poll = isdn_divert_poll, - .ioctl = isdn_divert_ioctl, + .unlocked_ioctl = isdn_divert_ioctl, .open = isdn_divert_open, .release = isdn_divert_close, }; diff --git a/fs/proc/base.c b/fs/proc/base.c index 7621db800a74..aab4f34ba883 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -730,6 +730,7 @@ out_no_task: static const struct file_operations proc_info_file_operations = { .read = proc_info_read, + .llseek = generic_file_llseek, }; static int proc_single_show(struct seq_file *m, void *v) @@ -987,6 +988,7 @@ out_no_task: static const struct file_operations proc_environ_operations = { .read = environ_read, + .llseek = generic_file_llseek, }; static ssize_t oom_adjust_read(struct file *file, char __user *buf, @@ -1060,6 +1062,7 @@ static ssize_t oom_adjust_write(struct file *file, const char __user *buf, static const struct file_operations proc_oom_adjust_operations = { .read = oom_adjust_read, .write = oom_adjust_write, + .llseek = generic_file_llseek, }; #ifdef CONFIG_AUDITSYSCALL @@ -1131,6 +1134,7 @@ out_free_page: static const struct file_operations proc_loginuid_operations = { .read = proc_loginuid_read, .write = proc_loginuid_write, + .llseek = generic_file_llseek, }; static ssize_t proc_sessionid_read(struct file * file, char __user * buf, @@ -1151,6 +1155,7 @@ static ssize_t proc_sessionid_read(struct file * file, char __user * buf, static const struct file_operations proc_sessionid_operations = { .read = proc_sessionid_read, + .llseek = generic_file_llseek, }; #endif @@ -1202,6 +1207,7 @@ static ssize_t proc_fault_inject_write(struct file * file, static const struct file_operations proc_fault_inject_operations = { .read = proc_fault_inject_read, .write = proc_fault_inject_write, + .llseek = generic_file_llseek, }; #endif @@ -1943,7 +1949,7 @@ static ssize_t proc_fdinfo_read(struct file *file, char __user *buf, } static const struct file_operations proc_fdinfo_file_operations = { - .open = nonseekable_open, + .open = nonseekable_open, .read = proc_fdinfo_read, }; @@ -2227,6 +2233,7 @@ out_no_task: static const struct file_operations proc_pid_attr_operations = { .read = proc_pid_attr_read, .write = proc_pid_attr_write, + .llseek = generic_file_llseek, }; static const struct pid_entry attr_dir_stuff[] = { @@ -2347,6 +2354,7 @@ static ssize_t proc_coredump_filter_write(struct file *file, static const struct file_operations proc_coredump_filter_operations = { .read = proc_coredump_filter_read, .write = proc_coredump_filter_write, + .llseek = generic_file_llseek, }; #endif diff --git a/fs/proc/inode.c b/fs/proc/inode.c index d35b23238fb1..aea8502e58a3 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c @@ -232,9 +232,9 @@ static long proc_reg_unlocked_ioctl(struct file *file, unsigned int cmd, unsigne if (rv == -ENOIOCTLCMD) rv = -EINVAL; } else if (ioctl) { - lock_kernel(); + WARN_ONCE(1, "Procfs ioctl handlers must use unlocked_ioctl, " + "%pf will be called without the Bkl held\n", ioctl); rv = ioctl(file->f_path.dentry->d_inode, file, cmd, arg); - unlock_kernel(); } pde_users_dec(pde); diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index 19979a2ce272..c837a77351be 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c @@ -558,6 +558,7 @@ static int open_kcore(struct inode *inode, struct file *filp) static const struct file_operations proc_kcore_operations = { .read = read_kcore, .open = open_kcore, + .llseek = generic_file_llseek, }; #ifdef CONFIG_MEMORY_HOTPLUG diff --git a/fs/proc/kmsg.c b/fs/proc/kmsg.c index cfe90a48a6e8..bd4b5a740ff1 100644 --- a/fs/proc/kmsg.c +++ b/fs/proc/kmsg.c @@ -53,6 +53,7 @@ static const struct file_operations proc_kmsg_operations = { .poll = kmsg_poll, .open = kmsg_open, .release = kmsg_release, + .llseek = generic_file_llseek, }; static int __init proc_kmsg_init(void) diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c index 9fbc99ec799a..91c817ff02c3 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c @@ -163,6 +163,7 @@ static ssize_t read_vmcore(struct file *file, char __user *buffer, static const struct file_operations proc_vmcore_operations = { .read = read_vmcore, + .llseek = generic_file_llseek, }; static struct vmcore* __init get_new_element(void) diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index a3f340c8b79a..7170635687ab 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c @@ -28,6 +28,7 @@ #include <linux/workqueue.h> #include <linux/mutex.h> #include <linux/pagemap.h> +#include <linux/smp_lock.h> #include <asm/ioctls.h> #include <linux/sunrpc/types.h> #include <linux/sunrpc/cache.h> @@ -1344,12 +1345,21 @@ static unsigned int cache_poll_procfs(struct file *filp, poll_table *wait) return cache_poll(filp, wait, cd); } -static int cache_ioctl_procfs(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +static long cache_ioctl_procfs(struct file *filp, + unsigned int cmd, unsigned long arg) { + long ret; + struct inode *inode = filp->f_path.dentry->d_inode; struct cache_detail *cd = PDE(inode)->data; - return cache_ioctl(inode, filp, cmd, arg, cd); + /* Pushed down from procfs ioctl handler */ + lock_kernel(); + + ret = cache_ioctl(inode, filp, cmd, arg, cd); + + unlock_kernel(); + + return ret; } static int cache_open_procfs(struct inode *inode, struct file *filp) @@ -1372,7 +1382,7 @@ static const struct file_operations cache_file_operations_procfs = { .read = cache_read_procfs, .write = cache_write_procfs, .poll = cache_poll_procfs, - .ioctl = cache_ioctl_procfs, /* for FIONREAD */ + .unlocked_ioctl = cache_ioctl_procfs, /* for FIONREAD */ .open = cache_open_procfs, .release = cache_release_procfs, }; |