aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-10-04 11:06:42 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-11-09 00:16:20 -0500
commiteee5cc2702929fd41cce28058dc6d6717f723f87 (patch)
treed405e2302511adec7d25024679b8ac2cbd95d608 /fs
parent8b61e74ffc6310e1d35a9b51c8463093851f8bcf (diff)
get rid of s_files and files_lock
The only thing we need it for is alt-sysrq-r (emergency remount r/o) and these days we can do just as well without going through the list of files. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r--fs/file_table.c125
-rw-r--r--fs/internal.h3
-rw-r--r--fs/open.c2
-rw-r--r--fs/super.c15
4 files changed, 2 insertions, 143 deletions
diff --git a/fs/file_table.c b/fs/file_table.c
index e61e5529fa9d..23b6dca03ba0 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -36,8 +36,6 @@ struct files_stat_struct files_stat = {
36 .max_files = NR_FILE 36 .max_files = NR_FILE
37}; 37};
38 38
39DEFINE_STATIC_LGLOCK(files_lglock);
40
41/* SLAB cache for file structures */ 39/* SLAB cache for file structures */
42static struct kmem_cache *filp_cachep __read_mostly; 40static struct kmem_cache *filp_cachep __read_mostly;
43 41
@@ -134,7 +132,6 @@ struct file *get_empty_filp(void)
134 return ERR_PTR(error); 132 return ERR_PTR(error);
135 } 133 }
136 134
137 INIT_LIST_HEAD(&f->f_u.fu_list);
138 atomic_long_set(&f->f_count, 1); 135 atomic_long_set(&f->f_count, 1);
139 rwlock_init(&f->f_owner.lock); 136 rwlock_init(&f->f_owner.lock);
140 spin_lock_init(&f->f_lock); 137 spin_lock_init(&f->f_lock);
@@ -304,7 +301,6 @@ void fput(struct file *file)
304 if (atomic_long_dec_and_test(&file->f_count)) { 301 if (atomic_long_dec_and_test(&file->f_count)) {
305 struct task_struct *task = current; 302 struct task_struct *task = current;
306 303
307 file_sb_list_del(file);
308 if (likely(!in_interrupt() && !(task->flags & PF_KTHREAD))) { 304 if (likely(!in_interrupt() && !(task->flags & PF_KTHREAD))) {
309 init_task_work(&file->f_u.fu_rcuhead, ____fput); 305 init_task_work(&file->f_u.fu_rcuhead, ____fput);
310 if (!task_work_add(task, &file->f_u.fu_rcuhead, true)) 306 if (!task_work_add(task, &file->f_u.fu_rcuhead, true))
@@ -333,7 +329,6 @@ void __fput_sync(struct file *file)
333{ 329{
334 if (atomic_long_dec_and_test(&file->f_count)) { 330 if (atomic_long_dec_and_test(&file->f_count)) {
335 struct task_struct *task = current; 331 struct task_struct *task = current;
336 file_sb_list_del(file);
337 BUG_ON(!(task->flags & PF_KTHREAD)); 332 BUG_ON(!(task->flags & PF_KTHREAD));
338 __fput(file); 333 __fput(file);
339 } 334 }
@@ -345,129 +340,10 @@ void put_filp(struct file *file)
345{ 340{
346 if (atomic_long_dec_and_test(&file->f_count)) { 341 if (atomic_long_dec_and_test(&file->f_count)) {
347 security_file_free(file); 342 security_file_free(file);
348 file_sb_list_del(file);
349 file_free(file); 343 file_free(file);
350 } 344 }
351} 345}
352 346
353static inline int file_list_cpu(struct file *file)
354{
355#ifdef CONFIG_SMP
356 return file->f_sb_list_cpu;
357#else
358 return smp_processor_id();
359#endif
360}
361
362/* helper for file_sb_list_add to reduce ifdefs */
363static inline void __file_sb_list_add(struct file *file, struct super_block *sb)
364{
365 struct list_head *list;
366#ifdef CONFIG_SMP
367 int cpu;
368 cpu = smp_processor_id();
369 file->f_sb_list_cpu = cpu;
370 list = per_cpu_ptr(sb->s_files, cpu);
371#else
372 list = &sb->s_files;
373#endif
374 list_add(&file->f_u.fu_list, list);
375}
376
377/**
378 * file_sb_list_add - add a file to the sb's file list
379 * @file: file to add
380 * @sb: sb to add it to
381 *
382 * Use this function to associate a file with the superblock of the inode it
383 * refers to.
384 */
385void file_sb_list_add(struct file *file, struct super_block *sb)
386{
387 if (likely(!(file->f_mode & FMODE_WRITE)))
388 return;
389 if (!S_ISREG(file_inode(file)->i_mode))
390 return;
391 lg_local_lock(&files_lglock);
392 __file_sb_list_add(file, sb);
393 lg_local_unlock(&files_lglock);
394}
395
396/**
397 * file_sb_list_del - remove a file from the sb's file list
398 * @file: file to remove
399 * @sb: sb to remove it from
400 *
401 * Use this function to remove a file from its superblock.
402 */
403void file_sb_list_del(struct file *file)
404{
405 if (!list_empty(&file->f_u.fu_list)) {
406 lg_local_lock_cpu(&files_lglock, file_list_cpu(file));
407 list_del_init(&file->f_u.fu_list);
408 lg_local_unlock_cpu(&files_lglock, file_list_cpu(file));
409 }
410}
411
412#ifdef CONFIG_SMP
413
414/*
415 * These macros iterate all files on all CPUs for a given superblock.
416 * files_lglock must be held globally.
417 */
418#define do_file_list_for_each_entry(__sb, __file) \
419{ \
420 int i; \
421 for_each_possible_cpu(i) { \
422 struct list_head *list; \
423 list = per_cpu_ptr((__sb)->s_files, i); \
424 list_for_each_entry((__file), list, f_u.fu_list)
425
426#define while_file_list_for_each_entry \
427 } \
428}
429
430#else
431
432#define do_file_list_for_each_entry(__sb, __file) \
433{ \
434 struct list_head *list; \
435 list = &(sb)->s_files; \
436 list_for_each_entry((__file), list, f_u.fu_list)
437
438#define while_file_list_for_each_entry \
439}
440
441#endif
442
443/**
444 * mark_files_ro - mark all files read-only
445 * @sb: superblock in question
446 *
447 * All files are marked read-only. We don't care about pending
448 * delete files so this should be used in 'force' mode only.
449 */
450void mark_files_ro(struct super_block *sb)
451{
452 struct file *f;
453
454 lg_global_lock(&files_lglock);
455 do_file_list_for_each_entry(sb, f) {
456 if (!file_count(f))
457 continue;
458 if (!(f->f_mode & FMODE_WRITE))
459 continue;
460 spin_lock(&f->f_lock);
461 f->f_mode &= ~FMODE_WRITE;
462 spin_unlock(&f->f_lock);
463 if (file_check_writeable(f) != 0)
464 continue;
465 __mnt_drop_write(f->f_path.mnt);
466 file_release_write(f);
467 } while_file_list_for_each_entry;
468 lg_global_unlock(&files_lglock);
469}
470
471void __init files_init(unsigned long mempages) 347void __init files_init(unsigned long mempages)
472{ 348{
473 unsigned long n; 349 unsigned long n;
@@ -483,6 +359,5 @@ void __init files_init(unsigned long mempages)
483 n = (mempages * (PAGE_SIZE / 1024)) / 10; 359 n = (mempages * (PAGE_SIZE / 1024)) / 10;
484 files_stat.max_files = max_t(unsigned long, n, NR_FILE); 360 files_stat.max_files = max_t(unsigned long, n, NR_FILE);
485 files_defer_init(); 361 files_defer_init();
486 lg_lock_init(&files_lglock, "files_lglock");
487 percpu_counter_init(&nr_files, 0); 362 percpu_counter_init(&nr_files, 0);
488} 363}
diff --git a/fs/internal.h b/fs/internal.h
index 4a11e75ce14d..465742407466 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -73,9 +73,6 @@ extern void chroot_fs_refs(const struct path *, const struct path *);
73/* 73/*
74 * file_table.c 74 * file_table.c
75 */ 75 */
76extern void file_sb_list_add(struct file *f, struct super_block *sb);
77extern void file_sb_list_del(struct file *f);
78extern void mark_files_ro(struct super_block *);
79extern struct file *get_empty_filp(void); 76extern struct file *get_empty_filp(void);
80 77
81/* 78/*
diff --git a/fs/open.c b/fs/open.c
index a1465b1ec8c7..fffbed40dbe9 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -685,7 +685,6 @@ static int do_dentry_open(struct file *f,
685 } 685 }
686 686
687 f->f_mapping = inode->i_mapping; 687 f->f_mapping = inode->i_mapping;
688 file_sb_list_add(f, inode->i_sb);
689 688
690 if (unlikely(f->f_mode & FMODE_PATH)) { 689 if (unlikely(f->f_mode & FMODE_PATH)) {
691 f->f_op = &empty_fops; 690 f->f_op = &empty_fops;
@@ -724,7 +723,6 @@ static int do_dentry_open(struct file *f,
724 723
725cleanup_all: 724cleanup_all:
726 fops_put(f->f_op); 725 fops_put(f->f_op);
727 file_sb_list_del(f);
728 if (f->f_mode & FMODE_WRITE) { 726 if (f->f_mode & FMODE_WRITE) {
729 put_write_access(inode); 727 put_write_access(inode);
730 if (!special_file(inode->i_mode)) { 728 if (!special_file(inode->i_mode)) {
diff --git a/fs/super.c b/fs/super.c
index 743bb7118053..e5f6c2cfac38 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -140,9 +140,6 @@ static void destroy_super(struct super_block *s)
140 int i; 140 int i;
141 list_lru_destroy(&s->s_dentry_lru); 141 list_lru_destroy(&s->s_dentry_lru);
142 list_lru_destroy(&s->s_inode_lru); 142 list_lru_destroy(&s->s_inode_lru);
143#ifdef CONFIG_SMP
144 free_percpu(s->s_files);
145#endif
146 for (i = 0; i < SB_FREEZE_LEVELS; i++) 143 for (i = 0; i < SB_FREEZE_LEVELS; i++)
147 percpu_counter_destroy(&s->s_writers.counter[i]); 144 percpu_counter_destroy(&s->s_writers.counter[i]);
148 security_sb_free(s); 145 security_sb_free(s);
@@ -172,15 +169,6 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags)
172 if (security_sb_alloc(s)) 169 if (security_sb_alloc(s))
173 goto fail; 170 goto fail;
174 171
175#ifdef CONFIG_SMP
176 s->s_files = alloc_percpu(struct list_head);
177 if (!s->s_files)
178 goto fail;
179 for_each_possible_cpu(i)
180 INIT_LIST_HEAD(per_cpu_ptr(s->s_files, i));
181#else
182 INIT_LIST_HEAD(&s->s_files);
183#endif
184 for (i = 0; i < SB_FREEZE_LEVELS; i++) { 172 for (i = 0; i < SB_FREEZE_LEVELS; i++) {
185 if (percpu_counter_init(&s->s_writers.counter[i], 0) < 0) 173 if (percpu_counter_init(&s->s_writers.counter[i], 0) < 0)
186 goto fail; 174 goto fail;
@@ -722,7 +710,8 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
722 make sure there are no rw files opened */ 710 make sure there are no rw files opened */
723 if (remount_ro) { 711 if (remount_ro) {
724 if (force) { 712 if (force) {
725 mark_files_ro(sb); 713 sb->s_readonly_remount = 1;
714 smp_wmb();
726 } else { 715 } else {
727 retval = sb_prepare_remount_readonly(sb); 716 retval = sb_prepare_remount_readonly(sb);
728 if (retval) 717 if (retval)