diff options
author | Maxim Patlasov <mpatlasov@parallels.com> | 2013-02-20 13:13:32 +1100 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-02-26 02:46:14 -0500 |
commit | 87e0aab37ff6c4284810a48d6034314fbf4eb319 (patch) | |
tree | 8e60b24d094edef3d5b6d347444fe4db8c688f10 /fs/proc/inode.c | |
parent | 41735818766c0ec215b9a69591e7eae642061954 (diff) |
proc: avoid extra pde_put() in proc_fill_super()
If proc_get_inode() succeeded, but d_make_root() failed, pde_put() for
proc_root will be called twice: the first time due to iput() called from
d_make_root() and the second time directly in the end of
proc_fill_super().
Signed-off-by: Maxim Patlasov <mpatlasov@parallels.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/proc/inode.c')
-rw-r--r-- | fs/proc/inode.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 38f5c119b806..98a7d2870bef 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c @@ -486,6 +486,8 @@ struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de) int proc_fill_super(struct super_block *s) { + struct inode *root_inode; + s->s_flags |= MS_NODIRATIME | MS_NOSUID | MS_NOEXEC; s->s_blocksize = 1024; s->s_blocksize_bits = 10; @@ -494,11 +496,18 @@ int proc_fill_super(struct super_block *s) s->s_time_gran = 1; pde_get(&proc_root); - s->s_root = d_make_root(proc_get_inode(s, &proc_root)); - if (s->s_root) - return 0; + root_inode = proc_get_inode(s, &proc_root); + if (!root_inode) { + printk(KERN_ERR "proc_fill_super: get root inode failed\n"); + pde_put(&proc_root); + return -ENOMEM; + } - printk("proc_read_super: get root inode failed\n"); - pde_put(&proc_root); - return -ENOMEM; + s->s_root = d_make_root(root_inode); + if (!s->s_root) { + printk(KERN_ERR "proc_fill_super: allocate dentry failed\n"); + return -ENOMEM; + } + + return 0; } |