aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc/base.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-11-02 19:07:27 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-11-02 19:07:27 -0400
commit092f4c56c1927e4b61a41ee8055005f1cb437009 (patch)
tree616ceb54b7671ccc13922ae9e002b8b972f6e09e /fs/proc/base.c
parent80c2861672bbf000f6af838656959ee937e4ee4d (diff)
parentc1e2ee2dc436574880758b3836fc96935b774c32 (diff)
Merge branch 'akpm' (Andrew's incoming - part two)
Says Andrew: "60 patches. That's good enough for -rc1 I guess. I have quite a lot of detritus to be rechecked, work through maintainers, etc. - most of the remains of MM - rtc - various misc - cgroups - memcg - cpusets - procfs - ipc - rapidio - sysctl - pps - w1 - drivers/misc - aio" * akpm: (60 commits) memcg: replace ss->id_lock with a rwlock aio: allocate kiocbs in batches drivers/misc/vmw_balloon.c: fix typo in code comment drivers/misc/vmw_balloon.c: determine page allocation flag can_sleep outside loop w1: disable irqs in critical section drivers/w1/w1_int.c: multiple masters used same init_name drivers/power/ds2780_battery.c: fix deadlock upon insertion and removal drivers/power/ds2780_battery.c: add a nolock function to w1 interface drivers/power/ds2780_battery.c: create central point for calling w1 interface w1: ds2760 and ds2780, use ida for id and ida_simple_get() to get it pps gpio client: add missing dependency pps: new client driver using GPIO pps: default echo function include/linux/dma-mapping.h: add dma_zalloc_coherent() sysctl: make CONFIG_SYSCTL_SYSCALL default to n sysctl: add support for poll() RapidIO: documentation update drivers/net/rionet.c: fix ethernet address macros for LE platforms RapidIO: fix potential null deref in rio_setup_device() RapidIO: add mport driver for Tsi721 bridge ...
Diffstat (limited to 'fs/proc/base.c')
-rw-r--r--fs/proc/base.c146
1 files changed, 103 insertions, 43 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 851ba3dcdc29..2db1bd3173b2 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1652,12 +1652,46 @@ out:
1652 return error; 1652 return error;
1653} 1653}
1654 1654
1655static int proc_pid_fd_link_getattr(struct vfsmount *mnt, struct dentry *dentry,
1656 struct kstat *stat)
1657{
1658 struct inode *inode = dentry->d_inode;
1659 struct task_struct *task = get_proc_task(inode);
1660 int rc;
1661
1662 if (task == NULL)
1663 return -ESRCH;
1664
1665 rc = -EACCES;
1666 if (lock_trace(task))
1667 goto out_task;
1668
1669 generic_fillattr(inode, stat);
1670 unlock_trace(task);
1671 rc = 0;
1672out_task:
1673 put_task_struct(task);
1674 return rc;
1675}
1676
1655static const struct inode_operations proc_pid_link_inode_operations = { 1677static const struct inode_operations proc_pid_link_inode_operations = {
1656 .readlink = proc_pid_readlink, 1678 .readlink = proc_pid_readlink,
1657 .follow_link = proc_pid_follow_link, 1679 .follow_link = proc_pid_follow_link,
1658 .setattr = proc_setattr, 1680 .setattr = proc_setattr,
1659}; 1681};
1660 1682
1683static const struct inode_operations proc_fdinfo_link_inode_operations = {
1684 .setattr = proc_setattr,
1685 .getattr = proc_pid_fd_link_getattr,
1686};
1687
1688static const struct inode_operations proc_fd_link_inode_operations = {
1689 .readlink = proc_pid_readlink,
1690 .follow_link = proc_pid_follow_link,
1691 .setattr = proc_setattr,
1692 .getattr = proc_pid_fd_link_getattr,
1693};
1694
1661 1695
1662/* building an inode */ 1696/* building an inode */
1663 1697
@@ -1889,49 +1923,61 @@ out:
1889 1923
1890static int proc_fd_info(struct inode *inode, struct path *path, char *info) 1924static int proc_fd_info(struct inode *inode, struct path *path, char *info)
1891{ 1925{
1892 struct task_struct *task = get_proc_task(inode); 1926 struct task_struct *task;
1893 struct files_struct *files = NULL; 1927 struct files_struct *files;
1894 struct file *file; 1928 struct file *file;
1895 int fd = proc_fd(inode); 1929 int fd = proc_fd(inode);
1930 int rc;
1896 1931
1897 if (task) { 1932 task = get_proc_task(inode);
1898 files = get_files_struct(task); 1933 if (!task)
1899 put_task_struct(task); 1934 return -ENOENT;
1900 } 1935
1901 if (files) { 1936 rc = -EACCES;
1902 /* 1937 if (lock_trace(task))
1903 * We are not taking a ref to the file structure, so we must 1938 goto out_task;
1904 * hold ->file_lock. 1939
1905 */ 1940 rc = -ENOENT;
1906 spin_lock(&files->file_lock); 1941 files = get_files_struct(task);
1907 file = fcheck_files(files, fd); 1942 if (files == NULL)
1908 if (file) { 1943 goto out_unlock;
1909 unsigned int f_flags; 1944
1910 struct fdtable *fdt; 1945 /*
1911 1946 * We are not taking a ref to the file structure, so we must
1912 fdt = files_fdtable(files); 1947 * hold ->file_lock.
1913 f_flags = file->f_flags & ~O_CLOEXEC; 1948 */
1914 if (FD_ISSET(fd, fdt->close_on_exec)) 1949 spin_lock(&files->file_lock);
1915 f_flags |= O_CLOEXEC; 1950 file = fcheck_files(files, fd);
1916 1951 if (file) {
1917 if (path) { 1952 unsigned int f_flags;
1918 *path = file->f_path; 1953 struct fdtable *fdt;
1919 path_get(&file->f_path); 1954
1920 } 1955 fdt = files_fdtable(files);
1921 if (info) 1956 f_flags = file->f_flags & ~O_CLOEXEC;
1922 snprintf(info, PROC_FDINFO_MAX, 1957 if (FD_ISSET(fd, fdt->close_on_exec))
1923 "pos:\t%lli\n" 1958 f_flags |= O_CLOEXEC;
1924 "flags:\t0%o\n", 1959
1925 (long long) file->f_pos, 1960 if (path) {
1926 f_flags); 1961 *path = file->f_path;
1927 spin_unlock(&files->file_lock); 1962 path_get(&file->f_path);
1928 put_files_struct(files);
1929 return 0;
1930 } 1963 }
1931 spin_unlock(&files->file_lock); 1964 if (info)
1932 put_files_struct(files); 1965 snprintf(info, PROC_FDINFO_MAX,
1933 } 1966 "pos:\t%lli\n"
1934 return -ENOENT; 1967 "flags:\t0%o\n",
1968 (long long) file->f_pos,
1969 f_flags);
1970 rc = 0;
1971 } else
1972 rc = -ENOENT;
1973 spin_unlock(&files->file_lock);
1974 put_files_struct(files);
1975
1976out_unlock:
1977 unlock_trace(task);
1978out_task:
1979 put_task_struct(task);
1980 return rc;
1935} 1981}
1936 1982
1937static int proc_fd_link(struct inode *inode, struct path *path) 1983static int proc_fd_link(struct inode *inode, struct path *path)
@@ -2026,7 +2072,7 @@ static struct dentry *proc_fd_instantiate(struct inode *dir,
2026 spin_unlock(&files->file_lock); 2072 spin_unlock(&files->file_lock);
2027 put_files_struct(files); 2073 put_files_struct(files);
2028 2074
2029 inode->i_op = &proc_pid_link_inode_operations; 2075 inode->i_op = &proc_fd_link_inode_operations;
2030 inode->i_size = 64; 2076 inode->i_size = 64;
2031 ei->op.proc_get_link = proc_fd_link; 2077 ei->op.proc_get_link = proc_fd_link;
2032 d_set_d_op(dentry, &tid_fd_dentry_operations); 2078 d_set_d_op(dentry, &tid_fd_dentry_operations);
@@ -2058,7 +2104,12 @@ static struct dentry *proc_lookupfd_common(struct inode *dir,
2058 if (fd == ~0U) 2104 if (fd == ~0U)
2059 goto out; 2105 goto out;
2060 2106
2107 result = ERR_PTR(-EACCES);
2108 if (lock_trace(task))
2109 goto out;
2110
2061 result = instantiate(dir, dentry, task, &fd); 2111 result = instantiate(dir, dentry, task, &fd);
2112 unlock_trace(task);
2062out: 2113out:
2063 put_task_struct(task); 2114 put_task_struct(task);
2064out_no_task: 2115out_no_task:
@@ -2078,23 +2129,28 @@ static int proc_readfd_common(struct file * filp, void * dirent,
2078 retval = -ENOENT; 2129 retval = -ENOENT;
2079 if (!p) 2130 if (!p)
2080 goto out_no_task; 2131 goto out_no_task;
2132
2133 retval = -EACCES;
2134 if (lock_trace(p))
2135 goto out;
2136
2081 retval = 0; 2137 retval = 0;
2082 2138
2083 fd = filp->f_pos; 2139 fd = filp->f_pos;
2084 switch (fd) { 2140 switch (fd) {
2085 case 0: 2141 case 0:
2086 if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0) 2142 if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0)
2087 goto out; 2143 goto out_unlock;
2088 filp->f_pos++; 2144 filp->f_pos++;
2089 case 1: 2145 case 1:
2090 ino = parent_ino(dentry); 2146 ino = parent_ino(dentry);
2091 if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0) 2147 if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0)
2092 goto out; 2148 goto out_unlock;
2093 filp->f_pos++; 2149 filp->f_pos++;
2094 default: 2150 default:
2095 files = get_files_struct(p); 2151 files = get_files_struct(p);
2096 if (!files) 2152 if (!files)
2097 goto out; 2153 goto out_unlock;
2098 rcu_read_lock(); 2154 rcu_read_lock();
2099 for (fd = filp->f_pos-2; 2155 for (fd = filp->f_pos-2;
2100 fd < files_fdtable(files)->max_fds; 2156 fd < files_fdtable(files)->max_fds;
@@ -2118,6 +2174,9 @@ static int proc_readfd_common(struct file * filp, void * dirent,
2118 rcu_read_unlock(); 2174 rcu_read_unlock();
2119 put_files_struct(files); 2175 put_files_struct(files);
2120 } 2176 }
2177
2178out_unlock:
2179 unlock_trace(p);
2121out: 2180out:
2122 put_task_struct(p); 2181 put_task_struct(p);
2123out_no_task: 2182out_no_task:
@@ -2195,6 +2254,7 @@ static struct dentry *proc_fdinfo_instantiate(struct inode *dir,
2195 ei->fd = fd; 2254 ei->fd = fd;
2196 inode->i_mode = S_IFREG | S_IRUSR; 2255 inode->i_mode = S_IFREG | S_IRUSR;
2197 inode->i_fop = &proc_fdinfo_file_operations; 2256 inode->i_fop = &proc_fdinfo_file_operations;
2257 inode->i_op = &proc_fdinfo_link_inode_operations;
2198 d_set_d_op(dentry, &tid_fd_dentry_operations); 2258 d_set_d_op(dentry, &tid_fd_dentry_operations);
2199 d_add(dentry, inode); 2259 d_add(dentry, inode);
2200 /* Close the race of the process dying before we return the dentry */ 2260 /* Close the race of the process dying before we return the dentry */