aboutsummaryrefslogtreecommitdiffstats
path: root/fs/autofs4/inode.c
diff options
context:
space:
mode:
authorNick Piggin <npiggin@suse.de>2010-01-29 18:38:22 -0500
committerThomas Gleixner <tglx@linutronix.de>2010-04-27 11:32:33 -0400
commitb9ab2f38fdee96ff49b8a7bbb65cbfc60921e40c (patch)
treee5e785ba4ae7ec89564914c50638a22d756b6d19 /fs/autofs4/inode.c
parentd4fe09131b66c5a7176a5dbfc9bd1ef6939643e8 (diff)
fs-dcache-scale-d_subdirs
Protect d_subdirs and d_child with d_lock, except in filesystems that aren't using dcache_lock for these anyway (eg. using i_mutex). XXX: probably don't need parent lock in inotify (because child lock should stabilize parent). Also, possibly some filesystems don't need so much locking (eg. of child dentry when modifying d_child, so long as parent is locked)... but be on the safe side. Hmm, maybe we should just say d_child list is protected by d_parent->d_lock. d_parent could remain protected with d_lock. Signed-off-by: Nick Piggin <npiggin@suse.de> Signed-off-by: John Stultz <johnstul@us.ibm.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'fs/autofs4/inode.c')
-rw-r--r--fs/autofs4/inode.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index d0a3de247458..cf6192583b73 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -113,6 +113,7 @@ static void autofs4_force_release(struct autofs_sb_info *sbi)
113 113
114 spin_lock(&dcache_lock); 114 spin_lock(&dcache_lock);
115repeat: 115repeat:
116 spin_lock(&this_parent->d_lock);
116 next = this_parent->d_subdirs.next; 117 next = this_parent->d_subdirs.next;
117resume: 118resume:
118 while (next != &this_parent->d_subdirs) { 119 while (next != &this_parent->d_subdirs) {
@@ -125,11 +126,13 @@ resume:
125 } 126 }
126 127
127 if (!list_empty(&dentry->d_subdirs)) { 128 if (!list_empty(&dentry->d_subdirs)) {
129 spin_unlock(&this_parent->d_lock);
128 this_parent = dentry; 130 this_parent = dentry;
129 goto repeat; 131 goto repeat;
130 } 132 }
131 133
132 next = next->next; 134 next = next->next;
135 spin_unlock(&this_parent->d_lock);
133 spin_unlock(&dcache_lock); 136 spin_unlock(&dcache_lock);
134 137
135 DPRINTK("dentry %p %.*s", 138 DPRINTK("dentry %p %.*s",
@@ -137,20 +140,24 @@ resume:
137 140
138 dput(dentry); 141 dput(dentry);
139 spin_lock(&dcache_lock); 142 spin_lock(&dcache_lock);
143 spin_lock(&this_parent->d_lock);
140 } 144 }
141 145
142 if (this_parent != sbi->sb->s_root) { 146 if (this_parent != sbi->sb->s_root) {
143 struct dentry *dentry = this_parent; 147 struct dentry *dentry = this_parent;
144 148
145 next = this_parent->d_u.d_child.next; 149 next = this_parent->d_u.d_child.next;
150 spin_unlock(&this_parent->d_lock);
146 this_parent = this_parent->d_parent; 151 this_parent = this_parent->d_parent;
147 spin_unlock(&dcache_lock); 152 spin_unlock(&dcache_lock);
148 DPRINTK("parent dentry %p %.*s", 153 DPRINTK("parent dentry %p %.*s",
149 dentry, (int)dentry->d_name.len, dentry->d_name.name); 154 dentry, (int)dentry->d_name.len, dentry->d_name.name);
150 dput(dentry); 155 dput(dentry);
151 spin_lock(&dcache_lock); 156 spin_lock(&dcache_lock);
157 spin_lock(&this_parent->d_lock);
152 goto resume; 158 goto resume;
153 } 159 }
160 spin_unlock(&this_parent->d_lock);
154 spin_unlock(&dcache_lock); 161 spin_unlock(&dcache_lock);
155} 162}
156 163