summaryrefslogtreecommitdiffstats
path: root/fs/libfs.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2016-06-10 11:32:47 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2016-06-10 11:32:47 -0400
commitba65dc5ef16f82fba77869cecf7a7d515f61446b (patch)
tree58368a848f6b396be2ffcc2a43a4bee44fb354ef /fs/libfs.c
parent1607f09c226d1378439c411baaaa020042750338 (diff)
downloadlinux-stable-ba65dc5ef16f82fba77869cecf7a7d515f61446b.tar.gz
linux-stable-ba65dc5ef16f82fba77869cecf7a7d515f61446b.tar.bz2
linux-stable-ba65dc5ef16f82fba77869cecf7a7d515f61446b.zip
much milder d_walk() race
d_walk() relies upon the tree not getting rearranged under it without rename_lock being touched. And we do grab rename_lock around the places that change the tree topology. Unfortunately, branch reordering is just as bad from d_walk() POV and we have two places that do it without touching rename_lock - one in handling of cursors (for ramfs-style directories) and another in autofs. autofs one is a separate story; this commit deals with the cursors. * mark cursor dentries explicitly at allocation time * make __dentry_kill() leave ->d_child.next pointing to the next non-cursor sibling, making sure that it won't be moved around unnoticed before the parent is relocked on ascend-to-parent path in d_walk(). * make d_walk() skip cursors explicitly; strictly speaking it's not necessary (all callbacks we pass to d_walk() are no-ops on cursors), but it makes analysis easier. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/libfs.c')
-rw-r--r--fs/libfs.c4
1 files changed, 1 insertions, 3 deletions
diff --git a/fs/libfs.c b/fs/libfs.c
index 3db2721144c2..cedeacbae303 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -71,9 +71,7 @@ EXPORT_SYMBOL(simple_lookup);
int dcache_dir_open(struct inode *inode, struct file *file)
{
- static struct qstr cursor_name = QSTR_INIT(".", 1);
-
- file->private_data = d_alloc(file->f_path.dentry, &cursor_name);
+ file->private_data = d_alloc_cursor(file->f_path.dentry);
return file->private_data ? 0 : -ENOMEM;
}