dcache: don't need rcu in shrink_dentry_list()
Since now the shrink list is private and nobody can free the dentry while it is on the shrink list, we can remove RCU protection from this. Signed-off-by: Miklos Szeredi <mszeredi@suse.cz> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
9c8c10e262
commit
60942f2f23
1 changed files with 4 additions and 23 deletions
27
fs/dcache.c
27
fs/dcache.c
|
@ -796,23 +796,9 @@ static void shrink_dentry_list(struct list_head *list)
|
||||||
{
|
{
|
||||||
struct dentry *dentry, *parent;
|
struct dentry *dentry, *parent;
|
||||||
|
|
||||||
rcu_read_lock();
|
while (!list_empty(list)) {
|
||||||
for (;;) {
|
dentry = list_entry(list->prev, struct dentry, d_lru);
|
||||||
dentry = list_entry_rcu(list->prev, struct dentry, d_lru);
|
|
||||||
if (&dentry->d_lru == list)
|
|
||||||
break; /* empty */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get the dentry lock, and re-verify that the dentry is
|
|
||||||
* this on the shrinking list. If it is, we know that
|
|
||||||
* DCACHE_SHRINK_LIST and DCACHE_LRU_LIST are set.
|
|
||||||
*/
|
|
||||||
spin_lock(&dentry->d_lock);
|
spin_lock(&dentry->d_lock);
|
||||||
if (dentry != list_entry(list->prev, struct dentry, d_lru)) {
|
|
||||||
spin_unlock(&dentry->d_lock);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The dispose list is isolated and dentries are not accounted
|
* The dispose list is isolated and dentries are not accounted
|
||||||
* to the LRU here, so we can simply remove it from the list
|
* to the LRU here, so we can simply remove it from the list
|
||||||
|
@ -828,23 +814,20 @@ static void shrink_dentry_list(struct list_head *list)
|
||||||
spin_unlock(&dentry->d_lock);
|
spin_unlock(&dentry->d_lock);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
|
||||||
|
|
||||||
parent = dentry_kill(dentry, 0);
|
parent = dentry_kill(dentry, 0);
|
||||||
/*
|
/*
|
||||||
* If dentry_kill returns NULL, we have nothing more to do.
|
* If dentry_kill returns NULL, we have nothing more to do.
|
||||||
*/
|
*/
|
||||||
if (!parent) {
|
if (!parent)
|
||||||
rcu_read_lock();
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
if (unlikely(parent == dentry)) {
|
if (unlikely(parent == dentry)) {
|
||||||
/*
|
/*
|
||||||
* trylocks have failed and d_lock has been held the
|
* trylocks have failed and d_lock has been held the
|
||||||
* whole time, so it could not have been added to any
|
* whole time, so it could not have been added to any
|
||||||
* other lists. Just add it back to the shrink list.
|
* other lists. Just add it back to the shrink list.
|
||||||
*/
|
*/
|
||||||
rcu_read_lock();
|
|
||||||
d_shrink_add(dentry, list);
|
d_shrink_add(dentry, list);
|
||||||
spin_unlock(&dentry->d_lock);
|
spin_unlock(&dentry->d_lock);
|
||||||
continue;
|
continue;
|
||||||
|
@ -858,9 +841,7 @@ static void shrink_dentry_list(struct list_head *list)
|
||||||
dentry = parent;
|
dentry = parent;
|
||||||
while (dentry && !lockref_put_or_lock(&dentry->d_lockref))
|
while (dentry && !lockref_put_or_lock(&dentry->d_lockref))
|
||||||
dentry = dentry_kill(dentry, 1);
|
dentry = dentry_kill(dentry, 1);
|
||||||
rcu_read_lock();
|
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum lru_status
|
static enum lru_status
|
||||||
|
|
Loading…
Add table
Reference in a new issue