aboutsummaryrefslogtreecommitdiffstats
path: root/fs/file_table.c
diff options
context:
space:
mode:
authorNick Piggin <npiggin@kernel.dk>2010-08-17 14:37:35 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2010-08-18 08:35:47 -0400
commitee2ffa0dfdd2db19705f2ba1c6a4c0bfe8122dd8 (patch)
treee48400d1a33f8d2e68589ccfd61637aa64462f08 /fs/file_table.c
parentb04f784e5d19ed58892833dae845738972cea260 (diff)
fs: cleanup files_lock locking
fs: cleanup files_lock locking Lock tty_files with a new spinlock, tty_files_lock; provide helpers to manipulate the per-sb files list; unexport the files_lock spinlock. Cc: linux-kernel@vger.kernel.org Cc: Christoph Hellwig <hch@infradead.org> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Acked-by: Andi Kleen <ak@linux.intel.com> Acked-by: Greg Kroah-Hartman <gregkh@suse.de> Signed-off-by: Nick Piggin <npiggin@kernel.dk> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/file_table.c')
-rw-r--r--fs/file_table.c42
1 files changed, 18 insertions, 24 deletions
diff --git a/fs/file_table.c b/fs/file_table.c
index edecd36fed9b..6f0e62ecfddd 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -32,8 +32,7 @@ struct files_stat_struct files_stat = {
32 .max_files = NR_FILE 32 .max_files = NR_FILE
33}; 33};
34 34
35/* public. Not pretty! */ 35static __cacheline_aligned_in_smp DEFINE_SPINLOCK(files_lock);
36__cacheline_aligned_in_smp DEFINE_SPINLOCK(files_lock);
37 36
38/* SLAB cache for file structures */ 37/* SLAB cache for file structures */
39static struct kmem_cache *filp_cachep __read_mostly; 38static struct kmem_cache *filp_cachep __read_mostly;
@@ -249,7 +248,7 @@ static void __fput(struct file *file)
249 cdev_put(inode->i_cdev); 248 cdev_put(inode->i_cdev);
250 fops_put(file->f_op); 249 fops_put(file->f_op);
251 put_pid(file->f_owner.pid); 250 put_pid(file->f_owner.pid);
252 file_kill(file); 251 file_sb_list_del(file);
253 if (file->f_mode & FMODE_WRITE) 252 if (file->f_mode & FMODE_WRITE)
254 drop_file_write_access(file); 253 drop_file_write_access(file);
255 file->f_path.dentry = NULL; 254 file->f_path.dentry = NULL;
@@ -328,31 +327,29 @@ struct file *fget_light(unsigned int fd, int *fput_needed)
328 return file; 327 return file;
329} 328}
330 329
331
332void put_filp(struct file *file) 330void put_filp(struct file *file)
333{ 331{
334 if (atomic_long_dec_and_test(&file->f_count)) { 332 if (atomic_long_dec_and_test(&file->f_count)) {
335 security_file_free(file); 333 security_file_free(file);
336 file_kill(file); 334 file_sb_list_del(file);
337 file_free(file); 335 file_free(file);
338 } 336 }
339} 337}
340 338
341void file_move(struct file *file, struct list_head *list) 339void file_sb_list_add(struct file *file, struct super_block *sb)
342{ 340{
343 if (!list) 341 spin_lock(&files_lock);
344 return; 342 BUG_ON(!list_empty(&file->f_u.fu_list));
345 file_list_lock(); 343 list_add(&file->f_u.fu_list, &sb->s_files);
346 list_move(&file->f_u.fu_list, list); 344 spin_unlock(&files_lock);
347 file_list_unlock();
348} 345}
349 346
350void file_kill(struct file *file) 347void file_sb_list_del(struct file *file)
351{ 348{
352 if (!list_empty(&file->f_u.fu_list)) { 349 if (!list_empty(&file->f_u.fu_list)) {
353 file_list_lock(); 350 spin_lock(&files_lock);
354 list_del_init(&file->f_u.fu_list); 351 list_del_init(&file->f_u.fu_list);
355 file_list_unlock(); 352 spin_unlock(&files_lock);
356 } 353 }
357} 354}
358 355
@@ -361,7 +358,7 @@ int fs_may_remount_ro(struct super_block *sb)
361 struct file *file; 358 struct file *file;
362 359
363 /* Check that no files are currently opened for writing. */ 360 /* Check that no files are currently opened for writing. */
364 file_list_lock(); 361 spin_lock(&files_lock);
365 list_for_each_entry(file, &sb->s_files, f_u.fu_list) { 362 list_for_each_entry(file, &sb->s_files, f_u.fu_list) {
366 struct inode *inode = file->f_path.dentry->d_inode; 363 struct inode *inode = file->f_path.dentry->d_inode;
367 364
@@ -373,10 +370,10 @@ int fs_may_remount_ro(struct super_block *sb)
373 if (S_ISREG(inode->i_mode) && (file->f_mode & FMODE_WRITE)) 370 if (S_ISREG(inode->i_mode) && (file->f_mode & FMODE_WRITE))
374 goto too_bad; 371 goto too_bad;
375 } 372 }
376 file_list_unlock(); 373 spin_unlock(&files_lock);
377 return 1; /* Tis' cool bro. */ 374 return 1; /* Tis' cool bro. */
378too_bad: 375too_bad:
379 file_list_unlock(); 376 spin_unlock(&files_lock);
380 return 0; 377 return 0;
381} 378}
382 379
@@ -392,7 +389,7 @@ void mark_files_ro(struct super_block *sb)
392 struct file *f; 389 struct file *f;
393 390
394retry: 391retry:
395 file_list_lock(); 392 spin_lock(&files_lock);
396 list_for_each_entry(f, &sb->s_files, f_u.fu_list) { 393 list_for_each_entry(f, &sb->s_files, f_u.fu_list) {
397 struct vfsmount *mnt; 394 struct vfsmount *mnt;
398 if (!S_ISREG(f->f_path.dentry->d_inode->i_mode)) 395 if (!S_ISREG(f->f_path.dentry->d_inode->i_mode))
@@ -408,16 +405,13 @@ retry:
408 continue; 405 continue;
409 file_release_write(f); 406 file_release_write(f);
410 mnt = mntget(f->f_path.mnt); 407 mnt = mntget(f->f_path.mnt);
411 file_list_unlock(); 408 /* This can sleep, so we can't hold the spinlock. */
412 /* 409 spin_unlock(&files_lock);
413 * This can sleep, so we can't hold
414 * the file_list_lock() spinlock.
415 */
416 mnt_drop_write(mnt); 410 mnt_drop_write(mnt);
417 mntput(mnt); 411 mntput(mnt);
418 goto retry; 412 goto retry;
419 } 413 }
420 file_list_unlock(); 414 spin_unlock(&files_lock);
421} 415}
422 416
423void __init files_init(unsigned long mempages) 417void __init files_init(unsigned long mempages)