aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-06-04 13:00:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-04 13:00:01 -0400
commitcf626b0da78df6669c6b5f51ddd9a70a0702e579 (patch)
tree45d29a4cb7574aed7f140814ed22088ded21c291 /fs/proc
parent9c50eafc32ddbd166c8a2bbaecd4ad201c452b14 (diff)
parent5ef03dbd91855544cd4c7c1910c3ef5226ee87e8 (diff)
Merge branch 'hch.procfs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull procfs updates from Al Viro: "Christoph's proc_create_... cleanups series" * 'hch.procfs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (44 commits) xfs, proc: hide unused xfs procfs helpers isdn/gigaset: add back gigaset_procinfo assignment proc: update SIZEOF_PDE_INLINE_NAME for the new pde fields tty: replace ->proc_fops with ->proc_show ide: replace ->proc_fops with ->proc_show ide: remove ide_driver_proc_write isdn: replace ->proc_fops with ->proc_show atm: switch to proc_create_seq_private atm: simplify procfs code bluetooth: switch to proc_create_seq_data netfilter/x_tables: switch to proc_create_seq_private netfilter/xt_hashlimit: switch to proc_create_{seq,single}_data neigh: switch to proc_create_seq_data hostap: switch to proc_create_{seq,single}_data bonding: switch to proc_create_seq_data rtc/proc: switch to proc_create_single_data drbd: switch to proc_create_single resource: switch to proc_create_seq_data staging/rtl8192u: simplify procfs code jfs: simplify procfs code ...
Diffstat (limited to 'fs/proc')
-rw-r--r--fs/proc/array.c23
-rw-r--r--fs/proc/base.c18
-rw-r--r--fs/proc/cmdline.c14
-rw-r--r--fs/proc/consoles.c14
-rw-r--r--fs/proc/devices.c14
-rw-r--r--fs/proc/generic.c148
-rw-r--r--fs/proc/internal.h13
-rw-r--r--fs/proc/interrupts.c14
-rw-r--r--fs/proc/loadavg.c14
-rw-r--r--fs/proc/meminfo.c14
-rw-r--r--fs/proc/nommu.c14
-rw-r--r--fs/proc/proc_net.c104
-rw-r--r--fs/proc/proc_tty.c22
-rw-r--r--fs/proc/self.c4
-rw-r--r--fs/proc/softirqs.c14
-rw-r--r--fs/proc/thread_self.c4
-rw-r--r--fs/proc/uptime.c14
-rw-r--r--fs/proc/version.c14
18 files changed, 215 insertions, 261 deletions
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 72391b3f6927..e6d7f41b6684 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -702,25 +702,22 @@ out:
702 702
703static int children_seq_show(struct seq_file *seq, void *v) 703static int children_seq_show(struct seq_file *seq, void *v)
704{ 704{
705 struct inode *inode = seq->private; 705 struct inode *inode = file_inode(seq->file);
706 pid_t pid;
707
708 pid = pid_nr_ns(v, inode->i_sb->s_fs_info);
709 seq_printf(seq, "%d ", pid);
710 706
707 seq_printf(seq, "%d ", pid_nr_ns(v, proc_pid_ns(inode)));
711 return 0; 708 return 0;
712} 709}
713 710
714static void *children_seq_start(struct seq_file *seq, loff_t *pos) 711static void *children_seq_start(struct seq_file *seq, loff_t *pos)
715{ 712{
716 return get_children_pid(seq->private, NULL, *pos); 713 return get_children_pid(file_inode(seq->file), NULL, *pos);
717} 714}
718 715
719static void *children_seq_next(struct seq_file *seq, void *v, loff_t *pos) 716static void *children_seq_next(struct seq_file *seq, void *v, loff_t *pos)
720{ 717{
721 struct pid *pid; 718 struct pid *pid;
722 719
723 pid = get_children_pid(seq->private, v, *pos + 1); 720 pid = get_children_pid(file_inode(seq->file), v, *pos + 1);
724 put_pid(v); 721 put_pid(v);
725 722
726 ++*pos; 723 ++*pos;
@@ -741,17 +738,7 @@ static const struct seq_operations children_seq_ops = {
741 738
742static int children_seq_open(struct inode *inode, struct file *file) 739static int children_seq_open(struct inode *inode, struct file *file)
743{ 740{
744 struct seq_file *m; 741 return seq_open(file, &children_seq_ops);
745 int ret;
746
747 ret = seq_open(file, &children_seq_ops);
748 if (ret)
749 return ret;
750
751 m = file->private_data;
752 m->private = inode;
753
754 return ret;
755} 742}
756 743
757const struct file_operations proc_tid_children_operations = { 744const struct file_operations proc_tid_children_operations = {
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 1a76d751cf3c..4e35593546b1 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -698,7 +698,7 @@ static bool has_pid_permissions(struct pid_namespace *pid,
698 698
699static int proc_pid_permission(struct inode *inode, int mask) 699static int proc_pid_permission(struct inode *inode, int mask)
700{ 700{
701 struct pid_namespace *pid = inode->i_sb->s_fs_info; 701 struct pid_namespace *pid = proc_pid_ns(inode);
702 struct task_struct *task; 702 struct task_struct *task;
703 bool has_perms; 703 bool has_perms;
704 704
@@ -733,13 +733,11 @@ static const struct inode_operations proc_def_inode_operations = {
733static int proc_single_show(struct seq_file *m, void *v) 733static int proc_single_show(struct seq_file *m, void *v)
734{ 734{
735 struct inode *inode = m->private; 735 struct inode *inode = m->private;
736 struct pid_namespace *ns; 736 struct pid_namespace *ns = proc_pid_ns(inode);
737 struct pid *pid; 737 struct pid *pid = proc_pid(inode);
738 struct task_struct *task; 738 struct task_struct *task;
739 int ret; 739 int ret;
740 740
741 ns = inode->i_sb->s_fs_info;
742 pid = proc_pid(inode);
743 task = get_pid_task(pid, PIDTYPE_PID); 741 task = get_pid_task(pid, PIDTYPE_PID);
744 if (!task) 742 if (!task)
745 return -ESRCH; 743 return -ESRCH;
@@ -1410,7 +1408,7 @@ static const struct file_operations proc_fail_nth_operations = {
1410static int sched_show(struct seq_file *m, void *v) 1408static int sched_show(struct seq_file *m, void *v)
1411{ 1409{
1412 struct inode *inode = m->private; 1410 struct inode *inode = m->private;
1413 struct pid_namespace *ns = inode->i_sb->s_fs_info; 1411 struct pid_namespace *ns = proc_pid_ns(inode);
1414 struct task_struct *p; 1412 struct task_struct *p;
1415 1413
1416 p = get_proc_task(inode); 1414 p = get_proc_task(inode);
@@ -1782,8 +1780,8 @@ int pid_getattr(const struct path *path, struct kstat *stat,
1782 u32 request_mask, unsigned int query_flags) 1780 u32 request_mask, unsigned int query_flags)
1783{ 1781{
1784 struct inode *inode = d_inode(path->dentry); 1782 struct inode *inode = d_inode(path->dentry);
1783 struct pid_namespace *pid = proc_pid_ns(inode);
1785 struct task_struct *task; 1784 struct task_struct *task;
1786 struct pid_namespace *pid = path->dentry->d_sb->s_fs_info;
1787 1785
1788 generic_fillattr(inode, stat); 1786 generic_fillattr(inode, stat);
1789 1787
@@ -2337,7 +2335,7 @@ static int proc_timers_open(struct inode *inode, struct file *file)
2337 return -ENOMEM; 2335 return -ENOMEM;
2338 2336
2339 tp->pid = proc_pid(inode); 2337 tp->pid = proc_pid(inode);
2340 tp->ns = inode->i_sb->s_fs_info; 2338 tp->ns = proc_pid_ns(inode);
2341 return 0; 2339 return 0;
2342} 2340}
2343 2341
@@ -3239,7 +3237,7 @@ retry:
3239int proc_pid_readdir(struct file *file, struct dir_context *ctx) 3237int proc_pid_readdir(struct file *file, struct dir_context *ctx)
3240{ 3238{
3241 struct tgid_iter iter; 3239 struct tgid_iter iter;
3242 struct pid_namespace *ns = file_inode(file)->i_sb->s_fs_info; 3240 struct pid_namespace *ns = proc_pid_ns(file_inode(file));
3243 loff_t pos = ctx->pos; 3241 loff_t pos = ctx->pos;
3244 3242
3245 if (pos >= PID_MAX_LIMIT + TGID_OFFSET) 3243 if (pos >= PID_MAX_LIMIT + TGID_OFFSET)
@@ -3588,7 +3586,7 @@ static int proc_task_readdir(struct file *file, struct dir_context *ctx)
3588 /* f_version caches the tgid value that the last readdir call couldn't 3586 /* f_version caches the tgid value that the last readdir call couldn't
3589 * return. lseek aka telldir automagically resets f_version to 0. 3587 * return. lseek aka telldir automagically resets f_version to 0.
3590 */ 3588 */
3591 ns = inode->i_sb->s_fs_info; 3589 ns = proc_pid_ns(inode);
3592 tid = (int)file->f_version; 3590 tid = (int)file->f_version;
3593 file->f_version = 0; 3591 file->f_version = 0;
3594 for (task = first_tid(proc_pid(inode), tid, ctx->pos - 2, ns); 3592 for (task = first_tid(proc_pid(inode), tid, ctx->pos - 2, ns);
diff --git a/fs/proc/cmdline.c b/fs/proc/cmdline.c
index 8233e7af9389..fa762c5fbcb2 100644
--- a/fs/proc/cmdline.c
+++ b/fs/proc/cmdline.c
@@ -11,21 +11,9 @@ static int cmdline_proc_show(struct seq_file *m, void *v)
11 return 0; 11 return 0;
12} 12}
13 13
14static int cmdline_proc_open(struct inode *inode, struct file *file)
15{
16 return single_open(file, cmdline_proc_show, NULL);
17}
18
19static const struct file_operations cmdline_proc_fops = {
20 .open = cmdline_proc_open,
21 .read = seq_read,
22 .llseek = seq_lseek,
23 .release = single_release,
24};
25
26static int __init proc_cmdline_init(void) 14static int __init proc_cmdline_init(void)
27{ 15{
28 proc_create("cmdline", 0, NULL, &cmdline_proc_fops); 16 proc_create_single("cmdline", 0, NULL, cmdline_proc_show);
29 return 0; 17 return 0;
30} 18}
31fs_initcall(proc_cmdline_init); 19fs_initcall(proc_cmdline_init);
diff --git a/fs/proc/consoles.c b/fs/proc/consoles.c
index a8ac48aebd59..954caf0b7fee 100644
--- a/fs/proc/consoles.c
+++ b/fs/proc/consoles.c
@@ -91,21 +91,9 @@ static const struct seq_operations consoles_op = {
91 .show = show_console_dev 91 .show = show_console_dev
92}; 92};
93 93
94static int consoles_open(struct inode *inode, struct file *file)
95{
96 return seq_open(file, &consoles_op);
97}
98
99static const struct file_operations proc_consoles_operations = {
100 .open = consoles_open,
101 .read = seq_read,
102 .llseek = seq_lseek,
103 .release = seq_release,
104};
105
106static int __init proc_consoles_init(void) 94static int __init proc_consoles_init(void)
107{ 95{
108 proc_create("consoles", 0, NULL, &proc_consoles_operations); 96 proc_create_seq("consoles", 0, NULL, &consoles_op);
109 return 0; 97 return 0;
110} 98}
111fs_initcall(proc_consoles_init); 99fs_initcall(proc_consoles_init);
diff --git a/fs/proc/devices.c b/fs/proc/devices.c
index 2c7f22b14489..37d38697eaf8 100644
--- a/fs/proc/devices.c
+++ b/fs/proc/devices.c
@@ -51,21 +51,9 @@ static const struct seq_operations devinfo_ops = {
51 .show = devinfo_show 51 .show = devinfo_show
52}; 52};
53 53
54static int devinfo_open(struct inode *inode, struct file *filp)
55{
56 return seq_open(filp, &devinfo_ops);
57}
58
59static const struct file_operations proc_devinfo_operations = {
60 .open = devinfo_open,
61 .read = seq_read,
62 .llseek = seq_lseek,
63 .release = seq_release,
64};
65
66static int __init proc_devices_init(void) 54static int __init proc_devices_init(void)
67{ 55{
68 proc_create("devices", 0, NULL, &proc_devinfo_operations); 56 proc_create_seq("devices", 0, NULL, &devinfo_ops);
69 return 0; 57 return 0;
70} 58}
71fs_initcall(proc_devices_init); 59fs_initcall(proc_devices_init);
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 2078e70e1595..02bb1914f5f7 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -25,6 +25,7 @@
25#include <linux/spinlock.h> 25#include <linux/spinlock.h>
26#include <linux/completion.h> 26#include <linux/completion.h>
27#include <linux/uaccess.h> 27#include <linux/uaccess.h>
28#include <linux/seq_file.h>
28 29
29#include "internal.h" 30#include "internal.h"
30 31
@@ -346,13 +347,12 @@ static const struct inode_operations proc_dir_inode_operations = {
346 .setattr = proc_notify_change, 347 .setattr = proc_notify_change,
347}; 348};
348 349
349static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp) 350/* returns the registered entry, or frees dp and returns NULL on failure */
351struct proc_dir_entry *proc_register(struct proc_dir_entry *dir,
352 struct proc_dir_entry *dp)
350{ 353{
351 int ret; 354 if (proc_alloc_inum(&dp->low_ino))
352 355 goto out_free_entry;
353 ret = proc_alloc_inum(&dp->low_ino);
354 if (ret)
355 return ret;
356 356
357 write_lock(&proc_subdir_lock); 357 write_lock(&proc_subdir_lock);
358 dp->parent = dir; 358 dp->parent = dir;
@@ -360,12 +360,16 @@ static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp
360 WARN(1, "proc_dir_entry '%s/%s' already registered\n", 360 WARN(1, "proc_dir_entry '%s/%s' already registered\n",
361 dir->name, dp->name); 361 dir->name, dp->name);
362 write_unlock(&proc_subdir_lock); 362 write_unlock(&proc_subdir_lock);
363 proc_free_inum(dp->low_ino); 363 goto out_free_inum;
364 return -EEXIST;
365 } 364 }
366 write_unlock(&proc_subdir_lock); 365 write_unlock(&proc_subdir_lock);
367 366
368 return 0; 367 return dp;
368out_free_inum:
369 proc_free_inum(dp->low_ino);
370out_free_entry:
371 pde_free(dp);
372 return NULL;
369} 373}
370 374
371static struct proc_dir_entry *__proc_create(struct proc_dir_entry **parent, 375static struct proc_dir_entry *__proc_create(struct proc_dir_entry **parent,
@@ -443,10 +447,7 @@ struct proc_dir_entry *proc_symlink(const char *name,
443 if (ent->data) { 447 if (ent->data) {
444 strcpy((char*)ent->data,dest); 448 strcpy((char*)ent->data,dest);
445 ent->proc_iops = &proc_link_inode_operations; 449 ent->proc_iops = &proc_link_inode_operations;
446 if (proc_register(parent, ent) < 0) { 450 ent = proc_register(parent, ent);
447 pde_free(ent);
448 ent = NULL;
449 }
450 } else { 451 } else {
451 pde_free(ent); 452 pde_free(ent);
452 ent = NULL; 453 ent = NULL;
@@ -470,11 +471,9 @@ struct proc_dir_entry *proc_mkdir_data(const char *name, umode_t mode,
470 ent->proc_fops = &proc_dir_operations; 471 ent->proc_fops = &proc_dir_operations;
471 ent->proc_iops = &proc_dir_inode_operations; 472 ent->proc_iops = &proc_dir_inode_operations;
472 parent->nlink++; 473 parent->nlink++;
473 if (proc_register(parent, ent) < 0) { 474 ent = proc_register(parent, ent);
474 pde_free(ent); 475 if (!ent)
475 parent->nlink--; 476 parent->nlink--;
476 ent = NULL;
477 }
478 } 477 }
479 return ent; 478 return ent;
480} 479}
@@ -505,47 +504,47 @@ struct proc_dir_entry *proc_create_mount_point(const char *name)
505 ent->proc_fops = NULL; 504 ent->proc_fops = NULL;
506 ent->proc_iops = NULL; 505 ent->proc_iops = NULL;
507 parent->nlink++; 506 parent->nlink++;
508 if (proc_register(parent, ent) < 0) { 507 ent = proc_register(parent, ent);
509 pde_free(ent); 508 if (!ent)
510 parent->nlink--; 509 parent->nlink--;
511 ent = NULL;
512 }
513 } 510 }
514 return ent; 511 return ent;
515} 512}
516EXPORT_SYMBOL(proc_create_mount_point); 513EXPORT_SYMBOL(proc_create_mount_point);
517 514
518struct proc_dir_entry *proc_create_data(const char *name, umode_t mode, 515struct proc_dir_entry *proc_create_reg(const char *name, umode_t mode,
519 struct proc_dir_entry *parent, 516 struct proc_dir_entry **parent, void *data)
520 const struct file_operations *proc_fops,
521 void *data)
522{ 517{
523 struct proc_dir_entry *pde; 518 struct proc_dir_entry *p;
519
524 if ((mode & S_IFMT) == 0) 520 if ((mode & S_IFMT) == 0)
525 mode |= S_IFREG; 521 mode |= S_IFREG;
526 522 if ((mode & S_IALLUGO) == 0)
527 if (!S_ISREG(mode)) { 523 mode |= S_IRUGO;
528 WARN_ON(1); /* use proc_mkdir() */ 524 if (WARN_ON_ONCE(!S_ISREG(mode)))
529 return NULL; 525 return NULL;
526
527 p = __proc_create(parent, name, mode, 1);
528 if (p) {
529 p->proc_iops = &proc_file_inode_operations;
530 p->data = data;
530 } 531 }
532 return p;
533}
534
535struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
536 struct proc_dir_entry *parent,
537 const struct file_operations *proc_fops, void *data)
538{
539 struct proc_dir_entry *p;
531 540
532 BUG_ON(proc_fops == NULL); 541 BUG_ON(proc_fops == NULL);
533 542
534 if ((mode & S_IALLUGO) == 0) 543 p = proc_create_reg(name, mode, &parent, data);
535 mode |= S_IRUGO; 544 if (!p)
536 pde = __proc_create(&parent, name, mode, 1); 545 return NULL;
537 if (!pde) 546 p->proc_fops = proc_fops;
538 goto out; 547 return proc_register(parent, p);
539 pde->proc_fops = proc_fops;
540 pde->data = data;
541 pde->proc_iops = &proc_file_inode_operations;
542 if (proc_register(parent, pde) < 0)
543 goto out_free;
544 return pde;
545out_free:
546 pde_free(pde);
547out:
548 return NULL;
549} 548}
550EXPORT_SYMBOL(proc_create_data); 549EXPORT_SYMBOL(proc_create_data);
551 550
@@ -557,6 +556,67 @@ struct proc_dir_entry *proc_create(const char *name, umode_t mode,
557} 556}
558EXPORT_SYMBOL(proc_create); 557EXPORT_SYMBOL(proc_create);
559 558
559static int proc_seq_open(struct inode *inode, struct file *file)
560{
561 struct proc_dir_entry *de = PDE(inode);
562
563 if (de->state_size)
564 return seq_open_private(file, de->seq_ops, de->state_size);
565 return seq_open(file, de->seq_ops);
566}
567
568static const struct file_operations proc_seq_fops = {
569 .open = proc_seq_open,
570 .read = seq_read,
571 .llseek = seq_lseek,
572 .release = seq_release,
573};
574
575struct proc_dir_entry *proc_create_seq_private(const char *name, umode_t mode,
576 struct proc_dir_entry *parent, const struct seq_operations *ops,
577 unsigned int state_size, void *data)
578{
579 struct proc_dir_entry *p;
580
581 p = proc_create_reg(name, mode, &parent, data);
582 if (!p)
583 return NULL;
584 p->proc_fops = &proc_seq_fops;
585 p->seq_ops = ops;
586 p->state_size = state_size;
587 return proc_register(parent, p);
588}
589EXPORT_SYMBOL(proc_create_seq_private);
590
591static int proc_single_open(struct inode *inode, struct file *file)
592{
593 struct proc_dir_entry *de = PDE(inode);
594
595 return single_open(file, de->single_show, de->data);
596}
597
598static const struct file_operations proc_single_fops = {
599 .open = proc_single_open,
600 .read = seq_read,
601 .llseek = seq_lseek,
602 .release = single_release,
603};
604
605struct proc_dir_entry *proc_create_single_data(const char *name, umode_t mode,
606 struct proc_dir_entry *parent,
607 int (*show)(struct seq_file *, void *), void *data)
608{
609 struct proc_dir_entry *p;
610
611 p = proc_create_reg(name, mode, &parent, data);
612 if (!p)
613 return NULL;
614 p->proc_fops = &proc_single_fops;
615 p->single_show = show;
616 return proc_register(parent, p);
617}
618EXPORT_SYMBOL(proc_create_single_data);
619
560void proc_set_size(struct proc_dir_entry *de, loff_t size) 620void proc_set_size(struct proc_dir_entry *de, loff_t size)
561{ 621{
562 de->size = size; 622 de->size = size;
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index 0f1692e63cb6..a318ae5b36b4 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -44,7 +44,12 @@ struct proc_dir_entry {
44 struct completion *pde_unload_completion; 44 struct completion *pde_unload_completion;
45 const struct inode_operations *proc_iops; 45 const struct inode_operations *proc_iops;
46 const struct file_operations *proc_fops; 46 const struct file_operations *proc_fops;
47 union {
48 const struct seq_operations *seq_ops;
49 int (*single_show)(struct seq_file *, void *);
50 };
47 void *data; 51 void *data;
52 unsigned int state_size;
48 unsigned int low_ino; 53 unsigned int low_ino;
49 nlink_t nlink; 54 nlink_t nlink;
50 kuid_t uid; 55 kuid_t uid;
@@ -57,9 +62,9 @@ struct proc_dir_entry {
57 umode_t mode; 62 umode_t mode;
58 u8 namelen; 63 u8 namelen;
59#ifdef CONFIG_64BIT 64#ifdef CONFIG_64BIT
60#define SIZEOF_PDE_INLINE_NAME (192-139) 65#define SIZEOF_PDE_INLINE_NAME (192-155)
61#else 66#else
62#define SIZEOF_PDE_INLINE_NAME (128-87) 67#define SIZEOF_PDE_INLINE_NAME (128-95)
63#endif 68#endif
64 char inline_name[SIZEOF_PDE_INLINE_NAME]; 69 char inline_name[SIZEOF_PDE_INLINE_NAME];
65} __randomize_layout; 70} __randomize_layout;
@@ -162,6 +167,10 @@ extern bool proc_fill_cache(struct file *, struct dir_context *, const char *, i
162/* 167/*
163 * generic.c 168 * generic.c
164 */ 169 */
170struct proc_dir_entry *proc_create_reg(const char *name, umode_t mode,
171 struct proc_dir_entry **parent, void *data);
172struct proc_dir_entry *proc_register(struct proc_dir_entry *dir,
173 struct proc_dir_entry *dp);
165extern struct dentry *proc_lookup(struct inode *, struct dentry *, unsigned int); 174extern struct dentry *proc_lookup(struct inode *, struct dentry *, unsigned int);
166struct dentry *proc_lookup_de(struct inode *, struct dentry *, struct proc_dir_entry *); 175struct dentry *proc_lookup_de(struct inode *, struct dentry *, struct proc_dir_entry *);
167extern int proc_readdir(struct file *, struct dir_context *); 176extern int proc_readdir(struct file *, struct dir_context *);
diff --git a/fs/proc/interrupts.c b/fs/proc/interrupts.c
index 6a6bee9c603c..cb0edc7cbf09 100644
--- a/fs/proc/interrupts.c
+++ b/fs/proc/interrupts.c
@@ -34,21 +34,9 @@ static const struct seq_operations int_seq_ops = {
34 .show = show_interrupts 34 .show = show_interrupts
35}; 35};
36 36
37static int interrupts_open(struct inode *inode, struct file *filp)
38{
39 return seq_open(filp, &int_seq_ops);
40}
41
42static const struct file_operations proc_interrupts_operations = {
43 .open = interrupts_open,
44 .read = seq_read,
45 .llseek = seq_lseek,
46 .release = seq_release,
47};
48
49static int __init proc_interrupts_init(void) 37static int __init proc_interrupts_init(void)
50{ 38{
51 proc_create("interrupts", 0, NULL, &proc_interrupts_operations); 39 proc_create_seq("interrupts", 0, NULL, &int_seq_ops);
52 return 0; 40 return 0;
53} 41}
54fs_initcall(proc_interrupts_init); 42fs_initcall(proc_interrupts_init);
diff --git a/fs/proc/loadavg.c b/fs/proc/loadavg.c
index b572cc865b92..d06694757201 100644
--- a/fs/proc/loadavg.c
+++ b/fs/proc/loadavg.c
@@ -28,21 +28,9 @@ static int loadavg_proc_show(struct seq_file *m, void *v)
28 return 0; 28 return 0;
29} 29}
30 30
31static int loadavg_proc_open(struct inode *inode, struct file *file)
32{
33 return single_open(file, loadavg_proc_show, NULL);
34}
35
36static const struct file_operations loadavg_proc_fops = {
37 .open = loadavg_proc_open,
38 .read = seq_read,
39 .llseek = seq_lseek,
40 .release = single_release,
41};
42
43static int __init proc_loadavg_init(void) 31static int __init proc_loadavg_init(void)
44{ 32{
45 proc_create("loadavg", 0, NULL, &loadavg_proc_fops); 33 proc_create_single("loadavg", 0, NULL, loadavg_proc_show);
46 return 0; 34 return 0;
47} 35}
48fs_initcall(proc_loadavg_init); 36fs_initcall(proc_loadavg_init);
diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c
index 65a72ab57471..2fb04846ed11 100644
--- a/fs/proc/meminfo.c
+++ b/fs/proc/meminfo.c
@@ -149,21 +149,9 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
149 return 0; 149 return 0;
150} 150}
151 151
152static int meminfo_proc_open(struct inode *inode, struct file *file)
153{
154 return single_open(file, meminfo_proc_show, NULL);
155}
156
157static const struct file_operations meminfo_proc_fops = {
158 .open = meminfo_proc_open,
159 .read = seq_read,
160 .llseek = seq_lseek,
161 .release = single_release,
162};
163
164static int __init proc_meminfo_init(void) 152static int __init proc_meminfo_init(void)
165{ 153{
166 proc_create("meminfo", 0, NULL, &meminfo_proc_fops); 154 proc_create_single("meminfo", 0, NULL, meminfo_proc_show);
167 return 0; 155 return 0;
168} 156}
169fs_initcall(proc_meminfo_init); 157fs_initcall(proc_meminfo_init);
diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c
index 75634379f82e..3b63be64e436 100644
--- a/fs/proc/nommu.c
+++ b/fs/proc/nommu.c
@@ -113,21 +113,9 @@ static const struct seq_operations proc_nommu_region_list_seqop = {
113 .show = nommu_region_list_show 113 .show = nommu_region_list_show
114}; 114};
115 115
116static int proc_nommu_region_list_open(struct inode *inode, struct file *file)
117{
118 return seq_open(file, &proc_nommu_region_list_seqop);
119}
120
121static const struct file_operations proc_nommu_region_list_operations = {
122 .open = proc_nommu_region_list_open,
123 .read = seq_read,
124 .llseek = seq_lseek,
125 .release = seq_release,
126};
127
128static int __init proc_nommu_init(void) 116static int __init proc_nommu_init(void)
129{ 117{
130 proc_create("maps", S_IRUGO, NULL, &proc_nommu_region_list_operations); 118 proc_create_seq("maps", S_IRUGO, NULL, &proc_nommu_region_list_seqop);
131 return 0; 119 return 0;
132} 120}
133 121
diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c
index 1763f370489d..7d94fa005b0d 100644
--- a/fs/proc/proc_net.c
+++ b/fs/proc/proc_net.c
@@ -38,20 +38,20 @@ static struct net *get_proc_net(const struct inode *inode)
38 return maybe_get_net(PDE_NET(PDE(inode))); 38 return maybe_get_net(PDE_NET(PDE(inode)));
39} 39}
40 40
41int seq_open_net(struct inode *ino, struct file *f, 41static int seq_open_net(struct inode *inode, struct file *file)
42 const struct seq_operations *ops, int size)
43{ 42{
44 struct net *net; 43 unsigned int state_size = PDE(inode)->state_size;
45 struct seq_net_private *p; 44 struct seq_net_private *p;
45 struct net *net;
46 46
47 BUG_ON(size < sizeof(*p)); 47 WARN_ON_ONCE(state_size < sizeof(*p));
48 48
49 net = get_proc_net(ino); 49 net = get_proc_net(inode);
50 if (net == NULL) 50 if (!net)
51 return -ENXIO; 51 return -ENXIO;
52 52
53 p = __seq_open_private(f, ops, size); 53 p = __seq_open_private(file, PDE(inode)->seq_ops, state_size);
54 if (p == NULL) { 54 if (!p) {
55 put_net(net); 55 put_net(net);
56 return -ENOMEM; 56 return -ENOMEM;
57 } 57 }
@@ -60,51 +60,83 @@ int seq_open_net(struct inode *ino, struct file *f,
60#endif 60#endif
61 return 0; 61 return 0;
62} 62}
63EXPORT_SYMBOL_GPL(seq_open_net);
64 63
65int single_open_net(struct inode *inode, struct file *file, 64static int seq_release_net(struct inode *ino, struct file *f)
66 int (*show)(struct seq_file *, void *))
67{ 65{
68 int err; 66 struct seq_file *seq = f->private_data;
69 struct net *net;
70
71 err = -ENXIO;
72 net = get_proc_net(inode);
73 if (net == NULL)
74 goto err_net;
75
76 err = single_open(file, show, net);
77 if (err < 0)
78 goto err_open;
79 67
68 put_net(seq_file_net(seq));
69 seq_release_private(ino, f);
80 return 0; 70 return 0;
71}
81 72
82err_open: 73static const struct file_operations proc_net_seq_fops = {
83 put_net(net); 74 .open = seq_open_net,
84err_net: 75 .read = seq_read,
85 return err; 76 .llseek = seq_lseek,
77 .release = seq_release_net,
78};
79
80struct proc_dir_entry *proc_create_net_data(const char *name, umode_t mode,
81 struct proc_dir_entry *parent, const struct seq_operations *ops,
82 unsigned int state_size, void *data)
83{
84 struct proc_dir_entry *p;
85
86 p = proc_create_reg(name, mode, &parent, data);
87 if (!p)
88 return NULL;
89 p->proc_fops = &proc_net_seq_fops;
90 p->seq_ops = ops;
91 p->state_size = state_size;
92 return proc_register(parent, p);
86} 93}
87EXPORT_SYMBOL_GPL(single_open_net); 94EXPORT_SYMBOL_GPL(proc_create_net_data);
88 95
89int seq_release_net(struct inode *ino, struct file *f) 96static int single_open_net(struct inode *inode, struct file *file)
90{ 97{
91 struct seq_file *seq; 98 struct proc_dir_entry *de = PDE(inode);
99 struct net *net;
100 int err;
92 101
93 seq = f->private_data; 102 net = get_proc_net(inode);
103 if (!net)
104 return -ENXIO;
94 105
95 put_net(seq_file_net(seq)); 106 err = single_open(file, de->single_show, net);
96 seq_release_private(ino, f); 107 if (err)
97 return 0; 108 put_net(net);
109 return err;
98} 110}
99EXPORT_SYMBOL_GPL(seq_release_net);
100 111
101int single_release_net(struct inode *ino, struct file *f) 112static int single_release_net(struct inode *ino, struct file *f)
102{ 113{
103 struct seq_file *seq = f->private_data; 114 struct seq_file *seq = f->private_data;
104 put_net(seq->private); 115 put_net(seq->private);
105 return single_release(ino, f); 116 return single_release(ino, f);
106} 117}
107EXPORT_SYMBOL_GPL(single_release_net); 118
119static const struct file_operations proc_net_single_fops = {
120 .open = single_open_net,
121 .read = seq_read,
122 .llseek = seq_lseek,
123 .release = single_release_net,
124};
125
126struct proc_dir_entry *proc_create_net_single(const char *name, umode_t mode,
127 struct proc_dir_entry *parent,
128 int (*show)(struct seq_file *, void *), void *data)
129{
130 struct proc_dir_entry *p;
131
132 p = proc_create_reg(name, mode, &parent, data);
133 if (!p)
134 return NULL;
135 p->proc_fops = &proc_net_single_fops;
136 p->single_show = show;
137 return proc_register(parent, p);
138}
139EXPORT_SYMBOL_GPL(proc_create_net_single);
108 140
109static struct net *get_proc_task_net(struct inode *dir) 141static struct net *get_proc_task_net(struct inode *dir)
110{ 142{
diff --git a/fs/proc/proc_tty.c b/fs/proc/proc_tty.c
index d0cf1c50bb6c..c69ff191e5d8 100644
--- a/fs/proc/proc_tty.c
+++ b/fs/proc/proc_tty.c
@@ -126,18 +126,6 @@ static const struct seq_operations tty_drivers_op = {
126 .show = show_tty_driver 126 .show = show_tty_driver
127}; 127};
128 128
129static int tty_drivers_open(struct inode *inode, struct file *file)
130{
131 return seq_open(file, &tty_drivers_op);
132}
133
134static const struct file_operations proc_tty_drivers_operations = {
135 .open = tty_drivers_open,
136 .read = seq_read,
137 .llseek = seq_lseek,
138 .release = seq_release,
139};
140
141/* 129/*
142 * This function is called by tty_register_driver() to handle 130 * This function is called by tty_register_driver() to handle
143 * registering the driver's /proc handler into /proc/tty/driver/<foo> 131 * registering the driver's /proc handler into /proc/tty/driver/<foo>
@@ -147,11 +135,11 @@ void proc_tty_register_driver(struct tty_driver *driver)
147 struct proc_dir_entry *ent; 135 struct proc_dir_entry *ent;
148 136
149 if (!driver->driver_name || driver->proc_entry || 137 if (!driver->driver_name || driver->proc_entry ||
150 !driver->ops->proc_fops) 138 !driver->ops->proc_show)
151 return; 139 return;
152 140
153 ent = proc_create_data(driver->driver_name, 0, proc_tty_driver, 141 ent = proc_create_single_data(driver->driver_name, 0, proc_tty_driver,
154 driver->ops->proc_fops, driver); 142 driver->ops->proc_show, driver);
155 driver->proc_entry = ent; 143 driver->proc_entry = ent;
156} 144}
157 145
@@ -186,6 +174,6 @@ void __init proc_tty_init(void)
186 * entry. 174 * entry.
187 */ 175 */
188 proc_tty_driver = proc_mkdir_mode("tty/driver", S_IRUSR|S_IXUSR, NULL); 176 proc_tty_driver = proc_mkdir_mode("tty/driver", S_IRUSR|S_IXUSR, NULL);
189 proc_create("tty/ldiscs", 0, NULL, &tty_ldiscs_proc_fops); 177 proc_create_seq("tty/ldiscs", 0, NULL, &tty_ldiscs_seq_ops);
190 proc_create("tty/drivers", 0, NULL, &proc_tty_drivers_operations); 178 proc_create_seq("tty/drivers", 0, NULL, &tty_drivers_op);
191} 179}
diff --git a/fs/proc/self.c b/fs/proc/self.c
index 4d7d061696b3..127265e5c55f 100644
--- a/fs/proc/self.c
+++ b/fs/proc/self.c
@@ -12,7 +12,7 @@ static const char *proc_self_get_link(struct dentry *dentry,
12 struct inode *inode, 12 struct inode *inode,
13 struct delayed_call *done) 13 struct delayed_call *done)
14{ 14{
15 struct pid_namespace *ns = inode->i_sb->s_fs_info; 15 struct pid_namespace *ns = proc_pid_ns(inode);
16 pid_t tgid = task_tgid_nr_ns(current, ns); 16 pid_t tgid = task_tgid_nr_ns(current, ns);
17 char *name; 17 char *name;
18 18
@@ -36,7 +36,7 @@ static unsigned self_inum __ro_after_init;
36int proc_setup_self(struct super_block *s) 36int proc_setup_self(struct super_block *s)
37{ 37{
38 struct inode *root_inode = d_inode(s->s_root); 38 struct inode *root_inode = d_inode(s->s_root);
39 struct pid_namespace *ns = s->s_fs_info; 39 struct pid_namespace *ns = proc_pid_ns(root_inode);
40 struct dentry *self; 40 struct dentry *self;
41 41
42 inode_lock(root_inode); 42 inode_lock(root_inode);
diff --git a/fs/proc/softirqs.c b/fs/proc/softirqs.c
index 24072cc06e65..12901dcf57e2 100644
--- a/fs/proc/softirqs.c
+++ b/fs/proc/softirqs.c
@@ -25,21 +25,9 @@ static int show_softirqs(struct seq_file *p, void *v)
25 return 0; 25 return 0;
26} 26}
27 27
28static int softirqs_open(struct inode *inode, struct file *file)
29{
30 return single_open(file, show_softirqs, NULL);
31}
32
33static const struct file_operations proc_softirqs_operations = {
34 .open = softirqs_open,
35 .read = seq_read,
36 .llseek = seq_lseek,
37 .release = single_release,
38};
39
40static int __init proc_softirqs_init(void) 28static int __init proc_softirqs_init(void)
41{ 29{
42 proc_create("softirqs", 0, NULL, &proc_softirqs_operations); 30 proc_create_single("softirqs", 0, NULL, show_softirqs);
43 return 0; 31 return 0;
44} 32}
45fs_initcall(proc_softirqs_init); 33fs_initcall(proc_softirqs_init);
diff --git a/fs/proc/thread_self.c b/fs/proc/thread_self.c
index 9d2efaca499f..b905010ca9eb 100644
--- a/fs/proc/thread_self.c
+++ b/fs/proc/thread_self.c
@@ -12,7 +12,7 @@ static const char *proc_thread_self_get_link(struct dentry *dentry,
12 struct inode *inode, 12 struct inode *inode,
13 struct delayed_call *done) 13 struct delayed_call *done)
14{ 14{
15 struct pid_namespace *ns = inode->i_sb->s_fs_info; 15 struct pid_namespace *ns = proc_pid_ns(inode);
16 pid_t tgid = task_tgid_nr_ns(current, ns); 16 pid_t tgid = task_tgid_nr_ns(current, ns);
17 pid_t pid = task_pid_nr_ns(current, ns); 17 pid_t pid = task_pid_nr_ns(current, ns);
18 char *name; 18 char *name;
@@ -36,7 +36,7 @@ static unsigned thread_self_inum __ro_after_init;
36int proc_setup_thread_self(struct super_block *s) 36int proc_setup_thread_self(struct super_block *s)
37{ 37{
38 struct inode *root_inode = d_inode(s->s_root); 38 struct inode *root_inode = d_inode(s->s_root);
39 struct pid_namespace *ns = s->s_fs_info; 39 struct pid_namespace *ns = proc_pid_ns(root_inode);
40 struct dentry *thread_self; 40 struct dentry *thread_self;
41 41
42 inode_lock(root_inode); 42 inode_lock(root_inode);
diff --git a/fs/proc/uptime.c b/fs/proc/uptime.c
index 95a708d83721..3bd12f955867 100644
--- a/fs/proc/uptime.c
+++ b/fs/proc/uptime.c
@@ -30,21 +30,9 @@ static int uptime_proc_show(struct seq_file *m, void *v)
30 return 0; 30 return 0;
31} 31}
32 32
33static int uptime_proc_open(struct inode *inode, struct file *file)
34{
35 return single_open(file, uptime_proc_show, NULL);
36}
37
38static const struct file_operations uptime_proc_fops = {
39 .open = uptime_proc_open,
40 .read = seq_read,
41 .llseek = seq_lseek,
42 .release = single_release,
43};
44
45static int __init proc_uptime_init(void) 33static int __init proc_uptime_init(void)
46{ 34{
47 proc_create("uptime", 0, NULL, &uptime_proc_fops); 35 proc_create_single("uptime", 0, NULL, uptime_proc_show);
48 return 0; 36 return 0;
49} 37}
50fs_initcall(proc_uptime_init); 38fs_initcall(proc_uptime_init);
diff --git a/fs/proc/version.c b/fs/proc/version.c
index 94901e8e700d..b449f186577f 100644
--- a/fs/proc/version.c
+++ b/fs/proc/version.c
@@ -15,21 +15,9 @@ static int version_proc_show(struct seq_file *m, void *v)
15 return 0; 15 return 0;
16} 16}
17 17
18static int version_proc_open(struct inode *inode, struct file *file)
19{
20 return single_open(file, version_proc_show, NULL);
21}
22
23static const struct file_operations version_proc_fops = {
24 .open = version_proc_open,
25 .read = seq_read,
26 .llseek = seq_lseek,
27 .release = single_release,
28};
29
30static int __init proc_version_init(void) 18static int __init proc_version_init(void)
31{ 19{
32 proc_create("version", 0, NULL, &version_proc_fops); 20 proc_create_single("version", 0, NULL, version_proc_show);
33 return 0; 21 return 0;
34} 22}
35fs_initcall(proc_version_init); 23fs_initcall(proc_version_init);