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.c46
1 files changed, 6 insertions, 40 deletions
diff --git a/fs/file_table.c b/fs/file_table.c
index 5fff9030be34..a374f5033e97 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -52,7 +52,6 @@ static void file_free_rcu(struct rcu_head *head)
52static inline void file_free(struct file *f) 52static inline void file_free(struct file *f)
53{ 53{
54 percpu_counter_dec(&nr_files); 54 percpu_counter_dec(&nr_files);
55 file_check_state(f);
56 call_rcu(&f->f_u.fu_rcuhead, file_free_rcu); 55 call_rcu(&f->f_u.fu_rcuhead, file_free_rcu);
57} 56}
58 57
@@ -135,6 +134,7 @@ struct file *get_empty_filp(void)
135 atomic_long_set(&f->f_count, 1); 134 atomic_long_set(&f->f_count, 1);
136 rwlock_init(&f->f_owner.lock); 135 rwlock_init(&f->f_owner.lock);
137 spin_lock_init(&f->f_lock); 136 spin_lock_init(&f->f_lock);
137 mutex_init(&f->f_pos_lock);
138 eventpoll_init_file(f); 138 eventpoll_init_file(f);
139 /* f->f_version: 0 */ 139 /* f->f_version: 0 */
140 return f; 140 return f;
@@ -177,47 +177,12 @@ struct file *alloc_file(struct path *path, fmode_t mode,
177 file->f_mapping = path->dentry->d_inode->i_mapping; 177 file->f_mapping = path->dentry->d_inode->i_mapping;
178 file->f_mode = mode; 178 file->f_mode = mode;
179 file->f_op = fop; 179 file->f_op = fop;
180
181 /*
182 * These mounts don't really matter in practice
183 * for r/o bind mounts. They aren't userspace-
184 * visible. We do this for consistency, and so
185 * that we can do debugging checks at __fput()
186 */
187 if ((mode & FMODE_WRITE) && !special_file(path->dentry->d_inode->i_mode)) {
188 file_take_write(file);
189 WARN_ON(mnt_clone_write(path->mnt));
190 }
191 if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) 180 if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
192 i_readcount_inc(path->dentry->d_inode); 181 i_readcount_inc(path->dentry->d_inode);
193 return file; 182 return file;
194} 183}
195EXPORT_SYMBOL(alloc_file); 184EXPORT_SYMBOL(alloc_file);
196 185
197/**
198 * drop_file_write_access - give up ability to write to a file
199 * @file: the file to which we will stop writing
200 *
201 * This is a central place which will give up the ability
202 * to write to @file, along with access to write through
203 * its vfsmount.
204 */
205static void drop_file_write_access(struct file *file)
206{
207 struct vfsmount *mnt = file->f_path.mnt;
208 struct dentry *dentry = file->f_path.dentry;
209 struct inode *inode = dentry->d_inode;
210
211 put_write_access(inode);
212
213 if (special_file(inode->i_mode))
214 return;
215 if (file_check_writeable(file) != 0)
216 return;
217 __mnt_drop_write(mnt);
218 file_release_write(file);
219}
220
221/* the real guts of fput() - releasing the last reference to file 186/* the real guts of fput() - releasing the last reference to file
222 */ 187 */
223static void __fput(struct file *file) 188static void __fput(struct file *file)
@@ -234,7 +199,7 @@ static void __fput(struct file *file)
234 * in the file cleanup chain. 199 * in the file cleanup chain.
235 */ 200 */
236 eventpoll_release(file); 201 eventpoll_release(file);
237 locks_remove_flock(file); 202 locks_remove_file(file);
238 203
239 if (unlikely(file->f_flags & FASYNC)) { 204 if (unlikely(file->f_flags & FASYNC)) {
240 if (file->f_op->fasync) 205 if (file->f_op->fasync)
@@ -252,8 +217,10 @@ static void __fput(struct file *file)
252 put_pid(file->f_owner.pid); 217 put_pid(file->f_owner.pid);
253 if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) 218 if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
254 i_readcount_dec(inode); 219 i_readcount_dec(inode);
255 if (file->f_mode & FMODE_WRITE) 220 if (file->f_mode & FMODE_WRITER) {
256 drop_file_write_access(file); 221 put_write_access(inode);
222 __mnt_drop_write(mnt);
223 }
257 file->f_path.dentry = NULL; 224 file->f_path.dentry = NULL;
258 file->f_path.mnt = NULL; 225 file->f_path.mnt = NULL;
259 file->f_inode = NULL; 226 file->f_inode = NULL;
@@ -358,6 +325,5 @@ void __init files_init(unsigned long mempages)
358 325
359 n = (mempages * (PAGE_SIZE / 1024)) / 10; 326 n = (mempages * (PAGE_SIZE / 1024)) / 10;
360 files_stat.max_files = max_t(unsigned long, n, NR_FILE); 327 files_stat.max_files = max_t(unsigned long, n, NR_FILE);
361 files_defer_init();
362 percpu_counter_init(&nr_files, 0); 328 percpu_counter_init(&nr_files, 0);
363} 329}