mirror of https://gitee.com/openkylin/linux.git
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:
parent
b6dd6f4738
commit
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;
|
struct dentry *parent = NULL;
|
||||||
bool can_free = true;
|
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;
|
inode = dentry->d_inode;
|
||||||
if (inode && !spin_trylock(&inode->i_lock)) {
|
if (inode && !spin_trylock(&inode->i_lock)) {
|
||||||
relock:
|
relock:
|
||||||
|
@ -815,6 +809,15 @@ static void shrink_dentry_list(struct list_head *list)
|
||||||
continue;
|
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);
|
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.
|
||||||
|
|
Loading…
Reference in New Issue