Commit 430e285e authored by Dave Hansen's avatar Dave Hansen Committed by Al Viro

[PATCH] fix up new filp allocators

Some new uses of get_empty_filp() have crept in; switched
to alloc_file() to make sure that pieces of initialization
won't be missing.

We really need to kill get_empty_filp().

[AV] fixed dentry leak on failure exit in anon_inode_getfd()

Cc: Erez Zadok <ezk@cs.sunysb.edu>
Cc: Trond Myklebust <trond.myklebust@fys.uio.no>
Cc: "J Bruce Fields" <bfields@fieldses.org>
Acked-by: default avatarAl Viro <viro@ZenIV.linux.org.uk>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarDave Hansen <haveblue@us.ibm.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 322ee5b3
...@@ -81,13 +81,10 @@ int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile, ...@@ -81,13 +81,10 @@ int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile,
if (IS_ERR(anon_inode_inode)) if (IS_ERR(anon_inode_inode))
return -ENODEV; return -ENODEV;
file = get_empty_filp();
if (!file)
return -ENFILE;
error = get_unused_fd(); error = get_unused_fd();
if (error < 0) if (error < 0)
goto err_put_filp; return error;
fd = error; fd = error;
/* /*
...@@ -114,14 +111,15 @@ int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile, ...@@ -114,14 +111,15 @@ int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile,
dentry->d_flags &= ~DCACHE_UNHASHED; dentry->d_flags &= ~DCACHE_UNHASHED;
d_instantiate(dentry, anon_inode_inode); d_instantiate(dentry, anon_inode_inode);
file->f_path.mnt = mntget(anon_inode_mnt); error = -ENFILE;
file->f_path.dentry = dentry; file = alloc_file(anon_inode_mnt, dentry,
FMODE_READ | FMODE_WRITE, fops);
if (!file)
goto err_dput;
file->f_mapping = anon_inode_inode->i_mapping; file->f_mapping = anon_inode_inode->i_mapping;
file->f_pos = 0; file->f_pos = 0;
file->f_flags = O_RDWR; file->f_flags = O_RDWR;
file->f_op = fops;
file->f_mode = FMODE_READ | FMODE_WRITE;
file->f_version = 0; file->f_version = 0;
file->private_data = priv; file->private_data = priv;
...@@ -132,10 +130,10 @@ int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile, ...@@ -132,10 +130,10 @@ int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile,
*pfile = file; *pfile = file;
return 0; return 0;
err_dput:
dput(dentry);
err_put_unused_fd: err_put_unused_fd:
put_unused_fd(fd); put_unused_fd(fd);
err_put_filp:
put_filp(file);
return error; return error;
} }
EXPORT_SYMBOL_GPL(anon_inode_getfd); EXPORT_SYMBOL_GPL(anon_inode_getfd);
......
...@@ -83,6 +83,12 @@ int proc_nr_files(ctl_table *table, int write, struct file *filp, ...@@ -83,6 +83,12 @@ int proc_nr_files(ctl_table *table, int write, struct file *filp,
/* Find an unused file structure and return a pointer to it. /* Find an unused file structure and return a pointer to it.
* Returns NULL, if there are no more free file structures or * Returns NULL, if there are no more free file structures or
* we run out of memory. * we run out of memory.
*
* Be very careful using this. You are responsible for
* getting write access to any mount that you might assign
* to this filp, if it is opened for write. If this is not
* done, you will imbalance int the mount's writer count
* and a warning at __fput() time.
*/ */
struct file *get_empty_filp(void) struct file *get_empty_filp(void)
{ {
......
...@@ -957,13 +957,10 @@ struct file *create_write_pipe(void) ...@@ -957,13 +957,10 @@ struct file *create_write_pipe(void)
struct dentry *dentry; struct dentry *dentry;
struct qstr name = { .name = "" }; struct qstr name = { .name = "" };
f = get_empty_filp();
if (!f)
return ERR_PTR(-ENFILE);
err = -ENFILE; err = -ENFILE;
inode = get_pipe_inode(); inode = get_pipe_inode();
if (!inode) if (!inode)
goto err_file; goto err;
err = -ENOMEM; err = -ENOMEM;
dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &name); dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &name);
...@@ -978,22 +975,24 @@ struct file *create_write_pipe(void) ...@@ -978,22 +975,24 @@ struct file *create_write_pipe(void)
*/ */
dentry->d_flags &= ~DCACHE_UNHASHED; dentry->d_flags &= ~DCACHE_UNHASHED;
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
f->f_path.mnt = mntget(pipe_mnt);
f->f_path.dentry = dentry; err = -ENFILE;
f = alloc_file(pipe_mnt, dentry, FMODE_WRITE, &write_pipe_fops);
if (!f)
goto err_dentry;
f->f_mapping = inode->i_mapping; f->f_mapping = inode->i_mapping;
f->f_flags = O_WRONLY; f->f_flags = O_WRONLY;
f->f_op = &write_pipe_fops;
f->f_mode = FMODE_WRITE;
f->f_version = 0; f->f_version = 0;
return f; return f;
err_dentry:
dput(dentry);
err_inode: err_inode:
free_pipe_info(inode); free_pipe_info(inode);
iput(inode); iput(inode);
err_file: err:
put_filp(f);
return ERR_PTR(err); return ERR_PTR(err);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment