aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dcache.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-09-14 20:37:36 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-09-14 20:37:36 -0400
commit83373f702829dd9f6dcc56d275978d986fafee48 (patch)
tree6e816715ce2e9ea73da8b8462953262f47460897 /fs/dcache.c
parent9226b5b440f2b4fbb3b797f3cb74a9a627220660 (diff)
parent4023bfc9f351a7994fb6a7d515476c320f94a574 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs fixes from Al Viro: "double iput() on failure exit in lustre, racy removal of spliced dentries from ->s_anon in __d_materialise_dentry() plus a bunch of assorted RCU pathwalk fixes" The RCU pathwalk fixes end up fixing a couple of cases where we incorrectly dropped out of RCU walking, due to incorrect initialization and testing of the sequence locks in some corner cases. Since dropping out of RCU walk mode forces the slow locked accesses, those corner cases slowed down quite dramatically. * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: be careful with nd->inode in path_init() and follow_dotdot_rcu() don't bugger nd->seq on set_root_rcu() from follow_dotdot_rcu() fix bogus read_seqretry() checks introduced in b37199e move the call of __d_drop(anon) into __d_materialise_unique(dentry, anon) [fix] lustre: d_make_root() does iput() on dentry allocation failure
Diffstat (limited to 'fs/dcache.c')
-rw-r--r--fs/dcache.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index 4023e77b800e..7a5b51440afa 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -2655,6 +2655,12 @@ static void __d_materialise_dentry(struct dentry *dentry, struct dentry *anon)
2655 dentry->d_parent = dentry; 2655 dentry->d_parent = dentry;
2656 list_del_init(&dentry->d_u.d_child); 2656 list_del_init(&dentry->d_u.d_child);
2657 anon->d_parent = dparent; 2657 anon->d_parent = dparent;
2658 if (likely(!d_unhashed(anon))) {
2659 hlist_bl_lock(&anon->d_sb->s_anon);
2660 __hlist_bl_del(&anon->d_hash);
2661 anon->d_hash.pprev = NULL;
2662 hlist_bl_unlock(&anon->d_sb->s_anon);
2663 }
2658 list_move(&anon->d_u.d_child, &dparent->d_subdirs); 2664 list_move(&anon->d_u.d_child, &dparent->d_subdirs);
2659 2665
2660 write_seqcount_end(&dentry->d_seq); 2666 write_seqcount_end(&dentry->d_seq);
@@ -2713,7 +2719,6 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry)
2713 write_seqlock(&rename_lock); 2719 write_seqlock(&rename_lock);
2714 __d_materialise_dentry(dentry, new); 2720 __d_materialise_dentry(dentry, new);
2715 write_sequnlock(&rename_lock); 2721 write_sequnlock(&rename_lock);
2716 __d_drop(new);
2717 _d_rehash(new); 2722 _d_rehash(new);
2718 spin_unlock(&new->d_lock); 2723 spin_unlock(&new->d_lock);
2719 spin_unlock(&inode->i_lock); 2724 spin_unlock(&inode->i_lock);
@@ -2777,7 +2782,6 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
2777 * could splice into our tree? */ 2782 * could splice into our tree? */
2778 __d_materialise_dentry(dentry, alias); 2783 __d_materialise_dentry(dentry, alias);
2779 write_sequnlock(&rename_lock); 2784 write_sequnlock(&rename_lock);
2780 __d_drop(alias);
2781 goto found; 2785 goto found;
2782 } else { 2786 } else {
2783 /* Nope, but we must(!) avoid directory 2787 /* Nope, but we must(!) avoid directory