diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-08-27 14:55:26 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-09-26 21:10:26 -0400 |
commit | 7b540d0646ce122f0ba4520412be91e530719742 (patch) | |
tree | 4f19440bf503325dbce463c7bdafb3c6cee6c748 /fs/proc/base.c | |
parent | cb0942b81249798e15c3f04eee2946ef543e8115 (diff) |
proc_map_files_readdir(): don't bother with grabbing files
all we need is their ->f_mode, so just collect _that_
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/proc/base.c')
-rw-r--r-- | fs/proc/base.c | 28 |
1 files changed, 9 insertions, 19 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index f1e8438d21b5..df18db61d6d8 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -1805,7 +1805,7 @@ out: | |||
1805 | } | 1805 | } |
1806 | 1806 | ||
1807 | struct map_files_info { | 1807 | struct map_files_info { |
1808 | struct file *file; | 1808 | fmode_t mode; |
1809 | unsigned long len; | 1809 | unsigned long len; |
1810 | unsigned char name[4*sizeof(long)+2]; /* max: %lx-%lx\0 */ | 1810 | unsigned char name[4*sizeof(long)+2]; /* max: %lx-%lx\0 */ |
1811 | }; | 1811 | }; |
@@ -1814,13 +1814,10 @@ static struct dentry * | |||
1814 | proc_map_files_instantiate(struct inode *dir, struct dentry *dentry, | 1814 | proc_map_files_instantiate(struct inode *dir, struct dentry *dentry, |
1815 | struct task_struct *task, const void *ptr) | 1815 | struct task_struct *task, const void *ptr) |
1816 | { | 1816 | { |
1817 | const struct file *file = ptr; | 1817 | fmode_t mode = (fmode_t)(unsigned long)ptr; |
1818 | struct proc_inode *ei; | 1818 | struct proc_inode *ei; |
1819 | struct inode *inode; | 1819 | struct inode *inode; |
1820 | 1820 | ||
1821 | if (!file) | ||
1822 | return ERR_PTR(-ENOENT); | ||
1823 | |||
1824 | inode = proc_pid_make_inode(dir->i_sb, task); | 1821 | inode = proc_pid_make_inode(dir->i_sb, task); |
1825 | if (!inode) | 1822 | if (!inode) |
1826 | return ERR_PTR(-ENOENT); | 1823 | return ERR_PTR(-ENOENT); |
@@ -1832,9 +1829,9 @@ proc_map_files_instantiate(struct inode *dir, struct dentry *dentry, | |||
1832 | inode->i_size = 64; | 1829 | inode->i_size = 64; |
1833 | inode->i_mode = S_IFLNK; | 1830 | inode->i_mode = S_IFLNK; |
1834 | 1831 | ||
1835 | if (file->f_mode & FMODE_READ) | 1832 | if (mode & FMODE_READ) |
1836 | inode->i_mode |= S_IRUSR; | 1833 | inode->i_mode |= S_IRUSR; |
1837 | if (file->f_mode & FMODE_WRITE) | 1834 | if (mode & FMODE_WRITE) |
1838 | inode->i_mode |= S_IWUSR; | 1835 | inode->i_mode |= S_IWUSR; |
1839 | 1836 | ||
1840 | d_set_d_op(dentry, &tid_map_files_dentry_operations); | 1837 | d_set_d_op(dentry, &tid_map_files_dentry_operations); |
@@ -1878,7 +1875,8 @@ static struct dentry *proc_map_files_lookup(struct inode *dir, | |||
1878 | if (!vma) | 1875 | if (!vma) |
1879 | goto out_no_vma; | 1876 | goto out_no_vma; |
1880 | 1877 | ||
1881 | result = proc_map_files_instantiate(dir, dentry, task, vma->vm_file); | 1878 | result = proc_map_files_instantiate(dir, dentry, task, |
1879 | (void *)(unsigned long)vma->vm_file->f_mode); | ||
1882 | 1880 | ||
1883 | out_no_vma: | 1881 | out_no_vma: |
1884 | up_read(&mm->mmap_sem); | 1882 | up_read(&mm->mmap_sem); |
@@ -1979,7 +1977,7 @@ proc_map_files_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
1979 | if (++pos <= filp->f_pos) | 1977 | if (++pos <= filp->f_pos) |
1980 | continue; | 1978 | continue; |
1981 | 1979 | ||
1982 | info.file = get_file(vma->vm_file); | 1980 | info.mode = vma->vm_file->f_mode; |
1983 | info.len = snprintf(info.name, | 1981 | info.len = snprintf(info.name, |
1984 | sizeof(info.name), "%lx-%lx", | 1982 | sizeof(info.name), "%lx-%lx", |
1985 | vma->vm_start, vma->vm_end); | 1983 | vma->vm_start, vma->vm_end); |
@@ -1994,19 +1992,11 @@ proc_map_files_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
1994 | ret = proc_fill_cache(filp, dirent, filldir, | 1992 | ret = proc_fill_cache(filp, dirent, filldir, |
1995 | p->name, p->len, | 1993 | p->name, p->len, |
1996 | proc_map_files_instantiate, | 1994 | proc_map_files_instantiate, |
1997 | task, p->file); | 1995 | task, |
1996 | (void *)(unsigned long)p->mode); | ||
1998 | if (ret) | 1997 | if (ret) |
1999 | break; | 1998 | break; |
2000 | filp->f_pos++; | 1999 | filp->f_pos++; |
2001 | fput(p->file); | ||
2002 | } | ||
2003 | for (; i < nr_files; i++) { | ||
2004 | /* | ||
2005 | * In case of error don't forget | ||
2006 | * to put rest of file refs. | ||
2007 | */ | ||
2008 | p = flex_array_get(fa, i); | ||
2009 | fput(p->file); | ||
2010 | } | 2000 | } |
2011 | if (fa) | 2001 | if (fa) |
2012 | flex_array_free(fa); | 2002 | flex_array_free(fa); |