aboutsummaryrefslogtreecommitdiffstats
path: root/fs/file_table.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/file_table.c')
-rw-r--r--fs/file_table.c65
1 files changed, 62 insertions, 3 deletions
diff --git a/fs/file_table.c b/fs/file_table.c
index d17fd691b83..3176fefc92e 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -98,16 +98,15 @@ struct file *get_empty_filp(void)
98 * percpu_counters are inaccurate. Do an expensive check before 98 * percpu_counters are inaccurate. Do an expensive check before
99 * we go and fail. 99 * we go and fail.
100 */ 100 */
101 if (percpu_counter_sum(&nr_files) >= files_stat.max_files) 101 if (percpu_counter_sum_positive(&nr_files) >= files_stat.max_files)
102 goto over; 102 goto over;
103 } 103 }
104 104
105 f = kmem_cache_alloc(filp_cachep, GFP_KERNEL); 105 f = kmem_cache_zalloc(filp_cachep, GFP_KERNEL);
106 if (f == NULL) 106 if (f == NULL)
107 goto fail; 107 goto fail;
108 108
109 percpu_counter_inc(&nr_files); 109 percpu_counter_inc(&nr_files);
110 memset(f, 0, sizeof(*f));
111 if (security_file_alloc(f)) 110 if (security_file_alloc(f))
112 goto fail_sec; 111 goto fail_sec;
113 112
@@ -138,6 +137,66 @@ fail:
138 137
139EXPORT_SYMBOL(get_empty_filp); 138EXPORT_SYMBOL(get_empty_filp);
140 139
140/**
141 * alloc_file - allocate and initialize a 'struct file'
142 * @mnt: the vfsmount on which the file will reside
143 * @dentry: the dentry representing the new file
144 * @mode: the mode with which the new file will be opened
145 * @fop: the 'struct file_operations' for the new file
146 *
147 * Use this instead of get_empty_filp() to get a new
148 * 'struct file'. Do so because of the same initialization
149 * pitfalls reasons listed for init_file(). This is a
150 * preferred interface to using init_file().
151 *
152 * If all the callers of init_file() are eliminated, its
153 * code should be moved into this function.
154 */
155struct file *alloc_file(struct vfsmount *mnt, struct dentry *dentry,
156 mode_t mode, const struct file_operations *fop)
157{
158 struct file *file;
159 struct path;
160
161 file = get_empty_filp();
162 if (!file)
163 return NULL;
164
165 init_file(file, mnt, dentry, mode, fop);
166 return file;
167}
168EXPORT_SYMBOL(alloc_file);
169
170/**
171 * init_file - initialize a 'struct file'
172 * @file: the already allocated 'struct file' to initialized
173 * @mnt: the vfsmount on which the file resides
174 * @dentry: the dentry representing this file
175 * @mode: the mode the file is opened with
176 * @fop: the 'struct file_operations' for this file
177 *
178 * Use this instead of setting the members directly. Doing so
179 * avoids making mistakes like forgetting the mntget() or
180 * forgetting to take a write on the mnt.
181 *
182 * Note: This is a crappy interface. It is here to make
183 * merging with the existing users of get_empty_filp()
184 * who have complex failure logic easier. All users
185 * of this should be moving to alloc_file().
186 */
187int init_file(struct file *file, struct vfsmount *mnt, struct dentry *dentry,
188 mode_t mode, const struct file_operations *fop)
189{
190 int error = 0;
191 file->f_path.dentry = dentry;
192 file->f_path.mnt = mntget(mnt);
193 file->f_mapping = dentry->d_inode->i_mapping;
194 file->f_mode = mode;
195 file->f_op = fop;
196 return error;
197}
198EXPORT_SYMBOL(init_file);
199
141void fastcall fput(struct file *file) 200void fastcall fput(struct file *file)
142{ 201{
143 if (atomic_dec_and_test(&file->f_count)) 202 if (atomic_dec_and_test(&file->f_count))