diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2018-02-24 03:02:31 +0100 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2018-03-12 16:59:14 +0100 |
commit | c19457f0aed7fae73bb40e68ffcc72f36e3966a5 (patch) | |
tree | d2fc8be41a6fb201d6038c6ce6f3180ad3d81ad0 /fs/dcache.c | |
parent | fs/dcache: Move dentry_kill() below lock_parent() (diff) | |
download | linux-c19457f0aed7fae73bb40e68ffcc72f36e3966a5.tar.xz linux-c19457f0aed7fae73bb40e68ffcc72f36e3966a5.zip |
d_delete(): get rid of trylock loop
just grab ->i_lock first; we have a positive dentry, nothing's going
to happen to inode
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 28 |
1 files changed, 9 insertions, 19 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 01c0432ec83a..1684b6b262de 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -2377,32 +2377,22 @@ EXPORT_SYMBOL(d_hash_and_lookup); void d_delete(struct dentry * dentry) { - struct inode *inode; - int isdir = 0; + struct inode *inode = dentry->d_inode; + int isdir = d_is_dir(dentry); + + spin_lock(&inode->i_lock); + spin_lock(&dentry->d_lock); /* * Are we the only user? */ -again: - spin_lock(&dentry->d_lock); - inode = dentry->d_inode; - isdir = S_ISDIR(inode->i_mode); if (dentry->d_lockref.count == 1) { - if (!spin_trylock(&inode->i_lock)) { - spin_unlock(&dentry->d_lock); - cpu_relax(); - goto again; - } dentry->d_flags &= ~DCACHE_CANT_MOUNT; dentry_unlink_inode(dentry); - fsnotify_nameremove(dentry, isdir); - return; - } - - if (!d_unhashed(dentry)) + } else { __d_drop(dentry); - - spin_unlock(&dentry->d_lock); - + spin_unlock(&dentry->d_lock); + spin_unlock(&inode->i_lock); + } fsnotify_nameremove(dentry, isdir); } EXPORT_SYMBOL(d_delete); |