aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Piggin <npiggin@kernel.dk>2011-01-07 01:49:34 -0500
committerNick Piggin <npiggin@kernel.dk>2011-01-07 01:50:21 -0500
commit2fd6b7f50797f2e993eea59e0a0b8c6399c811dc (patch)
treece33b94b34844c09103836cf4cfa4364b742f217
parentda5029563a0a026c64821b09e8e7b4fd81d3fe1b (diff)
fs: dcache scale 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). Note: if we change the locking rule in future so that ->d_child protection is provided only with ->d_parent->d_lock, it may allow us to reduce some locking. But it would be an exception to an otherwise regular locking scheme, so we'd have to see some good results. Probably not worthwhile. Signed-off-by: Nick Piggin <npiggin@kernel.dk>
-rw-r--r--drivers/staging/smbfs/cache.c4
-rw-r--r--drivers/usb/core/inode.c8
-rw-r--r--fs/autofs4/autofs_i.h11
-rw-r--r--fs/autofs4/expire.c127
-rw-r--r--fs/autofs4/root.c18
-rw-r--r--fs/ceph/dir.c6
-rw-r--r--fs/ceph/inode.c8
-rw-r--r--fs/coda/cache.c2
-rw-r--r--fs/dcache.c248
-rw-r--r--fs/libfs.c24
-rw-r--r--fs/ncpfs/dir.c3
-rw-r--r--fs/ncpfs/ncplib_kernel.h4
-rw-r--r--fs/notify/fsnotify.c4
-rw-r--r--include/linux/dcache.h1
-rw-r--r--kernel/cgroup.c19
-rw-r--r--security/selinux/selinuxfs.c12
16 files changed, 339 insertions, 160 deletions
diff --git a/drivers/staging/smbfs/cache.c b/drivers/staging/smbfs/cache.c
index 0beded260b00..920434b6c071 100644
--- a/drivers/staging/smbfs/cache.c
+++ b/drivers/staging/smbfs/cache.c
@@ -63,6 +63,7 @@ smb_invalidate_dircache_entries(struct dentry *parent)
63 struct dentry *dentry; 63 struct dentry *dentry;
64 64
65 spin_lock(&dcache_lock); 65 spin_lock(&dcache_lock);
66 spin_lock(&parent->d_lock);
66 next = parent->d_subdirs.next; 67 next = parent->d_subdirs.next;
67 while (next != &parent->d_subdirs) { 68 while (next != &parent->d_subdirs) {
68 dentry = list_entry(next, struct dentry, d_u.d_child); 69 dentry = list_entry(next, struct dentry, d_u.d_child);
@@ -70,6 +71,7 @@ smb_invalidate_dircache_entries(struct dentry *parent)
70 smb_age_dentry(server, dentry); 71 smb_age_dentry(server, dentry);
71 next = next->next; 72 next = next->next;
72 } 73 }
74 spin_unlock(&parent->d_lock);
73 spin_unlock(&dcache_lock); 75 spin_unlock(&dcache_lock);
74} 76}
75 77
@@ -97,6 +99,7 @@ smb_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos)
97 99
98 /* If a pointer is invalid, we search the dentry. */ 100 /* If a pointer is invalid, we search the dentry. */
99 spin_lock(&dcache_lock); 101 spin_lock(&dcache_lock);
102 spin_lock(&parent->d_lock);
100 next = parent->d_subdirs.next; 103 next = parent->d_subdirs.next;
101 while (next != &parent->d_subdirs) { 104 while (next != &parent->d_subdirs) {
102 dent = list_entry(next, struct dentry, d_u.d_child); 105 dent = list_entry(next, struct dentry, d_u.d_child);
@@ -111,6 +114,7 @@ smb_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos)
111 } 114 }
112 dent = NULL; 115 dent = NULL;
113out_unlock: 116out_unlock:
117 spin_unlock(&parent->d_lock);
114 spin_unlock(&dcache_lock); 118 spin_unlock(&dcache_lock);
115 return dent; 119 return dent;
116} 120}
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index e3ab4437ea96..89a0e8366585 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -344,18 +344,20 @@ static int usbfs_empty (struct dentry *dentry)
344 struct list_head *list; 344 struct list_head *list;
345 345
346 spin_lock(&dcache_lock); 346 spin_lock(&dcache_lock);
347 347 spin_lock(&dentry->d_lock);
348 list_for_each(list, &dentry->d_subdirs) { 348 list_for_each(list, &dentry->d_subdirs) {
349 struct dentry *de = list_entry(list, struct dentry, d_u.d_child); 349 struct dentry *de = list_entry(list, struct dentry, d_u.d_child);
350 spin_lock(&de->d_lock); 350
351 spin_lock_nested(&de->d_lock, DENTRY_D_LOCK_NESTED);
351 if (usbfs_positive(de)) { 352 if (usbfs_positive(de)) {
352 spin_unlock(&de->d_lock); 353 spin_unlock(&de->d_lock);
354 spin_unlock(&dentry->d_lock);
353 spin_unlock(&dcache_lock); 355 spin_unlock(&dcache_lock);
354 return 0; 356 return 0;
355 } 357 }
356 spin_unlock(&de->d_lock); 358 spin_unlock(&de->d_lock);
357 } 359 }
358 360 spin_unlock(&dentry->d_lock);
359 spin_unlock(&dcache_lock); 361 spin_unlock(&dcache_lock);
360 return 1; 362 return 1;
361} 363}
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
index 3912dcf047e5..9d2ae9b30d9f 100644
--- a/fs/autofs4/autofs_i.h
+++ b/fs/autofs4/autofs_i.h
@@ -254,6 +254,17 @@ static inline int simple_positive(struct dentry *dentry)
254 return dentry->d_inode && !d_unhashed(dentry); 254 return dentry->d_inode && !d_unhashed(dentry);
255} 255}
256 256
257static inline void __autofs4_add_expiring(struct dentry *dentry)
258{
259 struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
260 struct autofs_info *ino = autofs4_dentry_ino(dentry);
261 if (ino) {
262 if (list_empty(&ino->expiring))
263 list_add(&ino->expiring, &sbi->expiring_list);
264 }
265 return;
266}
267
257static inline void autofs4_add_expiring(struct dentry *dentry) 268static inline void autofs4_add_expiring(struct dentry *dentry)
258{ 269{
259 struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); 270 struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c
index ee6402050f13..968c1434af62 100644
--- a/fs/autofs4/expire.c
+++ b/fs/autofs4/expire.c
@@ -91,24 +91,64 @@ done:
91} 91}
92 92
93/* 93/*
94 * Calculate next entry in top down tree traversal. 94 * Calculate and dget next entry in top down tree traversal.
95 * From next_mnt in namespace.c - elegant.
96 */ 95 */
97static struct dentry *next_dentry(struct dentry *p, struct dentry *root) 96static struct dentry *get_next_positive_dentry(struct dentry *prev,
97 struct dentry *root)
98{ 98{
99 struct list_head *next = p->d_subdirs.next; 99 struct list_head *next;
100 struct dentry *p, *ret;
101
102 if (prev == NULL)
103 return dget(prev);
100 104
105 spin_lock(&dcache_lock);
106relock:
107 p = prev;
108 spin_lock(&p->d_lock);
109again:
110 next = p->d_subdirs.next;
101 if (next == &p->d_subdirs) { 111 if (next == &p->d_subdirs) {
102 while (1) { 112 while (1) {
103 if (p == root) 113 struct dentry *parent;
114
115 if (p == root) {
116 spin_unlock(&p->d_lock);
117 spin_unlock(&dcache_lock);
118 dput(prev);
104 return NULL; 119 return NULL;
120 }
121
122 parent = p->d_parent;
123 if (!spin_trylock(&parent->d_lock)) {
124 spin_unlock(&p->d_lock);
125 cpu_relax();
126 goto relock;
127 }
128 spin_unlock(&p->d_lock);
105 next = p->d_u.d_child.next; 129 next = p->d_u.d_child.next;
106 if (next != &p->d_parent->d_subdirs) 130 p = parent;
131 if (next != &parent->d_subdirs)
107 break; 132 break;
108 p = p->d_parent;
109 } 133 }
110 } 134 }
111 return list_entry(next, struct dentry, d_u.d_child); 135 ret = list_entry(next, struct dentry, d_u.d_child);
136
137 spin_lock_nested(&ret->d_lock, DENTRY_D_LOCK_NESTED);
138 /* Negative dentry - try next */
139 if (!simple_positive(ret)) {
140 spin_unlock(&ret->d_lock);
141 p = ret;
142 goto again;
143 }
144 dget_dlock(ret);
145 spin_unlock(&ret->d_lock);
146 spin_unlock(&p->d_lock);
147 spin_unlock(&dcache_lock);
148
149 dput(prev);
150
151 return ret;
112} 152}
113 153
114/* 154/*
@@ -158,22 +198,11 @@ static int autofs4_tree_busy(struct vfsmount *mnt,
158 if (!simple_positive(top)) 198 if (!simple_positive(top))
159 return 1; 199 return 1;
160 200
161 spin_lock(&dcache_lock); 201 p = NULL;
162 for (p = top; p; p = next_dentry(p, top)) { 202 while ((p = get_next_positive_dentry(p, top))) {
163 spin_lock(&p->d_lock);
164 /* Negative dentry - give up */
165 if (!simple_positive(p)) {
166 spin_unlock(&p->d_lock);
167 continue;
168 }
169
170 DPRINTK("dentry %p %.*s", 203 DPRINTK("dentry %p %.*s",
171 p, (int) p->d_name.len, p->d_name.name); 204 p, (int) p->d_name.len, p->d_name.name);
172 205
173 p = dget_dlock(p);
174 spin_unlock(&p->d_lock);
175 spin_unlock(&dcache_lock);
176
177 /* 206 /*
178 * Is someone visiting anywhere in the subtree ? 207 * Is someone visiting anywhere in the subtree ?
179 * If there's no mount we need to check the usage 208 * If there's no mount we need to check the usage
@@ -208,10 +237,7 @@ static int autofs4_tree_busy(struct vfsmount *mnt,
208 return 1; 237 return 1;
209 } 238 }
210 } 239 }
211 dput(p);
212 spin_lock(&dcache_lock);
213 } 240 }
214 spin_unlock(&dcache_lock);
215 241
216 /* Timeout of a tree mount is ultimately determined by its top dentry */ 242 /* Timeout of a tree mount is ultimately determined by its top dentry */
217 if (!autofs4_can_expire(top, timeout, do_now)) 243 if (!autofs4_can_expire(top, timeout, do_now))
@@ -230,36 +256,21 @@ static struct dentry *autofs4_check_leaves(struct vfsmount *mnt,
230 DPRINTK("parent %p %.*s", 256 DPRINTK("parent %p %.*s",
231 parent, (int)parent->d_name.len, parent->d_name.name); 257 parent, (int)parent->d_name.len, parent->d_name.name);
232 258
233 spin_lock(&dcache_lock); 259 p = NULL;
234 for (p = parent; p; p = next_dentry(p, parent)) { 260 while ((p = get_next_positive_dentry(p, parent))) {
235 spin_lock(&p->d_lock);
236 /* Negative dentry - give up */
237 if (!simple_positive(p)) {
238 spin_unlock(&p->d_lock);
239 continue;
240 }
241
242 DPRINTK("dentry %p %.*s", 261 DPRINTK("dentry %p %.*s",
243 p, (int) p->d_name.len, p->d_name.name); 262 p, (int) p->d_name.len, p->d_name.name);
244 263
245 p = dget_dlock(p);
246 spin_unlock(&p->d_lock);
247 spin_unlock(&dcache_lock);
248
249 if (d_mountpoint(p)) { 264 if (d_mountpoint(p)) {
250 /* Can we umount this guy */ 265 /* Can we umount this guy */
251 if (autofs4_mount_busy(mnt, p)) 266 if (autofs4_mount_busy(mnt, p))
252 goto cont; 267 continue;
253 268
254 /* Can we expire this guy */ 269 /* Can we expire this guy */
255 if (autofs4_can_expire(p, timeout, do_now)) 270 if (autofs4_can_expire(p, timeout, do_now))
256 return p; 271 return p;
257 } 272 }
258cont:
259 dput(p);
260 spin_lock(&dcache_lock);
261 } 273 }
262 spin_unlock(&dcache_lock);
263 return NULL; 274 return NULL;
264} 275}
265 276
@@ -310,8 +321,8 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,
310{ 321{
311 unsigned long timeout; 322 unsigned long timeout;
312 struct dentry *root = sb->s_root; 323 struct dentry *root = sb->s_root;
324 struct dentry *dentry;
313 struct dentry *expired = NULL; 325 struct dentry *expired = NULL;
314 struct list_head *next;
315 int do_now = how & AUTOFS_EXP_IMMEDIATE; 326 int do_now = how & AUTOFS_EXP_IMMEDIATE;
316 int exp_leaves = how & AUTOFS_EXP_LEAVES; 327 int exp_leaves = how & AUTOFS_EXP_LEAVES;
317 struct autofs_info *ino; 328 struct autofs_info *ino;
@@ -323,26 +334,8 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,
323 now = jiffies; 334 now = jiffies;
324 timeout = sbi->exp_timeout; 335 timeout = sbi->exp_timeout;
325 336
326 spin_lock(&dcache_lock); 337 dentry = NULL;
327 next = root->d_subdirs.next; 338 while ((dentry = get_next_positive_dentry(dentry, root))) {
328
329 /* On exit from the loop expire is set to a dgot dentry
330 * to expire or it's NULL */
331 while ( next != &root->d_subdirs ) {
332 struct dentry *dentry = list_entry(next, struct dentry, d_u.d_child);
333
334 /* Negative dentry - give up */
335 spin_lock(&dentry->d_lock);
336 if (!simple_positive(dentry)) {
337 next = next->next;
338 spin_unlock(&dentry->d_lock);
339 continue;
340 }
341
342 dentry = dget_dlock(dentry);
343 spin_unlock(&dentry->d_lock);
344 spin_unlock(&dcache_lock);
345
346 spin_lock(&sbi->fs_lock); 339 spin_lock(&sbi->fs_lock);
347 ino = autofs4_dentry_ino(dentry); 340 ino = autofs4_dentry_ino(dentry);
348 341
@@ -405,11 +398,7 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,
405 } 398 }
406next: 399next:
407 spin_unlock(&sbi->fs_lock); 400 spin_unlock(&sbi->fs_lock);
408 dput(dentry);
409 spin_lock(&dcache_lock);
410 next = next->next;
411 } 401 }
412 spin_unlock(&dcache_lock);
413 return NULL; 402 return NULL;
414 403
415found: 404found:
@@ -420,7 +409,11 @@ found:
420 init_completion(&ino->expire_complete); 409 init_completion(&ino->expire_complete);
421 spin_unlock(&sbi->fs_lock); 410 spin_unlock(&sbi->fs_lock);
422 spin_lock(&dcache_lock); 411 spin_lock(&dcache_lock);
412 spin_lock(&expired->d_parent->d_lock);
413 spin_lock_nested(&expired->d_lock, DENTRY_D_LOCK_NESTED);
423 list_move(&expired->d_parent->d_subdirs, &expired->d_u.d_child); 414 list_move(&expired->d_parent->d_subdirs, &expired->d_u.d_child);
415 spin_unlock(&expired->d_lock);
416 spin_unlock(&expired->d_parent->d_lock);
424 spin_unlock(&dcache_lock); 417 spin_unlock(&dcache_lock);
425 return expired; 418 return expired;
426} 419}
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index 7922509b5b2b..7a9ed6b88291 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -143,10 +143,13 @@ static int autofs4_dir_open(struct inode *inode, struct file *file)
143 * it. 143 * it.
144 */ 144 */
145 spin_lock(&dcache_lock); 145 spin_lock(&dcache_lock);
146 spin_lock(&dentry->d_lock);
146 if (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) { 147 if (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) {
148 spin_unlock(&dentry->d_lock);
147 spin_unlock(&dcache_lock); 149 spin_unlock(&dcache_lock);
148 return -ENOENT; 150 return -ENOENT;
149 } 151 }
152 spin_unlock(&dentry->d_lock);
150 spin_unlock(&dcache_lock); 153 spin_unlock(&dcache_lock);
151 154
152out: 155out:
@@ -253,7 +256,9 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
253 lookup_type = autofs4_need_mount(nd->flags); 256 lookup_type = autofs4_need_mount(nd->flags);
254 spin_lock(&sbi->fs_lock); 257 spin_lock(&sbi->fs_lock);
255 spin_lock(&dcache_lock); 258 spin_lock(&dcache_lock);
259 spin_lock(&dentry->d_lock);
256 if (!(lookup_type || ino->flags & AUTOFS_INF_PENDING)) { 260 if (!(lookup_type || ino->flags & AUTOFS_INF_PENDING)) {
261 spin_unlock(&dentry->d_lock);
257 spin_unlock(&dcache_lock); 262 spin_unlock(&dcache_lock);
258 spin_unlock(&sbi->fs_lock); 263 spin_unlock(&sbi->fs_lock);
259 goto follow; 264 goto follow;
@@ -266,6 +271,7 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
266 */ 271 */
267 if (ino->flags & AUTOFS_INF_PENDING || 272 if (ino->flags & AUTOFS_INF_PENDING ||
268 (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs))) { 273 (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs))) {
274 spin_unlock(&dentry->d_lock);
269 spin_unlock(&dcache_lock); 275 spin_unlock(&dcache_lock);
270 spin_unlock(&sbi->fs_lock); 276 spin_unlock(&sbi->fs_lock);
271 277
@@ -275,6 +281,7 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
275 281
276 goto follow; 282 goto follow;
277 } 283 }
284 spin_unlock(&dentry->d_lock);
278 spin_unlock(&dcache_lock); 285 spin_unlock(&dcache_lock);
279 spin_unlock(&sbi->fs_lock); 286 spin_unlock(&sbi->fs_lock);
280follow: 287follow:
@@ -347,10 +354,12 @@ static int autofs4_revalidate(struct dentry *dentry, struct nameidata *nd)
347 354
348 /* Check for a non-mountpoint directory with no contents */ 355 /* Check for a non-mountpoint directory with no contents */
349 spin_lock(&dcache_lock); 356 spin_lock(&dcache_lock);
357 spin_lock(&dentry->d_lock);
350 if (S_ISDIR(dentry->d_inode->i_mode) && 358 if (S_ISDIR(dentry->d_inode->i_mode) &&
351 !d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) { 359 !d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) {
352 DPRINTK("dentry=%p %.*s, emptydir", 360 DPRINTK("dentry=%p %.*s, emptydir",
353 dentry, dentry->d_name.len, dentry->d_name.name); 361 dentry, dentry->d_name.len, dentry->d_name.name);
362 spin_unlock(&dentry->d_lock);
354 spin_unlock(&dcache_lock); 363 spin_unlock(&dcache_lock);
355 364
356 /* The daemon never causes a mount to trigger */ 365 /* The daemon never causes a mount to trigger */
@@ -367,6 +376,7 @@ static int autofs4_revalidate(struct dentry *dentry, struct nameidata *nd)
367 376
368 return status; 377 return status;
369 } 378 }
379 spin_unlock(&dentry->d_lock);
370 spin_unlock(&dcache_lock); 380 spin_unlock(&dcache_lock);
371 381
372 return 1; 382 return 1;
@@ -776,12 +786,16 @@ static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry)
776 return -EACCES; 786 return -EACCES;
777 787
778 spin_lock(&dcache_lock); 788 spin_lock(&dcache_lock);
789 spin_lock(&sbi->lookup_lock);
790 spin_lock(&dentry->d_lock);
779 if (!list_empty(&dentry->d_subdirs)) { 791 if (!list_empty(&dentry->d_subdirs)) {
792 spin_unlock(&dentry->d_lock);
793 spin_unlock(&sbi->lookup_lock);
780 spin_unlock(&dcache_lock); 794 spin_unlock(&dcache_lock);
781 return -ENOTEMPTY; 795 return -ENOTEMPTY;
782 } 796 }
783 autofs4_add_expiring(dentry); 797 __autofs4_add_expiring(dentry);
784 spin_lock(&dentry->d_lock); 798 spin_unlock(&sbi->lookup_lock);
785 __d_drop(dentry); 799 __d_drop(dentry);
786 spin_unlock(&dentry->d_lock); 800 spin_unlock(&dentry->d_lock);
787 spin_unlock(&dcache_lock); 801 spin_unlock(&dcache_lock);
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
index 571f270dca0f..2c924e8d85fe 100644
--- a/fs/ceph/dir.c
+++ b/fs/ceph/dir.c
@@ -113,6 +113,7 @@ static int __dcache_readdir(struct file *filp,
113 last); 113 last);
114 114
115 spin_lock(&dcache_lock); 115 spin_lock(&dcache_lock);
116 spin_lock(&parent->d_lock);
116 117
117 /* start at beginning? */ 118 /* start at beginning? */
118 if (filp->f_pos == 2 || last == NULL || 119 if (filp->f_pos == 2 || last == NULL ||
@@ -136,7 +137,7 @@ more:
136 fi->at_end = 1; 137 fi->at_end = 1;
137 goto out_unlock; 138 goto out_unlock;
138 } 139 }
139 spin_lock(&dentry->d_lock); 140 spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
140 if (!d_unhashed(dentry) && dentry->d_inode && 141 if (!d_unhashed(dentry) && dentry->d_inode &&
141 ceph_snap(dentry->d_inode) != CEPH_SNAPDIR && 142 ceph_snap(dentry->d_inode) != CEPH_SNAPDIR &&
142 ceph_ino(dentry->d_inode) != CEPH_INO_CEPH && 143 ceph_ino(dentry->d_inode) != CEPH_INO_CEPH &&
@@ -154,6 +155,7 @@ more:
154 155
155 dget_dlock(dentry); 156 dget_dlock(dentry);
156 spin_unlock(&dentry->d_lock); 157 spin_unlock(&dentry->d_lock);
158 spin_unlock(&parent->d_lock);
157 spin_unlock(&dcache_lock); 159 spin_unlock(&dcache_lock);
158 160
159 dout(" %llu (%llu) dentry %p %.*s %p\n", di->offset, filp->f_pos, 161 dout(" %llu (%llu) dentry %p %.*s %p\n", di->offset, filp->f_pos,
@@ -188,10 +190,12 @@ more:
188 } 190 }
189 191
190 spin_lock(&dcache_lock); 192 spin_lock(&dcache_lock);
193 spin_lock(&parent->d_lock);
191 p = p->prev; /* advance to next dentry */ 194 p = p->prev; /* advance to next dentry */
192 goto more; 195 goto more;
193 196
194out_unlock: 197out_unlock:
198 spin_unlock(&parent->d_lock);
195 spin_unlock(&dcache_lock); 199 spin_unlock(&dcache_lock);
196out: 200out:
197 if (last) 201 if (last)
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index bb68c799074d..2c6944473366 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -842,11 +842,13 @@ static void ceph_set_dentry_offset(struct dentry *dn)
842 spin_unlock(&inode->i_lock); 842 spin_unlock(&inode->i_lock);
843 843
844 spin_lock(&dcache_lock); 844 spin_lock(&dcache_lock);
845 spin_lock(&dn->d_lock); 845 spin_lock(&dir->d_lock);
846 spin_lock_nested(&dn->d_lock, DENTRY_D_LOCK_NESTED);
846 list_move(&dn->d_u.d_child, &dir->d_subdirs); 847 list_move(&dn->d_u.d_child, &dir->d_subdirs);
847 dout("set_dentry_offset %p %lld (%p %p)\n", dn, di->offset, 848 dout("set_dentry_offset %p %lld (%p %p)\n", dn, di->offset,
848 dn->d_u.d_child.prev, dn->d_u.d_child.next); 849 dn->d_u.d_child.prev, dn->d_u.d_child.next);
849 spin_unlock(&dn->d_lock); 850 spin_unlock(&dn->d_lock);
851 spin_unlock(&dir->d_lock);
850 spin_unlock(&dcache_lock); 852 spin_unlock(&dcache_lock);
851} 853}
852 854
@@ -1232,9 +1234,11 @@ retry_lookup:
1232 } else { 1234 } else {
1233 /* reorder parent's d_subdirs */ 1235 /* reorder parent's d_subdirs */
1234 spin_lock(&dcache_lock); 1236 spin_lock(&dcache_lock);
1235 spin_lock(&dn->d_lock); 1237 spin_lock(&parent->d_lock);
1238 spin_lock_nested(&dn->d_lock, DENTRY_D_LOCK_NESTED);
1236 list_move(&dn->d_u.d_child, &parent->d_subdirs); 1239 list_move(&dn->d_u.d_child, &parent->d_subdirs);
1237 spin_unlock(&dn->d_lock); 1240 spin_unlock(&dn->d_lock);
1241 spin_unlock(&parent->d_lock);
1238 spin_unlock(&dcache_lock); 1242 spin_unlock(&dcache_lock);
1239 } 1243 }
1240 1244
diff --git a/fs/coda/cache.c b/fs/coda/cache.c
index 9060f08e70cf..859393fca2b7 100644
--- a/fs/coda/cache.c
+++ b/fs/coda/cache.c
@@ -94,6 +94,7 @@ static void coda_flag_children(struct dentry *parent, int flag)
94 struct dentry *de; 94 struct dentry *de;
95 95
96 spin_lock(&dcache_lock); 96 spin_lock(&dcache_lock);
97 spin_lock(&parent->d_lock);
97 list_for_each(child, &parent->d_subdirs) 98 list_for_each(child, &parent->d_subdirs)
98 { 99 {
99 de = list_entry(child, struct dentry, d_u.d_child); 100 de = list_entry(child, struct dentry, d_u.d_child);
@@ -102,6 +103,7 @@ static void coda_flag_children(struct dentry *parent, int flag)
102 continue; 103 continue;
103 coda_flag_inode(de->d_inode, flag); 104 coda_flag_inode(de->d_inode, flag);
104 } 105 }
106 spin_unlock(&parent->d_lock);
105 spin_unlock(&dcache_lock); 107 spin_unlock(&dcache_lock);
106 return; 108 return;
107} 109}
diff --git a/fs/dcache.c b/fs/dcache.c
index ee127f9ab274..a661247a20d5 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -47,6 +47,8 @@
47 * - d_lru 47 * - d_lru
48 * - d_count 48 * - d_count
49 * - d_unhashed() 49 * - d_unhashed()
50 * - d_parent and d_subdirs
51 * - childrens' d_child and d_parent
50 * 52 *
51 * Ordering: 53 * Ordering:
52 * dcache_lock 54 * dcache_lock
@@ -223,24 +225,22 @@ static void dentry_lru_move_tail(struct dentry *dentry)
223 * 225 *
224 * If this is the root of the dentry tree, return NULL. 226 * If this is the root of the dentry tree, return NULL.
225 * 227 *
226 * dcache_lock and d_lock must be held by caller, are dropped by d_kill. 228 * dcache_lock and d_lock and d_parent->d_lock must be held by caller, and
229 * are dropped by d_kill.
227 */ 230 */
228static struct dentry *d_kill(struct dentry *dentry) 231static struct dentry *d_kill(struct dentry *dentry, struct dentry *parent)
229 __releases(dentry->d_lock) 232 __releases(dentry->d_lock)
233 __releases(parent->d_lock)
230 __releases(dcache_lock) 234 __releases(dcache_lock)
231{ 235{
232 struct dentry *parent;
233
234 list_del(&dentry->d_u.d_child); 236 list_del(&dentry->d_u.d_child);
237 if (parent)
238 spin_unlock(&parent->d_lock);
235 dentry_iput(dentry); 239 dentry_iput(dentry);
236 /* 240 /*
237 * dentry_iput drops the locks, at which point nobody (except 241 * dentry_iput drops the locks, at which point nobody (except
238 * transient RCU lookups) can reach this dentry. 242 * transient RCU lookups) can reach this dentry.
239 */ 243 */
240 if (IS_ROOT(dentry))
241 parent = NULL;
242 else
243 parent = dentry->d_parent;
244 d_free(dentry); 244 d_free(dentry);
245 return parent; 245 return parent;
246} 246}
@@ -312,6 +312,7 @@ EXPORT_SYMBOL(d_drop);
312 312
313void dput(struct dentry *dentry) 313void dput(struct dentry *dentry)
314{ 314{
315 struct dentry *parent;
315 if (!dentry) 316 if (!dentry)
316 return; 317 return;
317 318
@@ -319,6 +320,10 @@ repeat:
319 if (dentry->d_count == 1) 320 if (dentry->d_count == 1)
320 might_sleep(); 321 might_sleep();
321 spin_lock(&dentry->d_lock); 322 spin_lock(&dentry->d_lock);
323 if (IS_ROOT(dentry))
324 parent = NULL;
325 else
326 parent = dentry->d_parent;
322 if (dentry->d_count == 1) { 327 if (dentry->d_count == 1) {
323 if (!spin_trylock(&dcache_lock)) { 328 if (!spin_trylock(&dcache_lock)) {
324 /* 329 /*
@@ -330,10 +335,17 @@ repeat:
330 spin_unlock(&dentry->d_lock); 335 spin_unlock(&dentry->d_lock);
331 goto repeat; 336 goto repeat;
332 } 337 }
338 if (parent && !spin_trylock(&parent->d_lock)) {
339 spin_unlock(&dentry->d_lock);
340 spin_unlock(&dcache_lock);
341 goto repeat;
342 }
333 } 343 }
334 dentry->d_count--; 344 dentry->d_count--;
335 if (dentry->d_count) { 345 if (dentry->d_count) {
336 spin_unlock(&dentry->d_lock); 346 spin_unlock(&dentry->d_lock);
347 if (parent)
348 spin_unlock(&parent->d_lock);
337 spin_unlock(&dcache_lock); 349 spin_unlock(&dcache_lock);
338 return; 350 return;
339 } 351 }
@@ -355,6 +367,8 @@ repeat:
355 dentry_lru_add(dentry); 367 dentry_lru_add(dentry);
356 368
357 spin_unlock(&dentry->d_lock); 369 spin_unlock(&dentry->d_lock);
370 if (parent)
371 spin_unlock(&parent->d_lock);
358 spin_unlock(&dcache_lock); 372 spin_unlock(&dcache_lock);
359 return; 373 return;
360 374
@@ -363,7 +377,7 @@ unhash_it:
363kill_it: 377kill_it:
364 /* if dentry was on the d_lru list delete it from there */ 378 /* if dentry was on the d_lru list delete it from there */
365 dentry_lru_del(dentry); 379 dentry_lru_del(dentry);
366 dentry = d_kill(dentry); 380 dentry = d_kill(dentry, parent);
367 if (dentry) 381 if (dentry)
368 goto repeat; 382 goto repeat;
369} 383}
@@ -584,12 +598,13 @@ EXPORT_SYMBOL(d_prune_aliases);
584 * quadratic behavior of shrink_dcache_parent(), but is also expected 598 * quadratic behavior of shrink_dcache_parent(), but is also expected
585 * to be beneficial in reducing dentry cache fragmentation. 599 * to be beneficial in reducing dentry cache fragmentation.
586 */ 600 */
587static void prune_one_dentry(struct dentry * dentry) 601static void prune_one_dentry(struct dentry *dentry, struct dentry *parent)
588 __releases(dentry->d_lock) 602 __releases(dentry->d_lock)
603 __releases(parent->d_lock)
589 __releases(dcache_lock) 604 __releases(dcache_lock)
590{ 605{
591 __d_drop(dentry); 606 __d_drop(dentry);
592 dentry = d_kill(dentry); 607 dentry = d_kill(dentry, parent);
593 608
594 /* 609 /*
595 * Prune ancestors. Locking is simpler than in dput(), 610 * Prune ancestors. Locking is simpler than in dput(),
@@ -597,9 +612,20 @@ static void prune_one_dentry(struct dentry * dentry)
597 */ 612 */
598 while (dentry) { 613 while (dentry) {
599 spin_lock(&dcache_lock); 614 spin_lock(&dcache_lock);
615again:
600 spin_lock(&dentry->d_lock); 616 spin_lock(&dentry->d_lock);
617 if (IS_ROOT(dentry))
618 parent = NULL;
619 else
620 parent = dentry->d_parent;
621 if (parent && !spin_trylock(&parent->d_lock)) {
622 spin_unlock(&dentry->d_lock);
623 goto again;
624 }
601 dentry->d_count--; 625 dentry->d_count--;
602 if (dentry->d_count) { 626 if (dentry->d_count) {
627 if (parent)
628 spin_unlock(&parent->d_lock);
603 spin_unlock(&dentry->d_lock); 629 spin_unlock(&dentry->d_lock);
604 spin_unlock(&dcache_lock); 630 spin_unlock(&dcache_lock);
605 return; 631 return;
@@ -607,7 +633,7 @@ static void prune_one_dentry(struct dentry * dentry)
607 633
608 dentry_lru_del(dentry); 634 dentry_lru_del(dentry);
609 __d_drop(dentry); 635 __d_drop(dentry);
610 dentry = d_kill(dentry); 636 dentry = d_kill(dentry, parent);
611 } 637 }
612} 638}
613 639
@@ -616,29 +642,40 @@ static void shrink_dentry_list(struct list_head *list)
616 struct dentry *dentry; 642 struct dentry *dentry;
617 643
618 while (!list_empty(list)) { 644 while (!list_empty(list)) {
645 struct dentry *parent;
646
619 dentry = list_entry(list->prev, struct dentry, d_lru); 647 dentry = list_entry(list->prev, struct dentry, d_lru);
620 648
621 if (!spin_trylock(&dentry->d_lock)) { 649 if (!spin_trylock(&dentry->d_lock)) {
650relock:
622 spin_unlock(&dcache_lru_lock); 651 spin_unlock(&dcache_lru_lock);
623 cpu_relax(); 652 cpu_relax();
624 spin_lock(&dcache_lru_lock); 653 spin_lock(&dcache_lru_lock);
625 continue; 654 continue;
626 } 655 }
627 656
628 __dentry_lru_del(dentry);
629
630 /* 657 /*
631 * We found an inuse dentry which was not removed from 658 * We found an inuse dentry which was not removed from
632 * the LRU because of laziness during lookup. Do not free 659 * the LRU because of laziness during lookup. Do not free
633 * it - just keep it off the LRU list. 660 * it - just keep it off the LRU list.
634 */ 661 */
635 if (dentry->d_count) { 662 if (dentry->d_count) {
663 __dentry_lru_del(dentry);
636 spin_unlock(&dentry->d_lock); 664 spin_unlock(&dentry->d_lock);
637 continue; 665 continue;
638 } 666 }
667 if (IS_ROOT(dentry))
668 parent = NULL;
669 else
670 parent = dentry->d_parent;
671 if (parent && !spin_trylock(&parent->d_lock)) {
672 spin_unlock(&dentry->d_lock);
673 goto relock;
674 }
675 __dentry_lru_del(dentry);
639 spin_unlock(&dcache_lru_lock); 676 spin_unlock(&dcache_lru_lock);
640 677
641 prune_one_dentry(dentry); 678 prune_one_dentry(dentry, parent);
642 /* dcache_lock and dentry->d_lock dropped */ 679 /* dcache_lock and dentry->d_lock dropped */
643 spin_lock(&dcache_lock); 680 spin_lock(&dcache_lock);
644 spin_lock(&dcache_lru_lock); 681 spin_lock(&dcache_lru_lock);
@@ -833,14 +870,16 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
833 /* this is a branch with children - detach all of them 870 /* this is a branch with children - detach all of them
834 * from the system in one go */ 871 * from the system in one go */
835 spin_lock(&dcache_lock); 872 spin_lock(&dcache_lock);
873 spin_lock(&dentry->d_lock);
836 list_for_each_entry(loop, &dentry->d_subdirs, 874 list_for_each_entry(loop, &dentry->d_subdirs,
837 d_u.d_child) { 875 d_u.d_child) {
838 spin_lock(&loop->d_lock); 876 spin_lock_nested(&loop->d_lock,
877 DENTRY_D_LOCK_NESTED);
839 dentry_lru_del(loop); 878 dentry_lru_del(loop);
840 __d_drop(loop); 879 __d_drop(loop);
841 spin_unlock(&loop->d_lock); 880 spin_unlock(&loop->d_lock);
842 cond_resched_lock(&dcache_lock);
843 } 881 }
882 spin_unlock(&dentry->d_lock);
844 spin_unlock(&dcache_lock); 883 spin_unlock(&dcache_lock);
845 884
846 /* move to the first child */ 885 /* move to the first child */
@@ -868,16 +907,17 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
868 BUG(); 907 BUG();
869 } 908 }
870 909
871 if (IS_ROOT(dentry)) 910 if (IS_ROOT(dentry)) {
872 parent = NULL; 911 parent = NULL;
873 else { 912 list_del(&dentry->d_u.d_child);
913 } else {
874 parent = dentry->d_parent; 914 parent = dentry->d_parent;
875 spin_lock(&parent->d_lock); 915 spin_lock(&parent->d_lock);
876 parent->d_count--; 916 parent->d_count--;
917 list_del(&dentry->d_u.d_child);
877 spin_unlock(&parent->d_lock); 918 spin_unlock(&parent->d_lock);
878 } 919 }
879 920
880 list_del(&dentry->d_u.d_child);
881 detached++; 921 detached++;
882 922
883 inode = dentry->d_inode; 923 inode = dentry->d_inode;
@@ -958,6 +998,7 @@ int have_submounts(struct dentry *parent)
958 spin_lock(&dcache_lock); 998 spin_lock(&dcache_lock);
959 if (d_mountpoint(parent)) 999 if (d_mountpoint(parent))
960 goto positive; 1000 goto positive;
1001 spin_lock(&this_parent->d_lock);
961repeat: 1002repeat:
962 next = this_parent->d_subdirs.next; 1003 next = this_parent->d_subdirs.next;
963resume: 1004resume:
@@ -965,22 +1006,34 @@ resume:
965 struct list_head *tmp = next; 1006 struct list_head *tmp = next;
966 struct dentry *dentry = list_entry(tmp, struct dentry, d_u.d_child); 1007 struct dentry *dentry = list_entry(tmp, struct dentry, d_u.d_child);
967 next = tmp->next; 1008 next = tmp->next;
1009
1010 spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
968 /* Have we found a mount point ? */ 1011 /* Have we found a mount point ? */
969 if (d_mountpoint(dentry)) 1012 if (d_mountpoint(dentry)) {
1013 spin_unlock(&dentry->d_lock);
1014 spin_unlock(&this_parent->d_lock);
970 goto positive; 1015 goto positive;
1016 }
971 if (!list_empty(&dentry->d_subdirs)) { 1017 if (!list_empty(&dentry->d_subdirs)) {
1018 spin_unlock(&this_parent->d_lock);
1019 spin_release(&dentry->d_lock.dep_map, 1, _RET_IP_);
972 this_parent = dentry; 1020 this_parent = dentry;
1021 spin_acquire(&this_parent->d_lock.dep_map, 0, 1, _RET_IP_);
973 goto repeat; 1022 goto repeat;
974 } 1023 }
1024 spin_unlock(&dentry->d_lock);
975 } 1025 }
976 /* 1026 /*
977 * All done at this level ... ascend and resume the search. 1027 * All done at this level ... ascend and resume the search.
978 */ 1028 */
979 if (this_parent != parent) { 1029 if (this_parent != parent) {
980 next = this_parent->d_u.d_child.next; 1030 next = this_parent->d_u.d_child.next;
1031 spin_unlock(&this_parent->d_lock);
981 this_parent = this_parent->d_parent; 1032 this_parent = this_parent->d_parent;
1033 spin_lock(&this_parent->d_lock);
982 goto resume; 1034 goto resume;
983 } 1035 }
1036 spin_unlock(&this_parent->d_lock);
984 spin_unlock(&dcache_lock); 1037 spin_unlock(&dcache_lock);
985 return 0; /* No mount points found in tree */ 1038 return 0; /* No mount points found in tree */
986positive: 1039positive:
@@ -1010,6 +1063,7 @@ static int select_parent(struct dentry * parent)
1010 int found = 0; 1063 int found = 0;
1011 1064
1012 spin_lock(&dcache_lock); 1065 spin_lock(&dcache_lock);
1066 spin_lock(&this_parent->d_lock);
1013repeat: 1067repeat:
1014 next = this_parent->d_subdirs.next; 1068 next = this_parent->d_subdirs.next;
1015resume: 1069resume:
@@ -1017,8 +1071,9 @@ resume:
1017 struct list_head *tmp = next; 1071 struct list_head *tmp = next;
1018 struct dentry *dentry = list_entry(tmp, struct dentry, d_u.d_child); 1072 struct dentry *dentry = list_entry(tmp, struct dentry, d_u.d_child);
1019 next = tmp->next; 1073 next = tmp->next;
1074 BUG_ON(this_parent == dentry);
1020 1075
1021 spin_lock(&dentry->d_lock); 1076 spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
1022 1077
1023 /* 1078 /*
1024 * move only zero ref count dentries to the end 1079 * move only zero ref count dentries to the end
@@ -1031,33 +1086,44 @@ resume:
1031 dentry_lru_del(dentry); 1086 dentry_lru_del(dentry);
1032 } 1087 }
1033 1088
1034 spin_unlock(&dentry->d_lock);
1035
1036 /* 1089 /*
1037 * We can return to the caller if we have found some (this 1090 * We can return to the caller if we have found some (this
1038 * ensures forward progress). We'll be coming back to find 1091 * ensures forward progress). We'll be coming back to find
1039 * the rest. 1092 * the rest.
1040 */ 1093 */
1041 if (found && need_resched()) 1094 if (found && need_resched()) {
1095 spin_unlock(&dentry->d_lock);
1042 goto out; 1096 goto out;
1097 }
1043 1098
1044 /* 1099 /*
1045 * Descend a level if the d_subdirs list is non-empty. 1100 * Descend a level if the d_subdirs list is non-empty.
1046 */ 1101 */
1047 if (!list_empty(&dentry->d_subdirs)) { 1102 if (!list_empty(&dentry->d_subdirs)) {
1103 spin_unlock(&this_parent->d_lock);
1104 spin_release(&dentry->d_lock.dep_map, 1, _RET_IP_);
1048 this_parent = dentry; 1105 this_parent = dentry;
1106 spin_acquire(&this_parent->d_lock.dep_map, 0, 1, _RET_IP_);
1049 goto repeat; 1107 goto repeat;
1050 } 1108 }
1109
1110 spin_unlock(&dentry->d_lock);
1051 } 1111 }
1052 /* 1112 /*
1053 * All done at this level ... ascend and resume the search. 1113 * All done at this level ... ascend and resume the search.
1054 */ 1114 */
1055 if (this_parent != parent) { 1115 if (this_parent != parent) {
1116 struct dentry *tmp;
1056 next = this_parent->d_u.d_child.next; 1117 next = this_parent->d_u.d_child.next;
1057 this_parent = this_parent->d_parent; 1118 tmp = this_parent->d_parent;
1119 spin_unlock(&this_parent->d_lock);
1120 BUG_ON(tmp == this_parent);
1121 this_parent = tmp;
1122 spin_lock(&this_parent->d_lock);
1058 goto resume; 1123 goto resume;
1059 } 1124 }
1060out: 1125out:
1126 spin_unlock(&this_parent->d_lock);
1061 spin_unlock(&dcache_lock); 1127 spin_unlock(&dcache_lock);
1062 return found; 1128 return found;
1063} 1129}
@@ -1155,18 +1221,19 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)
1155 INIT_LIST_HEAD(&dentry->d_lru); 1221 INIT_LIST_HEAD(&dentry->d_lru);
1156 INIT_LIST_HEAD(&dentry->d_subdirs); 1222 INIT_LIST_HEAD(&dentry->d_subdirs);
1157 INIT_LIST_HEAD(&dentry->d_alias); 1223 INIT_LIST_HEAD(&dentry->d_alias);
1224 INIT_LIST_HEAD(&dentry->d_u.d_child);
1158 1225
1159 if (parent) { 1226 if (parent) {
1160 dentry->d_parent = dget(parent); 1227 spin_lock(&dcache_lock);
1228 spin_lock(&parent->d_lock);
1229 spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
1230 dentry->d_parent = dget_dlock(parent);
1161 dentry->d_sb = parent->d_sb; 1231 dentry->d_sb = parent->d_sb;
1162 } else {
1163 INIT_LIST_HEAD(&dentry->d_u.d_child);
1164 }
1165
1166 spin_lock(&dcache_lock);
1167 if (parent)
1168 list_add(&dentry->d_u.d_child, &parent->d_subdirs); 1232 list_add(&dentry->d_u.d_child, &parent->d_subdirs);
1169 spin_unlock(&dcache_lock); 1233 spin_unlock(&dentry->d_lock);
1234 spin_unlock(&parent->d_lock);
1235 spin_unlock(&dcache_lock);
1236 }
1170 1237
1171 this_cpu_inc(nr_dentry); 1238 this_cpu_inc(nr_dentry);
1172 1239
@@ -1684,13 +1751,18 @@ int d_validate(struct dentry *dentry, struct dentry *dparent)
1684 struct dentry *child; 1751 struct dentry *child;
1685 1752
1686 spin_lock(&dcache_lock); 1753 spin_lock(&dcache_lock);
1754 spin_lock(&dparent->d_lock);
1687 list_for_each_entry(child, &dparent->d_subdirs, d_u.d_child) { 1755 list_for_each_entry(child, &dparent->d_subdirs, d_u.d_child) {
1688 if (dentry == child) { 1756 if (dentry == child) {
1689 __dget_locked(dentry); 1757 spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
1758 __dget_locked_dlock(dentry);
1759 spin_unlock(&dentry->d_lock);
1760 spin_unlock(&dparent->d_lock);
1690 spin_unlock(&dcache_lock); 1761 spin_unlock(&dcache_lock);
1691 return 1; 1762 return 1;
1692 } 1763 }
1693 } 1764 }
1765 spin_unlock(&dparent->d_lock);
1694 spin_unlock(&dcache_lock); 1766 spin_unlock(&dcache_lock);
1695 1767
1696 return 0; 1768 return 0;
@@ -1802,17 +1874,6 @@ void dentry_update_name_case(struct dentry *dentry, struct qstr *name)
1802} 1874}
1803EXPORT_SYMBOL(dentry_update_name_case); 1875EXPORT_SYMBOL(dentry_update_name_case);
1804 1876
1805/*
1806 * When switching names, the actual string doesn't strictly have to
1807 * be preserved in the target - because we're dropping the target
1808 * anyway. As such, we can just do a simple memcpy() to copy over
1809 * the new name before we switch.
1810 *
1811 * Note that we have to be a lot more careful about getting the hash
1812 * switched - we have to switch the hash value properly even if it
1813 * then no longer matches the actual (corrupted) string of the target.
1814 * The hash value has to match the hash queue that the dentry is on..
1815 */
1816static void switch_names(struct dentry *dentry, struct dentry *target) 1877static void switch_names(struct dentry *dentry, struct dentry *target)
1817{ 1878{
1818 if (dname_external(target)) { 1879 if (dname_external(target)) {
@@ -1854,18 +1915,53 @@ static void switch_names(struct dentry *dentry, struct dentry *target)
1854 swap(dentry->d_name.len, target->d_name.len); 1915 swap(dentry->d_name.len, target->d_name.len);
1855} 1916}
1856 1917
1918static void dentry_lock_for_move(struct dentry *dentry, struct dentry *target)
1919{
1920 /*
1921 * XXXX: do we really need to take target->d_lock?
1922 */
1923 if (IS_ROOT(dentry) || dentry->d_parent == target->d_parent)
1924 spin_lock(&target->d_parent->d_lock);
1925 else {
1926 if (d_ancestor(dentry->d_parent, target->d_parent)) {
1927 spin_lock(&dentry->d_parent->d_lock);
1928 spin_lock_nested(&target->d_parent->d_lock,
1929 DENTRY_D_LOCK_NESTED);
1930 } else {
1931 spin_lock(&target->d_parent->d_lock);
1932 spin_lock_nested(&dentry->d_parent->d_lock,
1933 DENTRY_D_LOCK_NESTED);
1934 }
1935 }
1936 if (target < dentry) {
1937 spin_lock_nested(&target->d_lock, 2);
1938 spin_lock_nested(&dentry->d_lock, 3);
1939 } else {
1940 spin_lock_nested(&dentry->d_lock, 2);
1941 spin_lock_nested(&target->d_lock, 3);
1942 }
1943}
1944
1945static void dentry_unlock_parents_for_move(struct dentry *dentry,
1946 struct dentry *target)
1947{
1948 if (target->d_parent != dentry->d_parent)
1949 spin_unlock(&dentry->d_parent->d_lock);
1950 if (target->d_parent != target)
1951 spin_unlock(&target->d_parent->d_lock);
1952}
1953
1857/* 1954/*
1858 * We cannibalize "target" when moving dentry on top of it, 1955 * When switching names, the actual string doesn't strictly have to
1859 * because it's going to be thrown away anyway. We could be more 1956 * be preserved in the target - because we're dropping the target
1860 * polite about it, though. 1957 * anyway. As such, we can just do a simple memcpy() to copy over
1861 * 1958 * the new name before we switch.
1862 * This forceful removal will result in ugly /proc output if 1959 *
1863 * somebody holds a file open that got deleted due to a rename. 1960 * Note that we have to be a lot more careful about getting the hash
1864 * We could be nicer about the deleted file, and let it show 1961 * switched - we have to switch the hash value properly even if it
1865 * up under the name it had before it was deleted rather than 1962 * then no longer matches the actual (corrupted) string of the target.
1866 * under the original name of the file that was moved on top of it. 1963 * The hash value has to match the hash queue that the dentry is on..
1867 */ 1964 */
1868
1869/* 1965/*
1870 * d_move_locked - move a dentry 1966 * d_move_locked - move a dentry
1871 * @dentry: entry to move 1967 * @dentry: entry to move
@@ -1879,20 +1975,12 @@ static void d_move_locked(struct dentry * dentry, struct dentry * target)
1879 if (!dentry->d_inode) 1975 if (!dentry->d_inode)
1880 printk(KERN_WARNING "VFS: moving negative dcache entry\n"); 1976 printk(KERN_WARNING "VFS: moving negative dcache entry\n");
1881 1977
1978 BUG_ON(d_ancestor(dentry, target));
1979 BUG_ON(d_ancestor(target, dentry));
1980
1882 write_seqlock(&rename_lock); 1981 write_seqlock(&rename_lock);
1883 /* 1982
1884 * XXXX: do we really need to take target->d_lock? 1983 dentry_lock_for_move(dentry, target);
1885 */
1886 if (d_ancestor(dentry, target)) {
1887 spin_lock(&dentry->d_lock);
1888 spin_lock_nested(&target->d_lock, DENTRY_D_LOCK_NESTED);
1889 } else if (d_ancestor(target, dentry) || target < dentry) {
1890 spin_lock(&target->d_lock);
1891 spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
1892 } else {
1893 spin_lock(&dentry->d_lock);
1894 spin_lock_nested(&target->d_lock, DENTRY_D_LOCK_NESTED);
1895 }
1896 1984
1897 /* Move the dentry to the target hash queue, if on different bucket */ 1985 /* Move the dentry to the target hash queue, if on different bucket */
1898 spin_lock(&dcache_hash_lock); 1986 spin_lock(&dcache_hash_lock);
@@ -1924,6 +2012,8 @@ static void d_move_locked(struct dentry * dentry, struct dentry * target)
1924 } 2012 }
1925 2013
1926 list_add(&dentry->d_u.d_child, &dentry->d_parent->d_subdirs); 2014 list_add(&dentry->d_u.d_child, &dentry->d_parent->d_subdirs);
2015
2016 dentry_unlock_parents_for_move(dentry, target);
1927 spin_unlock(&target->d_lock); 2017 spin_unlock(&target->d_lock);
1928 fsnotify_d_move(dentry); 2018 fsnotify_d_move(dentry);
1929 spin_unlock(&dentry->d_lock); 2019 spin_unlock(&dentry->d_lock);
@@ -2013,17 +2103,20 @@ out_err:
2013/* 2103/*
2014 * Prepare an anonymous dentry for life in the superblock's dentry tree as a 2104 * Prepare an anonymous dentry for life in the superblock's dentry tree as a
2015 * named dentry in place of the dentry to be replaced. 2105 * named dentry in place of the dentry to be replaced.
2106 * returns with anon->d_lock held!
2016 */ 2107 */
2017static void __d_materialise_dentry(struct dentry *dentry, struct dentry *anon) 2108static void __d_materialise_dentry(struct dentry *dentry, struct dentry *anon)
2018{ 2109{
2019 struct dentry *dparent, *aparent; 2110 struct dentry *dparent, *aparent;
2020 2111
2021 switch_names(dentry, anon); 2112 dentry_lock_for_move(anon, dentry);
2022 swap(dentry->d_name.hash, anon->d_name.hash);
2023 2113
2024 dparent = dentry->d_parent; 2114 dparent = dentry->d_parent;
2025 aparent = anon->d_parent; 2115 aparent = anon->d_parent;
2026 2116
2117 switch_names(dentry, anon);
2118 swap(dentry->d_name.hash, anon->d_name.hash);
2119
2027 dentry->d_parent = (aparent == anon) ? dentry : aparent; 2120 dentry->d_parent = (aparent == anon) ? dentry : aparent;
2028 list_del(&dentry->d_u.d_child); 2121 list_del(&dentry->d_u.d_child);
2029 if (!IS_ROOT(dentry)) 2122 if (!IS_ROOT(dentry))
@@ -2038,6 +2131,10 @@ static void __d_materialise_dentry(struct dentry *dentry, struct dentry *anon)
2038 else 2131 else
2039 INIT_LIST_HEAD(&anon->d_u.d_child); 2132 INIT_LIST_HEAD(&anon->d_u.d_child);
2040 2133
2134 dentry_unlock_parents_for_move(anon, dentry);
2135 spin_unlock(&dentry->d_lock);
2136
2137 /* anon->d_lock still locked, returns locked */
2041 anon->d_flags &= ~DCACHE_DISCONNECTED; 2138 anon->d_flags &= ~DCACHE_DISCONNECTED;
2042} 2139}
2043 2140
@@ -2073,7 +2170,6 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
2073 /* Is this an anonymous mountpoint that we could splice 2170 /* Is this an anonymous mountpoint that we could splice
2074 * into our tree? */ 2171 * into our tree? */
2075 if (IS_ROOT(alias)) { 2172 if (IS_ROOT(alias)) {
2076 spin_lock(&alias->d_lock);
2077 __d_materialise_dentry(dentry, alias); 2173 __d_materialise_dentry(dentry, alias);
2078 __d_drop(alias); 2174 __d_drop(alias);
2079 goto found; 2175 goto found;
@@ -2558,6 +2654,7 @@ void d_genocide(struct dentry *root)
2558 struct list_head *next; 2654 struct list_head *next;
2559 2655
2560 spin_lock(&dcache_lock); 2656 spin_lock(&dcache_lock);
2657 spin_lock(&this_parent->d_lock);
2561repeat: 2658repeat:
2562 next = this_parent->d_subdirs.next; 2659 next = this_parent->d_subdirs.next;
2563resume: 2660resume:
@@ -2571,8 +2668,10 @@ resume:
2571 continue; 2668 continue;
2572 } 2669 }
2573 if (!list_empty(&dentry->d_subdirs)) { 2670 if (!list_empty(&dentry->d_subdirs)) {
2574 spin_unlock(&dentry->d_lock); 2671 spin_unlock(&this_parent->d_lock);
2672 spin_release(&dentry->d_lock.dep_map, 1, _RET_IP_);
2575 this_parent = dentry; 2673 this_parent = dentry;
2674 spin_acquire(&this_parent->d_lock.dep_map, 0, 1, _RET_IP_);
2576 goto repeat; 2675 goto repeat;
2577 } 2676 }
2578 dentry->d_count--; 2677 dentry->d_count--;
@@ -2580,12 +2679,13 @@ resume:
2580 } 2679 }
2581 if (this_parent != root) { 2680 if (this_parent != root) {
2582 next = this_parent->d_u.d_child.next; 2681 next = this_parent->d_u.d_child.next;
2583 spin_lock(&this_parent->d_lock);
2584 this_parent->d_count--; 2682 this_parent->d_count--;
2585 spin_unlock(&this_parent->d_lock); 2683 spin_unlock(&this_parent->d_lock);
2586 this_parent = this_parent->d_parent; 2684 this_parent = this_parent->d_parent;
2685 spin_lock(&this_parent->d_lock);
2587 goto resume; 2686 goto resume;
2588 } 2687 }
2688 spin_unlock(&this_parent->d_lock);
2589 spin_unlock(&dcache_lock); 2689 spin_unlock(&dcache_lock);
2590} 2690}
2591 2691
diff --git a/fs/libfs.c b/fs/libfs.c
index 433e7139c23a..cc4794914b52 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -81,7 +81,8 @@ int dcache_dir_close(struct inode *inode, struct file *file)
81 81
82loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin) 82loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin)
83{ 83{
84 mutex_lock(&file->f_path.dentry->d_inode->i_mutex); 84 struct dentry *dentry = file->f_path.dentry;
85 mutex_lock(&dentry->d_inode->i_mutex);
85 switch (origin) { 86 switch (origin) {
86 case 1: 87 case 1:
87 offset += file->f_pos; 88 offset += file->f_pos;
@@ -89,7 +90,7 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin)
89 if (offset >= 0) 90 if (offset >= 0)
90 break; 91 break;
91 default: 92 default:
92 mutex_unlock(&file->f_path.dentry->d_inode->i_mutex); 93 mutex_unlock(&dentry->d_inode->i_mutex);
93 return -EINVAL; 94 return -EINVAL;
94 } 95 }
95 if (offset != file->f_pos) { 96 if (offset != file->f_pos) {
@@ -100,22 +101,25 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin)
100 loff_t n = file->f_pos - 2; 101 loff_t n = file->f_pos - 2;
101 102
102 spin_lock(&dcache_lock); 103 spin_lock(&dcache_lock);
104 spin_lock(&dentry->d_lock);
105 /* d_lock not required for cursor */
103 list_del(&cursor->d_u.d_child); 106 list_del(&cursor->d_u.d_child);
104 p = file->f_path.dentry->d_subdirs.next; 107 p = dentry->d_subdirs.next;
105 while (n && p != &file->f_path.dentry->d_subdirs) { 108 while (n && p != &dentry->d_subdirs) {
106 struct dentry *next; 109 struct dentry *next;
107 next = list_entry(p, struct dentry, d_u.d_child); 110 next = list_entry(p, struct dentry, d_u.d_child);
108 spin_lock(&next->d_lock); 111 spin_lock_nested(&next->d_lock, DENTRY_D_LOCK_NESTED);
109 if (simple_positive(next)) 112 if (simple_positive(next))
110 n--; 113 n--;
111 spin_unlock(&next->d_lock); 114 spin_unlock(&next->d_lock);
112 p = p->next; 115 p = p->next;
113 } 116 }
114 list_add_tail(&cursor->d_u.d_child, p); 117 list_add_tail(&cursor->d_u.d_child, p);
118 spin_unlock(&dentry->d_lock);
115 spin_unlock(&dcache_lock); 119 spin_unlock(&dcache_lock);
116 } 120 }
117 } 121 }
118 mutex_unlock(&file->f_path.dentry->d_inode->i_mutex); 122 mutex_unlock(&dentry->d_inode->i_mutex);
119 return offset; 123 return offset;
120} 124}
121 125
@@ -156,6 +160,7 @@ int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
156 /* fallthrough */ 160 /* fallthrough */
157 default: 161 default:
158 spin_lock(&dcache_lock); 162 spin_lock(&dcache_lock);
163 spin_lock(&dentry->d_lock);
159 if (filp->f_pos == 2) 164 if (filp->f_pos == 2)
160 list_move(q, &dentry->d_subdirs); 165 list_move(q, &dentry->d_subdirs);
161 166
@@ -169,6 +174,7 @@ int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
169 } 174 }
170 175
171 spin_unlock(&next->d_lock); 176 spin_unlock(&next->d_lock);
177 spin_unlock(&dentry->d_lock);
172 spin_unlock(&dcache_lock); 178 spin_unlock(&dcache_lock);
173 if (filldir(dirent, next->d_name.name, 179 if (filldir(dirent, next->d_name.name,
174 next->d_name.len, filp->f_pos, 180 next->d_name.len, filp->f_pos,
@@ -176,11 +182,15 @@ int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
176 dt_type(next->d_inode)) < 0) 182 dt_type(next->d_inode)) < 0)
177 return 0; 183 return 0;
178 spin_lock(&dcache_lock); 184 spin_lock(&dcache_lock);
185 spin_lock(&dentry->d_lock);
186 spin_lock_nested(&next->d_lock, DENTRY_D_LOCK_NESTED);
179 /* next is still alive */ 187 /* next is still alive */
180 list_move(q, p); 188 list_move(q, p);
189 spin_unlock(&next->d_lock);
181 p = q; 190 p = q;
182 filp->f_pos++; 191 filp->f_pos++;
183 } 192 }
193 spin_unlock(&dentry->d_lock);
184 spin_unlock(&dcache_lock); 194 spin_unlock(&dcache_lock);
185 } 195 }
186 return 0; 196 return 0;
@@ -276,6 +286,7 @@ int simple_empty(struct dentry *dentry)
276 int ret = 0; 286 int ret = 0;
277 287
278 spin_lock(&dcache_lock); 288 spin_lock(&dcache_lock);
289 spin_lock(&dentry->d_lock);
279 list_for_each_entry(child, &dentry->d_subdirs, d_u.d_child) { 290 list_for_each_entry(child, &dentry->d_subdirs, d_u.d_child) {
280 spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED); 291 spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED);
281 if (simple_positive(child)) { 292 if (simple_positive(child)) {
@@ -286,6 +297,7 @@ int simple_empty(struct dentry *dentry)
286 } 297 }
287 ret = 1; 298 ret = 1;
288out: 299out:
300 spin_unlock(&dentry->d_lock);
289 spin_unlock(&dcache_lock); 301 spin_unlock(&dcache_lock);
290 return ret; 302 return ret;
291} 303}
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c
index bbbf7922f422..102278ed38bd 100644
--- a/fs/ncpfs/dir.c
+++ b/fs/ncpfs/dir.c
@@ -392,6 +392,7 @@ ncp_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos)
392 392
393 /* If a pointer is invalid, we search the dentry. */ 393 /* If a pointer is invalid, we search the dentry. */
394 spin_lock(&dcache_lock); 394 spin_lock(&dcache_lock);
395 spin_lock(&parent->d_lock);
395 next = parent->d_subdirs.next; 396 next = parent->d_subdirs.next;
396 while (next != &parent->d_subdirs) { 397 while (next != &parent->d_subdirs) {
397 dent = list_entry(next, struct dentry, d_u.d_child); 398 dent = list_entry(next, struct dentry, d_u.d_child);
@@ -400,11 +401,13 @@ ncp_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos)
400 dget_locked(dent); 401 dget_locked(dent);
401 else 402 else
402 dent = NULL; 403 dent = NULL;
404 spin_unlock(&parent->d_lock);
403 spin_unlock(&dcache_lock); 405 spin_unlock(&dcache_lock);
404 goto out; 406 goto out;
405 } 407 }
406 next = next->next; 408 next = next->next;
407 } 409 }
410 spin_unlock(&parent->d_lock);
408 spin_unlock(&dcache_lock); 411 spin_unlock(&dcache_lock);
409 return NULL; 412 return NULL;
410 413
diff --git a/fs/ncpfs/ncplib_kernel.h b/fs/ncpfs/ncplib_kernel.h
index 244d1b73fda7..c4b718ff9a6b 100644
--- a/fs/ncpfs/ncplib_kernel.h
+++ b/fs/ncpfs/ncplib_kernel.h
@@ -194,6 +194,7 @@ ncp_renew_dentries(struct dentry *parent)
194 struct dentry *dentry; 194 struct dentry *dentry;
195 195
196 spin_lock(&dcache_lock); 196 spin_lock(&dcache_lock);
197 spin_lock(&parent->d_lock);
197 next = parent->d_subdirs.next; 198 next = parent->d_subdirs.next;
198 while (next != &parent->d_subdirs) { 199 while (next != &parent->d_subdirs) {
199 dentry = list_entry(next, struct dentry, d_u.d_child); 200 dentry = list_entry(next, struct dentry, d_u.d_child);
@@ -205,6 +206,7 @@ ncp_renew_dentries(struct dentry *parent)
205 206
206 next = next->next; 207 next = next->next;
207 } 208 }
209 spin_unlock(&parent->d_lock);
208 spin_unlock(&dcache_lock); 210 spin_unlock(&dcache_lock);
209} 211}
210 212
@@ -216,6 +218,7 @@ ncp_invalidate_dircache_entries(struct dentry *parent)
216 struct dentry *dentry; 218 struct dentry *dentry;
217 219
218 spin_lock(&dcache_lock); 220 spin_lock(&dcache_lock);
221 spin_lock(&parent->d_lock);
219 next = parent->d_subdirs.next; 222 next = parent->d_subdirs.next;
220 while (next != &parent->d_subdirs) { 223 while (next != &parent->d_subdirs) {
221 dentry = list_entry(next, struct dentry, d_u.d_child); 224 dentry = list_entry(next, struct dentry, d_u.d_child);
@@ -223,6 +226,7 @@ ncp_invalidate_dircache_entries(struct dentry *parent)
223 ncp_age_dentry(server, dentry); 226 ncp_age_dentry(server, dentry);
224 next = next->next; 227 next = next->next;
225 } 228 }
229 spin_unlock(&parent->d_lock);
226 spin_unlock(&dcache_lock); 230 spin_unlock(&dcache_lock);
227} 231}
228 232
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index 20dc218707ca..aa4f25e803f6 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -68,17 +68,19 @@ void __fsnotify_update_child_dentry_flags(struct inode *inode)
68 /* run all of the children of the original inode and fix their 68 /* run all of the children of the original inode and fix their
69 * d_flags to indicate parental interest (their parent is the 69 * d_flags to indicate parental interest (their parent is the
70 * original inode) */ 70 * original inode) */
71 spin_lock(&alias->d_lock);
71 list_for_each_entry(child, &alias->d_subdirs, d_u.d_child) { 72 list_for_each_entry(child, &alias->d_subdirs, d_u.d_child) {
72 if (!child->d_inode) 73 if (!child->d_inode)
73 continue; 74 continue;
74 75
75 spin_lock(&child->d_lock); 76 spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED);
76 if (watched) 77 if (watched)
77 child->d_flags |= DCACHE_FSNOTIFY_PARENT_WATCHED; 78 child->d_flags |= DCACHE_FSNOTIFY_PARENT_WATCHED;
78 else 79 else
79 child->d_flags &= ~DCACHE_FSNOTIFY_PARENT_WATCHED; 80 child->d_flags &= ~DCACHE_FSNOTIFY_PARENT_WATCHED;
80 spin_unlock(&child->d_lock); 81 spin_unlock(&child->d_lock);
81 } 82 }
83 spin_unlock(&alias->d_lock);
82 } 84 }
83 spin_unlock(&dcache_lock); 85 spin_unlock(&dcache_lock);
84} 86}
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index b0ade2d46805..ddf4f55624f7 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -305,6 +305,7 @@ static inline struct dentry *dget_dlock(struct dentry *dentry)
305 } 305 }
306 return dentry; 306 return dentry;
307} 307}
308
308static inline struct dentry *dget(struct dentry *dentry) 309static inline struct dentry *dget(struct dentry *dentry)
309{ 310{
310 if (dentry) { 311 if (dentry) {
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index eb7af39350c6..7b4705b51d4a 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -877,23 +877,31 @@ static void cgroup_clear_directory(struct dentry *dentry)
877 877
878 BUG_ON(!mutex_is_locked(&dentry->d_inode->i_mutex)); 878 BUG_ON(!mutex_is_locked(&dentry->d_inode->i_mutex));
879 spin_lock(&dcache_lock); 879 spin_lock(&dcache_lock);
880 spin_lock(&dentry->d_lock);
880 node = dentry->d_subdirs.next; 881 node = dentry->d_subdirs.next;
881 while (node != &dentry->d_subdirs) { 882 while (node != &dentry->d_subdirs) {
882 struct dentry *d = list_entry(node, struct dentry, d_u.d_child); 883 struct dentry *d = list_entry(node, struct dentry, d_u.d_child);
884
885 spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
883 list_del_init(node); 886 list_del_init(node);
884 if (d->d_inode) { 887 if (d->d_inode) {
885 /* This should never be called on a cgroup 888 /* This should never be called on a cgroup
886 * directory with child cgroups */ 889 * directory with child cgroups */
887 BUG_ON(d->d_inode->i_mode & S_IFDIR); 890 BUG_ON(d->d_inode->i_mode & S_IFDIR);
888 d = dget_locked(d); 891 dget_locked_dlock(d);
892 spin_unlock(&d->d_lock);
893 spin_unlock(&dentry->d_lock);
889 spin_unlock(&dcache_lock); 894 spin_unlock(&dcache_lock);
890 d_delete(d); 895 d_delete(d);
891 simple_unlink(dentry->d_inode, d); 896 simple_unlink(dentry->d_inode, d);
892 dput(d); 897 dput(d);
893 spin_lock(&dcache_lock); 898 spin_lock(&dcache_lock);
894 } 899 spin_lock(&dentry->d_lock);
900 } else
901 spin_unlock(&d->d_lock);
895 node = dentry->d_subdirs.next; 902 node = dentry->d_subdirs.next;
896 } 903 }
904 spin_unlock(&dentry->d_lock);
897 spin_unlock(&dcache_lock); 905 spin_unlock(&dcache_lock);
898} 906}
899 907
@@ -902,10 +910,17 @@ static void cgroup_clear_directory(struct dentry *dentry)
902 */ 910 */
903static void cgroup_d_remove_dir(struct dentry *dentry) 911static void cgroup_d_remove_dir(struct dentry *dentry)
904{ 912{
913 struct dentry *parent;
914
905 cgroup_clear_directory(dentry); 915 cgroup_clear_directory(dentry);
906 916
907 spin_lock(&dcache_lock); 917 spin_lock(&dcache_lock);
918 parent = dentry->d_parent;
919 spin_lock(&parent->d_lock);
920 spin_lock(&dentry->d_lock);
908 list_del_init(&dentry->d_u.d_child); 921 list_del_init(&dentry->d_u.d_child);
922 spin_unlock(&dentry->d_lock);
923 spin_unlock(&parent->d_lock);
909 spin_unlock(&dcache_lock); 924 spin_unlock(&dcache_lock);
910 remove_dir(dentry); 925 remove_dir(dentry);
911} 926}
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 073fd5b0a53a..017ec096446e 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -1146,22 +1146,30 @@ static void sel_remove_entries(struct dentry *de)
1146 struct list_head *node; 1146 struct list_head *node;
1147 1147
1148 spin_lock(&dcache_lock); 1148 spin_lock(&dcache_lock);
1149 spin_lock(&de->d_lock);
1149 node = de->d_subdirs.next; 1150 node = de->d_subdirs.next;
1150 while (node != &de->d_subdirs) { 1151 while (node != &de->d_subdirs) {
1151 struct dentry *d = list_entry(node, struct dentry, d_u.d_child); 1152 struct dentry *d = list_entry(node, struct dentry, d_u.d_child);
1153
1154 spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
1152 list_del_init(node); 1155 list_del_init(node);
1153 1156
1154 if (d->d_inode) { 1157 if (d->d_inode) {
1155 d = dget_locked(d); 1158 dget_locked_dlock(d);
1159 spin_unlock(&de->d_lock);
1160 spin_unlock(&d->d_lock);
1156 spin_unlock(&dcache_lock); 1161 spin_unlock(&dcache_lock);
1157 d_delete(d); 1162 d_delete(d);
1158 simple_unlink(de->d_inode, d); 1163 simple_unlink(de->d_inode, d);
1159 dput(d); 1164 dput(d);
1160 spin_lock(&dcache_lock); 1165 spin_lock(&dcache_lock);
1161 } 1166 spin_lock(&de->d_lock);
1167 } else
1168 spin_unlock(&d->d_lock);
1162 node = de->d_subdirs.next; 1169 node = de->d_subdirs.next;
1163 } 1170 }
1164 1171
1172 spin_unlock(&de->d_lock);
1165 spin_unlock(&dcache_lock); 1173 spin_unlock(&dcache_lock);
1166} 1174}
1167 1175