diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2016-06-10 11:32:47 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-06-10 11:32:47 -0400 |
commit | ba65dc5ef16f82fba77869cecf7a7d515f61446b (patch) | |
tree | 58368a848f6b396be2ffcc2a43a4bee44fb354ef /fs/internal.h | |
parent | 1607f09c226d1378439c411baaaa020042750338 (diff) | |
download | lwn-ba65dc5ef16f82fba77869cecf7a7d515f61446b.tar.gz lwn-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/internal.h')
-rw-r--r-- | fs/internal.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/fs/internal.h b/fs/internal.h index b71deeecea17..f57ced528cde 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -130,6 +130,7 @@ extern int invalidate_inodes(struct super_block *, bool); extern struct dentry *__d_alloc(struct super_block *, const struct qstr *); extern int d_set_mounted(struct dentry *dentry); extern long prune_dcache_sb(struct super_block *sb, struct shrink_control *sc); +extern struct dentry *d_alloc_cursor(struct dentry *); /* * read_write.c |