summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2015-03-04 12:37:22 -0500
committerJosef Bacik <jbacik@fb.com>2015-08-17 18:39:46 -0400
commit74278da9f70d84d715601fe794567a6d2bfdf078 (patch)
tree49262a88fc42b85bfe4930f5cd7a832d5ba647c6
parentcbedaac63481dea52327127a9f1c60f092bd6b07 (diff)
inode: convert inode_sb_list_lock to per-sb
The process of reducing contention on per-superblock inode lists starts with moving the locking to match the per-superblock inode list. This takes the global lock out of the picture and reduces the contention problems to within a single filesystem. This doesn't get rid of contention as the locks still have global CPU scope, but it does isolate operations on different superblocks form each other. Signed-off-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Josef Bacik <jbacik@fb.com> Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Christoph Hellwig <hch@lst.de> Tested-by: Dave Chinner <dchinner@redhat.com>
-rw-r--r--fs/block_dev.c12
-rw-r--r--fs/drop_caches.c10
-rw-r--r--fs/fs-writeback.c12
-rw-r--r--fs/inode.c28
-rw-r--r--fs/internal.h1
-rw-r--r--fs/notify/inode_mark.c20
-rw-r--r--fs/quota/dquot.c16
-rw-r--r--fs/super.c3
-rw-r--r--include/linux/fs.h5
-rw-r--r--include/linux/fsnotify_backend.h4
10 files changed, 57 insertions, 54 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 198243717da5..33b813e04f79 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1769,7 +1769,7 @@ void iterate_bdevs(void (*func)(struct block_device *, void *), void *arg)
1769{ 1769{
1770 struct inode *inode, *old_inode = NULL; 1770 struct inode *inode, *old_inode = NULL;
1771 1771
1772 spin_lock(&inode_sb_list_lock); 1772 spin_lock(&blockdev_superblock->s_inode_list_lock);
1773 list_for_each_entry(inode, &blockdev_superblock->s_inodes, i_sb_list) { 1773 list_for_each_entry(inode, &blockdev_superblock->s_inodes, i_sb_list) {
1774 struct address_space *mapping = inode->i_mapping; 1774 struct address_space *mapping = inode->i_mapping;
1775 1775
@@ -1781,13 +1781,13 @@ void iterate_bdevs(void (*func)(struct block_device *, void *), void *arg)
1781 } 1781 }
1782 __iget(inode); 1782 __iget(inode);
1783 spin_unlock(&inode->i_lock); 1783 spin_unlock(&inode->i_lock);
1784 spin_unlock(&inode_sb_list_lock); 1784 spin_unlock(&blockdev_superblock->s_inode_list_lock);
1785 /* 1785 /*
1786 * We hold a reference to 'inode' so it couldn't have been 1786 * We hold a reference to 'inode' so it couldn't have been
1787 * removed from s_inodes list while we dropped the 1787 * removed from s_inodes list while we dropped the
1788 * inode_sb_list_lock. We cannot iput the inode now as we can 1788 * s_inode_list_lock We cannot iput the inode now as we can
1789 * be holding the last reference and we cannot iput it under 1789 * be holding the last reference and we cannot iput it under
1790 * inode_sb_list_lock. So we keep the reference and iput it 1790 * s_inode_list_lock. So we keep the reference and iput it
1791 * later. 1791 * later.
1792 */ 1792 */
1793 iput(old_inode); 1793 iput(old_inode);
@@ -1795,8 +1795,8 @@ void iterate_bdevs(void (*func)(struct block_device *, void *), void *arg)
1795 1795
1796 func(I_BDEV(inode), arg); 1796 func(I_BDEV(inode), arg);
1797 1797
1798 spin_lock(&inode_sb_list_lock); 1798 spin_lock(&blockdev_superblock->s_inode_list_lock);
1799 } 1799 }
1800 spin_unlock(&inode_sb_list_lock); 1800 spin_unlock(&blockdev_superblock->s_inode_list_lock);
1801 iput(old_inode); 1801 iput(old_inode);
1802} 1802}
diff --git a/fs/drop_caches.c b/fs/drop_caches.c
index 5718cb9f7273..d72d52b90433 100644
--- a/fs/drop_caches.c
+++ b/fs/drop_caches.c
@@ -17,7 +17,7 @@ static void drop_pagecache_sb(struct super_block *sb, void *unused)
17{ 17{
18 struct inode *inode, *toput_inode = NULL; 18 struct inode *inode, *toput_inode = NULL;
19 19
20 spin_lock(&inode_sb_list_lock); 20 spin_lock(&sb->s_inode_list_lock);
21 list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { 21 list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
22 spin_lock(&inode->i_lock); 22 spin_lock(&inode->i_lock);
23 if ((inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW)) || 23 if ((inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW)) ||
@@ -27,13 +27,15 @@ static void drop_pagecache_sb(struct super_block *sb, void *unused)
27 } 27 }
28 __iget(inode); 28 __iget(inode);
29 spin_unlock(&inode->i_lock); 29 spin_unlock(&inode->i_lock);
30 spin_unlock(&inode_sb_list_lock); 30 spin_unlock(&sb->s_inode_list_lock);
31
31 invalidate_mapping_pages(inode->i_mapping, 0, -1); 32 invalidate_mapping_pages(inode->i_mapping, 0, -1);
32 iput(toput_inode); 33 iput(toput_inode);
33 toput_inode = inode; 34 toput_inode = inode;
34 spin_lock(&inode_sb_list_lock); 35
36 spin_lock(&sb->s_inode_list_lock);
35 } 37 }
36 spin_unlock(&inode_sb_list_lock); 38 spin_unlock(&sb->s_inode_list_lock);
37 iput(toput_inode); 39 iput(toput_inode);
38} 40}
39 41
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index d98e37bbf417..f45bf876579f 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -2124,7 +2124,7 @@ static void wait_sb_inodes(struct super_block *sb)
2124 */ 2124 */
2125 WARN_ON(!rwsem_is_locked(&sb->s_umount)); 2125 WARN_ON(!rwsem_is_locked(&sb->s_umount));
2126 2126
2127 spin_lock(&inode_sb_list_lock); 2127 spin_lock(&sb->s_inode_list_lock);
2128 2128
2129 /* 2129 /*
2130 * Data integrity sync. Must wait for all pages under writeback, 2130 * Data integrity sync. Must wait for all pages under writeback,
@@ -2144,14 +2144,14 @@ static void wait_sb_inodes(struct super_block *sb)
2144 } 2144 }
2145 __iget(inode); 2145 __iget(inode);
2146 spin_unlock(&inode->i_lock); 2146 spin_unlock(&inode->i_lock);
2147 spin_unlock(&inode_sb_list_lock); 2147 spin_unlock(&sb->s_inode_list_lock);
2148 2148
2149 /* 2149 /*
2150 * We hold a reference to 'inode' so it couldn't have been 2150 * We hold a reference to 'inode' so it couldn't have been
2151 * removed from s_inodes list while we dropped the 2151 * removed from s_inodes list while we dropped the
2152 * inode_sb_list_lock. We cannot iput the inode now as we can 2152 * s_inode_list_lock. We cannot iput the inode now as we can
2153 * be holding the last reference and we cannot iput it under 2153 * be holding the last reference and we cannot iput it under
2154 * inode_sb_list_lock. So we keep the reference and iput it 2154 * s_inode_list_lock. So we keep the reference and iput it
2155 * later. 2155 * later.
2156 */ 2156 */
2157 iput(old_inode); 2157 iput(old_inode);
@@ -2161,9 +2161,9 @@ static void wait_sb_inodes(struct super_block *sb)
2161 2161
2162 cond_resched(); 2162 cond_resched();
2163 2163
2164 spin_lock(&inode_sb_list_lock); 2164 spin_lock(&sb->s_inode_list_lock);
2165 } 2165 }
2166 spin_unlock(&inode_sb_list_lock); 2166 spin_unlock(&sb->s_inode_list_lock);
2167 iput(old_inode); 2167 iput(old_inode);
2168} 2168}
2169 2169
diff --git a/fs/inode.c b/fs/inode.c
index d30640f7a193..a2de294f6b77 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -28,8 +28,8 @@
28 * inode->i_state, inode->i_hash, __iget() 28 * inode->i_state, inode->i_hash, __iget()
29 * Inode LRU list locks protect: 29 * Inode LRU list locks protect:
30 * inode->i_sb->s_inode_lru, inode->i_lru 30 * inode->i_sb->s_inode_lru, inode->i_lru
31 * inode_sb_list_lock protects: 31 * inode->i_sb->s_inode_list_lock protects:
32 * sb->s_inodes, inode->i_sb_list 32 * inode->i_sb->s_inodes, inode->i_sb_list
33 * bdi->wb.list_lock protects: 33 * bdi->wb.list_lock protects:
34 * bdi->wb.b_{dirty,io,more_io,dirty_time}, inode->i_wb_list 34 * bdi->wb.b_{dirty,io,more_io,dirty_time}, inode->i_wb_list
35 * inode_hash_lock protects: 35 * inode_hash_lock protects:
@@ -37,7 +37,7 @@
37 * 37 *
38 * Lock ordering: 38 * Lock ordering:
39 * 39 *
40 * inode_sb_list_lock 40 * inode->i_sb->s_inode_list_lock
41 * inode->i_lock 41 * inode->i_lock
42 * Inode LRU list locks 42 * Inode LRU list locks
43 * 43 *
@@ -45,7 +45,7 @@
45 * inode->i_lock 45 * inode->i_lock
46 * 46 *
47 * inode_hash_lock 47 * inode_hash_lock
48 * inode_sb_list_lock 48 * inode->i_sb->s_inode_list_lock
49 * inode->i_lock 49 * inode->i_lock
50 * 50 *
51 * iunique_lock 51 * iunique_lock
@@ -57,8 +57,6 @@ static unsigned int i_hash_shift __read_mostly;
57static struct hlist_head *inode_hashtable __read_mostly; 57static struct hlist_head *inode_hashtable __read_mostly;
58static __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_hash_lock); 58static __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_hash_lock);
59 59
60__cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_sb_list_lock);
61
62/* 60/*
63 * Empty aops. Can be used for the cases where the user does not 61 * Empty aops. Can be used for the cases where the user does not
64 * define any of the address_space operations. 62 * define any of the address_space operations.
@@ -426,18 +424,18 @@ static void inode_lru_list_del(struct inode *inode)
426 */ 424 */
427void inode_sb_list_add(struct inode *inode) 425void inode_sb_list_add(struct inode *inode)
428{ 426{
429 spin_lock(&inode_sb_list_lock); 427 spin_lock(&inode->i_sb->s_inode_list_lock);
430 list_add(&inode->i_sb_list, &inode->i_sb->s_inodes); 428 list_add(&inode->i_sb_list, &inode->i_sb->s_inodes);
431 spin_unlock(&inode_sb_list_lock); 429 spin_unlock(&inode->i_sb->s_inode_list_lock);
432} 430}
433EXPORT_SYMBOL_GPL(inode_sb_list_add); 431EXPORT_SYMBOL_GPL(inode_sb_list_add);
434 432
435static inline void inode_sb_list_del(struct inode *inode) 433static inline void inode_sb_list_del(struct inode *inode)
436{ 434{
437 if (!list_empty(&inode->i_sb_list)) { 435 if (!list_empty(&inode->i_sb_list)) {
438 spin_lock(&inode_sb_list_lock); 436 spin_lock(&inode->i_sb->s_inode_list_lock);
439 list_del_init(&inode->i_sb_list); 437 list_del_init(&inode->i_sb_list);
440 spin_unlock(&inode_sb_list_lock); 438 spin_unlock(&inode->i_sb->s_inode_list_lock);
441 } 439 }
442} 440}
443 441
@@ -594,7 +592,7 @@ void evict_inodes(struct super_block *sb)
594 struct inode *inode, *next; 592 struct inode *inode, *next;
595 LIST_HEAD(dispose); 593 LIST_HEAD(dispose);
596 594
597 spin_lock(&inode_sb_list_lock); 595 spin_lock(&sb->s_inode_list_lock);
598 list_for_each_entry_safe(inode, next, &sb->s_inodes, i_sb_list) { 596 list_for_each_entry_safe(inode, next, &sb->s_inodes, i_sb_list) {
599 if (atomic_read(&inode->i_count)) 597 if (atomic_read(&inode->i_count))
600 continue; 598 continue;
@@ -610,7 +608,7 @@ void evict_inodes(struct super_block *sb)
610 spin_unlock(&inode->i_lock); 608 spin_unlock(&inode->i_lock);
611 list_add(&inode->i_lru, &dispose); 609 list_add(&inode->i_lru, &dispose);
612 } 610 }
613 spin_unlock(&inode_sb_list_lock); 611 spin_unlock(&sb->s_inode_list_lock);
614 612
615 dispose_list(&dispose); 613 dispose_list(&dispose);
616} 614}
@@ -631,7 +629,7 @@ int invalidate_inodes(struct super_block *sb, bool kill_dirty)
631 struct inode *inode, *next; 629 struct inode *inode, *next;
632 LIST_HEAD(dispose); 630 LIST_HEAD(dispose);
633 631
634 spin_lock(&inode_sb_list_lock); 632 spin_lock(&sb->s_inode_list_lock);
635 list_for_each_entry_safe(inode, next, &sb->s_inodes, i_sb_list) { 633 list_for_each_entry_safe(inode, next, &sb->s_inodes, i_sb_list) {
636 spin_lock(&inode->i_lock); 634 spin_lock(&inode->i_lock);
637 if (inode->i_state & (I_NEW | I_FREEING | I_WILL_FREE)) { 635 if (inode->i_state & (I_NEW | I_FREEING | I_WILL_FREE)) {
@@ -654,7 +652,7 @@ int invalidate_inodes(struct super_block *sb, bool kill_dirty)
654 spin_unlock(&inode->i_lock); 652 spin_unlock(&inode->i_lock);
655 list_add(&inode->i_lru, &dispose); 653 list_add(&inode->i_lru, &dispose);
656 } 654 }
657 spin_unlock(&inode_sb_list_lock); 655 spin_unlock(&sb->s_inode_list_lock);
658 656
659 dispose_list(&dispose); 657 dispose_list(&dispose);
660 658
@@ -890,7 +888,7 @@ struct inode *new_inode(struct super_block *sb)
890{ 888{
891 struct inode *inode; 889 struct inode *inode;
892 890
893 spin_lock_prefetch(&inode_sb_list_lock); 891 spin_lock_prefetch(&sb->s_inode_list_lock);
894 892
895 inode = new_inode_pseudo(sb); 893 inode = new_inode_pseudo(sb);
896 if (inode) 894 if (inode)
diff --git a/fs/internal.h b/fs/internal.h
index 4d5af583ab03..ee1209c54eb1 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -112,7 +112,6 @@ extern int vfs_open(const struct path *, struct file *, const struct cred *);
112/* 112/*
113 * inode.c 113 * inode.c
114 */ 114 */
115extern spinlock_t inode_sb_list_lock;
116extern long prune_icache_sb(struct super_block *sb, struct shrink_control *sc); 115extern long prune_icache_sb(struct super_block *sb, struct shrink_control *sc);
117extern void inode_add_lru(struct inode *inode); 116extern void inode_add_lru(struct inode *inode);
118 117
diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c
index 3daf513ee99e..a4e1a8f6c329 100644
--- a/fs/notify/inode_mark.c
+++ b/fs/notify/inode_mark.c
@@ -163,17 +163,17 @@ int fsnotify_add_inode_mark(struct fsnotify_mark *mark,
163 163
164/** 164/**
165 * fsnotify_unmount_inodes - an sb is unmounting. handle any watched inodes. 165 * fsnotify_unmount_inodes - an sb is unmounting. handle any watched inodes.
166 * @list: list of inodes being unmounted (sb->s_inodes) 166 * @sb: superblock being unmounted.
167 * 167 *
168 * Called during unmount with no locks held, so needs to be safe against 168 * Called during unmount with no locks held, so needs to be safe against
169 * concurrent modifiers. We temporarily drop inode_sb_list_lock and CAN block. 169 * concurrent modifiers. We temporarily drop sb->s_inode_list_lock and CAN block.
170 */ 170 */
171void fsnotify_unmount_inodes(struct list_head *list) 171void fsnotify_unmount_inodes(struct super_block *sb)
172{ 172{
173 struct inode *inode, *next_i, *need_iput = NULL; 173 struct inode *inode, *next_i, *need_iput = NULL;
174 174
175 spin_lock(&inode_sb_list_lock); 175 spin_lock(&sb->s_inode_list_lock);
176 list_for_each_entry_safe(inode, next_i, list, i_sb_list) { 176 list_for_each_entry_safe(inode, next_i, &sb->s_inodes, i_sb_list) {
177 struct inode *need_iput_tmp; 177 struct inode *need_iput_tmp;
178 178
179 /* 179 /*
@@ -209,7 +209,7 @@ void fsnotify_unmount_inodes(struct list_head *list)
209 spin_unlock(&inode->i_lock); 209 spin_unlock(&inode->i_lock);
210 210
211 /* In case the dropping of a reference would nuke next_i. */ 211 /* In case the dropping of a reference would nuke next_i. */
212 while (&next_i->i_sb_list != list) { 212 while (&next_i->i_sb_list != &sb->s_inodes) {
213 spin_lock(&next_i->i_lock); 213 spin_lock(&next_i->i_lock);
214 if (!(next_i->i_state & (I_FREEING | I_WILL_FREE)) && 214 if (!(next_i->i_state & (I_FREEING | I_WILL_FREE)) &&
215 atomic_read(&next_i->i_count)) { 215 atomic_read(&next_i->i_count)) {
@@ -224,12 +224,12 @@ void fsnotify_unmount_inodes(struct list_head *list)
224 } 224 }
225 225
226 /* 226 /*
227 * We can safely drop inode_sb_list_lock here because either 227 * We can safely drop s_inode_list_lock here because either
228 * we actually hold references on both inode and next_i or 228 * we actually hold references on both inode and next_i or
229 * end of list. Also no new inodes will be added since the 229 * end of list. Also no new inodes will be added since the
230 * umount has begun. 230 * umount has begun.
231 */ 231 */
232 spin_unlock(&inode_sb_list_lock); 232 spin_unlock(&sb->s_inode_list_lock);
233 233
234 if (need_iput_tmp) 234 if (need_iput_tmp)
235 iput(need_iput_tmp); 235 iput(need_iput_tmp);
@@ -241,7 +241,7 @@ void fsnotify_unmount_inodes(struct list_head *list)
241 241
242 iput(inode); 242 iput(inode);
243 243
244 spin_lock(&inode_sb_list_lock); 244 spin_lock(&sb->s_inode_list_lock);
245 } 245 }
246 spin_unlock(&inode_sb_list_lock); 246 spin_unlock(&sb->s_inode_list_lock);
247} 247}
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 20d1f74561cf..2863ec6cbadf 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -923,7 +923,7 @@ static void add_dquot_ref(struct super_block *sb, int type)
923 int reserved = 0; 923 int reserved = 0;
924#endif 924#endif
925 925
926 spin_lock(&inode_sb_list_lock); 926 spin_lock(&sb->s_inode_list_lock);
927 list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { 927 list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
928 spin_lock(&inode->i_lock); 928 spin_lock(&inode->i_lock);
929 if ((inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW)) || 929 if ((inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW)) ||
@@ -934,7 +934,7 @@ static void add_dquot_ref(struct super_block *sb, int type)
934 } 934 }
935 __iget(inode); 935 __iget(inode);
936 spin_unlock(&inode->i_lock); 936 spin_unlock(&inode->i_lock);
937 spin_unlock(&inode_sb_list_lock); 937 spin_unlock(&sb->s_inode_list_lock);
938 938
939#ifdef CONFIG_QUOTA_DEBUG 939#ifdef CONFIG_QUOTA_DEBUG
940 if (unlikely(inode_get_rsv_space(inode) > 0)) 940 if (unlikely(inode_get_rsv_space(inode) > 0))
@@ -946,15 +946,15 @@ static void add_dquot_ref(struct super_block *sb, int type)
946 /* 946 /*
947 * We hold a reference to 'inode' so it couldn't have been 947 * We hold a reference to 'inode' so it couldn't have been
948 * removed from s_inodes list while we dropped the 948 * removed from s_inodes list while we dropped the
949 * inode_sb_list_lock We cannot iput the inode now as we can be 949 * s_inode_list_lock. We cannot iput the inode now as we can be
950 * holding the last reference and we cannot iput it under 950 * holding the last reference and we cannot iput it under
951 * inode_sb_list_lock. So we keep the reference and iput it 951 * s_inode_list_lock. So we keep the reference and iput it
952 * later. 952 * later.
953 */ 953 */
954 old_inode = inode; 954 old_inode = inode;
955 spin_lock(&inode_sb_list_lock); 955 spin_lock(&sb->s_inode_list_lock);
956 } 956 }
957 spin_unlock(&inode_sb_list_lock); 957 spin_unlock(&sb->s_inode_list_lock);
958 iput(old_inode); 958 iput(old_inode);
959 959
960#ifdef CONFIG_QUOTA_DEBUG 960#ifdef CONFIG_QUOTA_DEBUG
@@ -1023,7 +1023,7 @@ static void remove_dquot_ref(struct super_block *sb, int type,
1023 struct inode *inode; 1023 struct inode *inode;
1024 int reserved = 0; 1024 int reserved = 0;
1025 1025
1026 spin_lock(&inode_sb_list_lock); 1026 spin_lock(&sb->s_inode_list_lock);
1027 list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { 1027 list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
1028 /* 1028 /*
1029 * We have to scan also I_NEW inodes because they can already 1029 * We have to scan also I_NEW inodes because they can already
@@ -1039,7 +1039,7 @@ static void remove_dquot_ref(struct super_block *sb, int type,
1039 } 1039 }
1040 spin_unlock(&dq_data_lock); 1040 spin_unlock(&dq_data_lock);
1041 } 1041 }
1042 spin_unlock(&inode_sb_list_lock); 1042 spin_unlock(&sb->s_inode_list_lock);
1043#ifdef CONFIG_QUOTA_DEBUG 1043#ifdef CONFIG_QUOTA_DEBUG
1044 if (reserved) { 1044 if (reserved) {
1045 printk(KERN_WARNING "VFS (%s): Writes happened after quota" 1045 printk(KERN_WARNING "VFS (%s): Writes happened after quota"
diff --git a/fs/super.c b/fs/super.c
index b61372354f2b..c808183554a2 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -191,6 +191,7 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags)
191 INIT_HLIST_NODE(&s->s_instances); 191 INIT_HLIST_NODE(&s->s_instances);
192 INIT_HLIST_BL_HEAD(&s->s_anon); 192 INIT_HLIST_BL_HEAD(&s->s_anon);
193 INIT_LIST_HEAD(&s->s_inodes); 193 INIT_LIST_HEAD(&s->s_inodes);
194 spin_lock_init(&s->s_inode_list_lock);
194 195
195 if (list_lru_init_memcg(&s->s_dentry_lru)) 196 if (list_lru_init_memcg(&s->s_dentry_lru))
196 goto fail; 197 goto fail;
@@ -399,7 +400,7 @@ void generic_shutdown_super(struct super_block *sb)
399 sync_filesystem(sb); 400 sync_filesystem(sb);
400 sb->s_flags &= ~MS_ACTIVE; 401 sb->s_flags &= ~MS_ACTIVE;
401 402
402 fsnotify_unmount_inodes(&sb->s_inodes); 403 fsnotify_unmount_inodes(sb);
403 404
404 evict_inodes(sb); 405 evict_inodes(sb);
405 406
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 4a40fa843040..09bbd38485f9 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1309,7 +1309,6 @@ struct super_block {
1309#endif 1309#endif
1310 const struct xattr_handler **s_xattr; 1310 const struct xattr_handler **s_xattr;
1311 1311
1312 struct list_head s_inodes; /* all inodes */
1313 struct hlist_bl_head s_anon; /* anonymous dentries for (nfs) exporting */ 1312 struct hlist_bl_head s_anon; /* anonymous dentries for (nfs) exporting */
1314 struct list_head s_mounts; /* list of mounts; _not_ for fs use */ 1313 struct list_head s_mounts; /* list of mounts; _not_ for fs use */
1315 struct block_device *s_bdev; 1314 struct block_device *s_bdev;
@@ -1380,6 +1379,10 @@ struct super_block {
1380 * Indicates how deep in a filesystem stack this SB is 1379 * Indicates how deep in a filesystem stack this SB is
1381 */ 1380 */
1382 int s_stack_depth; 1381 int s_stack_depth;
1382
1383 /* s_inode_list_lock protects s_inodes */
1384 spinlock_t s_inode_list_lock ____cacheline_aligned_in_smp;
1385 struct list_head s_inodes; /* all inodes */
1383}; 1386};
1384 1387
1385extern struct timespec current_fs_time(struct super_block *sb); 1388extern struct timespec current_fs_time(struct super_block *sb);
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index 65a517dd32f7..0390ee69c439 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -357,7 +357,7 @@ extern void fsnotify_clear_marks_by_group_flags(struct fsnotify_group *group, un
357extern void fsnotify_clear_marks_by_group(struct fsnotify_group *group); 357extern void fsnotify_clear_marks_by_group(struct fsnotify_group *group);
358extern void fsnotify_get_mark(struct fsnotify_mark *mark); 358extern void fsnotify_get_mark(struct fsnotify_mark *mark);
359extern void fsnotify_put_mark(struct fsnotify_mark *mark); 359extern void fsnotify_put_mark(struct fsnotify_mark *mark);
360extern void fsnotify_unmount_inodes(struct list_head *list); 360extern void fsnotify_unmount_inodes(struct super_block *sb);
361 361
362/* put here because inotify does some weird stuff when destroying watches */ 362/* put here because inotify does some weird stuff when destroying watches */
363extern void fsnotify_init_event(struct fsnotify_event *event, 363extern void fsnotify_init_event(struct fsnotify_event *event,
@@ -393,7 +393,7 @@ static inline u32 fsnotify_get_cookie(void)
393 return 0; 393 return 0;
394} 394}
395 395
396static inline void fsnotify_unmount_inodes(struct list_head *list) 396static inline void fsnotify_unmount_inodes(struct super_block *sb)
397{} 397{}
398 398
399#endif /* CONFIG_FSNOTIFY */ 399#endif /* CONFIG_FSNOTIFY */