Skip to content

Commit

Permalink
split dentry_kill()
Browse files Browse the repository at this point in the history
... into trylocks and everything else.  The latter (actual killing)
is __dentry_kill().

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
  • Loading branch information
Al Viro committed May 29, 2014
1 parent 64fd72e commit e55fd01
Showing 1 changed file with 36 additions and 26 deletions.
62 changes: 36 additions & 26 deletions fs/dcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -441,36 +441,12 @@ void d_drop(struct dentry *dentry)
}
EXPORT_SYMBOL(d_drop);

/*
* Finish off a dentry we've decided to kill.
* dentry->d_lock must be held, returns with it unlocked.
* If ref is non-zero, then decrement the refcount too.
* Returns dentry requiring refcount drop, or NULL if we're done.
*/
static struct dentry *
dentry_kill(struct dentry *dentry, int unlock_on_failure)
__releases(dentry->d_lock)
static void __dentry_kill(struct dentry *dentry)
{
struct inode *inode;
struct dentry *parent = NULL;
bool can_free = true;

inode = dentry->d_inode;
if (inode && !spin_trylock(&inode->i_lock)) {
relock:
if (unlock_on_failure) {
spin_unlock(&dentry->d_lock);
cpu_relax();
}
return dentry; /* try again with same dentry */
}
if (!IS_ROOT(dentry))
parent = dentry->d_parent;
if (parent && !spin_trylock(&parent->d_lock)) {
if (inode)
spin_unlock(&inode->i_lock);
goto relock;
}

/*
* The dentry is now unrecoverably dead to the world.
Expand Down Expand Up @@ -514,10 +490,44 @@ dentry_kill(struct dentry *dentry, int unlock_on_failure)
can_free = false;
}
spin_unlock(&dentry->d_lock);
out:
if (likely(can_free))
dentry_free(dentry);
}

/*
* Finish off a dentry we've decided to kill.
* dentry->d_lock must be held, returns with it unlocked.
* If ref is non-zero, then decrement the refcount too.
* Returns dentry requiring refcount drop, or NULL if we're done.
*/
static struct dentry *
dentry_kill(struct dentry *dentry, int unlock_on_failure)
__releases(dentry->d_lock)
{
struct inode *inode = dentry->d_inode;
struct dentry *parent = NULL;

if (inode && unlikely(!spin_trylock(&inode->i_lock)))
goto failed;

if (!IS_ROOT(dentry)) {
parent = dentry->d_parent;
if (unlikely(!spin_trylock(&parent->d_lock))) {
if (inode)
spin_unlock(&inode->i_lock);
goto failed;
}
}

__dentry_kill(dentry);
return parent;

failed:
if (unlock_on_failure) {
spin_unlock(&dentry->d_lock);
cpu_relax();
}
return dentry; /* try again with same dentry */
}

/*
Expand Down

0 comments on commit e55fd01

Please sign in to comment.