aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc
diff options
context:
space:
mode:
authorCyrill Gorcunov <gorcunov@openvz.org>2012-08-23 06:43:24 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-09-26 21:10:01 -0400
commitfaf60af17f8da87e1c87a6be527344791025ce9e (patch)
tree72f58a1061383a38dc6618f911d4becc95a22c03 /fs/proc
parent864bdb3b6cbd9911222543fef1cfe36f88183f44 (diff)
procfs: Move /proc/pid/fd[info] handling code to fd.[ch]
This patch prepares the ground for further extension of /proc/pid/fd[info] handling code by moving fdinfo handling code into fs/proc/fd.c. I think such move makes both fs/proc/base.c and fs/proc/fd.c easier to read. Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org> Acked-by: Pavel Emelyanov <xemul@parallels.com> CC: Al Viro <viro@ZenIV.linux.org.uk> CC: Alexey Dobriyan <adobriyan@gmail.com> CC: Andrew Morton <akpm@linux-foundation.org> CC: James Bottomley <jbottomley@parallels.com> CC: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com> CC: Alexey Dobriyan <adobriyan@gmail.com> CC: Matthew Helsley <matt.helsley@gmail.com> CC: "J. Bruce Fields" <bfields@fieldses.org> CC: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/proc')
-rw-r--r--fs/proc/Makefile2
-rw-r--r--fs/proc/base.c388
-rw-r--r--fs/proc/fd.c351
-rw-r--r--fs/proc/fd.h14
-rw-r--r--fs/proc/internal.h48
5 files changed, 416 insertions, 387 deletions
diff --git a/fs/proc/Makefile b/fs/proc/Makefile
index c1c729335924..99349efbbc2b 100644
--- a/fs/proc/Makefile
+++ b/fs/proc/Makefile
@@ -8,7 +8,7 @@ proc-y := nommu.o task_nommu.o
8proc-$(CONFIG_MMU) := mmu.o task_mmu.o 8proc-$(CONFIG_MMU) := mmu.o task_mmu.o
9 9
10proc-y += inode.o root.o base.o generic.o array.o \ 10proc-y += inode.o root.o base.o generic.o array.o \
11 proc_tty.o 11 proc_tty.o fd.o
12proc-y += cmdline.o 12proc-y += cmdline.o
13proc-y += consoles.o 13proc-y += consoles.o
14proc-y += cpuinfo.o 14proc-y += cpuinfo.o
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 1b6c84cbdb73..b55c3bb298e3 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -90,6 +90,7 @@
90#endif 90#endif
91#include <trace/events/oom.h> 91#include <trace/events/oom.h>
92#include "internal.h" 92#include "internal.h"
93#include "fd.h"
93 94
94/* NOTE: 95/* NOTE:
95 * Implementing inode permission operations in /proc is almost 96 * Implementing inode permission operations in /proc is almost
@@ -136,8 +137,6 @@ struct pid_entry {
136 NULL, &proc_single_file_operations, \ 137 NULL, &proc_single_file_operations, \
137 { .proc_show = show } ) 138 { .proc_show = show } )
138 139
139static int proc_fd_permission(struct inode *inode, int mask);
140
141/* 140/*
142 * Count the number of hardlinks for the pid_entry table, excluding the . 141 * Count the number of hardlinks for the pid_entry table, excluding the .
143 * and .. links. 142 * and .. links.
@@ -1492,7 +1491,7 @@ out:
1492 return error; 1491 return error;
1493} 1492}
1494 1493
1495static const struct inode_operations proc_pid_link_inode_operations = { 1494const struct inode_operations proc_pid_link_inode_operations = {
1496 .readlink = proc_pid_readlink, 1495 .readlink = proc_pid_readlink,
1497 .follow_link = proc_pid_follow_link, 1496 .follow_link = proc_pid_follow_link,
1498 .setattr = proc_setattr, 1497 .setattr = proc_setattr,
@@ -1501,21 +1500,6 @@ static const struct inode_operations proc_pid_link_inode_operations = {
1501 1500
1502/* building an inode */ 1501/* building an inode */
1503 1502
1504static int task_dumpable(struct task_struct *task)
1505{
1506 int dumpable = 0;
1507 struct mm_struct *mm;
1508
1509 task_lock(task);
1510 mm = task->mm;
1511 if (mm)
1512 dumpable = get_dumpable(mm);
1513 task_unlock(task);
1514 if(dumpable == 1)
1515 return 1;
1516 return 0;
1517}
1518
1519struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task) 1503struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task)
1520{ 1504{
1521 struct inode * inode; 1505 struct inode * inode;
@@ -1641,15 +1625,6 @@ int pid_revalidate(struct dentry *dentry, unsigned int flags)
1641 return 0; 1625 return 0;
1642} 1626}
1643 1627
1644static int pid_delete_dentry(const struct dentry * dentry)
1645{
1646 /* Is the task we represent dead?
1647 * If so, then don't put the dentry on the lru list,
1648 * kill it immediately.
1649 */
1650 return !proc_pid(dentry->d_inode)->tasks[PIDTYPE_PID].first;
1651}
1652
1653const struct dentry_operations pid_dentry_operations = 1628const struct dentry_operations pid_dentry_operations =
1654{ 1629{
1655 .d_revalidate = pid_revalidate, 1630 .d_revalidate = pid_revalidate,
@@ -1712,289 +1687,6 @@ end_instantiate:
1712 return filldir(dirent, name, len, filp->f_pos, ino, type); 1687 return filldir(dirent, name, len, filp->f_pos, ino, type);
1713} 1688}
1714 1689
1715static unsigned name_to_int(struct dentry *dentry)
1716{
1717 const char *name = dentry->d_name.name;
1718 int len = dentry->d_name.len;
1719 unsigned n = 0;
1720
1721 if (len > 1 && *name == '0')
1722 goto out;
1723 while (len-- > 0) {
1724 unsigned c = *name++ - '0';
1725 if (c > 9)
1726 goto out;
1727 if (n >= (~0U-9)/10)
1728 goto out;
1729 n *= 10;
1730 n += c;
1731 }
1732 return n;
1733out:
1734 return ~0U;
1735}
1736
1737#define PROC_FDINFO_MAX 64
1738
1739static int proc_fd_info(struct inode *inode, struct path *path, char *info)
1740{
1741 struct task_struct *task = get_proc_task(inode);
1742 struct files_struct *files = NULL;
1743 struct file *file;
1744 int fd = proc_fd(inode);
1745
1746 if (task) {
1747 files = get_files_struct(task);
1748 put_task_struct(task);
1749 }
1750 if (files) {
1751 /*
1752 * We are not taking a ref to the file structure, so we must
1753 * hold ->file_lock.
1754 */
1755 spin_lock(&files->file_lock);
1756 file = fcheck_files(files, fd);
1757 if (file) {
1758 unsigned int f_flags;
1759 struct fdtable *fdt;
1760
1761 fdt = files_fdtable(files);
1762 f_flags = file->f_flags & ~O_CLOEXEC;
1763 if (close_on_exec(fd, fdt))
1764 f_flags |= O_CLOEXEC;
1765
1766 if (path) {
1767 *path = file->f_path;
1768 path_get(&file->f_path);
1769 }
1770 if (info)
1771 snprintf(info, PROC_FDINFO_MAX,
1772 "pos:\t%lli\n"
1773 "flags:\t0%o\n",
1774 (long long) file->f_pos,
1775 f_flags);
1776 spin_unlock(&files->file_lock);
1777 put_files_struct(files);
1778 return 0;
1779 }
1780 spin_unlock(&files->file_lock);
1781 put_files_struct(files);
1782 }
1783 return -ENOENT;
1784}
1785
1786static int proc_fd_link(struct dentry *dentry, struct path *path)
1787{
1788 return proc_fd_info(dentry->d_inode, path, NULL);
1789}
1790
1791static int tid_fd_revalidate(struct dentry *dentry, unsigned int flags)
1792{
1793 struct inode *inode;
1794 struct task_struct *task;
1795 int fd;
1796 struct files_struct *files;
1797 const struct cred *cred;
1798
1799 if (flags & LOOKUP_RCU)
1800 return -ECHILD;
1801
1802 inode = dentry->d_inode;
1803 task = get_proc_task(inode);
1804 fd = proc_fd(inode);
1805
1806 if (task) {
1807 files = get_files_struct(task);
1808 if (files) {
1809 struct file *file;
1810 rcu_read_lock();
1811 file = fcheck_files(files, fd);
1812 if (file) {
1813 unsigned f_mode = file->f_mode;
1814
1815 rcu_read_unlock();
1816 put_files_struct(files);
1817
1818 if (task_dumpable(task)) {
1819 rcu_read_lock();
1820 cred = __task_cred(task);
1821 inode->i_uid = cred->euid;
1822 inode->i_gid = cred->egid;
1823 rcu_read_unlock();
1824 } else {
1825 inode->i_uid = GLOBAL_ROOT_UID;
1826 inode->i_gid = GLOBAL_ROOT_GID;
1827 }
1828
1829 if (S_ISLNK(inode->i_mode)) {
1830 unsigned i_mode = S_IFLNK;
1831 if (f_mode & FMODE_READ)
1832 i_mode |= S_IRUSR | S_IXUSR;
1833 if (f_mode & FMODE_WRITE)
1834 i_mode |= S_IWUSR | S_IXUSR;
1835 inode->i_mode = i_mode;
1836 }
1837
1838 security_task_to_inode(task, inode);
1839 put_task_struct(task);
1840 return 1;
1841 }
1842 rcu_read_unlock();
1843 put_files_struct(files);
1844 }
1845 put_task_struct(task);
1846 }
1847 d_drop(dentry);
1848 return 0;
1849}
1850
1851static const struct dentry_operations tid_fd_dentry_operations =
1852{
1853 .d_revalidate = tid_fd_revalidate,
1854 .d_delete = pid_delete_dentry,
1855};
1856
1857static struct dentry *proc_fd_instantiate(struct inode *dir,
1858 struct dentry *dentry, struct task_struct *task, const void *ptr)
1859{
1860 unsigned fd = (unsigned long)ptr;
1861 struct inode *inode;
1862 struct proc_inode *ei;
1863 struct dentry *error = ERR_PTR(-ENOENT);
1864
1865 inode = proc_pid_make_inode(dir->i_sb, task);
1866 if (!inode)
1867 goto out;
1868 ei = PROC_I(inode);
1869 ei->fd = fd;
1870
1871 inode->i_mode = S_IFLNK;
1872 inode->i_op = &proc_pid_link_inode_operations;
1873 inode->i_size = 64;
1874 ei->op.proc_get_link = proc_fd_link;
1875 d_set_d_op(dentry, &tid_fd_dentry_operations);
1876 d_add(dentry, inode);
1877 /* Close the race of the process dying before we return the dentry */
1878 if (tid_fd_revalidate(dentry, 0))
1879 error = NULL;
1880
1881 out:
1882 return error;
1883}
1884
1885static struct dentry *proc_lookupfd_common(struct inode *dir,
1886 struct dentry *dentry,
1887 instantiate_t instantiate)
1888{
1889 struct task_struct *task = get_proc_task(dir);
1890 unsigned fd = name_to_int(dentry);
1891 struct dentry *result = ERR_PTR(-ENOENT);
1892
1893 if (!task)
1894 goto out_no_task;
1895 if (fd == ~0U)
1896 goto out;
1897
1898 result = instantiate(dir, dentry, task, (void *)(unsigned long)fd);
1899out:
1900 put_task_struct(task);
1901out_no_task:
1902 return result;
1903}
1904
1905static int proc_readfd_common(struct file * filp, void * dirent,
1906 filldir_t filldir, instantiate_t instantiate)
1907{
1908 struct dentry *dentry = filp->f_path.dentry;
1909 struct inode *inode = dentry->d_inode;
1910 struct task_struct *p = get_proc_task(inode);
1911 unsigned int fd, ino;
1912 int retval;
1913 struct files_struct * files;
1914
1915 retval = -ENOENT;
1916 if (!p)
1917 goto out_no_task;
1918 retval = 0;
1919
1920 fd = filp->f_pos;
1921 switch (fd) {
1922 case 0:
1923 if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0)
1924 goto out;
1925 filp->f_pos++;
1926 case 1:
1927 ino = parent_ino(dentry);
1928 if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0)
1929 goto out;
1930 filp->f_pos++;
1931 default:
1932 files = get_files_struct(p);
1933 if (!files)
1934 goto out;
1935 rcu_read_lock();
1936 for (fd = filp->f_pos-2;
1937 fd < files_fdtable(files)->max_fds;
1938 fd++, filp->f_pos++) {
1939 char name[PROC_NUMBUF];
1940 int len;
1941 int rv;
1942
1943 if (!fcheck_files(files, fd))
1944 continue;
1945 rcu_read_unlock();
1946
1947 len = snprintf(name, sizeof(name), "%d", fd);
1948 rv = proc_fill_cache(filp, dirent, filldir,
1949 name, len, instantiate, p,
1950 (void *)(unsigned long)fd);
1951 if (rv < 0)
1952 goto out_fd_loop;
1953 rcu_read_lock();
1954 }
1955 rcu_read_unlock();
1956out_fd_loop:
1957 put_files_struct(files);
1958 }
1959out:
1960 put_task_struct(p);
1961out_no_task:
1962 return retval;
1963}
1964
1965static struct dentry *proc_lookupfd(struct inode *dir, struct dentry *dentry,
1966 unsigned int flags)
1967{
1968 return proc_lookupfd_common(dir, dentry, proc_fd_instantiate);
1969}
1970
1971static int proc_readfd(struct file *filp, void *dirent, filldir_t filldir)
1972{
1973 return proc_readfd_common(filp, dirent, filldir, proc_fd_instantiate);
1974}
1975
1976static ssize_t proc_fdinfo_read(struct file *file, char __user *buf,
1977 size_t len, loff_t *ppos)
1978{
1979 char tmp[PROC_FDINFO_MAX];
1980 int err = proc_fd_info(file->f_path.dentry->d_inode, NULL, tmp);
1981 if (!err)
1982 err = simple_read_from_buffer(buf, len, ppos, tmp, strlen(tmp));
1983 return err;
1984}
1985
1986static const struct file_operations proc_fdinfo_file_operations = {
1987 .open = nonseekable_open,
1988 .read = proc_fdinfo_read,
1989 .llseek = no_llseek,
1990};
1991
1992static const struct file_operations proc_fd_operations = {
1993 .read = generic_read_dir,
1994 .readdir = proc_readfd,
1995 .llseek = default_llseek,
1996};
1997
1998#ifdef CONFIG_CHECKPOINT_RESTORE 1690#ifdef CONFIG_CHECKPOINT_RESTORE
1999 1691
2000/* 1692/*
@@ -2337,82 +2029,6 @@ static const struct file_operations proc_map_files_operations = {
2337 2029
2338#endif /* CONFIG_CHECKPOINT_RESTORE */ 2030#endif /* CONFIG_CHECKPOINT_RESTORE */
2339 2031
2340/*
2341 * /proc/pid/fd needs a special permission handler so that a process can still
2342 * access /proc/self/fd after it has executed a setuid().
2343 */
2344static int proc_fd_permission(struct inode *inode, int mask)
2345{
2346 int rv = generic_permission(inode, mask);
2347 if (rv == 0)
2348 return 0;
2349 if (task_pid(current) == proc_pid(inode))
2350 rv = 0;
2351 return rv;
2352}
2353
2354/*
2355 * proc directories can do almost nothing..
2356 */
2357static const struct inode_operations proc_fd_inode_operations = {
2358 .lookup = proc_lookupfd,
2359 .permission = proc_fd_permission,
2360 .setattr = proc_setattr,
2361};
2362
2363static struct dentry *proc_fdinfo_instantiate(struct inode *dir,
2364 struct dentry *dentry, struct task_struct *task, const void *ptr)
2365{
2366 unsigned fd = (unsigned long)ptr;
2367 struct inode *inode;
2368 struct proc_inode *ei;
2369 struct dentry *error = ERR_PTR(-ENOENT);
2370
2371 inode = proc_pid_make_inode(dir->i_sb, task);
2372 if (!inode)
2373 goto out;
2374 ei = PROC_I(inode);
2375 ei->fd = fd;
2376 inode->i_mode = S_IFREG | S_IRUSR;
2377 inode->i_fop = &proc_fdinfo_file_operations;
2378 d_set_d_op(dentry, &tid_fd_dentry_operations);
2379 d_add(dentry, inode);
2380 /* Close the race of the process dying before we return the dentry */
2381 if (tid_fd_revalidate(dentry, 0))
2382 error = NULL;
2383
2384 out:
2385 return error;
2386}
2387
2388static struct dentry *proc_lookupfdinfo(struct inode *dir,
2389 struct dentry *dentry,
2390 unsigned int flags)
2391{
2392 return proc_lookupfd_common(dir, dentry, proc_fdinfo_instantiate);
2393}
2394
2395static int proc_readfdinfo(struct file *filp, void *dirent, filldir_t filldir)
2396{
2397 return proc_readfd_common(filp, dirent, filldir,
2398 proc_fdinfo_instantiate);
2399}
2400
2401static const struct file_operations proc_fdinfo_operations = {
2402 .read = generic_read_dir,
2403 .readdir = proc_readfdinfo,
2404 .llseek = default_llseek,
2405};
2406
2407/*
2408 * proc directories can do almost nothing..
2409 */
2410static const struct inode_operations proc_fdinfo_inode_operations = {
2411 .lookup = proc_lookupfdinfo,
2412 .setattr = proc_setattr,
2413};
2414
2415
2416static struct dentry *proc_pident_instantiate(struct inode *dir, 2032static struct dentry *proc_pident_instantiate(struct inode *dir,
2417 struct dentry *dentry, struct task_struct *task, const void *ptr) 2033 struct dentry *dentry, struct task_struct *task, const void *ptr)
2418{ 2034{
diff --git a/fs/proc/fd.c b/fs/proc/fd.c
new file mode 100644
index 000000000000..1b0f932b4bd9
--- /dev/null
+++ b/fs/proc/fd.c
@@ -0,0 +1,351 @@
1#include <linux/sched.h>
2#include <linux/errno.h>
3#include <linux/dcache.h>
4#include <linux/path.h>
5#include <linux/fdtable.h>
6#include <linux/namei.h>
7#include <linux/pid.h>
8#include <linux/security.h>
9
10#include <linux/proc_fs.h>
11
12#include "internal.h"
13#include "fd.h"
14
15#define PROC_FDINFO_MAX 64
16
17static int proc_fd_info(struct inode *inode, struct path *path, char *info)
18{
19 struct task_struct *task = get_proc_task(inode);
20 struct files_struct *files = NULL;
21 int fd = proc_fd(inode);
22 struct file *file;
23
24 if (task) {
25 files = get_files_struct(task);
26 put_task_struct(task);
27 }
28 if (files) {
29 /*
30 * We are not taking a ref to the file structure, so we must
31 * hold ->file_lock.
32 */
33 spin_lock(&files->file_lock);
34 file = fcheck_files(files, fd);
35 if (file) {
36 unsigned int f_flags;
37 struct fdtable *fdt;
38
39 fdt = files_fdtable(files);
40 f_flags = file->f_flags & ~O_CLOEXEC;
41 if (close_on_exec(fd, fdt))
42 f_flags |= O_CLOEXEC;
43
44 if (path) {
45 *path = file->f_path;
46 path_get(&file->f_path);
47 }
48 if (info)
49 snprintf(info, PROC_FDINFO_MAX,
50 "pos:\t%lli\n"
51 "flags:\t0%o\n",
52 (long long) file->f_pos,
53 f_flags);
54 spin_unlock(&files->file_lock);
55 put_files_struct(files);
56 return 0;
57 }
58 spin_unlock(&files->file_lock);
59 put_files_struct(files);
60 }
61 return -ENOENT;
62}
63
64static int tid_fd_revalidate(struct dentry *dentry, unsigned int flags)
65{
66 struct files_struct *files;
67 struct task_struct *task;
68 const struct cred *cred;
69 struct inode *inode;
70 int fd;
71
72 if (flags & LOOKUP_RCU)
73 return -ECHILD;
74
75 inode = dentry->d_inode;
76 task = get_proc_task(inode);
77 fd = proc_fd(inode);
78
79 if (task) {
80 files = get_files_struct(task);
81 if (files) {
82 struct file *file;
83
84 rcu_read_lock();
85 file = fcheck_files(files, fd);
86 if (file) {
87 unsigned f_mode = file->f_mode;
88
89 rcu_read_unlock();
90 put_files_struct(files);
91
92 if (task_dumpable(task)) {
93 rcu_read_lock();
94 cred = __task_cred(task);
95 inode->i_uid = cred->euid;
96 inode->i_gid = cred->egid;
97 rcu_read_unlock();
98 } else {
99 inode->i_uid = GLOBAL_ROOT_UID;
100 inode->i_gid = GLOBAL_ROOT_GID;
101 }
102
103 if (S_ISLNK(inode->i_mode)) {
104 unsigned i_mode = S_IFLNK;
105 if (f_mode & FMODE_READ)
106 i_mode |= S_IRUSR | S_IXUSR;
107 if (f_mode & FMODE_WRITE)
108 i_mode |= S_IWUSR | S_IXUSR;
109 inode->i_mode = i_mode;
110 }
111
112 security_task_to_inode(task, inode);
113 put_task_struct(task);
114 return 1;
115 }
116 rcu_read_unlock();
117 put_files_struct(files);
118 }
119 put_task_struct(task);
120 }
121
122 d_drop(dentry);
123 return 0;
124}
125
126static const struct dentry_operations tid_fd_dentry_operations = {
127 .d_revalidate = tid_fd_revalidate,
128 .d_delete = pid_delete_dentry,
129};
130
131static int proc_fd_link(struct dentry *dentry, struct path *path)
132{
133 return proc_fd_info(dentry->d_inode, path, NULL);
134}
135
136static struct dentry *
137proc_fd_instantiate(struct inode *dir, struct dentry *dentry,
138 struct task_struct *task, const void *ptr)
139{
140 struct dentry *error = ERR_PTR(-ENOENT);
141 unsigned fd = (unsigned long)ptr;
142 struct proc_inode *ei;
143 struct inode *inode;
144
145 inode = proc_pid_make_inode(dir->i_sb, task);
146 if (!inode)
147 goto out;
148
149 ei = PROC_I(inode);
150 ei->fd = fd;
151
152 inode->i_mode = S_IFLNK;
153 inode->i_op = &proc_pid_link_inode_operations;
154 inode->i_size = 64;
155
156 ei->op.proc_get_link = proc_fd_link;
157
158 d_set_d_op(dentry, &tid_fd_dentry_operations);
159 d_add(dentry, inode);
160
161 /* Close the race of the process dying before we return the dentry */
162 if (tid_fd_revalidate(dentry, 0))
163 error = NULL;
164 out:
165 return error;
166}
167
168static struct dentry *proc_lookupfd_common(struct inode *dir,
169 struct dentry *dentry,
170 instantiate_t instantiate)
171{
172 struct task_struct *task = get_proc_task(dir);
173 struct dentry *result = ERR_PTR(-ENOENT);
174 unsigned fd = name_to_int(dentry);
175
176 if (!task)
177 goto out_no_task;
178 if (fd == ~0U)
179 goto out;
180
181 result = instantiate(dir, dentry, task, (void *)(unsigned long)fd);
182out:
183 put_task_struct(task);
184out_no_task:
185 return result;
186}
187
188static int proc_readfd_common(struct file * filp, void * dirent,
189 filldir_t filldir, instantiate_t instantiate)
190{
191 struct dentry *dentry = filp->f_path.dentry;
192 struct inode *inode = dentry->d_inode;
193 struct task_struct *p = get_proc_task(inode);
194 struct files_struct *files;
195 unsigned int fd, ino;
196 int retval;
197
198 retval = -ENOENT;
199 if (!p)
200 goto out_no_task;
201 retval = 0;
202
203 fd = filp->f_pos;
204 switch (fd) {
205 case 0:
206 if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0)
207 goto out;
208 filp->f_pos++;
209 case 1:
210 ino = parent_ino(dentry);
211 if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0)
212 goto out;
213 filp->f_pos++;
214 default:
215 files = get_files_struct(p);
216 if (!files)
217 goto out;
218 rcu_read_lock();
219 for (fd = filp->f_pos - 2;
220 fd < files_fdtable(files)->max_fds;
221 fd++, filp->f_pos++) {
222 char name[PROC_NUMBUF];
223 int len;
224 int rv;
225
226 if (!fcheck_files(files, fd))
227 continue;
228 rcu_read_unlock();
229
230 len = snprintf(name, sizeof(name), "%d", fd);
231 rv = proc_fill_cache(filp, dirent, filldir,
232 name, len, instantiate, p,
233 (void *)(unsigned long)fd);
234 if (rv < 0)
235 goto out_fd_loop;
236 rcu_read_lock();
237 }
238 rcu_read_unlock();
239out_fd_loop:
240 put_files_struct(files);
241 }
242out:
243 put_task_struct(p);
244out_no_task:
245 return retval;
246}
247
248static ssize_t proc_fdinfo_read(struct file *file, char __user *buf,
249 size_t len, loff_t *ppos)
250{
251 char tmp[PROC_FDINFO_MAX];
252 int err = proc_fd_info(file->f_path.dentry->d_inode, NULL, tmp);
253 if (!err)
254 err = simple_read_from_buffer(buf, len, ppos, tmp, strlen(tmp));
255 return err;
256}
257
258static const struct file_operations proc_fdinfo_file_operations = {
259 .open = nonseekable_open,
260 .read = proc_fdinfo_read,
261 .llseek = no_llseek,
262};
263
264static int proc_readfd(struct file *filp, void *dirent, filldir_t filldir)
265{
266 return proc_readfd_common(filp, dirent, filldir, proc_fd_instantiate);
267}
268
269const struct file_operations proc_fd_operations = {
270 .read = generic_read_dir,
271 .readdir = proc_readfd,
272 .llseek = default_llseek,
273};
274
275static struct dentry *proc_lookupfd(struct inode *dir, struct dentry *dentry,
276 unsigned int flags)
277{
278 return proc_lookupfd_common(dir, dentry, proc_fd_instantiate);
279}
280
281/*
282 * /proc/pid/fd needs a special permission handler so that a process can still
283 * access /proc/self/fd after it has executed a setuid().
284 */
285int proc_fd_permission(struct inode *inode, int mask)
286{
287 int rv = generic_permission(inode, mask);
288 if (rv == 0)
289 return 0;
290 if (task_pid(current) == proc_pid(inode))
291 rv = 0;
292 return rv;
293}
294
295const struct inode_operations proc_fd_inode_operations = {
296 .lookup = proc_lookupfd,
297 .permission = proc_fd_permission,
298 .setattr = proc_setattr,
299};
300
301static struct dentry *
302proc_fdinfo_instantiate(struct inode *dir, struct dentry *dentry,
303 struct task_struct *task, const void *ptr)
304{
305 struct dentry *error = ERR_PTR(-ENOENT);
306 unsigned fd = (unsigned long)ptr;
307 struct proc_inode *ei;
308 struct inode *inode;
309
310 inode = proc_pid_make_inode(dir->i_sb, task);
311 if (!inode)
312 goto out;
313
314 ei = PROC_I(inode);
315 ei->fd = fd;
316
317 inode->i_mode = S_IFREG | S_IRUSR;
318 inode->i_fop = &proc_fdinfo_file_operations;
319
320 d_set_d_op(dentry, &tid_fd_dentry_operations);
321 d_add(dentry, inode);
322
323 /* Close the race of the process dying before we return the dentry */
324 if (tid_fd_revalidate(dentry, 0))
325 error = NULL;
326 out:
327 return error;
328}
329
330static struct dentry *
331proc_lookupfdinfo(struct inode *dir, struct dentry *dentry, unsigned int flags)
332{
333 return proc_lookupfd_common(dir, dentry, proc_fdinfo_instantiate);
334}
335
336static int proc_readfdinfo(struct file *filp, void *dirent, filldir_t filldir)
337{
338 return proc_readfd_common(filp, dirent, filldir,
339 proc_fdinfo_instantiate);
340}
341
342const struct inode_operations proc_fdinfo_inode_operations = {
343 .lookup = proc_lookupfdinfo,
344 .setattr = proc_setattr,
345};
346
347const struct file_operations proc_fdinfo_operations = {
348 .read = generic_read_dir,
349 .readdir = proc_readfdinfo,
350 .llseek = default_llseek,
351};
diff --git a/fs/proc/fd.h b/fs/proc/fd.h
new file mode 100644
index 000000000000..cbb1d47deda8
--- /dev/null
+++ b/fs/proc/fd.h
@@ -0,0 +1,14 @@
1#ifndef __PROCFS_FD_H__
2#define __PROCFS_FD_H__
3
4#include <linux/fs.h>
5
6extern const struct file_operations proc_fd_operations;
7extern const struct inode_operations proc_fd_inode_operations;
8
9extern const struct file_operations proc_fdinfo_operations;
10extern const struct inode_operations proc_fdinfo_inode_operations;
11
12extern int proc_fd_permission(struct inode *inode, int mask);
13
14#endif /* __PROCFS_FD_H__ */
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index e1167a1c9126..67925a7bd8cb 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -9,6 +9,7 @@
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>
12#include <linux/proc_fs.h> 13#include <linux/proc_fs.h>
13struct ctl_table_header; 14struct ctl_table_header;
14 15
@@ -65,6 +66,7 @@ extern const struct file_operations proc_clear_refs_operations;
65extern const struct file_operations proc_pagemap_operations; 66extern const struct file_operations proc_pagemap_operations;
66extern const struct file_operations proc_net_operations; 67extern const struct file_operations proc_net_operations;
67extern const struct inode_operations proc_net_inode_operations; 68extern const struct inode_operations proc_net_inode_operations;
69extern const struct inode_operations proc_pid_link_inode_operations;
68 70
69struct proc_maps_private { 71struct proc_maps_private {
70 struct pid *pid; 72 struct pid *pid;
@@ -91,6 +93,52 @@ static inline int proc_fd(struct inode *inode)
91 return PROC_I(inode)->fd; 93 return PROC_I(inode)->fd;
92} 94}
93 95
96static inline int task_dumpable(struct task_struct *task)
97{
98 int dumpable = 0;
99 struct mm_struct *mm;
100
101 task_lock(task);
102 mm = task->mm;
103 if (mm)
104 dumpable = get_dumpable(mm);
105 task_unlock(task);
106 if(dumpable == 1)
107 return 1;
108 return 0;
109}
110
111static inline int pid_delete_dentry(const struct dentry * dentry)
112{
113 /* Is the task we represent dead?
114 * If so, then don't put the dentry on the lru list,
115 * kill it immediately.
116 */
117 return !proc_pid(dentry->d_inode)->tasks[PIDTYPE_PID].first;
118}
119
120static inline unsigned name_to_int(struct dentry *dentry)
121{
122 const char *name = dentry->d_name.name;
123 int len = dentry->d_name.len;
124 unsigned n = 0;
125
126 if (len > 1 && *name == '0')
127 goto out;
128 while (len-- > 0) {
129 unsigned c = *name++ - '0';
130 if (c > 9)
131 goto out;
132 if (n >= (~0U-9)/10)
133 goto out;
134 n *= 10;
135 n += c;
136 }
137 return n;
138out:
139 return ~0U;
140}
141
94struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *ino, 142struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *ino,
95 struct dentry *dentry); 143 struct dentry *dentry);
96int proc_readdir_de(struct proc_dir_entry *de, struct file *filp, void *dirent, 144int proc_readdir_de(struct proc_dir_entry *de, struct file *filp, void *dirent,