summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-08-27 14:55:26 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-09-26 21:10:26 -0400
commit7b540d0646ce122f0ba4520412be91e530719742 (patch)
tree4f19440bf503325dbce463c7bdafb3c6cee6c748
parentcb0942b81249798e15c3f04eee2946ef543e8115 (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>
-rw-r--r--fs/proc/base.c28
1 files changed, 9 insertions, 19 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index f1e8438d21b..df18db61d6d 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1805,7 +1805,7 @@ out:
}
struct map_files_info {
- struct file *file;
+ fmode_t mode;
unsigned long len;
unsigned char name[4*sizeof(long)+2]; /* max: %lx-%lx\0 */
};
@@ -1814,13 +1814,10 @@ static struct dentry *
proc_map_files_instantiate(struct inode *dir, struct dentry *dentry,
struct task_struct *task, const void *ptr)
{
- const struct file *file = ptr;
+ fmode_t mode = (fmode_t)(unsigned long)ptr;
struct proc_inode *ei;
struct inode *inode;
- if (!file)
- return ERR_PTR(-ENOENT);
-
inode = proc_pid_make_inode(dir->i_sb, task);
if (!inode)
return ERR_PTR(-ENOENT);
@@ -1832,9 +1829,9 @@ proc_map_files_instantiate(struct inode *dir, struct dentry *dentry,
inode->i_size = 64;
inode->i_mode = S_IFLNK;
- if (file->f_mode & FMODE_READ)
+ if (mode & FMODE_READ)
inode->i_mode |= S_IRUSR;
- if (file->f_mode & FMODE_WRITE)
+ if (mode & FMODE_WRITE)
inode->i_mode |= S_IWUSR;
d_set_d_op(dentry, &tid_map_files_dentry_operations);
@@ -1878,7 +1875,8 @@ static struct dentry *proc_map_files_lookup(struct inode *dir,
if (!vma)
goto out_no_vma;
- result = proc_map_files_instantiate(dir, dentry, task, vma->vm_file);
+ result = proc_map_files_instantiate(dir, dentry, task,
+ (void *)(unsigned long)vma->vm_file->f_mode);
out_no_vma:
up_read(&mm->mmap_sem);
@@ -1979,7 +1977,7 @@ proc_map_files_readdir(struct file *filp, void *dirent, filldir_t filldir)
if (++pos <= filp->f_pos)
continue;
- info.file = get_file(vma->vm_file);
+ info.mode = vma->vm_file->f_mode;
info.len = snprintf(info.name,
sizeof(info.name), "%lx-%lx",
vma->vm_start, vma->vm_end);
@@ -1994,19 +1992,11 @@ proc_map_files_readdir(struct file *filp, void *dirent, filldir_t filldir)
ret = proc_fill_cache(filp, dirent, filldir,
p->name, p->len,
proc_map_files_instantiate,
- task, p->file);
+ task,
+ (void *)(unsigned long)p->mode);
if (ret)
break;
filp->f_pos++;
- fput(p->file);
- }
- for (; i < nr_files; i++) {
- /*
- * In case of error don't forget
- * to put rest of file refs.
- */
- p = flex_array_get(fa, i);
- fput(p->file);
}
if (fa)
flex_array_free(fa);