summaryrefslogtreecommitdiff
path: root/fs/drop_caches.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/drop_caches.c')
-rw-r--r--fs/drop_caches.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/fs/drop_caches.c b/fs/drop_caches.c
index d45ef541d848..72c59fb22c81 100644
--- a/fs/drop_caches.c
+++ b/fs/drop_caches.c
@@ -18,10 +18,15 @@ int sysctl_drop_caches;
static void drop_pagecache_sb(struct super_block *sb, void *unused)
{
- struct inode *inode, *toput_inode = NULL;
+ struct genradix_iter iter;
+ void **i;
+
+ rcu_read_lock();
+ genradix_for_each(&sb->s_inodes.items, iter, i) {
+ struct inode *inode = *((struct inode **) i);
+ if (!inode)
+ continue;
- spin_lock(&sb->s_inode_list_lock);
- list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
spin_lock(&inode->i_lock);
/*
* We must skip inodes in unusual state. We may also skip
@@ -35,17 +40,15 @@ static void drop_pagecache_sb(struct super_block *sb, void *unused)
}
__iget(inode);
spin_unlock(&inode->i_lock);
- spin_unlock(&sb->s_inode_list_lock);
+ rcu_read_unlock();
invalidate_mapping_pages(inode->i_mapping, 0, -1);
- iput(toput_inode);
- toput_inode = inode;
+ iput(inode);
cond_resched();
- spin_lock(&sb->s_inode_list_lock);
+ rcu_read_lock();
}
- spin_unlock(&sb->s_inode_list_lock);
- iput(toput_inode);
+ rcu_read_unlock();
}
int drop_caches_sysctl_handler(const struct ctl_table *table, int write,