aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-01 20:51:54 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-01 20:51:54 -0400
commit20b4fb485227404329e41ad15588afad3df23050 (patch)
treef3e099f0ab3da8a93b447203e294d2bb22f6dc05 /fs/proc
parentb9394d8a657cd3c064fa432aa0905c1b58b38fe9 (diff)
parentac3e3c5b1164397656df81b9e9ab4991184d3236 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull VFS updates from Al Viro, Misc cleanups all over the place, mainly wrt /proc interfaces (switch create_proc_entry to proc_create(), get rid of the deprecated create_proc_read_entry() in favor of using proc_create_data() and seq_file etc). 7kloc removed. * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (204 commits) don't bother with deferred freeing of fdtables proc: Move non-public stuff from linux/proc_fs.h to fs/proc/internal.h proc: Make the PROC_I() and PDE() macros internal to procfs proc: Supply a function to remove a proc entry by PDE take cgroup_open() and cpuset_open() to fs/proc/base.c ppc: Clean up scanlog ppc: Clean up rtas_flash driver somewhat hostap: proc: Use remove_proc_subtree() drm: proc: Use remove_proc_subtree() drm: proc: Use minor->index to label things, not PDE->name drm: Constify drm_proc_list[] zoran: Don't print proc_dir_entry data in debug reiserfs: Don't access the proc_dir_entry in r_open(), r_start() r_show() proc: Supply an accessor for getting the data from a PDE's parent airo: Use remove_proc_subtree() rtl8192u: Don't need to save device proc dir PDE rtl8187se: Use a dir under /proc/net/r8180/ proc: Add proc_mkdir_data() proc: Move some bits from linux/proc_fs.h to linux/{of.h,signal.h,tty.h} proc: Move PDE_NET() to fs/proc/proc_net.c ...
Diffstat (limited to 'fs/proc')
-rw-r--r--fs/proc/base.c56
-rw-r--r--fs/proc/fd.h5
-rw-r--r--fs/proc/generic.c377
-rw-r--r--fs/proc/inode.c283
-rw-r--r--fs/proc/internal.h313
-rw-r--r--fs/proc/kcore.c2
-rw-r--r--fs/proc/namespaces.c17
-rw-r--r--fs/proc/proc_devtree.c2
-rw-r--r--fs/proc/proc_net.c4
-rw-r--r--fs/proc/root.c2
-rw-r--r--fs/proc/self.c47
-rw-r--r--fs/proc/vmcore.c5
12 files changed, 501 insertions, 612 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 3861bcec41ff..dd51e50001fe 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -405,6 +405,37 @@ static const struct file_operations proc_lstats_operations = {
405 405
406#endif 406#endif
407 407
408#ifdef CONFIG_CGROUPS
409static int cgroup_open(struct inode *inode, struct file *file)
410{
411 struct pid *pid = PROC_I(inode)->pid;
412 return single_open(file, proc_cgroup_show, pid);
413}
414
415static const struct file_operations proc_cgroup_operations = {
416 .open = cgroup_open,
417 .read = seq_read,
418 .llseek = seq_lseek,
419 .release = single_release,
420};
421#endif
422
423#ifdef CONFIG_PROC_PID_CPUSET
424
425static int cpuset_open(struct inode *inode, struct file *file)
426{
427 struct pid *pid = PROC_I(inode)->pid;
428 return single_open(file, proc_cpuset_show, pid);
429}
430
431static const struct file_operations proc_cpuset_operations = {
432 .open = cpuset_open,
433 .read = seq_read,
434 .llseek = seq_lseek,
435 .release = single_release,
436};
437#endif
438
408static int proc_oom_score(struct task_struct *task, char *buffer) 439static int proc_oom_score(struct task_struct *task, char *buffer)
409{ 440{
410 unsigned long totalpages = totalram_pages + total_swap_pages; 441 unsigned long totalpages = totalram_pages + total_swap_pages;
@@ -1621,6 +1652,15 @@ int pid_revalidate(struct dentry *dentry, unsigned int flags)
1621 return 0; 1652 return 0;
1622} 1653}
1623 1654
1655int pid_delete_dentry(const struct dentry *dentry)
1656{
1657 /* Is the task we represent dead?
1658 * If so, then don't put the dentry on the lru list,
1659 * kill it immediately.
1660 */
1661 return !proc_pid(dentry->d_inode)->tasks[PIDTYPE_PID].first;
1662}
1663
1624const struct dentry_operations pid_dentry_operations = 1664const struct dentry_operations pid_dentry_operations =
1625{ 1665{
1626 .d_revalidate = pid_revalidate, 1666 .d_revalidate = pid_revalidate,
@@ -2893,7 +2933,7 @@ retry:
2893 return iter; 2933 return iter;
2894} 2934}
2895 2935
2896#define TGID_OFFSET (FIRST_PROCESS_ENTRY) 2936#define TGID_OFFSET (FIRST_PROCESS_ENTRY + 1)
2897 2937
2898static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldir, 2938static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
2899 struct tgid_iter iter) 2939 struct tgid_iter iter)
@@ -2916,13 +2956,21 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
2916 struct tgid_iter iter; 2956 struct tgid_iter iter;
2917 struct pid_namespace *ns; 2957 struct pid_namespace *ns;
2918 filldir_t __filldir; 2958 filldir_t __filldir;
2959 loff_t pos = filp->f_pos;
2919 2960
2920 if (filp->f_pos >= PID_MAX_LIMIT + TGID_OFFSET) 2961 if (pos >= PID_MAX_LIMIT + TGID_OFFSET)
2921 goto out; 2962 goto out;
2922 2963
2923 ns = filp->f_dentry->d_sb->s_fs_info; 2964 if (pos == TGID_OFFSET - 1) {
2965 if (proc_fill_cache(filp, dirent, filldir, "self", 4,
2966 NULL, NULL, NULL) < 0)
2967 goto out;
2968 iter.tgid = 0;
2969 } else {
2970 iter.tgid = pos - TGID_OFFSET;
2971 }
2924 iter.task = NULL; 2972 iter.task = NULL;
2925 iter.tgid = filp->f_pos - TGID_OFFSET; 2973 ns = filp->f_dentry->d_sb->s_fs_info;
2926 for (iter = next_tgid(ns, iter); 2974 for (iter = next_tgid(ns, iter);
2927 iter.task; 2975 iter.task;
2928 iter.tgid += 1, iter = next_tgid(ns, iter)) { 2976 iter.tgid += 1, iter = next_tgid(ns, iter)) {
diff --git a/fs/proc/fd.h b/fs/proc/fd.h
index cbb1d47deda8..7c047f256ae2 100644
--- a/fs/proc/fd.h
+++ b/fs/proc/fd.h
@@ -11,4 +11,9 @@ extern const struct inode_operations proc_fdinfo_inode_operations;
11 11
12extern int proc_fd_permission(struct inode *inode, int mask); 12extern int proc_fd_permission(struct inode *inode, int mask);
13 13
14static inline int proc_fd(struct inode *inode)
15{
16 return PROC_I(inode)->fd;
17}
18
14#endif /* __PROCFS_FD_H__ */ 19#endif /* __PROCFS_FD_H__ */
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 21e1a8f1659d..a2596afffae6 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -36,212 +36,6 @@ static int proc_match(unsigned int len, const char *name, struct proc_dir_entry
36 return !memcmp(name, de->name, len); 36 return !memcmp(name, de->name, len);
37} 37}
38 38
39/* buffer size is one page but our output routines use some slack for overruns */
40#define PROC_BLOCK_SIZE (PAGE_SIZE - 1024)
41
42static ssize_t
43__proc_file_read(struct file *file, char __user *buf, size_t nbytes,
44 loff_t *ppos)
45{
46 struct inode * inode = file_inode(file);
47 char *page;
48 ssize_t retval=0;
49 int eof=0;
50 ssize_t n, count;
51 char *start;
52 struct proc_dir_entry * dp;
53 unsigned long long pos;
54
55 /*
56 * Gaah, please just use "seq_file" instead. The legacy /proc
57 * interfaces cut loff_t down to off_t for reads, and ignore
58 * the offset entirely for writes..
59 */
60 pos = *ppos;
61 if (pos > MAX_NON_LFS)
62 return 0;
63 if (nbytes > MAX_NON_LFS - pos)
64 nbytes = MAX_NON_LFS - pos;
65
66 dp = PDE(inode);
67 if (!(page = (char*) __get_free_page(GFP_TEMPORARY)))
68 return -ENOMEM;
69
70 while ((nbytes > 0) && !eof) {
71 count = min_t(size_t, PROC_BLOCK_SIZE, nbytes);
72
73 start = NULL;
74 if (dp->read_proc) {
75 /*
76 * How to be a proc read function
77 * ------------------------------
78 * Prototype:
79 * int f(char *buffer, char **start, off_t offset,
80 * int count, int *peof, void *dat)
81 *
82 * Assume that the buffer is "count" bytes in size.
83 *
84 * If you know you have supplied all the data you
85 * have, set *peof.
86 *
87 * You have three ways to return data:
88 * 0) Leave *start = NULL. (This is the default.)
89 * Put the data of the requested offset at that
90 * offset within the buffer. Return the number (n)
91 * of bytes there are from the beginning of the
92 * buffer up to the last byte of data. If the
93 * number of supplied bytes (= n - offset) is
94 * greater than zero and you didn't signal eof
95 * and the reader is prepared to take more data
96 * you will be called again with the requested
97 * offset advanced by the number of bytes
98 * absorbed. This interface is useful for files
99 * no larger than the buffer.
100 * 1) Set *start = an unsigned long value less than
101 * the buffer address but greater than zero.
102 * Put the data of the requested offset at the
103 * beginning of the buffer. Return the number of
104 * bytes of data placed there. If this number is
105 * greater than zero and you didn't signal eof
106 * and the reader is prepared to take more data
107 * you will be called again with the requested
108 * offset advanced by *start. This interface is
109 * useful when you have a large file consisting
110 * of a series of blocks which you want to count
111 * and return as wholes.
112 * (Hack by Paul.Russell@rustcorp.com.au)
113 * 2) Set *start = an address within the buffer.
114 * Put the data of the requested offset at *start.
115 * Return the number of bytes of data placed there.
116 * If this number is greater than zero and you
117 * didn't signal eof and the reader is prepared to
118 * take more data you will be called again with the
119 * requested offset advanced by the number of bytes
120 * absorbed.
121 */
122 n = dp->read_proc(page, &start, *ppos,
123 count, &eof, dp->data);
124 } else
125 break;
126
127 if (n == 0) /* end of file */
128 break;
129 if (n < 0) { /* error */
130 if (retval == 0)
131 retval = n;
132 break;
133 }
134
135 if (start == NULL) {
136 if (n > PAGE_SIZE) /* Apparent buffer overflow */
137 n = PAGE_SIZE;
138 n -= *ppos;
139 if (n <= 0)
140 break;
141 if (n > count)
142 n = count;
143 start = page + *ppos;
144 } else if (start < page) {
145 if (n > PAGE_SIZE) /* Apparent buffer overflow */
146 n = PAGE_SIZE;
147 if (n > count) {
148 /*
149 * Don't reduce n because doing so might
150 * cut off part of a data block.
151 */
152 pr_warn("proc_file_read: count exceeded\n");
153 }
154 } else /* start >= page */ {
155 unsigned long startoff = (unsigned long)(start - page);
156 if (n > (PAGE_SIZE - startoff)) /* buffer overflow? */
157 n = PAGE_SIZE - startoff;
158 if (n > count)
159 n = count;
160 }
161
162 n -= copy_to_user(buf, start < page ? page : start, n);
163 if (n == 0) {
164 if (retval == 0)
165 retval = -EFAULT;
166 break;
167 }
168
169 *ppos += start < page ? (unsigned long)start : n;
170 nbytes -= n;
171 buf += n;
172 retval += n;
173 }
174 free_page((unsigned long) page);
175 return retval;
176}
177
178static ssize_t
179proc_file_read(struct file *file, char __user *buf, size_t nbytes,
180 loff_t *ppos)
181{
182 struct proc_dir_entry *pde = PDE(file_inode(file));
183 ssize_t rv = -EIO;
184
185 spin_lock(&pde->pde_unload_lock);
186 if (!pde->proc_fops) {
187 spin_unlock(&pde->pde_unload_lock);
188 return rv;
189 }
190 pde->pde_users++;
191 spin_unlock(&pde->pde_unload_lock);
192
193 rv = __proc_file_read(file, buf, nbytes, ppos);
194
195 pde_users_dec(pde);
196 return rv;
197}
198
199static ssize_t
200proc_file_write(struct file *file, const char __user *buffer,
201 size_t count, loff_t *ppos)
202{
203 struct proc_dir_entry *pde = PDE(file_inode(file));
204 ssize_t rv = -EIO;
205
206 if (pde->write_proc) {
207 spin_lock(&pde->pde_unload_lock);
208 if (!pde->proc_fops) {
209 spin_unlock(&pde->pde_unload_lock);
210 return rv;
211 }
212 pde->pde_users++;
213 spin_unlock(&pde->pde_unload_lock);
214
215 /* FIXME: does this routine need ppos? probably... */
216 rv = pde->write_proc(file, buffer, count, pde->data);
217 pde_users_dec(pde);
218 }
219 return rv;
220}
221
222
223static loff_t
224proc_file_lseek(struct file *file, loff_t offset, int orig)
225{
226 loff_t retval = -EINVAL;
227 switch (orig) {
228 case 1:
229 offset += file->f_pos;
230 /* fallthrough */
231 case 0:
232 if (offset < 0 || offset > MAX_NON_LFS)
233 break;
234 file->f_pos = retval = offset;
235 }
236 return retval;
237}
238
239static const struct file_operations proc_file_operations = {
240 .llseek = proc_file_lseek,
241 .read = proc_file_read,
242 .write = proc_file_write,
243};
244
245static int proc_notify_change(struct dentry *dentry, struct iattr *iattr) 39static int proc_notify_change(struct dentry *dentry, struct iattr *iattr)
246{ 40{
247 struct inode *inode = dentry->d_inode; 41 struct inode *inode = dentry->d_inode;
@@ -371,7 +165,7 @@ void proc_free_inum(unsigned int inum)
371 165
372static void *proc_follow_link(struct dentry *dentry, struct nameidata *nd) 166static void *proc_follow_link(struct dentry *dentry, struct nameidata *nd)
373{ 167{
374 nd_set_link(nd, PDE(dentry->d_inode)->data); 168 nd_set_link(nd, __PDE_DATA(dentry->d_inode));
375 return NULL; 169 return NULL;
376} 170}
377 171
@@ -541,19 +335,17 @@ static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp
541 return ret; 335 return ret;
542 336
543 if (S_ISDIR(dp->mode)) { 337 if (S_ISDIR(dp->mode)) {
544 if (dp->proc_iops == NULL) { 338 dp->proc_fops = &proc_dir_operations;
545 dp->proc_fops = &proc_dir_operations; 339 dp->proc_iops = &proc_dir_inode_operations;
546 dp->proc_iops = &proc_dir_inode_operations;
547 }
548 dir->nlink++; 340 dir->nlink++;
549 } else if (S_ISLNK(dp->mode)) { 341 } else if (S_ISLNK(dp->mode)) {
550 if (dp->proc_iops == NULL) 342 dp->proc_iops = &proc_link_inode_operations;
551 dp->proc_iops = &proc_link_inode_operations;
552 } else if (S_ISREG(dp->mode)) { 343 } else if (S_ISREG(dp->mode)) {
553 if (dp->proc_fops == NULL) 344 BUG_ON(dp->proc_fops == NULL);
554 dp->proc_fops = &proc_file_operations; 345 dp->proc_iops = &proc_file_inode_operations;
555 if (dp->proc_iops == NULL) 346 } else {
556 dp->proc_iops = &proc_file_inode_operations; 347 WARN_ON(1);
348 return -EINVAL;
557 } 349 }
558 350
559 spin_lock(&proc_subdir_lock); 351 spin_lock(&proc_subdir_lock);
@@ -636,13 +428,17 @@ struct proc_dir_entry *proc_symlink(const char *name,
636} 428}
637EXPORT_SYMBOL(proc_symlink); 429EXPORT_SYMBOL(proc_symlink);
638 430
639struct proc_dir_entry *proc_mkdir_mode(const char *name, umode_t mode, 431struct proc_dir_entry *proc_mkdir_data(const char *name, umode_t mode,
640 struct proc_dir_entry *parent) 432 struct proc_dir_entry *parent, void *data)
641{ 433{
642 struct proc_dir_entry *ent; 434 struct proc_dir_entry *ent;
643 435
436 if (mode == 0)
437 mode = S_IRUGO | S_IXUGO;
438
644 ent = __proc_create(&parent, name, S_IFDIR | mode, 2); 439 ent = __proc_create(&parent, name, S_IFDIR | mode, 2);
645 if (ent) { 440 if (ent) {
441 ent->data = data;
646 if (proc_register(parent, ent) < 0) { 442 if (proc_register(parent, ent) < 0) {
647 kfree(ent); 443 kfree(ent);
648 ent = NULL; 444 ent = NULL;
@@ -650,82 +446,39 @@ struct proc_dir_entry *proc_mkdir_mode(const char *name, umode_t mode,
650 } 446 }
651 return ent; 447 return ent;
652} 448}
653EXPORT_SYMBOL(proc_mkdir_mode); 449EXPORT_SYMBOL_GPL(proc_mkdir_data);
654 450
655struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name, 451struct proc_dir_entry *proc_mkdir_mode(const char *name, umode_t mode,
656 struct proc_dir_entry *parent) 452 struct proc_dir_entry *parent)
657{ 453{
658 struct proc_dir_entry *ent; 454 return proc_mkdir_data(name, mode, parent, NULL);
659
660 ent = __proc_create(&parent, name, S_IFDIR | S_IRUGO | S_IXUGO, 2);
661 if (ent) {
662 ent->data = net;
663 if (proc_register(parent, ent) < 0) {
664 kfree(ent);
665 ent = NULL;
666 }
667 }
668 return ent;
669} 455}
670EXPORT_SYMBOL_GPL(proc_net_mkdir); 456EXPORT_SYMBOL(proc_mkdir_mode);
671 457
672struct proc_dir_entry *proc_mkdir(const char *name, 458struct proc_dir_entry *proc_mkdir(const char *name,
673 struct proc_dir_entry *parent) 459 struct proc_dir_entry *parent)
674{ 460{
675 return proc_mkdir_mode(name, S_IRUGO | S_IXUGO, parent); 461 return proc_mkdir_data(name, 0, parent, NULL);
676} 462}
677EXPORT_SYMBOL(proc_mkdir); 463EXPORT_SYMBOL(proc_mkdir);
678 464
679struct proc_dir_entry *create_proc_entry(const char *name, umode_t mode,
680 struct proc_dir_entry *parent)
681{
682 struct proc_dir_entry *ent;
683 nlink_t nlink;
684
685 if (S_ISDIR(mode)) {
686 if ((mode & S_IALLUGO) == 0)
687 mode |= S_IRUGO | S_IXUGO;
688 nlink = 2;
689 } else {
690 if ((mode & S_IFMT) == 0)
691 mode |= S_IFREG;
692 if ((mode & S_IALLUGO) == 0)
693 mode |= S_IRUGO;
694 nlink = 1;
695 }
696
697 ent = __proc_create(&parent, name, mode, nlink);
698 if (ent) {
699 if (proc_register(parent, ent) < 0) {
700 kfree(ent);
701 ent = NULL;
702 }
703 }
704 return ent;
705}
706EXPORT_SYMBOL(create_proc_entry);
707
708struct proc_dir_entry *proc_create_data(const char *name, umode_t mode, 465struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
709 struct proc_dir_entry *parent, 466 struct proc_dir_entry *parent,
710 const struct file_operations *proc_fops, 467 const struct file_operations *proc_fops,
711 void *data) 468 void *data)
712{ 469{
713 struct proc_dir_entry *pde; 470 struct proc_dir_entry *pde;
714 nlink_t nlink; 471 if ((mode & S_IFMT) == 0)
472 mode |= S_IFREG;
715 473
716 if (S_ISDIR(mode)) { 474 if (!S_ISREG(mode)) {
717 if ((mode & S_IALLUGO) == 0) 475 WARN_ON(1); /* use proc_mkdir() */
718 mode |= S_IRUGO | S_IXUGO; 476 return NULL;
719 nlink = 2;
720 } else {
721 if ((mode & S_IFMT) == 0)
722 mode |= S_IFREG;
723 if ((mode & S_IALLUGO) == 0)
724 mode |= S_IRUGO;
725 nlink = 1;
726 } 477 }
727 478
728 pde = __proc_create(&parent, name, mode, nlink); 479 if ((mode & S_IALLUGO) == 0)
480 mode |= S_IRUGO;
481 pde = __proc_create(&parent, name, mode, 1);
729 if (!pde) 482 if (!pde)
730 goto out; 483 goto out;
731 pde->proc_fops = proc_fops; 484 pde->proc_fops = proc_fops;
@@ -739,6 +492,19 @@ out:
739 return NULL; 492 return NULL;
740} 493}
741EXPORT_SYMBOL(proc_create_data); 494EXPORT_SYMBOL(proc_create_data);
495
496void proc_set_size(struct proc_dir_entry *de, loff_t size)
497{
498 de->size = size;
499}
500EXPORT_SYMBOL(proc_set_size);
501
502void proc_set_user(struct proc_dir_entry *de, kuid_t uid, kgid_t gid)
503{
504 de->uid = uid;
505 de->gid = gid;
506}
507EXPORT_SYMBOL(proc_set_user);
742 508
743static void free_proc_entry(struct proc_dir_entry *de) 509static void free_proc_entry(struct proc_dir_entry *de)
744{ 510{
@@ -755,41 +521,6 @@ void pde_put(struct proc_dir_entry *pde)
755 free_proc_entry(pde); 521 free_proc_entry(pde);
756} 522}
757 523
758static void entry_rundown(struct proc_dir_entry *de)
759{
760 spin_lock(&de->pde_unload_lock);
761 /*
762 * Stop accepting new callers into module. If you're
763 * dynamically allocating ->proc_fops, save a pointer somewhere.
764 */
765 de->proc_fops = NULL;
766 /* Wait until all existing callers into module are done. */
767 if (de->pde_users > 0) {
768 DECLARE_COMPLETION_ONSTACK(c);
769
770 if (!de->pde_unload_completion)
771 de->pde_unload_completion = &c;
772
773 spin_unlock(&de->pde_unload_lock);
774
775 wait_for_completion(de->pde_unload_completion);
776
777 spin_lock(&de->pde_unload_lock);
778 }
779
780 while (!list_empty(&de->pde_openers)) {
781 struct pde_opener *pdeo;
782
783 pdeo = list_first_entry(&de->pde_openers, struct pde_opener, lh);
784 list_del(&pdeo->lh);
785 spin_unlock(&de->pde_unload_lock);
786 pdeo->release(pdeo->inode, pdeo->file);
787 kfree(pdeo);
788 spin_lock(&de->pde_unload_lock);
789 }
790 spin_unlock(&de->pde_unload_lock);
791}
792
793/* 524/*
794 * Remove a /proc entry and free it if it's not currently in use. 525 * Remove a /proc entry and free it if it's not currently in use.
795 */ 526 */
@@ -821,7 +552,7 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
821 return; 552 return;
822 } 553 }
823 554
824 entry_rundown(de); 555 proc_entry_rundown(de);
825 556
826 if (S_ISDIR(de->mode)) 557 if (S_ISDIR(de->mode))
827 parent->nlink--; 558 parent->nlink--;
@@ -870,7 +601,7 @@ int remove_proc_subtree(const char *name, struct proc_dir_entry *parent)
870 } 601 }
871 spin_unlock(&proc_subdir_lock); 602 spin_unlock(&proc_subdir_lock);
872 603
873 entry_rundown(de); 604 proc_entry_rundown(de);
874 next = de->parent; 605 next = de->parent;
875 if (S_ISDIR(de->mode)) 606 if (S_ISDIR(de->mode))
876 next->nlink--; 607 next->nlink--;
@@ -886,3 +617,23 @@ int remove_proc_subtree(const char *name, struct proc_dir_entry *parent)
886 return 0; 617 return 0;
887} 618}
888EXPORT_SYMBOL(remove_proc_subtree); 619EXPORT_SYMBOL(remove_proc_subtree);
620
621void *proc_get_parent_data(const struct inode *inode)
622{
623 struct proc_dir_entry *de = PDE(inode);
624 return de->parent->data;
625}
626EXPORT_SYMBOL_GPL(proc_get_parent_data);
627
628void proc_remove(struct proc_dir_entry *de)
629{
630 if (de)
631 remove_proc_subtree(de->name, de->parent);
632}
633EXPORT_SYMBOL(proc_remove);
634
635void *PDE_DATA(const struct inode *inode)
636{
637 return __PDE_DATA(inode);
638}
639EXPORT_SYMBOL(PDE_DATA);
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 869116c2afbe..073aea60cf8f 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -22,6 +22,7 @@
22#include <linux/seq_file.h> 22#include <linux/seq_file.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/mount.h> 24#include <linux/mount.h>
25#include <linux/magic.h>
25 26
26#include <asm/uaccess.h> 27#include <asm/uaccess.h>
27 28
@@ -50,8 +51,8 @@ static void proc_evict_inode(struct inode *inode)
50 sysctl_head_put(head); 51 sysctl_head_put(head);
51 } 52 }
52 /* Release any associated namespace */ 53 /* Release any associated namespace */
53 ns_ops = PROC_I(inode)->ns_ops; 54 ns_ops = PROC_I(inode)->ns.ns_ops;
54 ns = PROC_I(inode)->ns; 55 ns = PROC_I(inode)->ns.ns;
55 if (ns_ops && ns) 56 if (ns_ops && ns)
56 ns_ops->put(ns); 57 ns_ops->put(ns);
57} 58}
@@ -72,8 +73,8 @@ static struct inode *proc_alloc_inode(struct super_block *sb)
72 ei->pde = NULL; 73 ei->pde = NULL;
73 ei->sysctl = NULL; 74 ei->sysctl = NULL;
74 ei->sysctl_entry = NULL; 75 ei->sysctl_entry = NULL;
75 ei->ns = NULL; 76 ei->ns.ns = NULL;
76 ei->ns_ops = NULL; 77 ei->ns.ns_ops = NULL;
77 inode = &ei->vfs_inode; 78 inode = &ei->vfs_inode;
78 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; 79 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
79 return inode; 80 return inode;
@@ -129,96 +130,100 @@ static const struct super_operations proc_sops = {
129 .show_options = proc_show_options, 130 .show_options = proc_show_options,
130}; 131};
131 132
132static void __pde_users_dec(struct proc_dir_entry *pde) 133enum {BIAS = -1U<<31};
134
135static inline int use_pde(struct proc_dir_entry *pde)
136{
137 return atomic_inc_unless_negative(&pde->in_use);
138}
139
140static void unuse_pde(struct proc_dir_entry *pde)
133{ 141{
134 pde->pde_users--; 142 if (atomic_dec_return(&pde->in_use) == BIAS)
135 if (pde->pde_unload_completion && pde->pde_users == 0)
136 complete(pde->pde_unload_completion); 143 complete(pde->pde_unload_completion);
137} 144}
138 145
139void pde_users_dec(struct proc_dir_entry *pde) 146/* pde is locked */
147static void close_pdeo(struct proc_dir_entry *pde, struct pde_opener *pdeo)
140{ 148{
141 spin_lock(&pde->pde_unload_lock); 149 if (pdeo->closing) {
142 __pde_users_dec(pde); 150 /* somebody else is doing that, just wait */
143 spin_unlock(&pde->pde_unload_lock); 151 DECLARE_COMPLETION_ONSTACK(c);
152 pdeo->c = &c;
153 spin_unlock(&pde->pde_unload_lock);
154 wait_for_completion(&c);
155 spin_lock(&pde->pde_unload_lock);
156 } else {
157 struct file *file;
158 pdeo->closing = 1;
159 spin_unlock(&pde->pde_unload_lock);
160 file = pdeo->file;
161 pde->proc_fops->release(file_inode(file), file);
162 spin_lock(&pde->pde_unload_lock);
163 list_del_init(&pdeo->lh);
164 if (pdeo->c)
165 complete(pdeo->c);
166 kfree(pdeo);
167 }
168}
169
170void proc_entry_rundown(struct proc_dir_entry *de)
171{
172 DECLARE_COMPLETION_ONSTACK(c);
173 /* Wait until all existing callers into module are done. */
174 de->pde_unload_completion = &c;
175 if (atomic_add_return(BIAS, &de->in_use) != BIAS)
176 wait_for_completion(&c);
177
178 spin_lock(&de->pde_unload_lock);
179 while (!list_empty(&de->pde_openers)) {
180 struct pde_opener *pdeo;
181 pdeo = list_first_entry(&de->pde_openers, struct pde_opener, lh);
182 close_pdeo(de, pdeo);
183 }
184 spin_unlock(&de->pde_unload_lock);
144} 185}
145 186
146static loff_t proc_reg_llseek(struct file *file, loff_t offset, int whence) 187static loff_t proc_reg_llseek(struct file *file, loff_t offset, int whence)
147{ 188{
148 struct proc_dir_entry *pde = PDE(file_inode(file)); 189 struct proc_dir_entry *pde = PDE(file_inode(file));
149 loff_t rv = -EINVAL; 190 loff_t rv = -EINVAL;
150 loff_t (*llseek)(struct file *, loff_t, int); 191 if (use_pde(pde)) {
151 192 loff_t (*llseek)(struct file *, loff_t, int);
152 spin_lock(&pde->pde_unload_lock); 193 llseek = pde->proc_fops->llseek;
153 /* 194 if (!llseek)
154 * remove_proc_entry() is going to delete PDE (as part of module 195 llseek = default_llseek;
155 * cleanup sequence). No new callers into module allowed. 196 rv = llseek(file, offset, whence);
156 */ 197 unuse_pde(pde);
157 if (!pde->proc_fops) {
158 spin_unlock(&pde->pde_unload_lock);
159 return rv;
160 } 198 }
161 /*
162 * Bump refcount so that remove_proc_entry will wail for ->llseek to
163 * complete.
164 */
165 pde->pde_users++;
166 /*
167 * Save function pointer under lock, to protect against ->proc_fops
168 * NULL'ifying right after ->pde_unload_lock is dropped.
169 */
170 llseek = pde->proc_fops->llseek;
171 spin_unlock(&pde->pde_unload_lock);
172
173 if (!llseek)
174 llseek = default_llseek;
175 rv = llseek(file, offset, whence);
176
177 pde_users_dec(pde);
178 return rv; 199 return rv;
179} 200}
180 201
181static ssize_t proc_reg_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) 202static ssize_t proc_reg_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
182{ 203{
204 ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);
183 struct proc_dir_entry *pde = PDE(file_inode(file)); 205 struct proc_dir_entry *pde = PDE(file_inode(file));
184 ssize_t rv = -EIO; 206 ssize_t rv = -EIO;
185 ssize_t (*read)(struct file *, char __user *, size_t, loff_t *); 207 if (use_pde(pde)) {
186 208 read = pde->proc_fops->read;
187 spin_lock(&pde->pde_unload_lock); 209 if (read)
188 if (!pde->proc_fops) { 210 rv = read(file, buf, count, ppos);
189 spin_unlock(&pde->pde_unload_lock); 211 unuse_pde(pde);
190 return rv;
191 } 212 }
192 pde->pde_users++;
193 read = pde->proc_fops->read;
194 spin_unlock(&pde->pde_unload_lock);
195
196 if (read)
197 rv = read(file, buf, count, ppos);
198
199 pde_users_dec(pde);
200 return rv; 213 return rv;
201} 214}
202 215
203static ssize_t proc_reg_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) 216static ssize_t proc_reg_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
204{ 217{
218 ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);
205 struct proc_dir_entry *pde = PDE(file_inode(file)); 219 struct proc_dir_entry *pde = PDE(file_inode(file));
206 ssize_t rv = -EIO; 220 ssize_t rv = -EIO;
207 ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *); 221 if (use_pde(pde)) {
208 222 write = pde->proc_fops->write;
209 spin_lock(&pde->pde_unload_lock); 223 if (write)
210 if (!pde->proc_fops) { 224 rv = write(file, buf, count, ppos);
211 spin_unlock(&pde->pde_unload_lock); 225 unuse_pde(pde);
212 return rv;
213 } 226 }
214 pde->pde_users++;
215 write = pde->proc_fops->write;
216 spin_unlock(&pde->pde_unload_lock);
217
218 if (write)
219 rv = write(file, buf, count, ppos);
220
221 pde_users_dec(pde);
222 return rv; 227 return rv;
223} 228}
224 229
@@ -227,20 +232,12 @@ static unsigned int proc_reg_poll(struct file *file, struct poll_table_struct *p
227 struct proc_dir_entry *pde = PDE(file_inode(file)); 232 struct proc_dir_entry *pde = PDE(file_inode(file));
228 unsigned int rv = DEFAULT_POLLMASK; 233 unsigned int rv = DEFAULT_POLLMASK;
229 unsigned int (*poll)(struct file *, struct poll_table_struct *); 234 unsigned int (*poll)(struct file *, struct poll_table_struct *);
230 235 if (use_pde(pde)) {
231 spin_lock(&pde->pde_unload_lock); 236 poll = pde->proc_fops->poll;
232 if (!pde->proc_fops) { 237 if (poll)
233 spin_unlock(&pde->pde_unload_lock); 238 rv = poll(file, pts);
234 return rv; 239 unuse_pde(pde);
235 } 240 }
236 pde->pde_users++;
237 poll = pde->proc_fops->poll;
238 spin_unlock(&pde->pde_unload_lock);
239
240 if (poll)
241 rv = poll(file, pts);
242
243 pde_users_dec(pde);
244 return rv; 241 return rv;
245} 242}
246 243
@@ -249,20 +246,12 @@ static long proc_reg_unlocked_ioctl(struct file *file, unsigned int cmd, unsigne
249 struct proc_dir_entry *pde = PDE(file_inode(file)); 246 struct proc_dir_entry *pde = PDE(file_inode(file));
250 long rv = -ENOTTY; 247 long rv = -ENOTTY;
251 long (*ioctl)(struct file *, unsigned int, unsigned long); 248 long (*ioctl)(struct file *, unsigned int, unsigned long);
252 249 if (use_pde(pde)) {
253 spin_lock(&pde->pde_unload_lock); 250 ioctl = pde->proc_fops->unlocked_ioctl;
254 if (!pde->proc_fops) { 251 if (ioctl)
255 spin_unlock(&pde->pde_unload_lock); 252 rv = ioctl(file, cmd, arg);
256 return rv; 253 unuse_pde(pde);
257 } 254 }
258 pde->pde_users++;
259 ioctl = pde->proc_fops->unlocked_ioctl;
260 spin_unlock(&pde->pde_unload_lock);
261
262 if (ioctl)
263 rv = ioctl(file, cmd, arg);
264
265 pde_users_dec(pde);
266 return rv; 255 return rv;
267} 256}
268 257
@@ -272,20 +261,12 @@ static long proc_reg_compat_ioctl(struct file *file, unsigned int cmd, unsigned
272 struct proc_dir_entry *pde = PDE(file_inode(file)); 261 struct proc_dir_entry *pde = PDE(file_inode(file));
273 long rv = -ENOTTY; 262 long rv = -ENOTTY;
274 long (*compat_ioctl)(struct file *, unsigned int, unsigned long); 263 long (*compat_ioctl)(struct file *, unsigned int, unsigned long);
275 264 if (use_pde(pde)) {
276 spin_lock(&pde->pde_unload_lock); 265 compat_ioctl = pde->proc_fops->compat_ioctl;
277 if (!pde->proc_fops) { 266 if (compat_ioctl)
278 spin_unlock(&pde->pde_unload_lock); 267 rv = compat_ioctl(file, cmd, arg);
279 return rv; 268 unuse_pde(pde);
280 } 269 }
281 pde->pde_users++;
282 compat_ioctl = pde->proc_fops->compat_ioctl;
283 spin_unlock(&pde->pde_unload_lock);
284
285 if (compat_ioctl)
286 rv = compat_ioctl(file, cmd, arg);
287
288 pde_users_dec(pde);
289 return rv; 270 return rv;
290} 271}
291#endif 272#endif
@@ -295,20 +276,12 @@ static int proc_reg_mmap(struct file *file, struct vm_area_struct *vma)
295 struct proc_dir_entry *pde = PDE(file_inode(file)); 276 struct proc_dir_entry *pde = PDE(file_inode(file));
296 int rv = -EIO; 277 int rv = -EIO;
297 int (*mmap)(struct file *, struct vm_area_struct *); 278 int (*mmap)(struct file *, struct vm_area_struct *);
298 279 if (use_pde(pde)) {
299 spin_lock(&pde->pde_unload_lock); 280 mmap = pde->proc_fops->mmap;
300 if (!pde->proc_fops) { 281 if (mmap)
301 spin_unlock(&pde->pde_unload_lock); 282 rv = mmap(file, vma);
302 return rv; 283 unuse_pde(pde);
303 } 284 }
304 pde->pde_users++;
305 mmap = pde->proc_fops->mmap;
306 spin_unlock(&pde->pde_unload_lock);
307
308 if (mmap)
309 rv = mmap(file, vma);
310
311 pde_users_dec(pde);
312 return rv; 285 return rv;
313} 286}
314 287
@@ -330,91 +303,47 @@ static int proc_reg_open(struct inode *inode, struct file *file)
330 * by hand in remove_proc_entry(). For this, save opener's credentials 303 * by hand in remove_proc_entry(). For this, save opener's credentials
331 * for later. 304 * for later.
332 */ 305 */
333 pdeo = kmalloc(sizeof(struct pde_opener), GFP_KERNEL); 306 pdeo = kzalloc(sizeof(struct pde_opener), GFP_KERNEL);
334 if (!pdeo) 307 if (!pdeo)
335 return -ENOMEM; 308 return -ENOMEM;
336 309
337 spin_lock(&pde->pde_unload_lock); 310 if (!use_pde(pde)) {
338 if (!pde->proc_fops) {
339 spin_unlock(&pde->pde_unload_lock);
340 kfree(pdeo); 311 kfree(pdeo);
341 return -ENOENT; 312 return -ENOENT;
342 } 313 }
343 pde->pde_users++;
344 open = pde->proc_fops->open; 314 open = pde->proc_fops->open;
345 release = pde->proc_fops->release; 315 release = pde->proc_fops->release;
346 spin_unlock(&pde->pde_unload_lock);
347 316
348 if (open) 317 if (open)
349 rv = open(inode, file); 318 rv = open(inode, file);
350 319
351 spin_lock(&pde->pde_unload_lock);
352 if (rv == 0 && release) { 320 if (rv == 0 && release) {
353 /* To know what to release. */ 321 /* To know what to release. */
354 pdeo->inode = inode;
355 pdeo->file = file; 322 pdeo->file = file;
356 /* Strictly for "too late" ->release in proc_reg_release(). */ 323 /* Strictly for "too late" ->release in proc_reg_release(). */
357 pdeo->release = release; 324 spin_lock(&pde->pde_unload_lock);
358 list_add(&pdeo->lh, &pde->pde_openers); 325 list_add(&pdeo->lh, &pde->pde_openers);
326 spin_unlock(&pde->pde_unload_lock);
359 } else 327 } else
360 kfree(pdeo); 328 kfree(pdeo);
361 __pde_users_dec(pde);
362 spin_unlock(&pde->pde_unload_lock);
363 return rv;
364}
365
366static struct pde_opener *find_pde_opener(struct proc_dir_entry *pde,
367 struct inode *inode, struct file *file)
368{
369 struct pde_opener *pdeo;
370 329
371 list_for_each_entry(pdeo, &pde->pde_openers, lh) { 330 unuse_pde(pde);
372 if (pdeo->inode == inode && pdeo->file == file) 331 return rv;
373 return pdeo;
374 }
375 return NULL;
376} 332}
377 333
378static int proc_reg_release(struct inode *inode, struct file *file) 334static int proc_reg_release(struct inode *inode, struct file *file)
379{ 335{
380 struct proc_dir_entry *pde = PDE(inode); 336 struct proc_dir_entry *pde = PDE(inode);
381 int rv = 0;
382 int (*release)(struct inode *, struct file *);
383 struct pde_opener *pdeo; 337 struct pde_opener *pdeo;
384
385 spin_lock(&pde->pde_unload_lock); 338 spin_lock(&pde->pde_unload_lock);
386 pdeo = find_pde_opener(pde, inode, file); 339 list_for_each_entry(pdeo, &pde->pde_openers, lh) {
387 if (!pde->proc_fops) { 340 if (pdeo->file == file) {
388 /* 341 close_pdeo(pde, pdeo);
389 * Can't simply exit, __fput() will think that everything is OK, 342 break;
390 * and move on to freeing struct file. remove_proc_entry() will 343 }
391 * find slacker in opener's list and will try to do non-trivial
392 * things with struct file. Therefore, remove opener from list.
393 *
394 * But if opener is removed from list, who will ->release it?
395 */
396 if (pdeo) {
397 list_del(&pdeo->lh);
398 spin_unlock(&pde->pde_unload_lock);
399 rv = pdeo->release(inode, file);
400 kfree(pdeo);
401 } else
402 spin_unlock(&pde->pde_unload_lock);
403 return rv;
404 }
405 pde->pde_users++;
406 release = pde->proc_fops->release;
407 if (pdeo) {
408 list_del(&pdeo->lh);
409 kfree(pdeo);
410 } 344 }
411 spin_unlock(&pde->pde_unload_lock); 345 spin_unlock(&pde->pde_unload_lock);
412 346 return 0;
413 if (release)
414 rv = release(inode, file);
415
416 pde_users_dec(pde);
417 return rv;
418} 347}
419 348
420static const struct file_operations proc_reg_file_ops = { 349static const struct file_operations proc_reg_file_ops = {
@@ -462,8 +391,8 @@ struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de)
462 inode->i_size = de->size; 391 inode->i_size = de->size;
463 if (de->nlink) 392 if (de->nlink)
464 set_nlink(inode, de->nlink); 393 set_nlink(inode, de->nlink);
465 if (de->proc_iops) 394 WARN_ON(!de->proc_iops);
466 inode->i_op = de->proc_iops; 395 inode->i_op = de->proc_iops;
467 if (de->proc_fops) { 396 if (de->proc_fops) {
468 if (S_ISREG(inode->i_mode)) { 397 if (S_ISREG(inode->i_mode)) {
469#ifdef CONFIG_COMPAT 398#ifdef CONFIG_COMPAT
@@ -506,5 +435,5 @@ int proc_fill_super(struct super_block *s)
506 return -ENOMEM; 435 return -ENOMEM;
507 } 436 }
508 437
509 return 0; 438 return proc_setup_self(s);
510} 439}
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index 75710357a517..d600fb098b6a 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -1,4 +1,4 @@
1/* internal.h: internal procfs definitions 1/* Internal procfs definitions
2 * 2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
@@ -9,62 +9,83 @@
9 * 2 of the License, or (at your option) any later version. 9 * 2 of the License, or (at your option) any later version.
10 */ 10 */
11 11
12#include <linux/sched.h>
13#include <linux/proc_fs.h> 12#include <linux/proc_fs.h>
13#include <linux/proc_ns.h>
14#include <linux/spinlock.h>
15#include <linux/atomic.h>
14#include <linux/binfmts.h> 16#include <linux/binfmts.h>
15struct ctl_table_header;
16struct mempolicy;
17 17
18extern struct proc_dir_entry proc_root; 18struct ctl_table_header;
19extern void proc_self_init(void); 19struct mempolicy;
20#ifdef CONFIG_PROC_SYSCTL
21extern int proc_sys_init(void);
22extern void sysctl_head_put(struct ctl_table_header *head);
23#else
24static inline void proc_sys_init(void) { }
25static inline void sysctl_head_put(struct ctl_table_header *head) { }
26#endif
27#ifdef CONFIG_NET
28extern int proc_net_init(void);
29#else
30static inline int proc_net_init(void) { return 0; }
31#endif
32 20
33extern int proc_tid_stat(struct seq_file *m, struct pid_namespace *ns, 21/*
34 struct pid *pid, struct task_struct *task); 22 * This is not completely implemented yet. The idea is to
35extern int proc_tgid_stat(struct seq_file *m, struct pid_namespace *ns, 23 * create an in-memory tree (like the actual /proc filesystem
36 struct pid *pid, struct task_struct *task); 24 * tree) of these proc_dir_entries, so that we can dynamically
37extern int proc_pid_status(struct seq_file *m, struct pid_namespace *ns, 25 * add new files to /proc.
38 struct pid *pid, struct task_struct *task); 26 *
39extern int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns, 27 * The "next" pointer creates a linked list of one /proc directory,
40 struct pid *pid, struct task_struct *task); 28 * while parent/subdir create the directory structure (every
41extern loff_t mem_lseek(struct file *file, loff_t offset, int orig); 29 * /proc file has a parent, but "subdir" is NULL for all
30 * non-directory entries).
31 */
32struct proc_dir_entry {
33 unsigned int low_ino;
34 umode_t mode;
35 nlink_t nlink;
36 kuid_t uid;
37 kgid_t gid;
38 loff_t size;
39 const struct inode_operations *proc_iops;
40 const struct file_operations *proc_fops;
41 struct proc_dir_entry *next, *parent, *subdir;
42 void *data;
43 atomic_t count; /* use count */
44 atomic_t in_use; /* number of callers into module in progress; */
45 /* negative -> it's going away RSN */
46 struct completion *pde_unload_completion;
47 struct list_head pde_openers; /* who did ->open, but not ->release */
48 spinlock_t pde_unload_lock; /* proc_fops checks and pde_users bumps */
49 u8 namelen;
50 char name[];
51};
42 52
43extern const struct file_operations proc_tid_children_operations; 53union proc_op {
44extern const struct file_operations proc_pid_maps_operations; 54 int (*proc_get_link)(struct dentry *, struct path *);
45extern const struct file_operations proc_tid_maps_operations; 55 int (*proc_read)(struct task_struct *task, char *page);
46extern const struct file_operations proc_pid_numa_maps_operations; 56 int (*proc_show)(struct seq_file *m,
47extern const struct file_operations proc_tid_numa_maps_operations; 57 struct pid_namespace *ns, struct pid *pid,
48extern const struct file_operations proc_pid_smaps_operations; 58 struct task_struct *task);
49extern const struct file_operations proc_tid_smaps_operations; 59};
50extern const struct file_operations proc_clear_refs_operations;
51extern const struct file_operations proc_pagemap_operations;
52extern const struct file_operations proc_net_operations;
53extern const struct inode_operations proc_net_inode_operations;
54extern const struct inode_operations proc_pid_link_inode_operations;
55 60
56struct proc_maps_private { 61struct proc_inode {
57 struct pid *pid; 62 struct pid *pid;
58 struct task_struct *task; 63 int fd;
59#ifdef CONFIG_MMU 64 union proc_op op;
60 struct vm_area_struct *tail_vma; 65 struct proc_dir_entry *pde;
61#endif 66 struct ctl_table_header *sysctl;
62#ifdef CONFIG_NUMA 67 struct ctl_table *sysctl_entry;
63 struct mempolicy *task_mempolicy; 68 struct proc_ns ns;
64#endif 69 struct inode vfs_inode;
65}; 70};
66 71
67void proc_init_inodecache(void); 72/*
73 * General functions
74 */
75static inline struct proc_inode *PROC_I(const struct inode *inode)
76{
77 return container_of(inode, struct proc_inode, vfs_inode);
78}
79
80static inline struct proc_dir_entry *PDE(const struct inode *inode)
81{
82 return PROC_I(inode)->pde;
83}
84
85static inline void *__PDE_DATA(const struct inode *inode)
86{
87 return PDE(inode)->data;
88}
68 89
69static inline struct pid *proc_pid(struct inode *inode) 90static inline struct pid *proc_pid(struct inode *inode)
70{ 91{
@@ -76,11 +97,6 @@ static inline struct task_struct *get_proc_task(struct inode *inode)
76 return get_pid_task(proc_pid(inode), PIDTYPE_PID); 97 return get_pid_task(proc_pid(inode), PIDTYPE_PID);
77} 98}
78 99
79static inline int proc_fd(struct inode *inode)
80{
81 return PROC_I(inode)->fd;
82}
83
84static inline int task_dumpable(struct task_struct *task) 100static inline int task_dumpable(struct task_struct *task)
85{ 101{
86 int dumpable = 0; 102 int dumpable = 0;
@@ -96,15 +112,6 @@ static inline int task_dumpable(struct task_struct *task)
96 return 0; 112 return 0;
97} 113}
98 114
99static inline int pid_delete_dentry(const struct dentry * dentry)
100{
101 /* Is the task we represent dead?
102 * If so, then don't put the dentry on the lru list,
103 * kill it immediately.
104 */
105 return !proc_pid(dentry->d_inode)->tasks[PIDTYPE_PID].first;
106}
107
108static inline unsigned name_to_int(struct dentry *dentry) 115static inline unsigned name_to_int(struct dentry *dentry)
109{ 116{
110 const char *name = dentry->d_name.name; 117 const char *name = dentry->d_name.name;
@@ -127,63 +134,165 @@ out:
127 return ~0U; 134 return ~0U;
128} 135}
129 136
130struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *ino, 137/*
131 struct dentry *dentry); 138 * Offset of the first process in the /proc root directory..
132int proc_readdir_de(struct proc_dir_entry *de, struct file *filp, void *dirent, 139 */
133 filldir_t filldir); 140#define FIRST_PROCESS_ENTRY 256
141
142/* Worst case buffer size needed for holding an integer. */
143#define PROC_NUMBUF 13
134 144
135struct pde_opener { 145/*
136 struct inode *inode; 146 * array.c
137 struct file *file; 147 */
138 int (*release)(struct inode *, struct file *); 148extern const struct file_operations proc_tid_children_operations;
139 struct list_head lh;
140};
141void pde_users_dec(struct proc_dir_entry *pde);
142 149
150extern int proc_tid_stat(struct seq_file *, struct pid_namespace *,
151 struct pid *, struct task_struct *);
152extern int proc_tgid_stat(struct seq_file *, struct pid_namespace *,
153 struct pid *, struct task_struct *);
154extern int proc_pid_status(struct seq_file *, struct pid_namespace *,
155 struct pid *, struct task_struct *);
156extern int proc_pid_statm(struct seq_file *, struct pid_namespace *,
157 struct pid *, struct task_struct *);
158
159/*
160 * base.c
161 */
162extern const struct dentry_operations pid_dentry_operations;
163extern int pid_getattr(struct vfsmount *, struct dentry *, struct kstat *);
164extern int proc_setattr(struct dentry *, struct iattr *);
165extern struct inode *proc_pid_make_inode(struct super_block *, struct task_struct *);
166extern int pid_revalidate(struct dentry *, unsigned int);
167extern int pid_delete_dentry(const struct dentry *);
168extern int proc_pid_readdir(struct file *, void *, filldir_t);
169extern struct dentry *proc_pid_lookup(struct inode *, struct dentry *, unsigned int);
170extern loff_t mem_lseek(struct file *, loff_t, int);
171
172/* Lookups */
173typedef struct dentry *instantiate_t(struct inode *, struct dentry *,
174 struct task_struct *, const void *);
175extern int proc_fill_cache(struct file *, void *, filldir_t, const char *, int,
176 instantiate_t, struct task_struct *, const void *);
177
178/*
179 * generic.c
180 */
143extern spinlock_t proc_subdir_lock; 181extern spinlock_t proc_subdir_lock;
144 182
145struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, unsigned int); 183extern struct dentry *proc_lookup(struct inode *, struct dentry *, unsigned int);
146int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir); 184extern struct dentry *proc_lookup_de(struct proc_dir_entry *, struct inode *,
147unsigned long task_vsize(struct mm_struct *); 185 struct dentry *);
148unsigned long task_statm(struct mm_struct *, 186extern int proc_readdir(struct file *, void *, filldir_t);
149 unsigned long *, unsigned long *, unsigned long *, unsigned long *); 187extern int proc_readdir_de(struct proc_dir_entry *, struct file *, void *, filldir_t);
150void task_mem(struct seq_file *, struct mm_struct *);
151 188
152static inline struct proc_dir_entry *pde_get(struct proc_dir_entry *pde) 189static inline struct proc_dir_entry *pde_get(struct proc_dir_entry *pde)
153{ 190{
154 atomic_inc(&pde->count); 191 atomic_inc(&pde->count);
155 return pde; 192 return pde;
156} 193}
157void pde_put(struct proc_dir_entry *pde); 194extern void pde_put(struct proc_dir_entry *);
158
159int proc_fill_super(struct super_block *);
160struct inode *proc_get_inode(struct super_block *, struct proc_dir_entry *);
161int proc_remount(struct super_block *sb, int *flags, char *data);
162 195
163/* 196/*
164 * These are generic /proc routines that use the internal 197 * inode.c
165 * "struct proc_dir_entry" tree to traverse the filesystem.
166 *
167 * The /proc root directory has extended versions to take care
168 * of the /proc/<pid> subdirectories.
169 */ 198 */
170int proc_readdir(struct file *, void *, filldir_t); 199struct pde_opener {
171struct dentry *proc_lookup(struct inode *, struct dentry *, unsigned int); 200 struct file *file;
201 struct list_head lh;
202 int closing;
203 struct completion *c;
204};
172 205
206extern const struct inode_operations proc_pid_link_inode_operations;
173 207
208extern void proc_init_inodecache(void);
209extern struct inode *proc_get_inode(struct super_block *, struct proc_dir_entry *);
210extern int proc_fill_super(struct super_block *);
211extern void proc_entry_rundown(struct proc_dir_entry *);
174 212
175/* Lookups */ 213/*
176typedef struct dentry *instantiate_t(struct inode *, struct dentry *, 214 * proc_devtree.c
177 struct task_struct *, const void *); 215 */
178int proc_fill_cache(struct file *filp, void *dirent, filldir_t filldir, 216#ifdef CONFIG_PROC_DEVICETREE
179 const char *name, int len, 217extern void proc_device_tree_init(void);
180 instantiate_t instantiate, struct task_struct *task, const void *ptr); 218#endif
181int pid_revalidate(struct dentry *dentry, unsigned int flags);
182struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task);
183extern const struct dentry_operations pid_dentry_operations;
184int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat);
185int proc_setattr(struct dentry *dentry, struct iattr *attr);
186 219
220/*
221 * proc_namespaces.c
222 */
187extern const struct inode_operations proc_ns_dir_inode_operations; 223extern const struct inode_operations proc_ns_dir_inode_operations;
188extern const struct file_operations proc_ns_dir_operations; 224extern const struct file_operations proc_ns_dir_operations;
189 225
226/*
227 * proc_net.c
228 */
229extern const struct file_operations proc_net_operations;
230extern const struct inode_operations proc_net_inode_operations;
231
232#ifdef CONFIG_NET
233extern int proc_net_init(void);
234#else
235static inline int proc_net_init(void) { return 0; }
236#endif
237
238/*
239 * proc_self.c
240 */
241extern int proc_setup_self(struct super_block *);
242
243/*
244 * proc_sysctl.c
245 */
246#ifdef CONFIG_PROC_SYSCTL
247extern int proc_sys_init(void);
248extern void sysctl_head_put(struct ctl_table_header *);
249#else
250static inline void proc_sys_init(void) { }
251static inline void sysctl_head_put(struct ctl_table_header *head) { }
252#endif
253
254/*
255 * proc_tty.c
256 */
257#ifdef CONFIG_TTY
258extern void proc_tty_init(void);
259#else
260static inline void proc_tty_init(void) {}
261#endif
262
263/*
264 * root.c
265 */
266extern struct proc_dir_entry proc_root;
267
268extern void proc_self_init(void);
269extern int proc_remount(struct super_block *, int *, char *);
270
271/*
272 * task_[no]mmu.c
273 */
274struct proc_maps_private {
275 struct pid *pid;
276 struct task_struct *task;
277#ifdef CONFIG_MMU
278 struct vm_area_struct *tail_vma;
279#endif
280#ifdef CONFIG_NUMA
281 struct mempolicy *task_mempolicy;
282#endif
283};
284
285extern const struct file_operations proc_pid_maps_operations;
286extern const struct file_operations proc_tid_maps_operations;
287extern const struct file_operations proc_pid_numa_maps_operations;
288extern const struct file_operations proc_tid_numa_maps_operations;
289extern const struct file_operations proc_pid_smaps_operations;
290extern const struct file_operations proc_tid_smaps_operations;
291extern const struct file_operations proc_clear_refs_operations;
292extern const struct file_operations proc_pagemap_operations;
293
294extern unsigned long task_vsize(struct mm_struct *);
295extern unsigned long task_statm(struct mm_struct *,
296 unsigned long *, unsigned long *,
297 unsigned long *, unsigned long *);
298extern void task_mem(struct seq_file *, struct mm_struct *);
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
index f6a13f489e30..0a22194e5d58 100644
--- a/fs/proc/kcore.c
+++ b/fs/proc/kcore.c
@@ -11,6 +11,7 @@
11 11
12#include <linux/mm.h> 12#include <linux/mm.h>
13#include <linux/proc_fs.h> 13#include <linux/proc_fs.h>
14#include <linux/kcore.h>
14#include <linux/user.h> 15#include <linux/user.h>
15#include <linux/capability.h> 16#include <linux/capability.h>
16#include <linux/elf.h> 17#include <linux/elf.h>
@@ -28,6 +29,7 @@
28#include <linux/ioport.h> 29#include <linux/ioport.h>
29#include <linux/memory.h> 30#include <linux/memory.h>
30#include <asm/sections.h> 31#include <asm/sections.h>
32#include "internal.h"
31 33
32#define CORE_STR "CORE" 34#define CORE_STR "CORE"
33 35
diff --git a/fs/proc/namespaces.c b/fs/proc/namespaces.c
index 66b51c0383da..54bdc6701e9f 100644
--- a/fs/proc/namespaces.c
+++ b/fs/proc/namespaces.c
@@ -51,7 +51,7 @@ static int ns_delete_dentry(const struct dentry *dentry)
51static char *ns_dname(struct dentry *dentry, char *buffer, int buflen) 51static char *ns_dname(struct dentry *dentry, char *buffer, int buflen)
52{ 52{
53 struct inode *inode = dentry->d_inode; 53 struct inode *inode = dentry->d_inode;
54 const struct proc_ns_operations *ns_ops = PROC_I(inode)->ns_ops; 54 const struct proc_ns_operations *ns_ops = PROC_I(inode)->ns.ns_ops;
55 55
56 return dynamic_dname(dentry, buffer, buflen, "%s:[%lu]", 56 return dynamic_dname(dentry, buffer, buflen, "%s:[%lu]",
57 ns_ops->name, inode->i_ino); 57 ns_ops->name, inode->i_ino);
@@ -95,8 +95,8 @@ static struct dentry *proc_ns_get_dentry(struct super_block *sb,
95 inode->i_op = &ns_inode_operations; 95 inode->i_op = &ns_inode_operations;
96 inode->i_mode = S_IFREG | S_IRUGO; 96 inode->i_mode = S_IFREG | S_IRUGO;
97 inode->i_fop = &ns_file_operations; 97 inode->i_fop = &ns_file_operations;
98 ei->ns_ops = ns_ops; 98 ei->ns.ns_ops = ns_ops;
99 ei->ns = ns; 99 ei->ns.ns = ns;
100 unlock_new_inode(inode); 100 unlock_new_inode(inode);
101 } else { 101 } else {
102 ns_ops->put(ns); 102 ns_ops->put(ns);
@@ -128,7 +128,7 @@ static void *proc_ns_follow_link(struct dentry *dentry, struct nameidata *nd)
128 if (!ptrace_may_access(task, PTRACE_MODE_READ)) 128 if (!ptrace_may_access(task, PTRACE_MODE_READ))
129 goto out_put_task; 129 goto out_put_task;
130 130
131 ns_path.dentry = proc_ns_get_dentry(sb, task, ei->ns_ops); 131 ns_path.dentry = proc_ns_get_dentry(sb, task, ei->ns.ns_ops);
132 if (IS_ERR(ns_path.dentry)) { 132 if (IS_ERR(ns_path.dentry)) {
133 error = ERR_CAST(ns_path.dentry); 133 error = ERR_CAST(ns_path.dentry);
134 goto out_put_task; 134 goto out_put_task;
@@ -148,7 +148,7 @@ static int proc_ns_readlink(struct dentry *dentry, char __user *buffer, int bufl
148{ 148{
149 struct inode *inode = dentry->d_inode; 149 struct inode *inode = dentry->d_inode;
150 struct proc_inode *ei = PROC_I(inode); 150 struct proc_inode *ei = PROC_I(inode);
151 const struct proc_ns_operations *ns_ops = ei->ns_ops; 151 const struct proc_ns_operations *ns_ops = ei->ns.ns_ops;
152 struct task_struct *task; 152 struct task_struct *task;
153 void *ns; 153 void *ns;
154 char name[50]; 154 char name[50];
@@ -202,7 +202,7 @@ static struct dentry *proc_ns_instantiate(struct inode *dir,
202 ei = PROC_I(inode); 202 ei = PROC_I(inode);
203 inode->i_mode = S_IFLNK|S_IRWXUGO; 203 inode->i_mode = S_IFLNK|S_IRWXUGO;
204 inode->i_op = &proc_ns_link_inode_operations; 204 inode->i_op = &proc_ns_link_inode_operations;
205 ei->ns_ops = ns_ops; 205 ei->ns.ns_ops = ns_ops;
206 206
207 d_set_d_op(dentry, &pid_dentry_operations); 207 d_set_d_op(dentry, &pid_dentry_operations);
208 d_add(dentry, inode); 208 d_add(dentry, inode);
@@ -337,6 +337,11 @@ out_invalid:
337 return ERR_PTR(-EINVAL); 337 return ERR_PTR(-EINVAL);
338} 338}
339 339
340struct proc_ns *get_proc_ns(struct inode *inode)
341{
342 return &PROC_I(inode)->ns;
343}
344
340bool proc_ns_inode(struct inode *inode) 345bool proc_ns_inode(struct inode *inode)
341{ 346{
342 return inode->i_fop == &ns_file_operations; 347 return inode->i_fop == &ns_file_operations;
diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c
index 30b590f5bd35..505afc950e0a 100644
--- a/fs/proc/proc_devtree.c
+++ b/fs/proc/proc_devtree.c
@@ -41,7 +41,7 @@ static int property_proc_show(struct seq_file *m, void *v)
41 41
42static int property_proc_open(struct inode *inode, struct file *file) 42static int property_proc_open(struct inode *inode, struct file *file)
43{ 43{
44 return single_open(file, property_proc_show, PDE(inode)->data); 44 return single_open(file, property_proc_show, __PDE_DATA(inode));
45} 45}
46 46
47static const struct file_operations property_proc_fops = { 47static const struct file_operations property_proc_fops = {
diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c
index b4ac6572474f..986e83220d56 100644
--- a/fs/proc/proc_net.c
+++ b/fs/proc/proc_net.c
@@ -26,6 +26,10 @@
26 26
27#include "internal.h" 27#include "internal.h"
28 28
29static inline struct net *PDE_NET(struct proc_dir_entry *pde)
30{
31 return pde->parent->data;
32}
29 33
30static struct net *get_proc_net(const struct inode *inode) 34static struct net *get_proc_net(const struct inode *inode)
31{ 35{
diff --git a/fs/proc/root.c b/fs/proc/root.c
index 9c7fab1d23f0..41a6ea93f486 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -141,6 +141,8 @@ static void proc_kill_sb(struct super_block *sb)
141 struct pid_namespace *ns; 141 struct pid_namespace *ns;
142 142
143 ns = (struct pid_namespace *)sb->s_fs_info; 143 ns = (struct pid_namespace *)sb->s_fs_info;
144 if (ns->proc_self)
145 dput(ns->proc_self);
144 kill_anon_super(sb); 146 kill_anon_super(sb);
145 put_pid_ns(ns); 147 put_pid_ns(ns);
146} 148}
diff --git a/fs/proc/self.c b/fs/proc/self.c
index aa5cc3bff140..6b6a993b5c25 100644
--- a/fs/proc/self.c
+++ b/fs/proc/self.c
@@ -1,6 +1,8 @@
1#include <linux/proc_fs.h>
2#include <linux/sched.h> 1#include <linux/sched.h>
3#include <linux/namei.h> 2#include <linux/namei.h>
3#include <linux/slab.h>
4#include <linux/pid_namespace.h>
5#include "internal.h"
4 6
5/* 7/*
6 * /proc/self: 8 * /proc/self:
@@ -48,12 +50,43 @@ static const struct inode_operations proc_self_inode_operations = {
48 .put_link = proc_self_put_link, 50 .put_link = proc_self_put_link,
49}; 51};
50 52
51void __init proc_self_init(void) 53static unsigned self_inum;
54
55int proc_setup_self(struct super_block *s)
52{ 56{
53 struct proc_dir_entry *proc_self_symlink; 57 struct inode *root_inode = s->s_root->d_inode;
54 mode_t mode; 58 struct pid_namespace *ns = s->s_fs_info;
59 struct dentry *self;
60
61 mutex_lock(&root_inode->i_mutex);
62 self = d_alloc_name(s->s_root, "self");
63 if (self) {
64 struct inode *inode = new_inode_pseudo(s);
65 if (inode) {
66 inode->i_ino = self_inum;
67 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
68 inode->i_mode = S_IFLNK | S_IRWXUGO;
69 inode->i_uid = GLOBAL_ROOT_UID;
70 inode->i_gid = GLOBAL_ROOT_GID;
71 inode->i_op = &proc_self_inode_operations;
72 d_add(self, inode);
73 } else {
74 dput(self);
75 self = ERR_PTR(-ENOMEM);
76 }
77 } else {
78 self = ERR_PTR(-ENOMEM);
79 }
80 mutex_unlock(&root_inode->i_mutex);
81 if (IS_ERR(self)) {
82 pr_err("proc_fill_super: can't allocate /proc/self\n");
83 return PTR_ERR(self);
84 }
85 ns->proc_self = self;
86 return 0;
87}
55 88
56 mode = S_IFLNK | S_IRWXUGO; 89void __init proc_self_init(void)
57 proc_self_symlink = proc_create("self", mode, NULL, NULL ); 90{
58 proc_self_symlink->proc_iops = &proc_self_inode_operations; 91 proc_alloc_inum(&self_inum);
59} 92}
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
index b870f740ab5a..17f7e080d7ff 100644
--- a/fs/proc/vmcore.c
+++ b/fs/proc/vmcore.c
@@ -8,7 +8,7 @@
8 */ 8 */
9 9
10#include <linux/mm.h> 10#include <linux/mm.h>
11#include <linux/proc_fs.h> 11#include <linux/kcore.h>
12#include <linux/user.h> 12#include <linux/user.h>
13#include <linux/elf.h> 13#include <linux/elf.h>
14#include <linux/elfcore.h> 14#include <linux/elfcore.h>
@@ -22,6 +22,7 @@
22#include <linux/list.h> 22#include <linux/list.h>
23#include <asm/uaccess.h> 23#include <asm/uaccess.h>
24#include <asm/io.h> 24#include <asm/io.h>
25#include "internal.h"
25 26
26/* List representing chunks of contiguous memory areas and their offsets in 27/* List representing chunks of contiguous memory areas and their offsets in
27 * vmcore file. 28 * vmcore file.
@@ -698,7 +699,7 @@ void vmcore_cleanup(void)
698 struct list_head *pos, *next; 699 struct list_head *pos, *next;
699 700
700 if (proc_vmcore) { 701 if (proc_vmcore) {
701 remove_proc_entry(proc_vmcore->name, proc_vmcore->parent); 702 proc_remove(proc_vmcore);
702 proc_vmcore = NULL; 703 proc_vmcore = NULL;
703 } 704 }
704 705