Skip to content

Commit e55fd01

Browse files
author
Al Viro
committed
split dentry_kill()
... into trylocks and everything else. The latter (actual killing) is __dentry_kill(). Signed-off-by: Al Viro <[email protected]>
1 parent 64fd72e commit e55fd01

File tree

1 file changed

+36
-26
lines changed

1 file changed

+36
-26
lines changed

fs/dcache.c

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -441,36 +441,12 @@ void d_drop(struct dentry *dentry)
441441
}
442442
EXPORT_SYMBOL(d_drop);
443443

444-
/*
445-
* Finish off a dentry we've decided to kill.
446-
* dentry->d_lock must be held, returns with it unlocked.
447-
* If ref is non-zero, then decrement the refcount too.
448-
* Returns dentry requiring refcount drop, or NULL if we're done.
449-
*/
450-
static struct dentry *
451-
dentry_kill(struct dentry *dentry, int unlock_on_failure)
452-
__releases(dentry->d_lock)
444+
static void __dentry_kill(struct dentry *dentry)
453445
{
454-
struct inode *inode;
455446
struct dentry *parent = NULL;
456447
bool can_free = true;
457-
458-
inode = dentry->d_inode;
459-
if (inode && !spin_trylock(&inode->i_lock)) {
460-
relock:
461-
if (unlock_on_failure) {
462-
spin_unlock(&dentry->d_lock);
463-
cpu_relax();
464-
}
465-
return dentry; /* try again with same dentry */
466-
}
467448
if (!IS_ROOT(dentry))
468449
parent = dentry->d_parent;
469-
if (parent && !spin_trylock(&parent->d_lock)) {
470-
if (inode)
471-
spin_unlock(&inode->i_lock);
472-
goto relock;
473-
}
474450

475451
/*
476452
* The dentry is now unrecoverably dead to the world.
@@ -514,10 +490,44 @@ dentry_kill(struct dentry *dentry, int unlock_on_failure)
514490
can_free = false;
515491
}
516492
spin_unlock(&dentry->d_lock);
517-
out:
518493
if (likely(can_free))
519494
dentry_free(dentry);
495+
}
496+
497+
/*
498+
* Finish off a dentry we've decided to kill.
499+
* dentry->d_lock must be held, returns with it unlocked.
500+
* If ref is non-zero, then decrement the refcount too.
501+
* Returns dentry requiring refcount drop, or NULL if we're done.
502+
*/
503+
static struct dentry *
504+
dentry_kill(struct dentry *dentry, int unlock_on_failure)
505+
__releases(dentry->d_lock)
506+
{
507+
struct inode *inode = dentry->d_inode;
508+
struct dentry *parent = NULL;
509+
510+
if (inode && unlikely(!spin_trylock(&inode->i_lock)))
511+
goto failed;
512+
513+
if (!IS_ROOT(dentry)) {
514+
parent = dentry->d_parent;
515+
if (unlikely(!spin_trylock(&parent->d_lock))) {
516+
if (inode)
517+
spin_unlock(&inode->i_lock);
518+
goto failed;
519+
}
520+
}
521+
522+
__dentry_kill(dentry);
520523
return parent;
524+
525+
failed:
526+
if (unlock_on_failure) {
527+
spin_unlock(&dentry->d_lock);
528+
cpu_relax();
529+
}
530+
return dentry; /* try again with same dentry */
521531
}
522532

523533
/*

0 commit comments

Comments
 (0)