diff options
Diffstat (limited to 'fs/proc/base.c')
-rw-r--r-- | fs/proc/base.c | 462 |
1 files changed, 175 insertions, 287 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index c3834dad09b3..1485e38daaa3 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -1681,46 +1681,34 @@ const struct dentry_operations pid_dentry_operations = | |||
1681 | * reported by readdir in sync with the inode numbers reported | 1681 | * reported by readdir in sync with the inode numbers reported |
1682 | * by stat. | 1682 | * by stat. |
1683 | */ | 1683 | */ |
1684 | int proc_fill_cache(struct file *filp, void *dirent, filldir_t filldir, | 1684 | bool proc_fill_cache(struct file *file, struct dir_context *ctx, |
1685 | const char *name, int len, | 1685 | const char *name, int len, |
1686 | instantiate_t instantiate, struct task_struct *task, const void *ptr) | 1686 | instantiate_t instantiate, struct task_struct *task, const void *ptr) |
1687 | { | 1687 | { |
1688 | struct dentry *child, *dir = filp->f_path.dentry; | 1688 | struct dentry *child, *dir = file->f_path.dentry; |
1689 | struct qstr qname = QSTR_INIT(name, len); | ||
1689 | struct inode *inode; | 1690 | struct inode *inode; |
1690 | struct qstr qname; | 1691 | unsigned type; |
1691 | ino_t ino = 0; | 1692 | ino_t ino; |
1692 | unsigned type = DT_UNKNOWN; | ||
1693 | |||
1694 | qname.name = name; | ||
1695 | qname.len = len; | ||
1696 | qname.hash = full_name_hash(name, len); | ||
1697 | 1693 | ||
1698 | child = d_lookup(dir, &qname); | 1694 | child = d_hash_and_lookup(dir, &qname); |
1699 | if (!child) { | 1695 | if (!child) { |
1700 | struct dentry *new; | 1696 | child = d_alloc(dir, &qname); |
1701 | new = d_alloc(dir, &qname); | 1697 | if (!child) |
1702 | if (new) { | 1698 | goto end_instantiate; |
1703 | child = instantiate(dir->d_inode, new, task, ptr); | 1699 | if (instantiate(dir->d_inode, child, task, ptr) < 0) { |
1704 | if (child) | 1700 | dput(child); |
1705 | dput(new); | 1701 | goto end_instantiate; |
1706 | else | ||
1707 | child = new; | ||
1708 | } | 1702 | } |
1709 | } | 1703 | } |
1710 | if (!child || IS_ERR(child) || !child->d_inode) | ||
1711 | goto end_instantiate; | ||
1712 | inode = child->d_inode; | 1704 | inode = child->d_inode; |
1713 | if (inode) { | 1705 | ino = inode->i_ino; |
1714 | ino = inode->i_ino; | 1706 | type = inode->i_mode >> 12; |
1715 | type = inode->i_mode >> 12; | ||
1716 | } | ||
1717 | dput(child); | 1707 | dput(child); |
1708 | return dir_emit(ctx, name, len, ino, type); | ||
1709 | |||
1718 | end_instantiate: | 1710 | end_instantiate: |
1719 | if (!ino) | 1711 | return dir_emit(ctx, name, len, 1, DT_UNKNOWN); |
1720 | ino = find_inode_number(dir, &qname); | ||
1721 | if (!ino) | ||
1722 | ino = 1; | ||
1723 | return filldir(dirent, name, len, filp->f_pos, ino, type); | ||
1724 | } | 1712 | } |
1725 | 1713 | ||
1726 | #ifdef CONFIG_CHECKPOINT_RESTORE | 1714 | #ifdef CONFIG_CHECKPOINT_RESTORE |
@@ -1846,7 +1834,7 @@ struct map_files_info { | |||
1846 | unsigned char name[4*sizeof(long)+2]; /* max: %lx-%lx\0 */ | 1834 | unsigned char name[4*sizeof(long)+2]; /* max: %lx-%lx\0 */ |
1847 | }; | 1835 | }; |
1848 | 1836 | ||
1849 | static struct dentry * | 1837 | static int |
1850 | proc_map_files_instantiate(struct inode *dir, struct dentry *dentry, | 1838 | proc_map_files_instantiate(struct inode *dir, struct dentry *dentry, |
1851 | struct task_struct *task, const void *ptr) | 1839 | struct task_struct *task, const void *ptr) |
1852 | { | 1840 | { |
@@ -1856,7 +1844,7 @@ proc_map_files_instantiate(struct inode *dir, struct dentry *dentry, | |||
1856 | 1844 | ||
1857 | inode = proc_pid_make_inode(dir->i_sb, task); | 1845 | inode = proc_pid_make_inode(dir->i_sb, task); |
1858 | if (!inode) | 1846 | if (!inode) |
1859 | return ERR_PTR(-ENOENT); | 1847 | return -ENOENT; |
1860 | 1848 | ||
1861 | ei = PROC_I(inode); | 1849 | ei = PROC_I(inode); |
1862 | ei->op.proc_get_link = proc_map_files_get_link; | 1850 | ei->op.proc_get_link = proc_map_files_get_link; |
@@ -1873,7 +1861,7 @@ proc_map_files_instantiate(struct inode *dir, struct dentry *dentry, | |||
1873 | d_set_d_op(dentry, &tid_map_files_dentry_operations); | 1861 | d_set_d_op(dentry, &tid_map_files_dentry_operations); |
1874 | d_add(dentry, inode); | 1862 | d_add(dentry, inode); |
1875 | 1863 | ||
1876 | return NULL; | 1864 | return 0; |
1877 | } | 1865 | } |
1878 | 1866 | ||
1879 | static struct dentry *proc_map_files_lookup(struct inode *dir, | 1867 | static struct dentry *proc_map_files_lookup(struct inode *dir, |
@@ -1882,23 +1870,23 @@ static struct dentry *proc_map_files_lookup(struct inode *dir, | |||
1882 | unsigned long vm_start, vm_end; | 1870 | unsigned long vm_start, vm_end; |
1883 | struct vm_area_struct *vma; | 1871 | struct vm_area_struct *vma; |
1884 | struct task_struct *task; | 1872 | struct task_struct *task; |
1885 | struct dentry *result; | 1873 | int result; |
1886 | struct mm_struct *mm; | 1874 | struct mm_struct *mm; |
1887 | 1875 | ||
1888 | result = ERR_PTR(-EPERM); | 1876 | result = -EPERM; |
1889 | if (!capable(CAP_SYS_ADMIN)) | 1877 | if (!capable(CAP_SYS_ADMIN)) |
1890 | goto out; | 1878 | goto out; |
1891 | 1879 | ||
1892 | result = ERR_PTR(-ENOENT); | 1880 | result = -ENOENT; |
1893 | task = get_proc_task(dir); | 1881 | task = get_proc_task(dir); |
1894 | if (!task) | 1882 | if (!task) |
1895 | goto out; | 1883 | goto out; |
1896 | 1884 | ||
1897 | result = ERR_PTR(-EACCES); | 1885 | result = -EACCES; |
1898 | if (!ptrace_may_access(task, PTRACE_MODE_READ)) | 1886 | if (!ptrace_may_access(task, PTRACE_MODE_READ)) |
1899 | goto out_put_task; | 1887 | goto out_put_task; |
1900 | 1888 | ||
1901 | result = ERR_PTR(-ENOENT); | 1889 | result = -ENOENT; |
1902 | if (dname_to_vma_addr(dentry, &vm_start, &vm_end)) | 1890 | if (dname_to_vma_addr(dentry, &vm_start, &vm_end)) |
1903 | goto out_put_task; | 1891 | goto out_put_task; |
1904 | 1892 | ||
@@ -1921,7 +1909,7 @@ out_no_vma: | |||
1921 | out_put_task: | 1909 | out_put_task: |
1922 | put_task_struct(task); | 1910 | put_task_struct(task); |
1923 | out: | 1911 | out: |
1924 | return result; | 1912 | return ERR_PTR(result); |
1925 | } | 1913 | } |
1926 | 1914 | ||
1927 | static const struct inode_operations proc_map_files_inode_operations = { | 1915 | static const struct inode_operations proc_map_files_inode_operations = { |
@@ -1931,14 +1919,15 @@ static const struct inode_operations proc_map_files_inode_operations = { | |||
1931 | }; | 1919 | }; |
1932 | 1920 | ||
1933 | static int | 1921 | static int |
1934 | proc_map_files_readdir(struct file *filp, void *dirent, filldir_t filldir) | 1922 | proc_map_files_readdir(struct file *file, struct dir_context *ctx) |
1935 | { | 1923 | { |
1936 | struct dentry *dentry = filp->f_path.dentry; | ||
1937 | struct inode *inode = dentry->d_inode; | ||
1938 | struct vm_area_struct *vma; | 1924 | struct vm_area_struct *vma; |
1939 | struct task_struct *task; | 1925 | struct task_struct *task; |
1940 | struct mm_struct *mm; | 1926 | struct mm_struct *mm; |
1941 | ino_t ino; | 1927 | unsigned long nr_files, pos, i; |
1928 | struct flex_array *fa = NULL; | ||
1929 | struct map_files_info info; | ||
1930 | struct map_files_info *p; | ||
1942 | int ret; | 1931 | int ret; |
1943 | 1932 | ||
1944 | ret = -EPERM; | 1933 | ret = -EPERM; |
@@ -1946,7 +1935,7 @@ proc_map_files_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
1946 | goto out; | 1935 | goto out; |
1947 | 1936 | ||
1948 | ret = -ENOENT; | 1937 | ret = -ENOENT; |
1949 | task = get_proc_task(inode); | 1938 | task = get_proc_task(file_inode(file)); |
1950 | if (!task) | 1939 | if (!task) |
1951 | goto out; | 1940 | goto out; |
1952 | 1941 | ||
@@ -1955,91 +1944,73 @@ proc_map_files_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
1955 | goto out_put_task; | 1944 | goto out_put_task; |
1956 | 1945 | ||
1957 | ret = 0; | 1946 | ret = 0; |
1958 | switch (filp->f_pos) { | 1947 | if (!dir_emit_dots(file, ctx)) |
1959 | case 0: | 1948 | goto out_put_task; |
1960 | ino = inode->i_ino; | ||
1961 | if (filldir(dirent, ".", 1, 0, ino, DT_DIR) < 0) | ||
1962 | goto out_put_task; | ||
1963 | filp->f_pos++; | ||
1964 | case 1: | ||
1965 | ino = parent_ino(dentry); | ||
1966 | if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0) | ||
1967 | goto out_put_task; | ||
1968 | filp->f_pos++; | ||
1969 | default: | ||
1970 | { | ||
1971 | unsigned long nr_files, pos, i; | ||
1972 | struct flex_array *fa = NULL; | ||
1973 | struct map_files_info info; | ||
1974 | struct map_files_info *p; | ||
1975 | |||
1976 | mm = get_task_mm(task); | ||
1977 | if (!mm) | ||
1978 | goto out_put_task; | ||
1979 | down_read(&mm->mmap_sem); | ||
1980 | 1949 | ||
1981 | nr_files = 0; | 1950 | mm = get_task_mm(task); |
1951 | if (!mm) | ||
1952 | goto out_put_task; | ||
1953 | down_read(&mm->mmap_sem); | ||
1982 | 1954 | ||
1983 | /* | 1955 | nr_files = 0; |
1984 | * We need two passes here: | ||
1985 | * | ||
1986 | * 1) Collect vmas of mapped files with mmap_sem taken | ||
1987 | * 2) Release mmap_sem and instantiate entries | ||
1988 | * | ||
1989 | * otherwise we get lockdep complained, since filldir() | ||
1990 | * routine might require mmap_sem taken in might_fault(). | ||
1991 | */ | ||
1992 | 1956 | ||
1993 | for (vma = mm->mmap, pos = 2; vma; vma = vma->vm_next) { | 1957 | /* |
1994 | if (vma->vm_file && ++pos > filp->f_pos) | 1958 | * We need two passes here: |
1995 | nr_files++; | 1959 | * |
1996 | } | 1960 | * 1) Collect vmas of mapped files with mmap_sem taken |
1961 | * 2) Release mmap_sem and instantiate entries | ||
1962 | * | ||
1963 | * otherwise we get lockdep complained, since filldir() | ||
1964 | * routine might require mmap_sem taken in might_fault(). | ||
1965 | */ | ||
1997 | 1966 | ||
1998 | if (nr_files) { | 1967 | for (vma = mm->mmap, pos = 2; vma; vma = vma->vm_next) { |
1999 | fa = flex_array_alloc(sizeof(info), nr_files, | 1968 | if (vma->vm_file && ++pos > ctx->pos) |
2000 | GFP_KERNEL); | 1969 | nr_files++; |
2001 | if (!fa || flex_array_prealloc(fa, 0, nr_files, | 1970 | } |
2002 | GFP_KERNEL)) { | 1971 | |
2003 | ret = -ENOMEM; | 1972 | if (nr_files) { |
2004 | if (fa) | 1973 | fa = flex_array_alloc(sizeof(info), nr_files, |
2005 | flex_array_free(fa); | 1974 | GFP_KERNEL); |
2006 | up_read(&mm->mmap_sem); | 1975 | if (!fa || flex_array_prealloc(fa, 0, nr_files, |
2007 | mmput(mm); | 1976 | GFP_KERNEL)) { |
2008 | goto out_put_task; | 1977 | ret = -ENOMEM; |
2009 | } | 1978 | if (fa) |
2010 | for (i = 0, vma = mm->mmap, pos = 2; vma; | 1979 | flex_array_free(fa); |
2011 | vma = vma->vm_next) { | 1980 | up_read(&mm->mmap_sem); |
2012 | if (!vma->vm_file) | 1981 | mmput(mm); |
2013 | continue; | 1982 | goto out_put_task; |
2014 | if (++pos <= filp->f_pos) | ||
2015 | continue; | ||
2016 | |||
2017 | info.mode = vma->vm_file->f_mode; | ||
2018 | info.len = snprintf(info.name, | ||
2019 | sizeof(info.name), "%lx-%lx", | ||
2020 | vma->vm_start, vma->vm_end); | ||
2021 | if (flex_array_put(fa, i++, &info, GFP_KERNEL)) | ||
2022 | BUG(); | ||
2023 | } | ||
2024 | } | 1983 | } |
2025 | up_read(&mm->mmap_sem); | 1984 | for (i = 0, vma = mm->mmap, pos = 2; vma; |
2026 | 1985 | vma = vma->vm_next) { | |
2027 | for (i = 0; i < nr_files; i++) { | 1986 | if (!vma->vm_file) |
2028 | p = flex_array_get(fa, i); | 1987 | continue; |
2029 | ret = proc_fill_cache(filp, dirent, filldir, | 1988 | if (++pos <= ctx->pos) |
2030 | p->name, p->len, | 1989 | continue; |
2031 | proc_map_files_instantiate, | 1990 | |
2032 | task, | 1991 | info.mode = vma->vm_file->f_mode; |
2033 | (void *)(unsigned long)p->mode); | 1992 | info.len = snprintf(info.name, |
2034 | if (ret) | 1993 | sizeof(info.name), "%lx-%lx", |
2035 | break; | 1994 | vma->vm_start, vma->vm_end); |
2036 | filp->f_pos++; | 1995 | if (flex_array_put(fa, i++, &info, GFP_KERNEL)) |
1996 | BUG(); | ||
2037 | } | 1997 | } |
2038 | if (fa) | ||
2039 | flex_array_free(fa); | ||
2040 | mmput(mm); | ||
2041 | } | 1998 | } |
1999 | up_read(&mm->mmap_sem); | ||
2000 | |||
2001 | for (i = 0; i < nr_files; i++) { | ||
2002 | p = flex_array_get(fa, i); | ||
2003 | if (!proc_fill_cache(file, ctx, | ||
2004 | p->name, p->len, | ||
2005 | proc_map_files_instantiate, | ||
2006 | task, | ||
2007 | (void *)(unsigned long)p->mode)) | ||
2008 | break; | ||
2009 | ctx->pos++; | ||
2042 | } | 2010 | } |
2011 | if (fa) | ||
2012 | flex_array_free(fa); | ||
2013 | mmput(mm); | ||
2043 | 2014 | ||
2044 | out_put_task: | 2015 | out_put_task: |
2045 | put_task_struct(task); | 2016 | put_task_struct(task); |
@@ -2049,7 +2020,7 @@ out: | |||
2049 | 2020 | ||
2050 | static const struct file_operations proc_map_files_operations = { | 2021 | static const struct file_operations proc_map_files_operations = { |
2051 | .read = generic_read_dir, | 2022 | .read = generic_read_dir, |
2052 | .readdir = proc_map_files_readdir, | 2023 | .iterate = proc_map_files_readdir, |
2053 | .llseek = default_llseek, | 2024 | .llseek = default_llseek, |
2054 | }; | 2025 | }; |
2055 | 2026 | ||
@@ -2152,13 +2123,12 @@ static const struct file_operations proc_timers_operations = { | |||
2152 | }; | 2123 | }; |
2153 | #endif /* CONFIG_CHECKPOINT_RESTORE */ | 2124 | #endif /* CONFIG_CHECKPOINT_RESTORE */ |
2154 | 2125 | ||
2155 | static struct dentry *proc_pident_instantiate(struct inode *dir, | 2126 | static int proc_pident_instantiate(struct inode *dir, |
2156 | struct dentry *dentry, struct task_struct *task, const void *ptr) | 2127 | struct dentry *dentry, struct task_struct *task, const void *ptr) |
2157 | { | 2128 | { |
2158 | const struct pid_entry *p = ptr; | 2129 | const struct pid_entry *p = ptr; |
2159 | struct inode *inode; | 2130 | struct inode *inode; |
2160 | struct proc_inode *ei; | 2131 | struct proc_inode *ei; |
2161 | struct dentry *error = ERR_PTR(-ENOENT); | ||
2162 | 2132 | ||
2163 | inode = proc_pid_make_inode(dir->i_sb, task); | 2133 | inode = proc_pid_make_inode(dir->i_sb, task); |
2164 | if (!inode) | 2134 | if (!inode) |
@@ -2177,9 +2147,9 @@ static struct dentry *proc_pident_instantiate(struct inode *dir, | |||
2177 | d_add(dentry, inode); | 2147 | d_add(dentry, inode); |
2178 | /* Close the race of the process dying before we return the dentry */ | 2148 | /* Close the race of the process dying before we return the dentry */ |
2179 | if (pid_revalidate(dentry, 0)) | 2149 | if (pid_revalidate(dentry, 0)) |
2180 | error = NULL; | 2150 | return 0; |
2181 | out: | 2151 | out: |
2182 | return error; | 2152 | return -ENOENT; |
2183 | } | 2153 | } |
2184 | 2154 | ||
2185 | static struct dentry *proc_pident_lookup(struct inode *dir, | 2155 | static struct dentry *proc_pident_lookup(struct inode *dir, |
@@ -2187,11 +2157,11 @@ static struct dentry *proc_pident_lookup(struct inode *dir, | |||
2187 | const struct pid_entry *ents, | 2157 | const struct pid_entry *ents, |
2188 | unsigned int nents) | 2158 | unsigned int nents) |
2189 | { | 2159 | { |
2190 | struct dentry *error; | 2160 | int error; |
2191 | struct task_struct *task = get_proc_task(dir); | 2161 | struct task_struct *task = get_proc_task(dir); |
2192 | const struct pid_entry *p, *last; | 2162 | const struct pid_entry *p, *last; |
2193 | 2163 | ||
2194 | error = ERR_PTR(-ENOENT); | 2164 | error = -ENOENT; |
2195 | 2165 | ||
2196 | if (!task) | 2166 | if (!task) |
2197 | goto out_no_task; | 2167 | goto out_no_task; |
@@ -2214,70 +2184,33 @@ static struct dentry *proc_pident_lookup(struct inode *dir, | |||
2214 | out: | 2184 | out: |
2215 | put_task_struct(task); | 2185 | put_task_struct(task); |
2216 | out_no_task: | 2186 | out_no_task: |
2217 | return error; | 2187 | return ERR_PTR(error); |
2218 | } | ||
2219 | |||
2220 | static int proc_pident_fill_cache(struct file *filp, void *dirent, | ||
2221 | filldir_t filldir, struct task_struct *task, const struct pid_entry *p) | ||
2222 | { | ||
2223 | return proc_fill_cache(filp, dirent, filldir, p->name, p->len, | ||
2224 | proc_pident_instantiate, task, p); | ||
2225 | } | 2188 | } |
2226 | 2189 | ||
2227 | static int proc_pident_readdir(struct file *filp, | 2190 | static int proc_pident_readdir(struct file *file, struct dir_context *ctx, |
2228 | void *dirent, filldir_t filldir, | ||
2229 | const struct pid_entry *ents, unsigned int nents) | 2191 | const struct pid_entry *ents, unsigned int nents) |
2230 | { | 2192 | { |
2231 | int i; | 2193 | struct task_struct *task = get_proc_task(file_inode(file)); |
2232 | struct dentry *dentry = filp->f_path.dentry; | 2194 | const struct pid_entry *p; |
2233 | struct inode *inode = dentry->d_inode; | ||
2234 | struct task_struct *task = get_proc_task(inode); | ||
2235 | const struct pid_entry *p, *last; | ||
2236 | ino_t ino; | ||
2237 | int ret; | ||
2238 | 2195 | ||
2239 | ret = -ENOENT; | ||
2240 | if (!task) | 2196 | if (!task) |
2241 | goto out_no_task; | 2197 | return -ENOENT; |
2242 | 2198 | ||
2243 | ret = 0; | 2199 | if (!dir_emit_dots(file, ctx)) |
2244 | i = filp->f_pos; | 2200 | goto out; |
2245 | switch (i) { | 2201 | |
2246 | case 0: | 2202 | if (ctx->pos >= nents + 2) |
2247 | ino = inode->i_ino; | 2203 | goto out; |
2248 | if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0) | ||
2249 | goto out; | ||
2250 | i++; | ||
2251 | filp->f_pos++; | ||
2252 | /* fall through */ | ||
2253 | case 1: | ||
2254 | ino = parent_ino(dentry); | ||
2255 | if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0) | ||
2256 | goto out; | ||
2257 | i++; | ||
2258 | filp->f_pos++; | ||
2259 | /* fall through */ | ||
2260 | default: | ||
2261 | i -= 2; | ||
2262 | if (i >= nents) { | ||
2263 | ret = 1; | ||
2264 | goto out; | ||
2265 | } | ||
2266 | p = ents + i; | ||
2267 | last = &ents[nents - 1]; | ||
2268 | while (p <= last) { | ||
2269 | if (proc_pident_fill_cache(filp, dirent, filldir, task, p) < 0) | ||
2270 | goto out; | ||
2271 | filp->f_pos++; | ||
2272 | p++; | ||
2273 | } | ||
2274 | } | ||
2275 | 2204 | ||
2276 | ret = 1; | 2205 | for (p = ents + (ctx->pos - 2); p <= ents + nents - 1; p++) { |
2206 | if (!proc_fill_cache(file, ctx, p->name, p->len, | ||
2207 | proc_pident_instantiate, task, p)) | ||
2208 | break; | ||
2209 | ctx->pos++; | ||
2210 | } | ||
2277 | out: | 2211 | out: |
2278 | put_task_struct(task); | 2212 | put_task_struct(task); |
2279 | out_no_task: | 2213 | return 0; |
2280 | return ret; | ||
2281 | } | 2214 | } |
2282 | 2215 | ||
2283 | #ifdef CONFIG_SECURITY | 2216 | #ifdef CONFIG_SECURITY |
@@ -2362,16 +2295,15 @@ static const struct pid_entry attr_dir_stuff[] = { | |||
2362 | REG("sockcreate", S_IRUGO|S_IWUGO, proc_pid_attr_operations), | 2295 | REG("sockcreate", S_IRUGO|S_IWUGO, proc_pid_attr_operations), |
2363 | }; | 2296 | }; |
2364 | 2297 | ||
2365 | static int proc_attr_dir_readdir(struct file * filp, | 2298 | static int proc_attr_dir_readdir(struct file *file, struct dir_context *ctx) |
2366 | void * dirent, filldir_t filldir) | ||
2367 | { | 2299 | { |
2368 | return proc_pident_readdir(filp,dirent,filldir, | 2300 | return proc_pident_readdir(file, ctx, |
2369 | attr_dir_stuff,ARRAY_SIZE(attr_dir_stuff)); | 2301 | attr_dir_stuff, ARRAY_SIZE(attr_dir_stuff)); |
2370 | } | 2302 | } |
2371 | 2303 | ||
2372 | static const struct file_operations proc_attr_dir_operations = { | 2304 | static const struct file_operations proc_attr_dir_operations = { |
2373 | .read = generic_read_dir, | 2305 | .read = generic_read_dir, |
2374 | .readdir = proc_attr_dir_readdir, | 2306 | .iterate = proc_attr_dir_readdir, |
2375 | .llseek = default_llseek, | 2307 | .llseek = default_llseek, |
2376 | }; | 2308 | }; |
2377 | 2309 | ||
@@ -2725,16 +2657,15 @@ static const struct pid_entry tgid_base_stuff[] = { | |||
2725 | #endif | 2657 | #endif |
2726 | }; | 2658 | }; |
2727 | 2659 | ||
2728 | static int proc_tgid_base_readdir(struct file * filp, | 2660 | static int proc_tgid_base_readdir(struct file *file, struct dir_context *ctx) |
2729 | void * dirent, filldir_t filldir) | ||
2730 | { | 2661 | { |
2731 | return proc_pident_readdir(filp,dirent,filldir, | 2662 | return proc_pident_readdir(file, ctx, |
2732 | tgid_base_stuff,ARRAY_SIZE(tgid_base_stuff)); | 2663 | tgid_base_stuff, ARRAY_SIZE(tgid_base_stuff)); |
2733 | } | 2664 | } |
2734 | 2665 | ||
2735 | static const struct file_operations proc_tgid_base_operations = { | 2666 | static const struct file_operations proc_tgid_base_operations = { |
2736 | .read = generic_read_dir, | 2667 | .read = generic_read_dir, |
2737 | .readdir = proc_tgid_base_readdir, | 2668 | .iterate = proc_tgid_base_readdir, |
2738 | .llseek = default_llseek, | 2669 | .llseek = default_llseek, |
2739 | }; | 2670 | }; |
2740 | 2671 | ||
@@ -2836,11 +2767,10 @@ void proc_flush_task(struct task_struct *task) | |||
2836 | } | 2767 | } |
2837 | } | 2768 | } |
2838 | 2769 | ||
2839 | static struct dentry *proc_pid_instantiate(struct inode *dir, | 2770 | static int proc_pid_instantiate(struct inode *dir, |
2840 | struct dentry * dentry, | 2771 | struct dentry * dentry, |
2841 | struct task_struct *task, const void *ptr) | 2772 | struct task_struct *task, const void *ptr) |
2842 | { | 2773 | { |
2843 | struct dentry *error = ERR_PTR(-ENOENT); | ||
2844 | struct inode *inode; | 2774 | struct inode *inode; |
2845 | 2775 | ||
2846 | inode = proc_pid_make_inode(dir->i_sb, task); | 2776 | inode = proc_pid_make_inode(dir->i_sb, task); |
@@ -2860,14 +2790,14 @@ static struct dentry *proc_pid_instantiate(struct inode *dir, | |||
2860 | d_add(dentry, inode); | 2790 | d_add(dentry, inode); |
2861 | /* Close the race of the process dying before we return the dentry */ | 2791 | /* Close the race of the process dying before we return the dentry */ |
2862 | if (pid_revalidate(dentry, 0)) | 2792 | if (pid_revalidate(dentry, 0)) |
2863 | error = NULL; | 2793 | return 0; |
2864 | out: | 2794 | out: |
2865 | return error; | 2795 | return -ENOENT; |
2866 | } | 2796 | } |
2867 | 2797 | ||
2868 | struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, unsigned int flags) | 2798 | struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, unsigned int flags) |
2869 | { | 2799 | { |
2870 | struct dentry *result = NULL; | 2800 | int result = 0; |
2871 | struct task_struct *task; | 2801 | struct task_struct *task; |
2872 | unsigned tgid; | 2802 | unsigned tgid; |
2873 | struct pid_namespace *ns; | 2803 | struct pid_namespace *ns; |
@@ -2888,7 +2818,7 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, unsign | |||
2888 | result = proc_pid_instantiate(dir, dentry, task, NULL); | 2818 | result = proc_pid_instantiate(dir, dentry, task, NULL); |
2889 | put_task_struct(task); | 2819 | put_task_struct(task); |
2890 | out: | 2820 | out: |
2891 | return result; | 2821 | return ERR_PTR(result); |
2892 | } | 2822 | } |
2893 | 2823 | ||
2894 | /* | 2824 | /* |
@@ -2936,58 +2866,42 @@ retry: | |||
2936 | 2866 | ||
2937 | #define TGID_OFFSET (FIRST_PROCESS_ENTRY + 1) | 2867 | #define TGID_OFFSET (FIRST_PROCESS_ENTRY + 1) |
2938 | 2868 | ||
2939 | static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldir, | ||
2940 | struct tgid_iter iter) | ||
2941 | { | ||
2942 | char name[PROC_NUMBUF]; | ||
2943 | int len = snprintf(name, sizeof(name), "%d", iter.tgid); | ||
2944 | return proc_fill_cache(filp, dirent, filldir, name, len, | ||
2945 | proc_pid_instantiate, iter.task, NULL); | ||
2946 | } | ||
2947 | |||
2948 | static int fake_filldir(void *buf, const char *name, int namelen, | ||
2949 | loff_t offset, u64 ino, unsigned d_type) | ||
2950 | { | ||
2951 | return 0; | ||
2952 | } | ||
2953 | |||
2954 | /* for the /proc/ directory itself, after non-process stuff has been done */ | 2869 | /* for the /proc/ directory itself, after non-process stuff has been done */ |
2955 | int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir) | 2870 | int proc_pid_readdir(struct file *file, struct dir_context *ctx) |
2956 | { | 2871 | { |
2957 | struct tgid_iter iter; | 2872 | struct tgid_iter iter; |
2958 | struct pid_namespace *ns; | 2873 | struct pid_namespace *ns = file->f_dentry->d_sb->s_fs_info; |
2959 | filldir_t __filldir; | 2874 | loff_t pos = ctx->pos; |
2960 | loff_t pos = filp->f_pos; | ||
2961 | 2875 | ||
2962 | if (pos >= PID_MAX_LIMIT + TGID_OFFSET) | 2876 | if (pos >= PID_MAX_LIMIT + TGID_OFFSET) |
2963 | goto out; | 2877 | return 0; |
2964 | 2878 | ||
2965 | if (pos == TGID_OFFSET - 1) { | 2879 | if (pos == TGID_OFFSET - 1) { |
2966 | if (proc_fill_cache(filp, dirent, filldir, "self", 4, | 2880 | struct inode *inode = ns->proc_self->d_inode; |
2967 | NULL, NULL, NULL) < 0) | 2881 | if (!dir_emit(ctx, "self", 4, inode->i_ino, DT_LNK)) |
2968 | goto out; | 2882 | return 0; |
2969 | iter.tgid = 0; | 2883 | iter.tgid = 0; |
2970 | } else { | 2884 | } else { |
2971 | iter.tgid = pos - TGID_OFFSET; | 2885 | iter.tgid = pos - TGID_OFFSET; |
2972 | } | 2886 | } |
2973 | iter.task = NULL; | 2887 | iter.task = NULL; |
2974 | ns = filp->f_dentry->d_sb->s_fs_info; | ||
2975 | for (iter = next_tgid(ns, iter); | 2888 | for (iter = next_tgid(ns, iter); |
2976 | iter.task; | 2889 | iter.task; |
2977 | iter.tgid += 1, iter = next_tgid(ns, iter)) { | 2890 | iter.tgid += 1, iter = next_tgid(ns, iter)) { |
2978 | if (has_pid_permissions(ns, iter.task, 2)) | 2891 | char name[PROC_NUMBUF]; |
2979 | __filldir = filldir; | 2892 | int len; |
2980 | else | 2893 | if (!has_pid_permissions(ns, iter.task, 2)) |
2981 | __filldir = fake_filldir; | 2894 | continue; |
2982 | 2895 | ||
2983 | filp->f_pos = iter.tgid + TGID_OFFSET; | 2896 | len = snprintf(name, sizeof(name), "%d", iter.tgid); |
2984 | if (proc_pid_fill_cache(filp, dirent, __filldir, iter) < 0) { | 2897 | ctx->pos = iter.tgid + TGID_OFFSET; |
2898 | if (!proc_fill_cache(file, ctx, name, len, | ||
2899 | proc_pid_instantiate, iter.task, NULL)) { | ||
2985 | put_task_struct(iter.task); | 2900 | put_task_struct(iter.task); |
2986 | goto out; | 2901 | return 0; |
2987 | } | 2902 | } |
2988 | } | 2903 | } |
2989 | filp->f_pos = PID_MAX_LIMIT + TGID_OFFSET; | 2904 | ctx->pos = PID_MAX_LIMIT + TGID_OFFSET; |
2990 | out: | ||
2991 | return 0; | 2905 | return 0; |
2992 | } | 2906 | } |
2993 | 2907 | ||
@@ -3075,11 +2989,10 @@ static const struct pid_entry tid_base_stuff[] = { | |||
3075 | #endif | 2989 | #endif |
3076 | }; | 2990 | }; |
3077 | 2991 | ||
3078 | static int proc_tid_base_readdir(struct file * filp, | 2992 | static int proc_tid_base_readdir(struct file *file, struct dir_context *ctx) |
3079 | void * dirent, filldir_t filldir) | ||
3080 | { | 2993 | { |
3081 | return proc_pident_readdir(filp,dirent,filldir, | 2994 | return proc_pident_readdir(file, ctx, |
3082 | tid_base_stuff,ARRAY_SIZE(tid_base_stuff)); | 2995 | tid_base_stuff, ARRAY_SIZE(tid_base_stuff)); |
3083 | } | 2996 | } |
3084 | 2997 | ||
3085 | static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) | 2998 | static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) |
@@ -3090,7 +3003,7 @@ static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *den | |||
3090 | 3003 | ||
3091 | static const struct file_operations proc_tid_base_operations = { | 3004 | static const struct file_operations proc_tid_base_operations = { |
3092 | .read = generic_read_dir, | 3005 | .read = generic_read_dir, |
3093 | .readdir = proc_tid_base_readdir, | 3006 | .iterate = proc_tid_base_readdir, |
3094 | .llseek = default_llseek, | 3007 | .llseek = default_llseek, |
3095 | }; | 3008 | }; |
3096 | 3009 | ||
@@ -3100,10 +3013,9 @@ static const struct inode_operations proc_tid_base_inode_operations = { | |||
3100 | .setattr = proc_setattr, | 3013 | .setattr = proc_setattr, |
3101 | }; | 3014 | }; |
3102 | 3015 | ||
3103 | static struct dentry *proc_task_instantiate(struct inode *dir, | 3016 | static int proc_task_instantiate(struct inode *dir, |
3104 | struct dentry *dentry, struct task_struct *task, const void *ptr) | 3017 | struct dentry *dentry, struct task_struct *task, const void *ptr) |
3105 | { | 3018 | { |
3106 | struct dentry *error = ERR_PTR(-ENOENT); | ||
3107 | struct inode *inode; | 3019 | struct inode *inode; |
3108 | inode = proc_pid_make_inode(dir->i_sb, task); | 3020 | inode = proc_pid_make_inode(dir->i_sb, task); |
3109 | 3021 | ||
@@ -3122,14 +3034,14 @@ static struct dentry *proc_task_instantiate(struct inode *dir, | |||
3122 | d_add(dentry, inode); | 3034 | d_add(dentry, inode); |
3123 | /* Close the race of the process dying before we return the dentry */ | 3035 | /* Close the race of the process dying before we return the dentry */ |
3124 | if (pid_revalidate(dentry, 0)) | 3036 | if (pid_revalidate(dentry, 0)) |
3125 | error = NULL; | 3037 | return 0; |
3126 | out: | 3038 | out: |
3127 | return error; | 3039 | return -ENOENT; |
3128 | } | 3040 | } |
3129 | 3041 | ||
3130 | static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, unsigned int flags) | 3042 | static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, unsigned int flags) |
3131 | { | 3043 | { |
3132 | struct dentry *result = ERR_PTR(-ENOENT); | 3044 | int result = -ENOENT; |
3133 | struct task_struct *task; | 3045 | struct task_struct *task; |
3134 | struct task_struct *leader = get_proc_task(dir); | 3046 | struct task_struct *leader = get_proc_task(dir); |
3135 | unsigned tid; | 3047 | unsigned tid; |
@@ -3159,7 +3071,7 @@ out_drop_task: | |||
3159 | out: | 3071 | out: |
3160 | put_task_struct(leader); | 3072 | put_task_struct(leader); |
3161 | out_no_task: | 3073 | out_no_task: |
3162 | return result; | 3074 | return ERR_PTR(result); |
3163 | } | 3075 | } |
3164 | 3076 | ||
3165 | /* | 3077 | /* |
@@ -3231,30 +3143,16 @@ static struct task_struct *next_tid(struct task_struct *start) | |||
3231 | return pos; | 3143 | return pos; |
3232 | } | 3144 | } |
3233 | 3145 | ||
3234 | static int proc_task_fill_cache(struct file *filp, void *dirent, filldir_t filldir, | ||
3235 | struct task_struct *task, int tid) | ||
3236 | { | ||
3237 | char name[PROC_NUMBUF]; | ||
3238 | int len = snprintf(name, sizeof(name), "%d", tid); | ||
3239 | return proc_fill_cache(filp, dirent, filldir, name, len, | ||
3240 | proc_task_instantiate, task, NULL); | ||
3241 | } | ||
3242 | |||
3243 | /* for the /proc/TGID/task/ directories */ | 3146 | /* for the /proc/TGID/task/ directories */ |
3244 | static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldir) | 3147 | static int proc_task_readdir(struct file *file, struct dir_context *ctx) |
3245 | { | 3148 | { |
3246 | struct dentry *dentry = filp->f_path.dentry; | ||
3247 | struct inode *inode = dentry->d_inode; | ||
3248 | struct task_struct *leader = NULL; | 3149 | struct task_struct *leader = NULL; |
3249 | struct task_struct *task; | 3150 | struct task_struct *task = get_proc_task(file_inode(file)); |
3250 | int retval = -ENOENT; | ||
3251 | ino_t ino; | ||
3252 | int tid; | ||
3253 | struct pid_namespace *ns; | 3151 | struct pid_namespace *ns; |
3152 | int tid; | ||
3254 | 3153 | ||
3255 | task = get_proc_task(inode); | ||
3256 | if (!task) | 3154 | if (!task) |
3257 | goto out_no_task; | 3155 | return -ENOENT; |
3258 | rcu_read_lock(); | 3156 | rcu_read_lock(); |
3259 | if (pid_alive(task)) { | 3157 | if (pid_alive(task)) { |
3260 | leader = task->group_leader; | 3158 | leader = task->group_leader; |
@@ -3263,46 +3161,36 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi | |||
3263 | rcu_read_unlock(); | 3161 | rcu_read_unlock(); |
3264 | put_task_struct(task); | 3162 | put_task_struct(task); |
3265 | if (!leader) | 3163 | if (!leader) |
3266 | goto out_no_task; | 3164 | return -ENOENT; |
3267 | retval = 0; | ||
3268 | 3165 | ||
3269 | switch ((unsigned long)filp->f_pos) { | 3166 | if (!dir_emit_dots(file, ctx)) |
3270 | case 0: | 3167 | goto out; |
3271 | ino = inode->i_ino; | ||
3272 | if (filldir(dirent, ".", 1, filp->f_pos, ino, DT_DIR) < 0) | ||
3273 | goto out; | ||
3274 | filp->f_pos++; | ||
3275 | /* fall through */ | ||
3276 | case 1: | ||
3277 | ino = parent_ino(dentry); | ||
3278 | if (filldir(dirent, "..", 2, filp->f_pos, ino, DT_DIR) < 0) | ||
3279 | goto out; | ||
3280 | filp->f_pos++; | ||
3281 | /* fall through */ | ||
3282 | } | ||
3283 | 3168 | ||
3284 | /* f_version caches the tgid value that the last readdir call couldn't | 3169 | /* f_version caches the tgid value that the last readdir call couldn't |
3285 | * return. lseek aka telldir automagically resets f_version to 0. | 3170 | * return. lseek aka telldir automagically resets f_version to 0. |
3286 | */ | 3171 | */ |
3287 | ns = filp->f_dentry->d_sb->s_fs_info; | 3172 | ns = file->f_dentry->d_sb->s_fs_info; |
3288 | tid = (int)filp->f_version; | 3173 | tid = (int)file->f_version; |
3289 | filp->f_version = 0; | 3174 | file->f_version = 0; |
3290 | for (task = first_tid(leader, tid, filp->f_pos - 2, ns); | 3175 | for (task = first_tid(leader, tid, ctx->pos - 2, ns); |
3291 | task; | 3176 | task; |
3292 | task = next_tid(task), filp->f_pos++) { | 3177 | task = next_tid(task), ctx->pos++) { |
3178 | char name[PROC_NUMBUF]; | ||
3179 | int len; | ||
3293 | tid = task_pid_nr_ns(task, ns); | 3180 | tid = task_pid_nr_ns(task, ns); |
3294 | if (proc_task_fill_cache(filp, dirent, filldir, task, tid) < 0) { | 3181 | len = snprintf(name, sizeof(name), "%d", tid); |
3182 | if (!proc_fill_cache(file, ctx, name, len, | ||
3183 | proc_task_instantiate, task, NULL)) { | ||
3295 | /* returning this tgid failed, save it as the first | 3184 | /* returning this tgid failed, save it as the first |
3296 | * pid for the next readir call */ | 3185 | * pid for the next readir call */ |
3297 | filp->f_version = (u64)tid; | 3186 | file->f_version = (u64)tid; |
3298 | put_task_struct(task); | 3187 | put_task_struct(task); |
3299 | break; | 3188 | break; |
3300 | } | 3189 | } |
3301 | } | 3190 | } |
3302 | out: | 3191 | out: |
3303 | put_task_struct(leader); | 3192 | put_task_struct(leader); |
3304 | out_no_task: | 3193 | return 0; |
3305 | return retval; | ||
3306 | } | 3194 | } |
3307 | 3195 | ||
3308 | static int proc_task_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | 3196 | static int proc_task_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) |
@@ -3328,6 +3216,6 @@ static const struct inode_operations proc_task_inode_operations = { | |||
3328 | 3216 | ||
3329 | static const struct file_operations proc_task_operations = { | 3217 | static const struct file_operations proc_task_operations = { |
3330 | .read = generic_read_dir, | 3218 | .read = generic_read_dir, |
3331 | .readdir = proc_task_readdir, | 3219 | .iterate = proc_task_readdir, |
3332 | .llseek = default_llseek, | 3220 | .llseek = default_llseek, |
3333 | }; | 3221 | }; |