diff options
author | Dave Hansen <haveblue@us.ibm.com> | 2008-02-15 17:37:26 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2008-03-19 06:54:05 -0400 |
commit | 430e285e0817e3e18aadd814bc078d50d8af0cbf (patch) | |
tree | cbd008864e18e76a7e2984bfd1898028762fd19a | |
parent | 322ee5b36eac42e762526b0df7fa432beba6e7a0 (diff) |
[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: Al Viro <viro@ZenIV.linux.org.uk>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Dave Hansen <haveblue@us.ibm.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/anon_inodes.c | 18 | ||||
-rw-r--r-- | fs/file_table.c | 6 | ||||
-rw-r--r-- | fs/pipe.c | 19 |
3 files changed, 23 insertions, 20 deletions
diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c index 23321889d9b0..f42be069e085 100644 --- a/fs/anon_inodes.c +++ b/fs/anon_inodes.c | |||
@@ -81,13 +81,10 @@ int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile, | |||
81 | 81 | ||
82 | if (IS_ERR(anon_inode_inode)) | 82 | if (IS_ERR(anon_inode_inode)) |
83 | return -ENODEV; | 83 | return -ENODEV; |
84 | file = get_empty_filp(); | ||
85 | if (!file) | ||
86 | return -ENFILE; | ||
87 | 84 | ||
88 | error = get_unused_fd(); | 85 | error = get_unused_fd(); |
89 | if (error < 0) | 86 | if (error < 0) |
90 | goto err_put_filp; | 87 | return error; |
91 | fd = error; | 88 | fd = error; |
92 | 89 | ||
93 | /* | 90 | /* |
@@ -114,14 +111,15 @@ int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile, | |||
114 | dentry->d_flags &= ~DCACHE_UNHASHED; | 111 | dentry->d_flags &= ~DCACHE_UNHASHED; |
115 | d_instantiate(dentry, anon_inode_inode); | 112 | d_instantiate(dentry, anon_inode_inode); |
116 | 113 | ||
117 | file->f_path.mnt = mntget(anon_inode_mnt); | 114 | error = -ENFILE; |
118 | file->f_path.dentry = dentry; | 115 | file = alloc_file(anon_inode_mnt, dentry, |
116 | FMODE_READ | FMODE_WRITE, fops); | ||
117 | if (!file) | ||
118 | goto err_dput; | ||
119 | file->f_mapping = anon_inode_inode->i_mapping; | 119 | file->f_mapping = anon_inode_inode->i_mapping; |
120 | 120 | ||
121 | file->f_pos = 0; | 121 | file->f_pos = 0; |
122 | file->f_flags = O_RDWR; | 122 | file->f_flags = O_RDWR; |
123 | file->f_op = fops; | ||
124 | file->f_mode = FMODE_READ | FMODE_WRITE; | ||
125 | file->f_version = 0; | 123 | file->f_version = 0; |
126 | file->private_data = priv; | 124 | file->private_data = priv; |
127 | 125 | ||
@@ -132,10 +130,10 @@ int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile, | |||
132 | *pfile = file; | 130 | *pfile = file; |
133 | return 0; | 131 | return 0; |
134 | 132 | ||
133 | err_dput: | ||
134 | dput(dentry); | ||
135 | err_put_unused_fd: | 135 | err_put_unused_fd: |
136 | put_unused_fd(fd); | 136 | put_unused_fd(fd); |
137 | err_put_filp: | ||
138 | put_filp(file); | ||
139 | return error; | 137 | return error; |
140 | } | 138 | } |
141 | EXPORT_SYMBOL_GPL(anon_inode_getfd); | 139 | EXPORT_SYMBOL_GPL(anon_inode_getfd); |
diff --git a/fs/file_table.c b/fs/file_table.c index 6d27befe2d48..986ff4ed0a7c 100644 --- a/fs/file_table.c +++ b/fs/file_table.c | |||
@@ -83,6 +83,12 @@ int proc_nr_files(ctl_table *table, int write, struct file *filp, | |||
83 | /* Find an unused file structure and return a pointer to it. | 83 | /* Find an unused file structure and return a pointer to it. |
84 | * Returns NULL, if there are no more free file structures or | 84 | * Returns NULL, if there are no more free file structures or |
85 | * we run out of memory. | 85 | * we run out of memory. |
86 | * | ||
87 | * Be very careful using this. You are responsible for | ||
88 | * getting write access to any mount that you might assign | ||
89 | * to this filp, if it is opened for write. If this is not | ||
90 | * done, you will imbalance int the mount's writer count | ||
91 | * and a warning at __fput() time. | ||
86 | */ | 92 | */ |
87 | struct file *get_empty_filp(void) | 93 | struct file *get_empty_filp(void) |
88 | { | 94 | { |
@@ -957,13 +957,10 @@ struct file *create_write_pipe(void) | |||
957 | struct dentry *dentry; | 957 | struct dentry *dentry; |
958 | struct qstr name = { .name = "" }; | 958 | struct qstr name = { .name = "" }; |
959 | 959 | ||
960 | f = get_empty_filp(); | ||
961 | if (!f) | ||
962 | return ERR_PTR(-ENFILE); | ||
963 | err = -ENFILE; | 960 | err = -ENFILE; |
964 | inode = get_pipe_inode(); | 961 | inode = get_pipe_inode(); |
965 | if (!inode) | 962 | if (!inode) |
966 | goto err_file; | 963 | goto err; |
967 | 964 | ||
968 | err = -ENOMEM; | 965 | err = -ENOMEM; |
969 | dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &name); | 966 | dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &name); |
@@ -978,22 +975,24 @@ struct file *create_write_pipe(void) | |||
978 | */ | 975 | */ |
979 | dentry->d_flags &= ~DCACHE_UNHASHED; | 976 | dentry->d_flags &= ~DCACHE_UNHASHED; |
980 | d_instantiate(dentry, inode); | 977 | d_instantiate(dentry, inode); |
981 | f->f_path.mnt = mntget(pipe_mnt); | 978 | |
982 | f->f_path.dentry = dentry; | 979 | err = -ENFILE; |
980 | f = alloc_file(pipe_mnt, dentry, FMODE_WRITE, &write_pipe_fops); | ||
981 | if (!f) | ||
982 | goto err_dentry; | ||
983 | f->f_mapping = inode->i_mapping; | 983 | f->f_mapping = inode->i_mapping; |
984 | 984 | ||
985 | f->f_flags = O_WRONLY; | 985 | f->f_flags = O_WRONLY; |
986 | f->f_op = &write_pipe_fops; | ||
987 | f->f_mode = FMODE_WRITE; | ||
988 | f->f_version = 0; | 986 | f->f_version = 0; |
989 | 987 | ||
990 | return f; | 988 | return f; |
991 | 989 | ||
990 | err_dentry: | ||
991 | dput(dentry); | ||
992 | err_inode: | 992 | err_inode: |
993 | free_pipe_info(inode); | 993 | free_pipe_info(inode); |
994 | iput(inode); | 994 | iput(inode); |
995 | err_file: | 995 | err: |
996 | put_filp(f); | ||
997 | return ERR_PTR(err); | 996 | return ERR_PTR(err); |
998 | } | 997 | } |
999 | 998 | ||