summaryrefslogtreecommitdiffstats
path: root/fs/dcache.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2016-04-15 15:08:36 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2016-05-02 19:49:28 -0400
commit9902af79c01a8e39bb99b922fa3eef6d4ea23d69 (patch)
treeb04cc75b5e4a028bfdb619e0a0a0f8cd71113ff2 /fs/dcache.c
parentd9171b9345261e0d941d92fdda5672b5db67f968 (diff)
downloadlinux-9902af79c01a8e39bb99b922fa3eef6d4ea23d69.tar.gz
linux-9902af79c01a8e39bb99b922fa3eef6d4ea23d69.tar.bz2
linux-9902af79c01a8e39bb99b922fa3eef6d4ea23d69.zip
parallel lookups: actual switch to rwsem
ta-da! The main issue is the lack of down_write_killable(), so the places like readdir.c switched to plain inode_lock(); once killable variants of rwsem primitives appear, that'll be dealt with. lockdep side also might need more work Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/dcache.c')
-rw-r--r--fs/dcache.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index 59fcffcbf096..e49ba7d1b957 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -2932,7 +2932,8 @@ struct dentry *d_ancestor(struct dentry *p1, struct dentry *p2)
static int __d_unalias(struct inode *inode,
struct dentry *dentry, struct dentry *alias)
{
- struct mutex *m1 = NULL, *m2 = NULL;
+ struct mutex *m1 = NULL;
+ struct rw_semaphore *m2 = NULL;
int ret = -ESTALE;
/* If alias and dentry share a parent, then no extra locks required */
@@ -2943,15 +2944,15 @@ static int __d_unalias(struct inode *inode,
if (!mutex_trylock(&dentry->d_sb->s_vfs_rename_mutex))
goto out_err;
m1 = &dentry->d_sb->s_vfs_rename_mutex;
- if (!inode_trylock(alias->d_parent->d_inode))
+ if (!inode_trylock_shared(alias->d_parent->d_inode))
goto out_err;
- m2 = &alias->d_parent->d_inode->i_mutex;
+ m2 = &alias->d_parent->d_inode->i_rwsem;
out_unalias:
__d_move(alias, dentry, false);
ret = 0;
out_err:
if (m2)
- mutex_unlock(m2);
+ up_read(m2);
if (m1)
mutex_unlock(m1);
return ret;