lift the "already marked killed" case into shrink_dentry_list()
It can happen only when dentry_kill() is called with unlock_on_failure equal to 0 - other callers had dentry pinned until the moment they've got ->d_lock and DCACHE_DENTRY_KILLED is set only after lockref_mark_dead(). IOW, only one of three call sites of dentry_kill() might end up reaching that code. Just move it there. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Родитель
b6dd6f4738
Коммит
64fd72e0a4
15
fs/dcache.c
15
fs/dcache.c
|
@ -455,12 +455,6 @@ dentry_kill(struct dentry *dentry, int unlock_on_failure)
|
|||
struct dentry *parent = NULL;
|
||||
bool can_free = true;
|
||||
|
||||
if (unlikely(dentry->d_flags & DCACHE_DENTRY_KILLED)) {
|
||||
can_free = dentry->d_flags & DCACHE_MAY_FREE;
|
||||
spin_unlock(&dentry->d_lock);
|
||||
goto out;
|
||||
}
|
||||
|
||||
inode = dentry->d_inode;
|
||||
if (inode && !spin_trylock(&inode->i_lock)) {
|
||||
relock:
|
||||
|
@ -815,6 +809,15 @@ static void shrink_dentry_list(struct list_head *list)
|
|||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (unlikely(dentry->d_flags & DCACHE_DENTRY_KILLED)) {
|
||||
bool can_free = dentry->d_flags & DCACHE_MAY_FREE;
|
||||
spin_unlock(&dentry->d_lock);
|
||||
if (can_free)
|
||||
dentry_free(dentry);
|
||||
continue;
|
||||
}
|
||||
|
||||
parent = dentry_kill(dentry, 0);
|
||||
/*
|
||||
* If dentry_kill returns NULL, we have nothing more to do.
|
||||
|
|
Загрузка…
Ссылка в новой задаче