aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc')
-rw-r--r--fs/proc/array.c6
-rw-r--r--fs/proc/base.c16
-rw-r--r--fs/proc/generic.c38
-rw-r--r--fs/proc/kcore.c2
-rw-r--r--fs/proc/kmsg.c14
-rw-r--r--fs/proc/proc_devtree.c7
-rw-r--r--fs/proc/root.c6
-rw-r--r--fs/proc/task_mmu.c13
8 files changed, 59 insertions, 43 deletions
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 13b5d0708175..aa8637b81028 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -270,8 +270,10 @@ static inline void task_sig(struct seq_file *m, struct task_struct *p)
270 blocked = p->blocked; 270 blocked = p->blocked;
271 collect_sigign_sigcatch(p, &ignored, &caught); 271 collect_sigign_sigcatch(p, &ignored, &caught);
272 num_threads = atomic_read(&p->signal->count); 272 num_threads = atomic_read(&p->signal->count);
273 rcu_read_lock(); /* FIXME: is this correct? */
273 qsize = atomic_read(&__task_cred(p)->user->sigpending); 274 qsize = atomic_read(&__task_cred(p)->user->sigpending);
274 qlim = p->signal->rlim[RLIMIT_SIGPENDING].rlim_cur; 275 rcu_read_unlock();
276 qlim = task_rlimit(p, RLIMIT_SIGPENDING);
275 unlock_task_sighand(p, &flags); 277 unlock_task_sighand(p, &flags);
276 } 278 }
277 279
@@ -418,7 +420,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
418 cutime = sig->cutime; 420 cutime = sig->cutime;
419 cstime = sig->cstime; 421 cstime = sig->cstime;
420 cgtime = sig->cgtime; 422 cgtime = sig->cgtime;
421 rsslim = sig->rlim[RLIMIT_RSS].rlim_cur; 423 rsslim = ACCESS_ONCE(sig->rlim[RLIMIT_RSS].rlim_cur);
422 424
423 /* add up live thread stats at the group level */ 425 /* add up live thread stats at the group level */
424 if (whole) { 426 if (whole) {
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 58324c299165..a7310841c831 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -647,17 +647,11 @@ static int mounts_release(struct inode *inode, struct file *file)
647static unsigned mounts_poll(struct file *file, poll_table *wait) 647static unsigned mounts_poll(struct file *file, poll_table *wait)
648{ 648{
649 struct proc_mounts *p = file->private_data; 649 struct proc_mounts *p = file->private_data;
650 struct mnt_namespace *ns = p->ns;
651 unsigned res = POLLIN | POLLRDNORM; 650 unsigned res = POLLIN | POLLRDNORM;
652 651
653 poll_wait(file, &ns->poll, wait); 652 poll_wait(file, &p->ns->poll, wait);
654 653 if (mnt_had_events(p))
655 spin_lock(&vfsmount_lock);
656 if (p->event != ns->event) {
657 p->event = ns->event;
658 res |= POLLERR | POLLPRI; 654 res |= POLLERR | POLLPRI;
659 }
660 spin_unlock(&vfsmount_lock);
661 655
662 return res; 656 return res;
663} 657}
@@ -1095,8 +1089,12 @@ static ssize_t proc_loginuid_write(struct file * file, const char __user * buf,
1095 if (!capable(CAP_AUDIT_CONTROL)) 1089 if (!capable(CAP_AUDIT_CONTROL))
1096 return -EPERM; 1090 return -EPERM;
1097 1091
1098 if (current != pid_task(proc_pid(inode), PIDTYPE_PID)) 1092 rcu_read_lock();
1093 if (current != pid_task(proc_pid(inode), PIDTYPE_PID)) {
1094 rcu_read_unlock();
1099 return -EPERM; 1095 return -EPERM;
1096 }
1097 rcu_read_unlock();
1100 1098
1101 if (count >= PAGE_SIZE) 1099 if (count >= PAGE_SIZE)
1102 count = PAGE_SIZE - 1; 1100 count = PAGE_SIZE - 1;
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 480cb1065eec..08f4d71dacd7 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -291,19 +291,17 @@ static const struct inode_operations proc_file_inode_operations = {
291 * returns the struct proc_dir_entry for "/proc/tty/driver", and 291 * returns the struct proc_dir_entry for "/proc/tty/driver", and
292 * returns "serial" in residual. 292 * returns "serial" in residual.
293 */ 293 */
294static int xlate_proc_name(const char *name, 294static int __xlate_proc_name(const char *name, struct proc_dir_entry **ret,
295 struct proc_dir_entry **ret, const char **residual) 295 const char **residual)
296{ 296{
297 const char *cp = name, *next; 297 const char *cp = name, *next;
298 struct proc_dir_entry *de; 298 struct proc_dir_entry *de;
299 int len; 299 int len;
300 int rtn = 0;
301 300
302 de = *ret; 301 de = *ret;
303 if (!de) 302 if (!de)
304 de = &proc_root; 303 de = &proc_root;
305 304
306 spin_lock(&proc_subdir_lock);
307 while (1) { 305 while (1) {
308 next = strchr(cp, '/'); 306 next = strchr(cp, '/');
309 if (!next) 307 if (!next)
@@ -315,16 +313,25 @@ static int xlate_proc_name(const char *name,
315 break; 313 break;
316 } 314 }
317 if (!de) { 315 if (!de) {
318 rtn = -ENOENT; 316 WARN(1, "name '%s'\n", name);
319 goto out; 317 return -ENOENT;
320 } 318 }
321 cp += len + 1; 319 cp += len + 1;
322 } 320 }
323 *residual = cp; 321 *residual = cp;
324 *ret = de; 322 *ret = de;
325out: 323 return 0;
324}
325
326static int xlate_proc_name(const char *name, struct proc_dir_entry **ret,
327 const char **residual)
328{
329 int rv;
330
331 spin_lock(&proc_subdir_lock);
332 rv = __xlate_proc_name(name, ret, residual);
326 spin_unlock(&proc_subdir_lock); 333 spin_unlock(&proc_subdir_lock);
327 return rtn; 334 return rv;
328} 335}
329 336
330static DEFINE_IDA(proc_inum_ida); 337static DEFINE_IDA(proc_inum_ida);
@@ -662,6 +669,7 @@ struct proc_dir_entry *proc_symlink(const char *name,
662 } 669 }
663 return ent; 670 return ent;
664} 671}
672EXPORT_SYMBOL(proc_symlink);
665 673
666struct proc_dir_entry *proc_mkdir_mode(const char *name, mode_t mode, 674struct proc_dir_entry *proc_mkdir_mode(const char *name, mode_t mode,
667 struct proc_dir_entry *parent) 675 struct proc_dir_entry *parent)
@@ -700,6 +708,7 @@ struct proc_dir_entry *proc_mkdir(const char *name,
700{ 708{
701 return proc_mkdir_mode(name, S_IRUGO | S_IXUGO, parent); 709 return proc_mkdir_mode(name, S_IRUGO | S_IXUGO, parent);
702} 710}
711EXPORT_SYMBOL(proc_mkdir);
703 712
704struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode, 713struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
705 struct proc_dir_entry *parent) 714 struct proc_dir_entry *parent)
@@ -728,6 +737,7 @@ struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
728 } 737 }
729 return ent; 738 return ent;
730} 739}
740EXPORT_SYMBOL(create_proc_entry);
731 741
732struct proc_dir_entry *proc_create_data(const char *name, mode_t mode, 742struct proc_dir_entry *proc_create_data(const char *name, mode_t mode,
733 struct proc_dir_entry *parent, 743 struct proc_dir_entry *parent,
@@ -762,6 +772,7 @@ out_free:
762out: 772out:
763 return NULL; 773 return NULL;
764} 774}
775EXPORT_SYMBOL(proc_create_data);
765 776
766static void free_proc_entry(struct proc_dir_entry *de) 777static void free_proc_entry(struct proc_dir_entry *de)
767{ 778{
@@ -793,11 +804,13 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
793 const char *fn = name; 804 const char *fn = name;
794 int len; 805 int len;
795 806
796 if (xlate_proc_name(name, &parent, &fn) != 0) 807 spin_lock(&proc_subdir_lock);
808 if (__xlate_proc_name(name, &parent, &fn) != 0) {
809 spin_unlock(&proc_subdir_lock);
797 return; 810 return;
811 }
798 len = strlen(fn); 812 len = strlen(fn);
799 813
800 spin_lock(&proc_subdir_lock);
801 for (p = &parent->subdir; *p; p=&(*p)->next ) { 814 for (p = &parent->subdir; *p; p=&(*p)->next ) {
802 if (proc_match(len, fn, *p)) { 815 if (proc_match(len, fn, *p)) {
803 de = *p; 816 de = *p;
@@ -807,8 +820,10 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
807 } 820 }
808 } 821 }
809 spin_unlock(&proc_subdir_lock); 822 spin_unlock(&proc_subdir_lock);
810 if (!de) 823 if (!de) {
824 WARN(1, "name '%s'\n", name);
811 return; 825 return;
826 }
812 827
813 spin_lock(&de->pde_unload_lock); 828 spin_lock(&de->pde_unload_lock);
814 /* 829 /*
@@ -853,3 +868,4 @@ continue_removing:
853 de->parent->name, de->name, de->subdir->name); 868 de->parent->name, de->name, de->subdir->name);
854 pde_put(de); 869 pde_put(de);
855} 870}
871EXPORT_SYMBOL(remove_proc_entry);
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
index a44a7897fd4d..b442dac8f5f9 100644
--- a/fs/proc/kcore.c
+++ b/fs/proc/kcore.c
@@ -490,7 +490,7 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos)
490 } 490 }
491 read_unlock(&kclist_lock); 491 read_unlock(&kclist_lock);
492 492
493 if (m == NULL) { 493 if (&m->list == &kclist_head) {
494 if (clear_user(buffer, tsz)) 494 if (clear_user(buffer, tsz))
495 return -EFAULT; 495 return -EFAULT;
496 } else if (is_vmalloc_or_module_addr((void *)start)) { 496 } else if (is_vmalloc_or_module_addr((void *)start)) {
diff --git a/fs/proc/kmsg.c b/fs/proc/kmsg.c
index 7ca78346d3f0..cfe90a48a6e8 100644
--- a/fs/proc/kmsg.c
+++ b/fs/proc/kmsg.c
@@ -12,37 +12,37 @@
12#include <linux/poll.h> 12#include <linux/poll.h>
13#include <linux/proc_fs.h> 13#include <linux/proc_fs.h>
14#include <linux/fs.h> 14#include <linux/fs.h>
15#include <linux/syslog.h>
15 16
16#include <asm/uaccess.h> 17#include <asm/uaccess.h>
17#include <asm/io.h> 18#include <asm/io.h>
18 19
19extern wait_queue_head_t log_wait; 20extern wait_queue_head_t log_wait;
20 21
21extern int do_syslog(int type, char __user *bug, int count);
22
23static int kmsg_open(struct inode * inode, struct file * file) 22static int kmsg_open(struct inode * inode, struct file * file)
24{ 23{
25 return do_syslog(1,NULL,0); 24 return do_syslog(SYSLOG_ACTION_OPEN, NULL, 0, SYSLOG_FROM_FILE);
26} 25}
27 26
28static int kmsg_release(struct inode * inode, struct file * file) 27static int kmsg_release(struct inode * inode, struct file * file)
29{ 28{
30 (void) do_syslog(0,NULL,0); 29 (void) do_syslog(SYSLOG_ACTION_CLOSE, NULL, 0, SYSLOG_FROM_FILE);
31 return 0; 30 return 0;
32} 31}
33 32
34static ssize_t kmsg_read(struct file *file, char __user *buf, 33static ssize_t kmsg_read(struct file *file, char __user *buf,
35 size_t count, loff_t *ppos) 34 size_t count, loff_t *ppos)
36{ 35{
37 if ((file->f_flags & O_NONBLOCK) && !do_syslog(9, NULL, 0)) 36 if ((file->f_flags & O_NONBLOCK) &&
37 !do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_FILE))
38 return -EAGAIN; 38 return -EAGAIN;
39 return do_syslog(2, buf, count); 39 return do_syslog(SYSLOG_ACTION_READ, buf, count, SYSLOG_FROM_FILE);
40} 40}
41 41
42static unsigned int kmsg_poll(struct file *file, poll_table *wait) 42static unsigned int kmsg_poll(struct file *file, poll_table *wait)
43{ 43{
44 poll_wait(file, &log_wait, wait); 44 poll_wait(file, &log_wait, wait);
45 if (do_syslog(9, NULL, 0)) 45 if (do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_FILE))
46 return POLLIN | POLLRDNORM; 46 return POLLIN | POLLRDNORM;
47 return 0; 47 return 0;
48} 48}
diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c
index 123257bb356b..f8650dce74fb 100644
--- a/fs/proc/proc_devtree.c
+++ b/fs/proc/proc_devtree.c
@@ -10,16 +10,19 @@
10#include <linux/seq_file.h> 10#include <linux/seq_file.h>
11#include <linux/stat.h> 11#include <linux/stat.h>
12#include <linux/string.h> 12#include <linux/string.h>
13#include <linux/of.h>
14#include <linux/module.h>
13#include <asm/prom.h> 15#include <asm/prom.h>
14#include <asm/uaccess.h> 16#include <asm/uaccess.h>
15#include "internal.h" 17#include "internal.h"
16 18
17#ifndef HAVE_ARCH_DEVTREE_FIXUPS
18static inline void set_node_proc_entry(struct device_node *np, 19static inline void set_node_proc_entry(struct device_node *np,
19 struct proc_dir_entry *de) 20 struct proc_dir_entry *de)
20{ 21{
21} 22#ifdef HAVE_ARCH_DEVTREE_FIXUPS
23 np->pde = de;
22#endif 24#endif
25}
23 26
24static struct proc_dir_entry *proc_device_tree; 27static struct proc_dir_entry *proc_device_tree;
25 28
diff --git a/fs/proc/root.c b/fs/proc/root.c
index b080b791d9e3..757c069f2a65 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -220,9 +220,3 @@ void pid_ns_release_proc(struct pid_namespace *ns)
220{ 220{
221 mntput(ns->proc_mnt); 221 mntput(ns->proc_mnt);
222} 222}
223
224EXPORT_SYMBOL(proc_symlink);
225EXPORT_SYMBOL(proc_mkdir);
226EXPORT_SYMBOL(create_proc_entry);
227EXPORT_SYMBOL(proc_create_data);
228EXPORT_SYMBOL(remove_proc_entry);
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index f277c4a111cb..183f8ff5f400 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -16,7 +16,7 @@
16 16
17void task_mem(struct seq_file *m, struct mm_struct *mm) 17void task_mem(struct seq_file *m, struct mm_struct *mm)
18{ 18{
19 unsigned long data, text, lib; 19 unsigned long data, text, lib, swap;
20 unsigned long hiwater_vm, total_vm, hiwater_rss, total_rss; 20 unsigned long hiwater_vm, total_vm, hiwater_rss, total_rss;
21 21
22 /* 22 /*
@@ -36,6 +36,7 @@ void task_mem(struct seq_file *m, struct mm_struct *mm)
36 data = mm->total_vm - mm->shared_vm - mm->stack_vm; 36 data = mm->total_vm - mm->shared_vm - mm->stack_vm;
37 text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) >> 10; 37 text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) >> 10;
38 lib = (mm->exec_vm << (PAGE_SHIFT-10)) - text; 38 lib = (mm->exec_vm << (PAGE_SHIFT-10)) - text;
39 swap = get_mm_counter(mm, MM_SWAPENTS);
39 seq_printf(m, 40 seq_printf(m,
40 "VmPeak:\t%8lu kB\n" 41 "VmPeak:\t%8lu kB\n"
41 "VmSize:\t%8lu kB\n" 42 "VmSize:\t%8lu kB\n"
@@ -46,7 +47,8 @@ void task_mem(struct seq_file *m, struct mm_struct *mm)
46 "VmStk:\t%8lu kB\n" 47 "VmStk:\t%8lu kB\n"
47 "VmExe:\t%8lu kB\n" 48 "VmExe:\t%8lu kB\n"
48 "VmLib:\t%8lu kB\n" 49 "VmLib:\t%8lu kB\n"
49 "VmPTE:\t%8lu kB\n", 50 "VmPTE:\t%8lu kB\n"
51 "VmSwap:\t%8lu kB\n",
50 hiwater_vm << (PAGE_SHIFT-10), 52 hiwater_vm << (PAGE_SHIFT-10),
51 (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10), 53 (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
52 mm->locked_vm << (PAGE_SHIFT-10), 54 mm->locked_vm << (PAGE_SHIFT-10),
@@ -54,7 +56,8 @@ void task_mem(struct seq_file *m, struct mm_struct *mm)
54 total_rss << (PAGE_SHIFT-10), 56 total_rss << (PAGE_SHIFT-10),
55 data << (PAGE_SHIFT-10), 57 data << (PAGE_SHIFT-10),
56 mm->stack_vm << (PAGE_SHIFT-10), text, lib, 58 mm->stack_vm << (PAGE_SHIFT-10), text, lib,
57 (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10); 59 (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10,
60 swap << (PAGE_SHIFT-10));
58} 61}
59 62
60unsigned long task_vsize(struct mm_struct *mm) 63unsigned long task_vsize(struct mm_struct *mm)
@@ -65,11 +68,11 @@ unsigned long task_vsize(struct mm_struct *mm)
65int task_statm(struct mm_struct *mm, int *shared, int *text, 68int task_statm(struct mm_struct *mm, int *shared, int *text,
66 int *data, int *resident) 69 int *data, int *resident)
67{ 70{
68 *shared = get_mm_counter(mm, file_rss); 71 *shared = get_mm_counter(mm, MM_FILEPAGES);
69 *text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) 72 *text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK))
70 >> PAGE_SHIFT; 73 >> PAGE_SHIFT;
71 *data = mm->total_vm - mm->shared_vm; 74 *data = mm->total_vm - mm->shared_vm;
72 *resident = *shared + get_mm_counter(mm, anon_rss); 75 *resident = *shared + get_mm_counter(mm, MM_ANONPAGES);
73 return mm->total_vm; 76 return mm->total_vm;
74} 77}
75 78