Commit 8d27a647 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] Fix dcache deadlock introduced by previous fix

So the fix for our problems is:

 a) in fs/namei.c replace d_unhash() with a safe version.
 b) in fs/nfs/dir.c replace d_drop(dentry) in beginning of nfs_unlink()
 with list_del_init(&dentry->d_hash);
parent 4872eacc
...@@ -1496,14 +1496,18 @@ asmlinkage long sys_mkdir(const char * pathname, int mode) ...@@ -1496,14 +1496,18 @@ asmlinkage long sys_mkdir(const char * pathname, int mode)
static void d_unhash(struct dentry *dentry) static void d_unhash(struct dentry *dentry)
{ {
dget(dentry); dget(dentry);
spin_lock(&dcache_lock);
switch (atomic_read(&dentry->d_count)) { switch (atomic_read(&dentry->d_count)) {
default: default:
spin_unlock(&dcache_lock);
shrink_dcache_parent(dentry); shrink_dcache_parent(dentry);
spin_lock(&dcache_lock);
if (atomic_read(&dentry->d_count) != 2) if (atomic_read(&dentry->d_count) != 2)
break; break;
case 2: case 2:
d_drop(dentry); list_del_init(&dentry->d_hash);
} }
spin_unlock(&dcache_lock);
} }
int vfs_rmdir(struct inode *dir, struct dentry *dentry) int vfs_rmdir(struct inode *dir, struct dentry *dentry)
......
...@@ -878,7 +878,7 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry) ...@@ -878,7 +878,7 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry)
return error; return error;
} }
if (!d_unhashed(dentry)) { if (!d_unhashed(dentry)) {
d_drop(dentry); list_del_init(&dentry->d_hash);
need_rehash = 1; need_rehash = 1;
} }
spin_unlock(&dcache_lock); spin_unlock(&dcache_lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment