diff options
Diffstat (limited to 'fs/file_table.c')
-rw-r--r-- | fs/file_table.c | 46 |
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) | |||
52 | static inline void file_free(struct file *f) | 52 | static 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 | } |
195 | EXPORT_SYMBOL(alloc_file); | 184 | EXPORT_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 | */ | ||
205 | static 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 | */ |
223 | static void __fput(struct file *file) | 188 | static 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 | } |