diff options
author | Nick Piggin <npiggin@kernel.dk> | 2011-01-07 01:49:38 -0500 |
---|---|---|
committer | Nick Piggin <npiggin@kernel.dk> | 2011-01-07 01:50:23 -0500 |
commit | b5c84bf6f6fa3a7dfdcb556023a62953574b60ee (patch) | |
tree | 7a2c299a180713e21d5cb653cb933121adf53c31 | |
parent | 949854d02455080d20cd3e1db28a3a18daf7599d (diff) |
fs: dcache remove dcache_lock
dcache_lock no longer protects anything. remove it.
Signed-off-by: Nick Piggin <npiggin@kernel.dk>
40 files changed, 109 insertions, 307 deletions
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index a15ee207b449..bdad6414dfa0 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking | |||
@@ -21,14 +21,14 @@ prototypes: | |||
21 | char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen); | 21 | char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen); |
22 | 22 | ||
23 | locking rules: | 23 | locking rules: |
24 | dcache_lock rename_lock ->d_lock may block | 24 | rename_lock ->d_lock may block |
25 | d_revalidate: no no no yes | 25 | d_revalidate: no no yes |
26 | d_hash no no no no | 26 | d_hash no no no |
27 | d_compare: no yes no no | 27 | d_compare: yes no no |
28 | d_delete: yes no yes no | 28 | d_delete: no yes no |
29 | d_release: no no no yes | 29 | d_release: no no yes |
30 | d_iput: no no no yes | 30 | d_iput: no no yes |
31 | d_dname: no no no no | 31 | d_dname: no no no |
32 | 32 | ||
33 | --------------------------- inode_operations --------------------------- | 33 | --------------------------- inode_operations --------------------------- |
34 | prototypes: | 34 | prototypes: |
diff --git a/Documentation/filesystems/dentry-locking.txt b/Documentation/filesystems/dentry-locking.txt index 79334ed5daa7..30b6a40f5650 100644 --- a/Documentation/filesystems/dentry-locking.txt +++ b/Documentation/filesystems/dentry-locking.txt | |||
@@ -31,6 +31,7 @@ significant change is the way d_lookup traverses the hash chain, it | |||
31 | doesn't acquire the dcache_lock for this and rely on RCU to ensure | 31 | doesn't acquire the dcache_lock for this and rely on RCU to ensure |
32 | that the dentry has not been *freed*. | 32 | that the dentry has not been *freed*. |
33 | 33 | ||
34 | dcache_lock no longer exists, dentry locking is explained in fs/dcache.c | ||
34 | 35 | ||
35 | Dcache locking details | 36 | Dcache locking details |
36 | ====================== | 37 | ====================== |
@@ -50,14 +51,12 @@ Safe lock-free look-up of dcache hash table | |||
50 | 51 | ||
51 | Dcache is a complex data structure with the hash table entries also | 52 | Dcache is a complex data structure with the hash table entries also |
52 | linked together in other lists. In 2.4 kernel, dcache_lock protected | 53 | linked together in other lists. In 2.4 kernel, dcache_lock protected |
53 | all the lists. We applied RCU only on hash chain walking. The rest of | 54 | all the lists. RCU dentry hash walking works like this: |
54 | the lists are still protected by dcache_lock. Some of the important | ||
55 | changes are : | ||
56 | 55 | ||
57 | 1. The deletion from hash chain is done using hlist_del_rcu() macro | 56 | 1. The deletion from hash chain is done using hlist_del_rcu() macro |
58 | which doesn't initialize next pointer of the deleted dentry and | 57 | which doesn't initialize next pointer of the deleted dentry and |
59 | this allows us to walk safely lock-free while a deletion is | 58 | this allows us to walk safely lock-free while a deletion is |
60 | happening. | 59 | happening. This is a standard hlist_rcu iteration. |
61 | 60 | ||
62 | 2. Insertion of a dentry into the hash table is done using | 61 | 2. Insertion of a dentry into the hash table is done using |
63 | hlist_add_head_rcu() which take care of ordering the writes - the | 62 | hlist_add_head_rcu() which take care of ordering the writes - the |
@@ -66,19 +65,18 @@ changes are : | |||
66 | which has since been replaced by hlist_for_each_entry_rcu(), while | 65 | which has since been replaced by hlist_for_each_entry_rcu(), while |
67 | walking the hash chain. The only requirement is that all | 66 | walking the hash chain. The only requirement is that all |
68 | initialization to the dentry must be done before | 67 | initialization to the dentry must be done before |
69 | hlist_add_head_rcu() since we don't have dcache_lock protection | 68 | hlist_add_head_rcu() since we don't have lock protection |
70 | while traversing the hash chain. This isn't different from the | 69 | while traversing the hash chain. |
71 | existing code. | 70 | |
72 | 71 | 3. The dentry looked up without holding locks cannot be returned for | |
73 | 3. The dentry looked up without holding dcache_lock by cannot be | 72 | walking if it is unhashed. It then may have a NULL d_inode or other |
74 | returned for walking if it is unhashed. It then may have a NULL | 73 | bogosity since RCU doesn't protect the other fields in the dentry. We |
75 | d_inode or other bogosity since RCU doesn't protect the other | 74 | therefore use a flag DCACHE_UNHASHED to indicate unhashed dentries |
76 | fields in the dentry. We therefore use a flag DCACHE_UNHASHED to | 75 | and use this in conjunction with a per-dentry lock (d_lock). Once |
77 | indicate unhashed dentries and use this in conjunction with a | 76 | looked up without locks, we acquire the per-dentry lock (d_lock) and |
78 | per-dentry lock (d_lock). Once looked up without the dcache_lock, | 77 | check if the dentry is unhashed. If so, the look-up is failed. If not, |
79 | we acquire the per-dentry lock (d_lock) and check if the dentry is | 78 | the reference count of the dentry is increased and the dentry is |
80 | unhashed. If so, the look-up is failed. If not, the reference count | 79 | returned. |
81 | of the dentry is increased and the dentry is returned. | ||
82 | 80 | ||
83 | 4. Once a dentry is looked up, it must be ensured during the path walk | 81 | 4. Once a dentry is looked up, it must be ensured during the path walk |
84 | for that component it doesn't go away. In pre-2.5.10 code, this was | 82 | for that component it doesn't go away. In pre-2.5.10 code, this was |
@@ -86,10 +84,10 @@ changes are : | |||
86 | In some sense, dcache_rcu path walking looks like the pre-2.5.10 | 84 | In some sense, dcache_rcu path walking looks like the pre-2.5.10 |
87 | version. | 85 | version. |
88 | 86 | ||
89 | 5. All dentry hash chain updates must take the dcache_lock as well as | 87 | 5. All dentry hash chain updates must take the per-dentry lock (see |
90 | the per-dentry lock in that order. dput() does this to ensure that | 88 | fs/dcache.c). This excludes dput() to ensure that a dentry that has |
91 | a dentry that has just been looked up in another CPU doesn't get | 89 | been looked up concurrently does not get deleted before dget() can |
92 | deleted before dget() can be done on it. | 90 | take a ref. |
93 | 91 | ||
94 | 6. There are several ways to do reference counting of RCU protected | 92 | 6. There are several ways to do reference counting of RCU protected |
95 | objects. One such example is in ipv4 route cache where deferred | 93 | objects. One such example is in ipv4 route cache where deferred |
diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting index 9fd31940a8ef..1eb76959d096 100644 --- a/Documentation/filesystems/porting +++ b/Documentation/filesystems/porting | |||
@@ -216,7 +216,6 @@ had ->revalidate()) add calls in ->follow_link()/->readlink(). | |||
216 | ->d_parent changes are not protected by BKL anymore. Read access is safe | 216 | ->d_parent changes are not protected by BKL anymore. Read access is safe |
217 | if at least one of the following is true: | 217 | if at least one of the following is true: |
218 | * filesystem has no cross-directory rename() | 218 | * filesystem has no cross-directory rename() |
219 | * dcache_lock is held | ||
220 | * we know that parent had been locked (e.g. we are looking at | 219 | * we know that parent had been locked (e.g. we are looking at |
221 | ->d_parent of ->lookup() argument). | 220 | ->d_parent of ->lookup() argument). |
222 | * we are called from ->rename(). | 221 | * we are called from ->rename(). |
@@ -340,3 +339,10 @@ look at examples of other filesystems) for guidance. | |||
340 | .d_hash() calling convention and locking rules are significantly | 339 | .d_hash() calling convention and locking rules are significantly |
341 | changed. Read updated documentation in Documentation/filesystems/vfs.txt (and | 340 | changed. Read updated documentation in Documentation/filesystems/vfs.txt (and |
342 | look at examples of other filesystems) for guidance. | 341 | look at examples of other filesystems) for guidance. |
342 | |||
343 | --- | ||
344 | [mandatory] | ||
345 | dcache_lock is gone, replaced by fine grained locks. See fs/dcache.c | ||
346 | for details of what locks to replace dcache_lock with in order to protect | ||
347 | particular things. Most of the time, a filesystem only needs ->d_lock, which | ||
348 | protects *all* the dcache state of a given dentry. | ||
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index 5aef1a7f5e4b..2662b50ea8d4 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c | |||
@@ -159,21 +159,18 @@ static void spufs_prune_dir(struct dentry *dir) | |||
159 | 159 | ||
160 | mutex_lock(&dir->d_inode->i_mutex); | 160 | mutex_lock(&dir->d_inode->i_mutex); |
161 | list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_u.d_child) { | 161 | list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_u.d_child) { |
162 | spin_lock(&dcache_lock); | ||
163 | spin_lock(&dentry->d_lock); | 162 | spin_lock(&dentry->d_lock); |
164 | if (!(d_unhashed(dentry)) && dentry->d_inode) { | 163 | if (!(d_unhashed(dentry)) && dentry->d_inode) { |
165 | dget_locked_dlock(dentry); | 164 | dget_locked_dlock(dentry); |
166 | __d_drop(dentry); | 165 | __d_drop(dentry); |
167 | spin_unlock(&dentry->d_lock); | 166 | spin_unlock(&dentry->d_lock); |
168 | simple_unlink(dir->d_inode, dentry); | 167 | simple_unlink(dir->d_inode, dentry); |
169 | /* XXX: what is dcache_lock protecting here? Other | 168 | /* XXX: what was dcache_lock protecting here? Other |
170 | * filesystems (IB, configfs) release dcache_lock | 169 | * filesystems (IB, configfs) release dcache_lock |
171 | * before unlink */ | 170 | * before unlink */ |
172 | spin_unlock(&dcache_lock); | ||
173 | dput(dentry); | 171 | dput(dentry); |
174 | } else { | 172 | } else { |
175 | spin_unlock(&dentry->d_lock); | 173 | spin_unlock(&dentry->d_lock); |
176 | spin_unlock(&dcache_lock); | ||
177 | } | 174 | } |
178 | } | 175 | } |
179 | shrink_dcache_parent(dir); | 176 | shrink_dcache_parent(dir); |
diff --git a/drivers/infiniband/hw/ipath/ipath_fs.c b/drivers/infiniband/hw/ipath/ipath_fs.c index 18aee04a8411..925e88227ded 100644 --- a/drivers/infiniband/hw/ipath/ipath_fs.c +++ b/drivers/infiniband/hw/ipath/ipath_fs.c | |||
@@ -277,18 +277,14 @@ static int remove_file(struct dentry *parent, char *name) | |||
277 | goto bail; | 277 | goto bail; |
278 | } | 278 | } |
279 | 279 | ||
280 | spin_lock(&dcache_lock); | ||
281 | spin_lock(&tmp->d_lock); | 280 | spin_lock(&tmp->d_lock); |
282 | if (!(d_unhashed(tmp) && tmp->d_inode)) { | 281 | if (!(d_unhashed(tmp) && tmp->d_inode)) { |
283 | dget_locked_dlock(tmp); | 282 | dget_locked_dlock(tmp); |
284 | __d_drop(tmp); | 283 | __d_drop(tmp); |
285 | spin_unlock(&tmp->d_lock); | 284 | spin_unlock(&tmp->d_lock); |
286 | spin_unlock(&dcache_lock); | ||
287 | simple_unlink(parent->d_inode, tmp); | 285 | simple_unlink(parent->d_inode, tmp); |
288 | } else { | 286 | } else |
289 | spin_unlock(&tmp->d_lock); | 287 | spin_unlock(&tmp->d_lock); |
290 | spin_unlock(&dcache_lock); | ||
291 | } | ||
292 | 288 | ||
293 | ret = 0; | 289 | ret = 0; |
294 | bail: | 290 | bail: |
diff --git a/drivers/infiniband/hw/qib/qib_fs.c b/drivers/infiniband/hw/qib/qib_fs.c index fe4b242f0094..49af4a6538ba 100644 --- a/drivers/infiniband/hw/qib/qib_fs.c +++ b/drivers/infiniband/hw/qib/qib_fs.c | |||
@@ -453,17 +453,14 @@ static int remove_file(struct dentry *parent, char *name) | |||
453 | goto bail; | 453 | goto bail; |
454 | } | 454 | } |
455 | 455 | ||
456 | spin_lock(&dcache_lock); | ||
457 | spin_lock(&tmp->d_lock); | 456 | spin_lock(&tmp->d_lock); |
458 | if (!(d_unhashed(tmp) && tmp->d_inode)) { | 457 | if (!(d_unhashed(tmp) && tmp->d_inode)) { |
459 | dget_locked_dlock(tmp); | 458 | dget_locked_dlock(tmp); |
460 | __d_drop(tmp); | 459 | __d_drop(tmp); |
461 | spin_unlock(&tmp->d_lock); | 460 | spin_unlock(&tmp->d_lock); |
462 | spin_unlock(&dcache_lock); | ||
463 | simple_unlink(parent->d_inode, tmp); | 461 | simple_unlink(parent->d_inode, tmp); |
464 | } else { | 462 | } else { |
465 | spin_unlock(&tmp->d_lock); | 463 | spin_unlock(&tmp->d_lock); |
466 | spin_unlock(&dcache_lock); | ||
467 | } | 464 | } |
468 | 465 | ||
469 | ret = 0; | 466 | ret = 0; |
diff --git a/drivers/staging/pohmelfs/path_entry.c b/drivers/staging/pohmelfs/path_entry.c index bbe42f42ca8f..400a9fc386ad 100644 --- a/drivers/staging/pohmelfs/path_entry.c +++ b/drivers/staging/pohmelfs/path_entry.c | |||
@@ -101,7 +101,6 @@ rename_retry: | |||
101 | d = first; | 101 | d = first; |
102 | seq = read_seqbegin(&rename_lock); | 102 | seq = read_seqbegin(&rename_lock); |
103 | rcu_read_lock(); | 103 | rcu_read_lock(); |
104 | spin_lock(&dcache_lock); | ||
105 | 104 | ||
106 | if (!IS_ROOT(d) && d_unhashed(d)) | 105 | if (!IS_ROOT(d) && d_unhashed(d)) |
107 | len += UNHASHED_OBSCURE_STRING_SIZE; /* Obscure " (deleted)" string */ | 106 | len += UNHASHED_OBSCURE_STRING_SIZE; /* Obscure " (deleted)" string */ |
@@ -110,7 +109,6 @@ rename_retry: | |||
110 | len += d->d_name.len + 1; /* Plus slash */ | 109 | len += d->d_name.len + 1; /* Plus slash */ |
111 | d = d->d_parent; | 110 | d = d->d_parent; |
112 | } | 111 | } |
113 | spin_unlock(&dcache_lock); | ||
114 | rcu_read_unlock(); | 112 | rcu_read_unlock(); |
115 | if (read_seqretry(&rename_lock, seq)) | 113 | if (read_seqretry(&rename_lock, seq)) |
116 | goto rename_retry; | 114 | goto rename_retry; |
diff --git a/drivers/staging/smbfs/cache.c b/drivers/staging/smbfs/cache.c index 920434b6c071..75dfd403fb90 100644 --- a/drivers/staging/smbfs/cache.c +++ b/drivers/staging/smbfs/cache.c | |||
@@ -62,7 +62,6 @@ smb_invalidate_dircache_entries(struct dentry *parent) | |||
62 | struct list_head *next; | 62 | struct list_head *next; |
63 | struct dentry *dentry; | 63 | struct dentry *dentry; |
64 | 64 | ||
65 | spin_lock(&dcache_lock); | ||
66 | spin_lock(&parent->d_lock); | 65 | spin_lock(&parent->d_lock); |
67 | next = parent->d_subdirs.next; | 66 | next = parent->d_subdirs.next; |
68 | while (next != &parent->d_subdirs) { | 67 | while (next != &parent->d_subdirs) { |
@@ -72,7 +71,6 @@ smb_invalidate_dircache_entries(struct dentry *parent) | |||
72 | next = next->next; | 71 | next = next->next; |
73 | } | 72 | } |
74 | spin_unlock(&parent->d_lock); | 73 | spin_unlock(&parent->d_lock); |
75 | spin_unlock(&dcache_lock); | ||
76 | } | 74 | } |
77 | 75 | ||
78 | /* | 76 | /* |
@@ -98,7 +96,6 @@ smb_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos) | |||
98 | } | 96 | } |
99 | 97 | ||
100 | /* If a pointer is invalid, we search the dentry. */ | 98 | /* If a pointer is invalid, we search the dentry. */ |
101 | spin_lock(&dcache_lock); | ||
102 | spin_lock(&parent->d_lock); | 99 | spin_lock(&parent->d_lock); |
103 | next = parent->d_subdirs.next; | 100 | next = parent->d_subdirs.next; |
104 | while (next != &parent->d_subdirs) { | 101 | while (next != &parent->d_subdirs) { |
@@ -115,7 +112,6 @@ smb_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos) | |||
115 | dent = NULL; | 112 | dent = NULL; |
116 | out_unlock: | 113 | out_unlock: |
117 | spin_unlock(&parent->d_lock); | 114 | spin_unlock(&parent->d_lock); |
118 | spin_unlock(&dcache_lock); | ||
119 | return dent; | 115 | return dent; |
120 | } | 116 | } |
121 | 117 | ||
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c index 89a0e8366585..1b125c224dcf 100644 --- a/drivers/usb/core/inode.c +++ b/drivers/usb/core/inode.c | |||
@@ -343,7 +343,6 @@ static int usbfs_empty (struct dentry *dentry) | |||
343 | { | 343 | { |
344 | struct list_head *list; | 344 | struct list_head *list; |
345 | 345 | ||
346 | spin_lock(&dcache_lock); | ||
347 | spin_lock(&dentry->d_lock); | 346 | spin_lock(&dentry->d_lock); |
348 | list_for_each(list, &dentry->d_subdirs) { | 347 | list_for_each(list, &dentry->d_subdirs) { |
349 | struct dentry *de = list_entry(list, struct dentry, d_u.d_child); | 348 | struct dentry *de = list_entry(list, struct dentry, d_u.d_child); |
@@ -352,13 +351,11 @@ static int usbfs_empty (struct dentry *dentry) | |||
352 | if (usbfs_positive(de)) { | 351 | if (usbfs_positive(de)) { |
353 | spin_unlock(&de->d_lock); | 352 | spin_unlock(&de->d_lock); |
354 | spin_unlock(&dentry->d_lock); | 353 | spin_unlock(&dentry->d_lock); |
355 | spin_unlock(&dcache_lock); | ||
356 | return 0; | 354 | return 0; |
357 | } | 355 | } |
358 | spin_unlock(&de->d_lock); | 356 | spin_unlock(&de->d_lock); |
359 | } | 357 | } |
360 | spin_unlock(&dentry->d_lock); | 358 | spin_unlock(&dentry->d_lock); |
361 | spin_unlock(&dcache_lock); | ||
362 | return 1; | 359 | return 1; |
363 | } | 360 | } |
364 | 361 | ||
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 47dfd5d29a6b..1073bca8488c 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -270,13 +270,11 @@ static struct dentry *v9fs_dentry_from_dir_inode(struct inode *inode) | |||
270 | { | 270 | { |
271 | struct dentry *dentry; | 271 | struct dentry *dentry; |
272 | 272 | ||
273 | spin_lock(&dcache_lock); | ||
274 | spin_lock(&dcache_inode_lock); | 273 | spin_lock(&dcache_inode_lock); |
275 | /* Directory should have only one entry. */ | 274 | /* Directory should have only one entry. */ |
276 | BUG_ON(S_ISDIR(inode->i_mode) && !list_is_singular(&inode->i_dentry)); | 275 | BUG_ON(S_ISDIR(inode->i_mode) && !list_is_singular(&inode->i_dentry)); |
277 | dentry = list_entry(inode->i_dentry.next, struct dentry, d_alias); | 276 | dentry = list_entry(inode->i_dentry.next, struct dentry, d_alias); |
278 | spin_unlock(&dcache_inode_lock); | 277 | spin_unlock(&dcache_inode_lock); |
279 | spin_unlock(&dcache_lock); | ||
280 | return dentry; | 278 | return dentry; |
281 | } | 279 | } |
282 | 280 | ||
diff --git a/fs/affs/amigaffs.c b/fs/affs/amigaffs.c index 2321cc92d44f..600101a21ba2 100644 --- a/fs/affs/amigaffs.c +++ b/fs/affs/amigaffs.c | |||
@@ -128,7 +128,6 @@ affs_fix_dcache(struct dentry *dentry, u32 entry_ino) | |||
128 | void *data = dentry->d_fsdata; | 128 | void *data = dentry->d_fsdata; |
129 | struct list_head *head, *next; | 129 | struct list_head *head, *next; |
130 | 130 | ||
131 | spin_lock(&dcache_lock); | ||
132 | spin_lock(&dcache_inode_lock); | 131 | spin_lock(&dcache_inode_lock); |
133 | head = &inode->i_dentry; | 132 | head = &inode->i_dentry; |
134 | next = head->next; | 133 | next = head->next; |
@@ -141,7 +140,6 @@ affs_fix_dcache(struct dentry *dentry, u32 entry_ino) | |||
141 | next = next->next; | 140 | next = next->next; |
142 | } | 141 | } |
143 | spin_unlock(&dcache_inode_lock); | 142 | spin_unlock(&dcache_inode_lock); |
144 | spin_unlock(&dcache_lock); | ||
145 | } | 143 | } |
146 | 144 | ||
147 | 145 | ||
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h index 9d2ae9b30d9f..0fffe1c24cec 100644 --- a/fs/autofs4/autofs_i.h +++ b/fs/autofs4/autofs_i.h | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/auto_fs4.h> | 16 | #include <linux/auto_fs4.h> |
17 | #include <linux/auto_dev-ioctl.h> | 17 | #include <linux/auto_dev-ioctl.h> |
18 | #include <linux/mutex.h> | 18 | #include <linux/mutex.h> |
19 | #include <linux/spinlock.h> | ||
19 | #include <linux/list.h> | 20 | #include <linux/list.h> |
20 | 21 | ||
21 | /* This is the range of ioctl() numbers we claim as ours */ | 22 | /* This is the range of ioctl() numbers we claim as ours */ |
@@ -60,6 +61,8 @@ do { \ | |||
60 | current->pid, __func__, ##args); \ | 61 | current->pid, __func__, ##args); \ |
61 | } while (0) | 62 | } while (0) |
62 | 63 | ||
64 | extern spinlock_t autofs4_lock; | ||
65 | |||
63 | /* Unified info structure. This is pointed to by both the dentry and | 66 | /* Unified info structure. This is pointed to by both the dentry and |
64 | inode structures. Each file in the filesystem has an instance of this | 67 | inode structures. Each file in the filesystem has an instance of this |
65 | structure. It holds a reference to the dentry, so dentries are never | 68 | structure. It holds a reference to the dentry, so dentries are never |
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c index 968c1434af62..2f7951d67d16 100644 --- a/fs/autofs4/expire.c +++ b/fs/autofs4/expire.c | |||
@@ -102,7 +102,7 @@ static struct dentry *get_next_positive_dentry(struct dentry *prev, | |||
102 | if (prev == NULL) | 102 | if (prev == NULL) |
103 | return dget(prev); | 103 | return dget(prev); |
104 | 104 | ||
105 | spin_lock(&dcache_lock); | 105 | spin_lock(&autofs4_lock); |
106 | relock: | 106 | relock: |
107 | p = prev; | 107 | p = prev; |
108 | spin_lock(&p->d_lock); | 108 | spin_lock(&p->d_lock); |
@@ -114,7 +114,7 @@ again: | |||
114 | 114 | ||
115 | if (p == root) { | 115 | if (p == root) { |
116 | spin_unlock(&p->d_lock); | 116 | spin_unlock(&p->d_lock); |
117 | spin_unlock(&dcache_lock); | 117 | spin_unlock(&autofs4_lock); |
118 | dput(prev); | 118 | dput(prev); |
119 | return NULL; | 119 | return NULL; |
120 | } | 120 | } |
@@ -144,7 +144,7 @@ again: | |||
144 | dget_dlock(ret); | 144 | dget_dlock(ret); |
145 | spin_unlock(&ret->d_lock); | 145 | spin_unlock(&ret->d_lock); |
146 | spin_unlock(&p->d_lock); | 146 | spin_unlock(&p->d_lock); |
147 | spin_unlock(&dcache_lock); | 147 | spin_unlock(&autofs4_lock); |
148 | 148 | ||
149 | dput(prev); | 149 | dput(prev); |
150 | 150 | ||
@@ -408,13 +408,13 @@ found: | |||
408 | ino->flags |= AUTOFS_INF_EXPIRING; | 408 | ino->flags |= AUTOFS_INF_EXPIRING; |
409 | init_completion(&ino->expire_complete); | 409 | init_completion(&ino->expire_complete); |
410 | spin_unlock(&sbi->fs_lock); | 410 | spin_unlock(&sbi->fs_lock); |
411 | spin_lock(&dcache_lock); | 411 | spin_lock(&autofs4_lock); |
412 | spin_lock(&expired->d_parent->d_lock); | 412 | spin_lock(&expired->d_parent->d_lock); |
413 | spin_lock_nested(&expired->d_lock, DENTRY_D_LOCK_NESTED); | 413 | spin_lock_nested(&expired->d_lock, DENTRY_D_LOCK_NESTED); |
414 | 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); | 415 | spin_unlock(&expired->d_lock); |
416 | spin_unlock(&expired->d_parent->d_lock); | 416 | spin_unlock(&expired->d_parent->d_lock); |
417 | spin_unlock(&dcache_lock); | 417 | spin_unlock(&autofs4_lock); |
418 | return expired; | 418 | return expired; |
419 | } | 419 | } |
420 | 420 | ||
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index 7a9ed6b88291..10ca68a96dc7 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c | |||
@@ -23,6 +23,8 @@ | |||
23 | 23 | ||
24 | #include "autofs_i.h" | 24 | #include "autofs_i.h" |
25 | 25 | ||
26 | DEFINE_SPINLOCK(autofs4_lock); | ||
27 | |||
26 | static int autofs4_dir_symlink(struct inode *,struct dentry *,const char *); | 28 | static int autofs4_dir_symlink(struct inode *,struct dentry *,const char *); |
27 | static int autofs4_dir_unlink(struct inode *,struct dentry *); | 29 | static int autofs4_dir_unlink(struct inode *,struct dentry *); |
28 | static int autofs4_dir_rmdir(struct inode *,struct dentry *); | 30 | static int autofs4_dir_rmdir(struct inode *,struct dentry *); |
@@ -142,15 +144,15 @@ static int autofs4_dir_open(struct inode *inode, struct file *file) | |||
142 | * autofs file system so just let the libfs routines handle | 144 | * autofs file system so just let the libfs routines handle |
143 | * it. | 145 | * it. |
144 | */ | 146 | */ |
145 | spin_lock(&dcache_lock); | 147 | spin_lock(&autofs4_lock); |
146 | spin_lock(&dentry->d_lock); | 148 | spin_lock(&dentry->d_lock); |
147 | if (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) { | 149 | if (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) { |
148 | spin_unlock(&dentry->d_lock); | 150 | spin_unlock(&dentry->d_lock); |
149 | spin_unlock(&dcache_lock); | 151 | spin_unlock(&autofs4_lock); |
150 | return -ENOENT; | 152 | return -ENOENT; |
151 | } | 153 | } |
152 | spin_unlock(&dentry->d_lock); | 154 | spin_unlock(&dentry->d_lock); |
153 | spin_unlock(&dcache_lock); | 155 | spin_unlock(&autofs4_lock); |
154 | 156 | ||
155 | out: | 157 | out: |
156 | return dcache_dir_open(inode, file); | 158 | return dcache_dir_open(inode, file); |
@@ -255,11 +257,11 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
255 | /* We trigger a mount for almost all flags */ | 257 | /* We trigger a mount for almost all flags */ |
256 | lookup_type = autofs4_need_mount(nd->flags); | 258 | lookup_type = autofs4_need_mount(nd->flags); |
257 | spin_lock(&sbi->fs_lock); | 259 | spin_lock(&sbi->fs_lock); |
258 | spin_lock(&dcache_lock); | 260 | spin_lock(&autofs4_lock); |
259 | spin_lock(&dentry->d_lock); | 261 | spin_lock(&dentry->d_lock); |
260 | if (!(lookup_type || ino->flags & AUTOFS_INF_PENDING)) { | 262 | if (!(lookup_type || ino->flags & AUTOFS_INF_PENDING)) { |
261 | spin_unlock(&dentry->d_lock); | 263 | spin_unlock(&dentry->d_lock); |
262 | spin_unlock(&dcache_lock); | 264 | spin_unlock(&autofs4_lock); |
263 | spin_unlock(&sbi->fs_lock); | 265 | spin_unlock(&sbi->fs_lock); |
264 | goto follow; | 266 | goto follow; |
265 | } | 267 | } |
@@ -272,7 +274,7 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
272 | if (ino->flags & AUTOFS_INF_PENDING || | 274 | if (ino->flags & AUTOFS_INF_PENDING || |
273 | (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs))) { | 275 | (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs))) { |
274 | spin_unlock(&dentry->d_lock); | 276 | spin_unlock(&dentry->d_lock); |
275 | spin_unlock(&dcache_lock); | 277 | spin_unlock(&autofs4_lock); |
276 | spin_unlock(&sbi->fs_lock); | 278 | spin_unlock(&sbi->fs_lock); |
277 | 279 | ||
278 | status = try_to_fill_dentry(dentry, nd->flags); | 280 | status = try_to_fill_dentry(dentry, nd->flags); |
@@ -282,7 +284,7 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
282 | goto follow; | 284 | goto follow; |
283 | } | 285 | } |
284 | spin_unlock(&dentry->d_lock); | 286 | spin_unlock(&dentry->d_lock); |
285 | spin_unlock(&dcache_lock); | 287 | spin_unlock(&autofs4_lock); |
286 | spin_unlock(&sbi->fs_lock); | 288 | spin_unlock(&sbi->fs_lock); |
287 | follow: | 289 | follow: |
288 | /* | 290 | /* |
@@ -353,14 +355,14 @@ static int autofs4_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
353 | return 0; | 355 | return 0; |
354 | 356 | ||
355 | /* Check for a non-mountpoint directory with no contents */ | 357 | /* Check for a non-mountpoint directory with no contents */ |
356 | spin_lock(&dcache_lock); | 358 | spin_lock(&autofs4_lock); |
357 | spin_lock(&dentry->d_lock); | 359 | spin_lock(&dentry->d_lock); |
358 | if (S_ISDIR(dentry->d_inode->i_mode) && | 360 | if (S_ISDIR(dentry->d_inode->i_mode) && |
359 | !d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) { | 361 | !d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) { |
360 | DPRINTK("dentry=%p %.*s, emptydir", | 362 | DPRINTK("dentry=%p %.*s, emptydir", |
361 | dentry, dentry->d_name.len, dentry->d_name.name); | 363 | dentry, dentry->d_name.len, dentry->d_name.name); |
362 | spin_unlock(&dentry->d_lock); | 364 | spin_unlock(&dentry->d_lock); |
363 | spin_unlock(&dcache_lock); | 365 | spin_unlock(&autofs4_lock); |
364 | 366 | ||
365 | /* The daemon never causes a mount to trigger */ | 367 | /* The daemon never causes a mount to trigger */ |
366 | if (oz_mode) | 368 | if (oz_mode) |
@@ -377,7 +379,7 @@ static int autofs4_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
377 | return status; | 379 | return status; |
378 | } | 380 | } |
379 | spin_unlock(&dentry->d_lock); | 381 | spin_unlock(&dentry->d_lock); |
380 | spin_unlock(&dcache_lock); | 382 | spin_unlock(&autofs4_lock); |
381 | 383 | ||
382 | return 1; | 384 | return 1; |
383 | } | 385 | } |
@@ -432,7 +434,7 @@ static struct dentry *autofs4_lookup_active(struct dentry *dentry) | |||
432 | const unsigned char *str = name->name; | 434 | const unsigned char *str = name->name; |
433 | struct list_head *p, *head; | 435 | struct list_head *p, *head; |
434 | 436 | ||
435 | spin_lock(&dcache_lock); | 437 | spin_lock(&autofs4_lock); |
436 | spin_lock(&sbi->lookup_lock); | 438 | spin_lock(&sbi->lookup_lock); |
437 | head = &sbi->active_list; | 439 | head = &sbi->active_list; |
438 | list_for_each(p, head) { | 440 | list_for_each(p, head) { |
@@ -465,14 +467,14 @@ static struct dentry *autofs4_lookup_active(struct dentry *dentry) | |||
465 | dget_dlock(active); | 467 | dget_dlock(active); |
466 | spin_unlock(&active->d_lock); | 468 | spin_unlock(&active->d_lock); |
467 | spin_unlock(&sbi->lookup_lock); | 469 | spin_unlock(&sbi->lookup_lock); |
468 | spin_unlock(&dcache_lock); | 470 | spin_unlock(&autofs4_lock); |
469 | return active; | 471 | return active; |
470 | } | 472 | } |
471 | next: | 473 | next: |
472 | spin_unlock(&active->d_lock); | 474 | spin_unlock(&active->d_lock); |
473 | } | 475 | } |
474 | spin_unlock(&sbi->lookup_lock); | 476 | spin_unlock(&sbi->lookup_lock); |
475 | spin_unlock(&dcache_lock); | 477 | spin_unlock(&autofs4_lock); |
476 | 478 | ||
477 | return NULL; | 479 | return NULL; |
478 | } | 480 | } |
@@ -487,7 +489,7 @@ static struct dentry *autofs4_lookup_expiring(struct dentry *dentry) | |||
487 | const unsigned char *str = name->name; | 489 | const unsigned char *str = name->name; |
488 | struct list_head *p, *head; | 490 | struct list_head *p, *head; |
489 | 491 | ||
490 | spin_lock(&dcache_lock); | 492 | spin_lock(&autofs4_lock); |
491 | spin_lock(&sbi->lookup_lock); | 493 | spin_lock(&sbi->lookup_lock); |
492 | head = &sbi->expiring_list; | 494 | head = &sbi->expiring_list; |
493 | list_for_each(p, head) { | 495 | list_for_each(p, head) { |
@@ -520,14 +522,14 @@ static struct dentry *autofs4_lookup_expiring(struct dentry *dentry) | |||
520 | dget_dlock(expiring); | 522 | dget_dlock(expiring); |
521 | spin_unlock(&expiring->d_lock); | 523 | spin_unlock(&expiring->d_lock); |
522 | spin_unlock(&sbi->lookup_lock); | 524 | spin_unlock(&sbi->lookup_lock); |
523 | spin_unlock(&dcache_lock); | 525 | spin_unlock(&autofs4_lock); |
524 | return expiring; | 526 | return expiring; |
525 | } | 527 | } |
526 | next: | 528 | next: |
527 | spin_unlock(&expiring->d_lock); | 529 | spin_unlock(&expiring->d_lock); |
528 | } | 530 | } |
529 | spin_unlock(&sbi->lookup_lock); | 531 | spin_unlock(&sbi->lookup_lock); |
530 | spin_unlock(&dcache_lock); | 532 | spin_unlock(&autofs4_lock); |
531 | 533 | ||
532 | return NULL; | 534 | return NULL; |
533 | } | 535 | } |
@@ -763,12 +765,12 @@ static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry) | |||
763 | 765 | ||
764 | dir->i_mtime = CURRENT_TIME; | 766 | dir->i_mtime = CURRENT_TIME; |
765 | 767 | ||
766 | spin_lock(&dcache_lock); | 768 | spin_lock(&autofs4_lock); |
767 | autofs4_add_expiring(dentry); | 769 | autofs4_add_expiring(dentry); |
768 | spin_lock(&dentry->d_lock); | 770 | spin_lock(&dentry->d_lock); |
769 | __d_drop(dentry); | 771 | __d_drop(dentry); |
770 | spin_unlock(&dentry->d_lock); | 772 | spin_unlock(&dentry->d_lock); |
771 | spin_unlock(&dcache_lock); | 773 | spin_unlock(&autofs4_lock); |
772 | 774 | ||
773 | return 0; | 775 | return 0; |
774 | } | 776 | } |
@@ -785,20 +787,20 @@ static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry) | |||
785 | if (!autofs4_oz_mode(sbi)) | 787 | if (!autofs4_oz_mode(sbi)) |
786 | return -EACCES; | 788 | return -EACCES; |
787 | 789 | ||
788 | spin_lock(&dcache_lock); | 790 | spin_lock(&autofs4_lock); |
789 | spin_lock(&sbi->lookup_lock); | 791 | spin_lock(&sbi->lookup_lock); |
790 | spin_lock(&dentry->d_lock); | 792 | spin_lock(&dentry->d_lock); |
791 | if (!list_empty(&dentry->d_subdirs)) { | 793 | if (!list_empty(&dentry->d_subdirs)) { |
792 | spin_unlock(&dentry->d_lock); | 794 | spin_unlock(&dentry->d_lock); |
793 | spin_unlock(&sbi->lookup_lock); | 795 | spin_unlock(&sbi->lookup_lock); |
794 | spin_unlock(&dcache_lock); | 796 | spin_unlock(&autofs4_lock); |
795 | return -ENOTEMPTY; | 797 | return -ENOTEMPTY; |
796 | } | 798 | } |
797 | __autofs4_add_expiring(dentry); | 799 | __autofs4_add_expiring(dentry); |
798 | spin_unlock(&sbi->lookup_lock); | 800 | spin_unlock(&sbi->lookup_lock); |
799 | __d_drop(dentry); | 801 | __d_drop(dentry); |
800 | spin_unlock(&dentry->d_lock); | 802 | spin_unlock(&dentry->d_lock); |
801 | spin_unlock(&dcache_lock); | 803 | spin_unlock(&autofs4_lock); |
802 | 804 | ||
803 | if (atomic_dec_and_test(&ino->count)) { | 805 | if (atomic_dec_and_test(&ino->count)) { |
804 | p_ino = autofs4_dentry_ino(dentry->d_parent); | 806 | p_ino = autofs4_dentry_ino(dentry->d_parent); |
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c index 4be8f778a418..c5f8459c905e 100644 --- a/fs/autofs4/waitq.c +++ b/fs/autofs4/waitq.c | |||
@@ -194,14 +194,15 @@ static int autofs4_getpath(struct autofs_sb_info *sbi, | |||
194 | rename_retry: | 194 | rename_retry: |
195 | buf = *name; | 195 | buf = *name; |
196 | len = 0; | 196 | len = 0; |
197 | |||
197 | seq = read_seqbegin(&rename_lock); | 198 | seq = read_seqbegin(&rename_lock); |
198 | rcu_read_lock(); | 199 | rcu_read_lock(); |
199 | spin_lock(&dcache_lock); | 200 | spin_lock(&autofs4_lock); |
200 | for (tmp = dentry ; tmp != root ; tmp = tmp->d_parent) | 201 | for (tmp = dentry ; tmp != root ; tmp = tmp->d_parent) |
201 | len += tmp->d_name.len + 1; | 202 | len += tmp->d_name.len + 1; |
202 | 203 | ||
203 | if (!len || --len > NAME_MAX) { | 204 | if (!len || --len > NAME_MAX) { |
204 | spin_unlock(&dcache_lock); | 205 | spin_unlock(&autofs4_lock); |
205 | rcu_read_unlock(); | 206 | rcu_read_unlock(); |
206 | if (read_seqretry(&rename_lock, seq)) | 207 | if (read_seqretry(&rename_lock, seq)) |
207 | goto rename_retry; | 208 | goto rename_retry; |
@@ -217,7 +218,7 @@ rename_retry: | |||
217 | p -= tmp->d_name.len; | 218 | p -= tmp->d_name.len; |
218 | strncpy(p, tmp->d_name.name, tmp->d_name.len); | 219 | strncpy(p, tmp->d_name.name, tmp->d_name.len); |
219 | } | 220 | } |
220 | spin_unlock(&dcache_lock); | 221 | spin_unlock(&autofs4_lock); |
221 | rcu_read_unlock(); | 222 | rcu_read_unlock(); |
222 | if (read_seqretry(&rename_lock, seq)) | 223 | if (read_seqretry(&rename_lock, seq)) |
223 | goto rename_retry; | 224 | goto rename_retry; |
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 2c924e8d85fe..58abc3da6111 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -112,7 +112,6 @@ static int __dcache_readdir(struct file *filp, | |||
112 | dout("__dcache_readdir %p at %llu (last %p)\n", dir, filp->f_pos, | 112 | dout("__dcache_readdir %p at %llu (last %p)\n", dir, filp->f_pos, |
113 | last); | 113 | last); |
114 | 114 | ||
115 | spin_lock(&dcache_lock); | ||
116 | spin_lock(&parent->d_lock); | 115 | spin_lock(&parent->d_lock); |
117 | 116 | ||
118 | /* start at beginning? */ | 117 | /* start at beginning? */ |
@@ -156,7 +155,6 @@ more: | |||
156 | dget_dlock(dentry); | 155 | dget_dlock(dentry); |
157 | spin_unlock(&dentry->d_lock); | 156 | spin_unlock(&dentry->d_lock); |
158 | spin_unlock(&parent->d_lock); | 157 | spin_unlock(&parent->d_lock); |
159 | spin_unlock(&dcache_lock); | ||
160 | 158 | ||
161 | dout(" %llu (%llu) dentry %p %.*s %p\n", di->offset, filp->f_pos, | 159 | dout(" %llu (%llu) dentry %p %.*s %p\n", di->offset, filp->f_pos, |
162 | dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_inode); | 160 | dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_inode); |
@@ -182,21 +180,19 @@ more: | |||
182 | 180 | ||
183 | filp->f_pos++; | 181 | filp->f_pos++; |
184 | 182 | ||
185 | /* make sure a dentry wasn't dropped while we didn't have dcache_lock */ | 183 | /* make sure a dentry wasn't dropped while we didn't have parent lock */ |
186 | if (!ceph_i_test(dir, CEPH_I_COMPLETE)) { | 184 | if (!ceph_i_test(dir, CEPH_I_COMPLETE)) { |
187 | dout(" lost I_COMPLETE on %p; falling back to mds\n", dir); | 185 | dout(" lost I_COMPLETE on %p; falling back to mds\n", dir); |
188 | err = -EAGAIN; | 186 | err = -EAGAIN; |
189 | goto out; | 187 | goto out; |
190 | } | 188 | } |
191 | 189 | ||
192 | spin_lock(&dcache_lock); | ||
193 | spin_lock(&parent->d_lock); | 190 | spin_lock(&parent->d_lock); |
194 | p = p->prev; /* advance to next dentry */ | 191 | p = p->prev; /* advance to next dentry */ |
195 | goto more; | 192 | goto more; |
196 | 193 | ||
197 | out_unlock: | 194 | out_unlock: |
198 | spin_unlock(&parent->d_lock); | 195 | spin_unlock(&parent->d_lock); |
199 | spin_unlock(&dcache_lock); | ||
200 | out: | 196 | out: |
201 | if (last) | 197 | if (last) |
202 | dput(last); | 198 | dput(last); |
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 2c6944473366..2a48cafc174b 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
@@ -841,7 +841,6 @@ static void ceph_set_dentry_offset(struct dentry *dn) | |||
841 | di->offset = ceph_inode(inode)->i_max_offset++; | 841 | di->offset = ceph_inode(inode)->i_max_offset++; |
842 | spin_unlock(&inode->i_lock); | 842 | spin_unlock(&inode->i_lock); |
843 | 843 | ||
844 | spin_lock(&dcache_lock); | ||
845 | spin_lock(&dir->d_lock); | 844 | spin_lock(&dir->d_lock); |
846 | spin_lock_nested(&dn->d_lock, DENTRY_D_LOCK_NESTED); | 845 | spin_lock_nested(&dn->d_lock, DENTRY_D_LOCK_NESTED); |
847 | list_move(&dn->d_u.d_child, &dir->d_subdirs); | 846 | list_move(&dn->d_u.d_child, &dir->d_subdirs); |
@@ -849,7 +848,6 @@ static void ceph_set_dentry_offset(struct dentry *dn) | |||
849 | dn->d_u.d_child.prev, dn->d_u.d_child.next); | 848 | dn->d_u.d_child.prev, dn->d_u.d_child.next); |
850 | spin_unlock(&dn->d_lock); | 849 | spin_unlock(&dn->d_lock); |
851 | spin_unlock(&dir->d_lock); | 850 | spin_unlock(&dir->d_lock); |
852 | spin_unlock(&dcache_lock); | ||
853 | } | 851 | } |
854 | 852 | ||
855 | /* | 853 | /* |
@@ -1233,13 +1231,11 @@ retry_lookup: | |||
1233 | goto retry_lookup; | 1231 | goto retry_lookup; |
1234 | } else { | 1232 | } else { |
1235 | /* reorder parent's d_subdirs */ | 1233 | /* reorder parent's d_subdirs */ |
1236 | spin_lock(&dcache_lock); | ||
1237 | spin_lock(&parent->d_lock); | 1234 | spin_lock(&parent->d_lock); |
1238 | spin_lock_nested(&dn->d_lock, DENTRY_D_LOCK_NESTED); | 1235 | spin_lock_nested(&dn->d_lock, DENTRY_D_LOCK_NESTED); |
1239 | list_move(&dn->d_u.d_child, &parent->d_subdirs); | 1236 | list_move(&dn->d_u.d_child, &parent->d_subdirs); |
1240 | spin_unlock(&dn->d_lock); | 1237 | spin_unlock(&dn->d_lock); |
1241 | spin_unlock(&parent->d_lock); | 1238 | spin_unlock(&parent->d_lock); |
1242 | spin_unlock(&dcache_lock); | ||
1243 | } | 1239 | } |
1244 | 1240 | ||
1245 | di = dn->d_fsdata; | 1241 | di = dn->d_fsdata; |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 003698365ece..99b9a2cc14b7 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -809,17 +809,14 @@ inode_has_hashed_dentries(struct inode *inode) | |||
809 | { | 809 | { |
810 | struct dentry *dentry; | 810 | struct dentry *dentry; |
811 | 811 | ||
812 | spin_lock(&dcache_lock); | ||
813 | spin_lock(&dcache_inode_lock); | 812 | spin_lock(&dcache_inode_lock); |
814 | list_for_each_entry(dentry, &inode->i_dentry, d_alias) { | 813 | list_for_each_entry(dentry, &inode->i_dentry, d_alias) { |
815 | if (!d_unhashed(dentry) || IS_ROOT(dentry)) { | 814 | if (!d_unhashed(dentry) || IS_ROOT(dentry)) { |
816 | spin_unlock(&dcache_inode_lock); | 815 | spin_unlock(&dcache_inode_lock); |
817 | spin_unlock(&dcache_lock); | ||
818 | return true; | 816 | return true; |
819 | } | 817 | } |
820 | } | 818 | } |
821 | spin_unlock(&dcache_inode_lock); | 819 | spin_unlock(&dcache_inode_lock); |
822 | spin_unlock(&dcache_lock); | ||
823 | return false; | 820 | return false; |
824 | } | 821 | } |
825 | 822 | ||
diff --git a/fs/coda/cache.c b/fs/coda/cache.c index 859393fca2b7..5525e1c660fd 100644 --- a/fs/coda/cache.c +++ b/fs/coda/cache.c | |||
@@ -93,7 +93,6 @@ static void coda_flag_children(struct dentry *parent, int flag) | |||
93 | struct list_head *child; | 93 | struct list_head *child; |
94 | struct dentry *de; | 94 | struct dentry *de; |
95 | 95 | ||
96 | spin_lock(&dcache_lock); | ||
97 | spin_lock(&parent->d_lock); | 96 | spin_lock(&parent->d_lock); |
98 | list_for_each(child, &parent->d_subdirs) | 97 | list_for_each(child, &parent->d_subdirs) |
99 | { | 98 | { |
@@ -104,7 +103,6 @@ static void coda_flag_children(struct dentry *parent, int flag) | |||
104 | coda_flag_inode(de->d_inode, flag); | 103 | coda_flag_inode(de->d_inode, flag); |
105 | } | 104 | } |
106 | spin_unlock(&parent->d_lock); | 105 | spin_unlock(&parent->d_lock); |
107 | spin_unlock(&dcache_lock); | ||
108 | return; | 106 | return; |
109 | } | 107 | } |
110 | 108 | ||
diff --git a/fs/configfs/configfs_internal.h b/fs/configfs/configfs_internal.h index e58b4c30e216..026cf68553a4 100644 --- a/fs/configfs/configfs_internal.h +++ b/fs/configfs/configfs_internal.h | |||
@@ -120,7 +120,6 @@ static inline struct config_item *configfs_get_config_item(struct dentry *dentry | |||
120 | { | 120 | { |
121 | struct config_item * item = NULL; | 121 | struct config_item * item = NULL; |
122 | 122 | ||
123 | spin_lock(&dcache_lock); | ||
124 | spin_lock(&dentry->d_lock); | 123 | spin_lock(&dentry->d_lock); |
125 | if (!d_unhashed(dentry)) { | 124 | if (!d_unhashed(dentry)) { |
126 | struct configfs_dirent * sd = dentry->d_fsdata; | 125 | struct configfs_dirent * sd = dentry->d_fsdata; |
@@ -131,7 +130,6 @@ static inline struct config_item *configfs_get_config_item(struct dentry *dentry | |||
131 | item = config_item_get(sd->s_element); | 130 | item = config_item_get(sd->s_element); |
132 | } | 131 | } |
133 | spin_unlock(&dentry->d_lock); | 132 | spin_unlock(&dentry->d_lock); |
134 | spin_unlock(&dcache_lock); | ||
135 | 133 | ||
136 | return item; | 134 | return item; |
137 | } | 135 | } |
diff --git a/fs/configfs/inode.c b/fs/configfs/inode.c index 79b37765d8ff..fb3a55fff82a 100644 --- a/fs/configfs/inode.c +++ b/fs/configfs/inode.c | |||
@@ -250,18 +250,14 @@ void configfs_drop_dentry(struct configfs_dirent * sd, struct dentry * parent) | |||
250 | struct dentry * dentry = sd->s_dentry; | 250 | struct dentry * dentry = sd->s_dentry; |
251 | 251 | ||
252 | if (dentry) { | 252 | if (dentry) { |
253 | spin_lock(&dcache_lock); | ||
254 | spin_lock(&dentry->d_lock); | 253 | spin_lock(&dentry->d_lock); |
255 | if (!(d_unhashed(dentry) && dentry->d_inode)) { | 254 | if (!(d_unhashed(dentry) && dentry->d_inode)) { |
256 | dget_locked_dlock(dentry); | 255 | dget_locked_dlock(dentry); |
257 | __d_drop(dentry); | 256 | __d_drop(dentry); |
258 | spin_unlock(&dentry->d_lock); | 257 | spin_unlock(&dentry->d_lock); |
259 | spin_unlock(&dcache_lock); | ||
260 | simple_unlink(parent->d_inode, dentry); | 258 | simple_unlink(parent->d_inode, dentry); |
261 | } else { | 259 | } else |
262 | spin_unlock(&dentry->d_lock); | 260 | spin_unlock(&dentry->d_lock); |
263 | spin_unlock(&dcache_lock); | ||
264 | } | ||
265 | } | 261 | } |
266 | } | 262 | } |
267 | 263 | ||
diff --git a/fs/dcache.c b/fs/dcache.c index a9bc4ecc21e1..0dbae053b664 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -54,11 +54,10 @@ | |||
54 | * - d_alias, d_inode | 54 | * - d_alias, d_inode |
55 | * | 55 | * |
56 | * Ordering: | 56 | * Ordering: |
57 | * dcache_lock | 57 | * dcache_inode_lock |
58 | * dcache_inode_lock | 58 | * dentry->d_lock |
59 | * dentry->d_lock | 59 | * dcache_lru_lock |
60 | * dcache_lru_lock | 60 | * dcache_hash_lock |
61 | * dcache_hash_lock | ||
62 | * | 61 | * |
63 | * If there is an ancestor relationship: | 62 | * If there is an ancestor relationship: |
64 | * dentry->d_parent->...->d_parent->d_lock | 63 | * dentry->d_parent->...->d_parent->d_lock |
@@ -77,12 +76,10 @@ EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure); | |||
77 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_inode_lock); | 76 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_inode_lock); |
78 | static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_hash_lock); | 77 | static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_hash_lock); |
79 | static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lru_lock); | 78 | static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lru_lock); |
80 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lock); | ||
81 | __cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock); | 79 | __cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock); |
82 | 80 | ||
83 | EXPORT_SYMBOL(rename_lock); | 81 | EXPORT_SYMBOL(rename_lock); |
84 | EXPORT_SYMBOL(dcache_inode_lock); | 82 | EXPORT_SYMBOL(dcache_inode_lock); |
85 | EXPORT_SYMBOL(dcache_lock); | ||
86 | 83 | ||
87 | static struct kmem_cache *dentry_cache __read_mostly; | 84 | static struct kmem_cache *dentry_cache __read_mostly; |
88 | 85 | ||
@@ -139,7 +136,7 @@ static void __d_free(struct rcu_head *head) | |||
139 | } | 136 | } |
140 | 137 | ||
141 | /* | 138 | /* |
142 | * no dcache_lock, please. | 139 | * no locks, please. |
143 | */ | 140 | */ |
144 | static void d_free(struct dentry *dentry) | 141 | static void d_free(struct dentry *dentry) |
145 | { | 142 | { |
@@ -162,7 +159,6 @@ static void d_free(struct dentry *dentry) | |||
162 | static void dentry_iput(struct dentry * dentry) | 159 | static void dentry_iput(struct dentry * dentry) |
163 | __releases(dentry->d_lock) | 160 | __releases(dentry->d_lock) |
164 | __releases(dcache_inode_lock) | 161 | __releases(dcache_inode_lock) |
165 | __releases(dcache_lock) | ||
166 | { | 162 | { |
167 | struct inode *inode = dentry->d_inode; | 163 | struct inode *inode = dentry->d_inode; |
168 | if (inode) { | 164 | if (inode) { |
@@ -170,7 +166,6 @@ static void dentry_iput(struct dentry * dentry) | |||
170 | list_del_init(&dentry->d_alias); | 166 | list_del_init(&dentry->d_alias); |
171 | spin_unlock(&dentry->d_lock); | 167 | spin_unlock(&dentry->d_lock); |
172 | spin_unlock(&dcache_inode_lock); | 168 | spin_unlock(&dcache_inode_lock); |
173 | spin_unlock(&dcache_lock); | ||
174 | if (!inode->i_nlink) | 169 | if (!inode->i_nlink) |
175 | fsnotify_inoderemove(inode); | 170 | fsnotify_inoderemove(inode); |
176 | if (dentry->d_op && dentry->d_op->d_iput) | 171 | if (dentry->d_op && dentry->d_op->d_iput) |
@@ -180,7 +175,6 @@ static void dentry_iput(struct dentry * dentry) | |||
180 | } else { | 175 | } else { |
181 | spin_unlock(&dentry->d_lock); | 176 | spin_unlock(&dentry->d_lock); |
182 | spin_unlock(&dcache_inode_lock); | 177 | spin_unlock(&dcache_inode_lock); |
183 | spin_unlock(&dcache_lock); | ||
184 | } | 178 | } |
185 | } | 179 | } |
186 | 180 | ||
@@ -235,14 +229,13 @@ static void dentry_lru_move_tail(struct dentry *dentry) | |||
235 | * | 229 | * |
236 | * If this is the root of the dentry tree, return NULL. | 230 | * If this is the root of the dentry tree, return NULL. |
237 | * | 231 | * |
238 | * dcache_lock and d_lock and d_parent->d_lock must be held by caller, and | 232 | * dentry->d_lock and parent->d_lock must be held by caller, and are dropped by |
239 | * are dropped by d_kill. | 233 | * d_kill. |
240 | */ | 234 | */ |
241 | static struct dentry *d_kill(struct dentry *dentry, struct dentry *parent) | 235 | static struct dentry *d_kill(struct dentry *dentry, struct dentry *parent) |
242 | __releases(dentry->d_lock) | 236 | __releases(dentry->d_lock) |
243 | __releases(parent->d_lock) | 237 | __releases(parent->d_lock) |
244 | __releases(dcache_inode_lock) | 238 | __releases(dcache_inode_lock) |
245 | __releases(dcache_lock) | ||
246 | { | 239 | { |
247 | dentry->d_parent = NULL; | 240 | dentry->d_parent = NULL; |
248 | list_del(&dentry->d_u.d_child); | 241 | list_del(&dentry->d_u.d_child); |
@@ -285,11 +278,9 @@ EXPORT_SYMBOL(__d_drop); | |||
285 | 278 | ||
286 | void d_drop(struct dentry *dentry) | 279 | void d_drop(struct dentry *dentry) |
287 | { | 280 | { |
288 | spin_lock(&dcache_lock); | ||
289 | spin_lock(&dentry->d_lock); | 281 | spin_lock(&dentry->d_lock); |
290 | __d_drop(dentry); | 282 | __d_drop(dentry); |
291 | spin_unlock(&dentry->d_lock); | 283 | spin_unlock(&dentry->d_lock); |
292 | spin_unlock(&dcache_lock); | ||
293 | } | 284 | } |
294 | EXPORT_SYMBOL(d_drop); | 285 | EXPORT_SYMBOL(d_drop); |
295 | 286 | ||
@@ -337,21 +328,10 @@ repeat: | |||
337 | else | 328 | else |
338 | parent = dentry->d_parent; | 329 | parent = dentry->d_parent; |
339 | if (dentry->d_count == 1) { | 330 | if (dentry->d_count == 1) { |
340 | if (!spin_trylock(&dcache_lock)) { | ||
341 | /* | ||
342 | * Something of a livelock possibility we could avoid | ||
343 | * by taking dcache_lock and trying again, but we | ||
344 | * want to reduce dcache_lock anyway so this will | ||
345 | * get improved. | ||
346 | */ | ||
347 | drop1: | ||
348 | spin_unlock(&dentry->d_lock); | ||
349 | goto repeat; | ||
350 | } | ||
351 | if (!spin_trylock(&dcache_inode_lock)) { | 331 | if (!spin_trylock(&dcache_inode_lock)) { |
352 | drop2: | 332 | drop2: |
353 | spin_unlock(&dcache_lock); | 333 | spin_unlock(&dentry->d_lock); |
354 | goto drop1; | 334 | goto repeat; |
355 | } | 335 | } |
356 | if (parent && !spin_trylock(&parent->d_lock)) { | 336 | if (parent && !spin_trylock(&parent->d_lock)) { |
357 | spin_unlock(&dcache_inode_lock); | 337 | spin_unlock(&dcache_inode_lock); |
@@ -363,7 +343,6 @@ drop2: | |||
363 | spin_unlock(&dentry->d_lock); | 343 | spin_unlock(&dentry->d_lock); |
364 | if (parent) | 344 | if (parent) |
365 | spin_unlock(&parent->d_lock); | 345 | spin_unlock(&parent->d_lock); |
366 | spin_unlock(&dcache_lock); | ||
367 | return; | 346 | return; |
368 | } | 347 | } |
369 | 348 | ||
@@ -387,7 +366,6 @@ drop2: | |||
387 | if (parent) | 366 | if (parent) |
388 | spin_unlock(&parent->d_lock); | 367 | spin_unlock(&parent->d_lock); |
389 | spin_unlock(&dcache_inode_lock); | 368 | spin_unlock(&dcache_inode_lock); |
390 | spin_unlock(&dcache_lock); | ||
391 | return; | 369 | return; |
392 | 370 | ||
393 | unhash_it: | 371 | unhash_it: |
@@ -418,11 +396,9 @@ int d_invalidate(struct dentry * dentry) | |||
418 | /* | 396 | /* |
419 | * If it's already been dropped, return OK. | 397 | * If it's already been dropped, return OK. |
420 | */ | 398 | */ |
421 | spin_lock(&dcache_lock); | ||
422 | spin_lock(&dentry->d_lock); | 399 | spin_lock(&dentry->d_lock); |
423 | if (d_unhashed(dentry)) { | 400 | if (d_unhashed(dentry)) { |
424 | spin_unlock(&dentry->d_lock); | 401 | spin_unlock(&dentry->d_lock); |
425 | spin_unlock(&dcache_lock); | ||
426 | return 0; | 402 | return 0; |
427 | } | 403 | } |
428 | /* | 404 | /* |
@@ -431,9 +407,7 @@ int d_invalidate(struct dentry * dentry) | |||
431 | */ | 407 | */ |
432 | if (!list_empty(&dentry->d_subdirs)) { | 408 | if (!list_empty(&dentry->d_subdirs)) { |
433 | spin_unlock(&dentry->d_lock); | 409 | spin_unlock(&dentry->d_lock); |
434 | spin_unlock(&dcache_lock); | ||
435 | shrink_dcache_parent(dentry); | 410 | shrink_dcache_parent(dentry); |
436 | spin_lock(&dcache_lock); | ||
437 | spin_lock(&dentry->d_lock); | 411 | spin_lock(&dentry->d_lock); |
438 | } | 412 | } |
439 | 413 | ||
@@ -450,19 +424,17 @@ int d_invalidate(struct dentry * dentry) | |||
450 | if (dentry->d_count > 1) { | 424 | if (dentry->d_count > 1) { |
451 | if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)) { | 425 | if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)) { |
452 | spin_unlock(&dentry->d_lock); | 426 | spin_unlock(&dentry->d_lock); |
453 | spin_unlock(&dcache_lock); | ||
454 | return -EBUSY; | 427 | return -EBUSY; |
455 | } | 428 | } |
456 | } | 429 | } |
457 | 430 | ||
458 | __d_drop(dentry); | 431 | __d_drop(dentry); |
459 | spin_unlock(&dentry->d_lock); | 432 | spin_unlock(&dentry->d_lock); |
460 | spin_unlock(&dcache_lock); | ||
461 | return 0; | 433 | return 0; |
462 | } | 434 | } |
463 | EXPORT_SYMBOL(d_invalidate); | 435 | EXPORT_SYMBOL(d_invalidate); |
464 | 436 | ||
465 | /* This must be called with dcache_lock and d_lock held */ | 437 | /* This must be called with d_lock held */ |
466 | static inline struct dentry * __dget_locked_dlock(struct dentry *dentry) | 438 | static inline struct dentry * __dget_locked_dlock(struct dentry *dentry) |
467 | { | 439 | { |
468 | dentry->d_count++; | 440 | dentry->d_count++; |
@@ -470,7 +442,7 @@ static inline struct dentry * __dget_locked_dlock(struct dentry *dentry) | |||
470 | return dentry; | 442 | return dentry; |
471 | } | 443 | } |
472 | 444 | ||
473 | /* This should be called _only_ with dcache_lock held */ | 445 | /* This must be called with d_lock held */ |
474 | static inline struct dentry * __dget_locked(struct dentry *dentry) | 446 | static inline struct dentry * __dget_locked(struct dentry *dentry) |
475 | { | 447 | { |
476 | spin_lock(&dentry->d_lock); | 448 | spin_lock(&dentry->d_lock); |
@@ -575,11 +547,9 @@ struct dentry *d_find_alias(struct inode *inode) | |||
575 | struct dentry *de = NULL; | 547 | struct dentry *de = NULL; |
576 | 548 | ||
577 | if (!list_empty(&inode->i_dentry)) { | 549 | if (!list_empty(&inode->i_dentry)) { |
578 | spin_lock(&dcache_lock); | ||
579 | spin_lock(&dcache_inode_lock); | 550 | spin_lock(&dcache_inode_lock); |
580 | de = __d_find_alias(inode, 0); | 551 | de = __d_find_alias(inode, 0); |
581 | spin_unlock(&dcache_inode_lock); | 552 | spin_unlock(&dcache_inode_lock); |
582 | spin_unlock(&dcache_lock); | ||
583 | } | 553 | } |
584 | return de; | 554 | return de; |
585 | } | 555 | } |
@@ -593,7 +563,6 @@ void d_prune_aliases(struct inode *inode) | |||
593 | { | 563 | { |
594 | struct dentry *dentry; | 564 | struct dentry *dentry; |
595 | restart: | 565 | restart: |
596 | spin_lock(&dcache_lock); | ||
597 | spin_lock(&dcache_inode_lock); | 566 | spin_lock(&dcache_inode_lock); |
598 | list_for_each_entry(dentry, &inode->i_dentry, d_alias) { | 567 | list_for_each_entry(dentry, &inode->i_dentry, d_alias) { |
599 | spin_lock(&dentry->d_lock); | 568 | spin_lock(&dentry->d_lock); |
@@ -602,14 +571,12 @@ restart: | |||
602 | __d_drop(dentry); | 571 | __d_drop(dentry); |
603 | spin_unlock(&dentry->d_lock); | 572 | spin_unlock(&dentry->d_lock); |
604 | spin_unlock(&dcache_inode_lock); | 573 | spin_unlock(&dcache_inode_lock); |
605 | spin_unlock(&dcache_lock); | ||
606 | dput(dentry); | 574 | dput(dentry); |
607 | goto restart; | 575 | goto restart; |
608 | } | 576 | } |
609 | spin_unlock(&dentry->d_lock); | 577 | spin_unlock(&dentry->d_lock); |
610 | } | 578 | } |
611 | spin_unlock(&dcache_inode_lock); | 579 | spin_unlock(&dcache_inode_lock); |
612 | spin_unlock(&dcache_lock); | ||
613 | } | 580 | } |
614 | EXPORT_SYMBOL(d_prune_aliases); | 581 | EXPORT_SYMBOL(d_prune_aliases); |
615 | 582 | ||
@@ -625,17 +592,14 @@ static void prune_one_dentry(struct dentry *dentry, struct dentry *parent) | |||
625 | __releases(dentry->d_lock) | 592 | __releases(dentry->d_lock) |
626 | __releases(parent->d_lock) | 593 | __releases(parent->d_lock) |
627 | __releases(dcache_inode_lock) | 594 | __releases(dcache_inode_lock) |
628 | __releases(dcache_lock) | ||
629 | { | 595 | { |
630 | __d_drop(dentry); | 596 | __d_drop(dentry); |
631 | dentry = d_kill(dentry, parent); | 597 | dentry = d_kill(dentry, parent); |
632 | 598 | ||
633 | /* | 599 | /* |
634 | * Prune ancestors. Locking is simpler than in dput(), | 600 | * Prune ancestors. |
635 | * because dcache_lock needs to be taken anyway. | ||
636 | */ | 601 | */ |
637 | while (dentry) { | 602 | while (dentry) { |
638 | spin_lock(&dcache_lock); | ||
639 | spin_lock(&dcache_inode_lock); | 603 | spin_lock(&dcache_inode_lock); |
640 | again: | 604 | again: |
641 | spin_lock(&dentry->d_lock); | 605 | spin_lock(&dentry->d_lock); |
@@ -653,7 +617,6 @@ again: | |||
653 | spin_unlock(&parent->d_lock); | 617 | spin_unlock(&parent->d_lock); |
654 | spin_unlock(&dentry->d_lock); | 618 | spin_unlock(&dentry->d_lock); |
655 | spin_unlock(&dcache_inode_lock); | 619 | spin_unlock(&dcache_inode_lock); |
656 | spin_unlock(&dcache_lock); | ||
657 | return; | 620 | return; |
658 | } | 621 | } |
659 | 622 | ||
@@ -702,8 +665,7 @@ relock: | |||
702 | spin_unlock(&dcache_lru_lock); | 665 | spin_unlock(&dcache_lru_lock); |
703 | 666 | ||
704 | prune_one_dentry(dentry, parent); | 667 | prune_one_dentry(dentry, parent); |
705 | /* dcache_lock, dcache_inode_lock and dentry->d_lock dropped */ | 668 | /* dcache_inode_lock and dentry->d_lock dropped */ |
706 | spin_lock(&dcache_lock); | ||
707 | spin_lock(&dcache_inode_lock); | 669 | spin_lock(&dcache_inode_lock); |
708 | spin_lock(&dcache_lru_lock); | 670 | spin_lock(&dcache_lru_lock); |
709 | } | 671 | } |
@@ -725,7 +687,6 @@ static void __shrink_dcache_sb(struct super_block *sb, int *count, int flags) | |||
725 | LIST_HEAD(tmp); | 687 | LIST_HEAD(tmp); |
726 | int cnt = *count; | 688 | int cnt = *count; |
727 | 689 | ||
728 | spin_lock(&dcache_lock); | ||
729 | spin_lock(&dcache_inode_lock); | 690 | spin_lock(&dcache_inode_lock); |
730 | relock: | 691 | relock: |
731 | spin_lock(&dcache_lru_lock); | 692 | spin_lock(&dcache_lru_lock); |
@@ -766,7 +727,6 @@ relock: | |||
766 | list_splice(&referenced, &sb->s_dentry_lru); | 727 | list_splice(&referenced, &sb->s_dentry_lru); |
767 | spin_unlock(&dcache_lru_lock); | 728 | spin_unlock(&dcache_lru_lock); |
768 | spin_unlock(&dcache_inode_lock); | 729 | spin_unlock(&dcache_inode_lock); |
769 | spin_unlock(&dcache_lock); | ||
770 | } | 730 | } |
771 | 731 | ||
772 | /** | 732 | /** |
@@ -788,7 +748,6 @@ static void prune_dcache(int count) | |||
788 | 748 | ||
789 | if (unused == 0 || count == 0) | 749 | if (unused == 0 || count == 0) |
790 | return; | 750 | return; |
791 | spin_lock(&dcache_lock); | ||
792 | if (count >= unused) | 751 | if (count >= unused) |
793 | prune_ratio = 1; | 752 | prune_ratio = 1; |
794 | else | 753 | else |
@@ -825,11 +784,9 @@ static void prune_dcache(int count) | |||
825 | if (down_read_trylock(&sb->s_umount)) { | 784 | if (down_read_trylock(&sb->s_umount)) { |
826 | if ((sb->s_root != NULL) && | 785 | if ((sb->s_root != NULL) && |
827 | (!list_empty(&sb->s_dentry_lru))) { | 786 | (!list_empty(&sb->s_dentry_lru))) { |
828 | spin_unlock(&dcache_lock); | ||
829 | __shrink_dcache_sb(sb, &w_count, | 787 | __shrink_dcache_sb(sb, &w_count, |
830 | DCACHE_REFERENCED); | 788 | DCACHE_REFERENCED); |
831 | pruned -= w_count; | 789 | pruned -= w_count; |
832 | spin_lock(&dcache_lock); | ||
833 | } | 790 | } |
834 | up_read(&sb->s_umount); | 791 | up_read(&sb->s_umount); |
835 | } | 792 | } |
@@ -845,7 +802,6 @@ static void prune_dcache(int count) | |||
845 | if (p) | 802 | if (p) |
846 | __put_super(p); | 803 | __put_super(p); |
847 | spin_unlock(&sb_lock); | 804 | spin_unlock(&sb_lock); |
848 | spin_unlock(&dcache_lock); | ||
849 | } | 805 | } |
850 | 806 | ||
851 | /** | 807 | /** |
@@ -859,7 +815,6 @@ void shrink_dcache_sb(struct super_block *sb) | |||
859 | { | 815 | { |
860 | LIST_HEAD(tmp); | 816 | LIST_HEAD(tmp); |
861 | 817 | ||
862 | spin_lock(&dcache_lock); | ||
863 | spin_lock(&dcache_inode_lock); | 818 | spin_lock(&dcache_inode_lock); |
864 | spin_lock(&dcache_lru_lock); | 819 | spin_lock(&dcache_lru_lock); |
865 | while (!list_empty(&sb->s_dentry_lru)) { | 820 | while (!list_empty(&sb->s_dentry_lru)) { |
@@ -868,7 +823,6 @@ void shrink_dcache_sb(struct super_block *sb) | |||
868 | } | 823 | } |
869 | spin_unlock(&dcache_lru_lock); | 824 | spin_unlock(&dcache_lru_lock); |
870 | spin_unlock(&dcache_inode_lock); | 825 | spin_unlock(&dcache_inode_lock); |
871 | spin_unlock(&dcache_lock); | ||
872 | } | 826 | } |
873 | EXPORT_SYMBOL(shrink_dcache_sb); | 827 | EXPORT_SYMBOL(shrink_dcache_sb); |
874 | 828 | ||
@@ -885,12 +839,10 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry) | |||
885 | BUG_ON(!IS_ROOT(dentry)); | 839 | BUG_ON(!IS_ROOT(dentry)); |
886 | 840 | ||
887 | /* detach this root from the system */ | 841 | /* detach this root from the system */ |
888 | spin_lock(&dcache_lock); | ||
889 | spin_lock(&dentry->d_lock); | 842 | spin_lock(&dentry->d_lock); |
890 | dentry_lru_del(dentry); | 843 | dentry_lru_del(dentry); |
891 | __d_drop(dentry); | 844 | __d_drop(dentry); |
892 | spin_unlock(&dentry->d_lock); | 845 | spin_unlock(&dentry->d_lock); |
893 | spin_unlock(&dcache_lock); | ||
894 | 846 | ||
895 | for (;;) { | 847 | for (;;) { |
896 | /* descend to the first leaf in the current subtree */ | 848 | /* descend to the first leaf in the current subtree */ |
@@ -899,7 +851,6 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry) | |||
899 | 851 | ||
900 | /* this is a branch with children - detach all of them | 852 | /* this is a branch with children - detach all of them |
901 | * from the system in one go */ | 853 | * from the system in one go */ |
902 | spin_lock(&dcache_lock); | ||
903 | spin_lock(&dentry->d_lock); | 854 | spin_lock(&dentry->d_lock); |
904 | list_for_each_entry(loop, &dentry->d_subdirs, | 855 | list_for_each_entry(loop, &dentry->d_subdirs, |
905 | d_u.d_child) { | 856 | d_u.d_child) { |
@@ -910,7 +861,6 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry) | |||
910 | spin_unlock(&loop->d_lock); | 861 | spin_unlock(&loop->d_lock); |
911 | } | 862 | } |
912 | spin_unlock(&dentry->d_lock); | 863 | spin_unlock(&dentry->d_lock); |
913 | spin_unlock(&dcache_lock); | ||
914 | 864 | ||
915 | /* move to the first child */ | 865 | /* move to the first child */ |
916 | dentry = list_entry(dentry->d_subdirs.next, | 866 | dentry = list_entry(dentry->d_subdirs.next, |
@@ -977,8 +927,7 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry) | |||
977 | 927 | ||
978 | /* | 928 | /* |
979 | * destroy the dentries attached to a superblock on unmounting | 929 | * destroy the dentries attached to a superblock on unmounting |
980 | * - we don't need to use dentry->d_lock, and only need dcache_lock when | 930 | * - we don't need to use dentry->d_lock because: |
981 | * removing the dentry from the system lists and hashes because: | ||
982 | * - the superblock is detached from all mountings and open files, so the | 931 | * - the superblock is detached from all mountings and open files, so the |
983 | * dentry trees will not be rearranged by the VFS | 932 | * dentry trees will not be rearranged by the VFS |
984 | * - s_umount is write-locked, so the memory pressure shrinker will ignore | 933 | * - s_umount is write-locked, so the memory pressure shrinker will ignore |
@@ -1029,7 +978,6 @@ rename_retry: | |||
1029 | this_parent = parent; | 978 | this_parent = parent; |
1030 | seq = read_seqbegin(&rename_lock); | 979 | seq = read_seqbegin(&rename_lock); |
1031 | 980 | ||
1032 | spin_lock(&dcache_lock); | ||
1033 | if (d_mountpoint(parent)) | 981 | if (d_mountpoint(parent)) |
1034 | goto positive; | 982 | goto positive; |
1035 | spin_lock(&this_parent->d_lock); | 983 | spin_lock(&this_parent->d_lock); |
@@ -1075,7 +1023,6 @@ resume: | |||
1075 | if (this_parent != child->d_parent || | 1023 | if (this_parent != child->d_parent || |
1076 | read_seqretry(&rename_lock, seq)) { | 1024 | read_seqretry(&rename_lock, seq)) { |
1077 | spin_unlock(&this_parent->d_lock); | 1025 | spin_unlock(&this_parent->d_lock); |
1078 | spin_unlock(&dcache_lock); | ||
1079 | rcu_read_unlock(); | 1026 | rcu_read_unlock(); |
1080 | goto rename_retry; | 1027 | goto rename_retry; |
1081 | } | 1028 | } |
@@ -1084,12 +1031,10 @@ resume: | |||
1084 | goto resume; | 1031 | goto resume; |
1085 | } | 1032 | } |
1086 | spin_unlock(&this_parent->d_lock); | 1033 | spin_unlock(&this_parent->d_lock); |
1087 | spin_unlock(&dcache_lock); | ||
1088 | if (read_seqretry(&rename_lock, seq)) | 1034 | if (read_seqretry(&rename_lock, seq)) |
1089 | goto rename_retry; | 1035 | goto rename_retry; |
1090 | return 0; /* No mount points found in tree */ | 1036 | return 0; /* No mount points found in tree */ |
1091 | positive: | 1037 | positive: |
1092 | spin_unlock(&dcache_lock); | ||
1093 | if (read_seqretry(&rename_lock, seq)) | 1038 | if (read_seqretry(&rename_lock, seq)) |
1094 | goto rename_retry; | 1039 | goto rename_retry; |
1095 | return 1; | 1040 | return 1; |
@@ -1121,7 +1066,6 @@ rename_retry: | |||
1121 | this_parent = parent; | 1066 | this_parent = parent; |
1122 | seq = read_seqbegin(&rename_lock); | 1067 | seq = read_seqbegin(&rename_lock); |
1123 | 1068 | ||
1124 | spin_lock(&dcache_lock); | ||
1125 | spin_lock(&this_parent->d_lock); | 1069 | spin_lock(&this_parent->d_lock); |
1126 | repeat: | 1070 | repeat: |
1127 | next = this_parent->d_subdirs.next; | 1071 | next = this_parent->d_subdirs.next; |
@@ -1185,7 +1129,6 @@ resume: | |||
1185 | if (this_parent != child->d_parent || | 1129 | if (this_parent != child->d_parent || |
1186 | read_seqretry(&rename_lock, seq)) { | 1130 | read_seqretry(&rename_lock, seq)) { |
1187 | spin_unlock(&this_parent->d_lock); | 1131 | spin_unlock(&this_parent->d_lock); |
1188 | spin_unlock(&dcache_lock); | ||
1189 | rcu_read_unlock(); | 1132 | rcu_read_unlock(); |
1190 | goto rename_retry; | 1133 | goto rename_retry; |
1191 | } | 1134 | } |
@@ -1195,7 +1138,6 @@ resume: | |||
1195 | } | 1138 | } |
1196 | out: | 1139 | out: |
1197 | spin_unlock(&this_parent->d_lock); | 1140 | spin_unlock(&this_parent->d_lock); |
1198 | spin_unlock(&dcache_lock); | ||
1199 | if (read_seqretry(&rename_lock, seq)) | 1141 | if (read_seqretry(&rename_lock, seq)) |
1200 | goto rename_retry; | 1142 | goto rename_retry; |
1201 | return found; | 1143 | return found; |
@@ -1297,7 +1239,6 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name) | |||
1297 | INIT_LIST_HEAD(&dentry->d_u.d_child); | 1239 | INIT_LIST_HEAD(&dentry->d_u.d_child); |
1298 | 1240 | ||
1299 | if (parent) { | 1241 | if (parent) { |
1300 | spin_lock(&dcache_lock); | ||
1301 | spin_lock(&parent->d_lock); | 1242 | spin_lock(&parent->d_lock); |
1302 | spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); | 1243 | spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); |
1303 | dentry->d_parent = dget_dlock(parent); | 1244 | dentry->d_parent = dget_dlock(parent); |
@@ -1305,7 +1246,6 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name) | |||
1305 | list_add(&dentry->d_u.d_child, &parent->d_subdirs); | 1246 | list_add(&dentry->d_u.d_child, &parent->d_subdirs); |
1306 | spin_unlock(&dentry->d_lock); | 1247 | spin_unlock(&dentry->d_lock); |
1307 | spin_unlock(&parent->d_lock); | 1248 | spin_unlock(&parent->d_lock); |
1308 | spin_unlock(&dcache_lock); | ||
1309 | } | 1249 | } |
1310 | 1250 | ||
1311 | this_cpu_inc(nr_dentry); | 1251 | this_cpu_inc(nr_dentry); |
@@ -1325,7 +1265,6 @@ struct dentry *d_alloc_name(struct dentry *parent, const char *name) | |||
1325 | } | 1265 | } |
1326 | EXPORT_SYMBOL(d_alloc_name); | 1266 | EXPORT_SYMBOL(d_alloc_name); |
1327 | 1267 | ||
1328 | /* the caller must hold dcache_lock */ | ||
1329 | static void __d_instantiate(struct dentry *dentry, struct inode *inode) | 1268 | static void __d_instantiate(struct dentry *dentry, struct inode *inode) |
1330 | { | 1269 | { |
1331 | spin_lock(&dentry->d_lock); | 1270 | spin_lock(&dentry->d_lock); |
@@ -1354,11 +1293,9 @@ static void __d_instantiate(struct dentry *dentry, struct inode *inode) | |||
1354 | void d_instantiate(struct dentry *entry, struct inode * inode) | 1293 | void d_instantiate(struct dentry *entry, struct inode * inode) |
1355 | { | 1294 | { |
1356 | BUG_ON(!list_empty(&entry->d_alias)); | 1295 | BUG_ON(!list_empty(&entry->d_alias)); |
1357 | spin_lock(&dcache_lock); | ||
1358 | spin_lock(&dcache_inode_lock); | 1296 | spin_lock(&dcache_inode_lock); |
1359 | __d_instantiate(entry, inode); | 1297 | __d_instantiate(entry, inode); |
1360 | spin_unlock(&dcache_inode_lock); | 1298 | spin_unlock(&dcache_inode_lock); |
1361 | spin_unlock(&dcache_lock); | ||
1362 | security_d_instantiate(entry, inode); | 1299 | security_d_instantiate(entry, inode); |
1363 | } | 1300 | } |
1364 | EXPORT_SYMBOL(d_instantiate); | 1301 | EXPORT_SYMBOL(d_instantiate); |
@@ -1422,11 +1359,9 @@ struct dentry *d_instantiate_unique(struct dentry *entry, struct inode *inode) | |||
1422 | 1359 | ||
1423 | BUG_ON(!list_empty(&entry->d_alias)); | 1360 | BUG_ON(!list_empty(&entry->d_alias)); |
1424 | 1361 | ||
1425 | spin_lock(&dcache_lock); | ||
1426 | spin_lock(&dcache_inode_lock); | 1362 | spin_lock(&dcache_inode_lock); |
1427 | result = __d_instantiate_unique(entry, inode); | 1363 | result = __d_instantiate_unique(entry, inode); |
1428 | spin_unlock(&dcache_inode_lock); | 1364 | spin_unlock(&dcache_inode_lock); |
1429 | spin_unlock(&dcache_lock); | ||
1430 | 1365 | ||
1431 | if (!result) { | 1366 | if (!result) { |
1432 | security_d_instantiate(entry, inode); | 1367 | security_d_instantiate(entry, inode); |
@@ -1515,12 +1450,11 @@ struct dentry *d_obtain_alias(struct inode *inode) | |||
1515 | } | 1450 | } |
1516 | tmp->d_parent = tmp; /* make sure dput doesn't croak */ | 1451 | tmp->d_parent = tmp; /* make sure dput doesn't croak */ |
1517 | 1452 | ||
1518 | spin_lock(&dcache_lock); | 1453 | |
1519 | spin_lock(&dcache_inode_lock); | 1454 | spin_lock(&dcache_inode_lock); |
1520 | res = __d_find_alias(inode, 0); | 1455 | res = __d_find_alias(inode, 0); |
1521 | if (res) { | 1456 | if (res) { |
1522 | spin_unlock(&dcache_inode_lock); | 1457 | spin_unlock(&dcache_inode_lock); |
1523 | spin_unlock(&dcache_lock); | ||
1524 | dput(tmp); | 1458 | dput(tmp); |
1525 | goto out_iput; | 1459 | goto out_iput; |
1526 | } | 1460 | } |
@@ -1538,7 +1472,6 @@ struct dentry *d_obtain_alias(struct inode *inode) | |||
1538 | spin_unlock(&tmp->d_lock); | 1472 | spin_unlock(&tmp->d_lock); |
1539 | spin_unlock(&dcache_inode_lock); | 1473 | spin_unlock(&dcache_inode_lock); |
1540 | 1474 | ||
1541 | spin_unlock(&dcache_lock); | ||
1542 | return tmp; | 1475 | return tmp; |
1543 | 1476 | ||
1544 | out_iput: | 1477 | out_iput: |
@@ -1568,21 +1501,18 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry) | |||
1568 | struct dentry *new = NULL; | 1501 | struct dentry *new = NULL; |
1569 | 1502 | ||
1570 | if (inode && S_ISDIR(inode->i_mode)) { | 1503 | if (inode && S_ISDIR(inode->i_mode)) { |
1571 | spin_lock(&dcache_lock); | ||
1572 | spin_lock(&dcache_inode_lock); | 1504 | spin_lock(&dcache_inode_lock); |
1573 | new = __d_find_alias(inode, 1); | 1505 | new = __d_find_alias(inode, 1); |
1574 | if (new) { | 1506 | if (new) { |
1575 | BUG_ON(!(new->d_flags & DCACHE_DISCONNECTED)); | 1507 | BUG_ON(!(new->d_flags & DCACHE_DISCONNECTED)); |
1576 | spin_unlock(&dcache_inode_lock); | 1508 | spin_unlock(&dcache_inode_lock); |
1577 | spin_unlock(&dcache_lock); | ||
1578 | security_d_instantiate(new, inode); | 1509 | security_d_instantiate(new, inode); |
1579 | d_move(new, dentry); | 1510 | d_move(new, dentry); |
1580 | iput(inode); | 1511 | iput(inode); |
1581 | } else { | 1512 | } else { |
1582 | /* already taking dcache_lock, so d_add() by hand */ | 1513 | /* already taking dcache_inode_lock, so d_add() by hand */ |
1583 | __d_instantiate(dentry, inode); | 1514 | __d_instantiate(dentry, inode); |
1584 | spin_unlock(&dcache_inode_lock); | 1515 | spin_unlock(&dcache_inode_lock); |
1585 | spin_unlock(&dcache_lock); | ||
1586 | security_d_instantiate(dentry, inode); | 1516 | security_d_instantiate(dentry, inode); |
1587 | d_rehash(dentry); | 1517 | d_rehash(dentry); |
1588 | } | 1518 | } |
@@ -1655,12 +1585,10 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode, | |||
1655 | * Negative dentry: instantiate it unless the inode is a directory and | 1585 | * Negative dentry: instantiate it unless the inode is a directory and |
1656 | * already has a dentry. | 1586 | * already has a dentry. |
1657 | */ | 1587 | */ |
1658 | spin_lock(&dcache_lock); | ||
1659 | spin_lock(&dcache_inode_lock); | 1588 | spin_lock(&dcache_inode_lock); |
1660 | if (!S_ISDIR(inode->i_mode) || list_empty(&inode->i_dentry)) { | 1589 | if (!S_ISDIR(inode->i_mode) || list_empty(&inode->i_dentry)) { |
1661 | __d_instantiate(found, inode); | 1590 | __d_instantiate(found, inode); |
1662 | spin_unlock(&dcache_inode_lock); | 1591 | spin_unlock(&dcache_inode_lock); |
1663 | spin_unlock(&dcache_lock); | ||
1664 | security_d_instantiate(found, inode); | 1592 | security_d_instantiate(found, inode); |
1665 | return found; | 1593 | return found; |
1666 | } | 1594 | } |
@@ -1672,7 +1600,6 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode, | |||
1672 | new = list_entry(inode->i_dentry.next, struct dentry, d_alias); | 1600 | new = list_entry(inode->i_dentry.next, struct dentry, d_alias); |
1673 | dget_locked(new); | 1601 | dget_locked(new); |
1674 | spin_unlock(&dcache_inode_lock); | 1602 | spin_unlock(&dcache_inode_lock); |
1675 | spin_unlock(&dcache_lock); | ||
1676 | security_d_instantiate(found, inode); | 1603 | security_d_instantiate(found, inode); |
1677 | d_move(new, found); | 1604 | d_move(new, found); |
1678 | iput(inode); | 1605 | iput(inode); |
@@ -1843,7 +1770,6 @@ int d_validate(struct dentry *dentry, struct dentry *dparent) | |||
1843 | { | 1770 | { |
1844 | struct dentry *child; | 1771 | struct dentry *child; |
1845 | 1772 | ||
1846 | spin_lock(&dcache_lock); | ||
1847 | spin_lock(&dparent->d_lock); | 1773 | spin_lock(&dparent->d_lock); |
1848 | list_for_each_entry(child, &dparent->d_subdirs, d_u.d_child) { | 1774 | list_for_each_entry(child, &dparent->d_subdirs, d_u.d_child) { |
1849 | if (dentry == child) { | 1775 | if (dentry == child) { |
@@ -1851,12 +1777,10 @@ int d_validate(struct dentry *dentry, struct dentry *dparent) | |||
1851 | __dget_locked_dlock(dentry); | 1777 | __dget_locked_dlock(dentry); |
1852 | spin_unlock(&dentry->d_lock); | 1778 | spin_unlock(&dentry->d_lock); |
1853 | spin_unlock(&dparent->d_lock); | 1779 | spin_unlock(&dparent->d_lock); |
1854 | spin_unlock(&dcache_lock); | ||
1855 | return 1; | 1780 | return 1; |
1856 | } | 1781 | } |
1857 | } | 1782 | } |
1858 | spin_unlock(&dparent->d_lock); | 1783 | spin_unlock(&dparent->d_lock); |
1859 | spin_unlock(&dcache_lock); | ||
1860 | 1784 | ||
1861 | return 0; | 1785 | return 0; |
1862 | } | 1786 | } |
@@ -1889,7 +1813,6 @@ void d_delete(struct dentry * dentry) | |||
1889 | /* | 1813 | /* |
1890 | * Are we the only user? | 1814 | * Are we the only user? |
1891 | */ | 1815 | */ |
1892 | spin_lock(&dcache_lock); | ||
1893 | spin_lock(&dcache_inode_lock); | 1816 | spin_lock(&dcache_inode_lock); |
1894 | spin_lock(&dentry->d_lock); | 1817 | spin_lock(&dentry->d_lock); |
1895 | isdir = S_ISDIR(dentry->d_inode->i_mode); | 1818 | isdir = S_ISDIR(dentry->d_inode->i_mode); |
@@ -1905,7 +1828,6 @@ void d_delete(struct dentry * dentry) | |||
1905 | 1828 | ||
1906 | spin_unlock(&dentry->d_lock); | 1829 | spin_unlock(&dentry->d_lock); |
1907 | spin_unlock(&dcache_inode_lock); | 1830 | spin_unlock(&dcache_inode_lock); |
1908 | spin_unlock(&dcache_lock); | ||
1909 | 1831 | ||
1910 | fsnotify_nameremove(dentry, isdir); | 1832 | fsnotify_nameremove(dentry, isdir); |
1911 | } | 1833 | } |
@@ -1932,13 +1854,11 @@ static void _d_rehash(struct dentry * entry) | |||
1932 | 1854 | ||
1933 | void d_rehash(struct dentry * entry) | 1855 | void d_rehash(struct dentry * entry) |
1934 | { | 1856 | { |
1935 | spin_lock(&dcache_lock); | ||
1936 | spin_lock(&entry->d_lock); | 1857 | spin_lock(&entry->d_lock); |
1937 | spin_lock(&dcache_hash_lock); | 1858 | spin_lock(&dcache_hash_lock); |
1938 | _d_rehash(entry); | 1859 | _d_rehash(entry); |
1939 | spin_unlock(&dcache_hash_lock); | 1860 | spin_unlock(&dcache_hash_lock); |
1940 | spin_unlock(&entry->d_lock); | 1861 | spin_unlock(&entry->d_lock); |
1941 | spin_unlock(&dcache_lock); | ||
1942 | } | 1862 | } |
1943 | EXPORT_SYMBOL(d_rehash); | 1863 | EXPORT_SYMBOL(d_rehash); |
1944 | 1864 | ||
@@ -1961,11 +1881,9 @@ void dentry_update_name_case(struct dentry *dentry, struct qstr *name) | |||
1961 | BUG_ON(!mutex_is_locked(&dentry->d_inode->i_mutex)); | 1881 | BUG_ON(!mutex_is_locked(&dentry->d_inode->i_mutex)); |
1962 | BUG_ON(dentry->d_name.len != name->len); /* d_lookup gives this */ | 1882 | BUG_ON(dentry->d_name.len != name->len); /* d_lookup gives this */ |
1963 | 1883 | ||
1964 | spin_lock(&dcache_lock); | ||
1965 | spin_lock(&dentry->d_lock); | 1884 | spin_lock(&dentry->d_lock); |
1966 | memcpy((unsigned char *)dentry->d_name.name, name->name, name->len); | 1885 | memcpy((unsigned char *)dentry->d_name.name, name->name, name->len); |
1967 | spin_unlock(&dentry->d_lock); | 1886 | spin_unlock(&dentry->d_lock); |
1968 | spin_unlock(&dcache_lock); | ||
1969 | } | 1887 | } |
1970 | EXPORT_SYMBOL(dentry_update_name_case); | 1888 | EXPORT_SYMBOL(dentry_update_name_case); |
1971 | 1889 | ||
@@ -2058,14 +1976,14 @@ static void dentry_unlock_parents_for_move(struct dentry *dentry, | |||
2058 | * The hash value has to match the hash queue that the dentry is on.. | 1976 | * The hash value has to match the hash queue that the dentry is on.. |
2059 | */ | 1977 | */ |
2060 | /* | 1978 | /* |
2061 | * d_move_locked - move a dentry | 1979 | * d_move - move a dentry |
2062 | * @dentry: entry to move | 1980 | * @dentry: entry to move |
2063 | * @target: new dentry | 1981 | * @target: new dentry |
2064 | * | 1982 | * |
2065 | * Update the dcache to reflect the move of a file name. Negative | 1983 | * Update the dcache to reflect the move of a file name. Negative |
2066 | * dcache entries should not be moved in this way. | 1984 | * dcache entries should not be moved in this way. |
2067 | */ | 1985 | */ |
2068 | static void d_move_locked(struct dentry * dentry, struct dentry * target) | 1986 | void d_move(struct dentry * dentry, struct dentry * target) |
2069 | { | 1987 | { |
2070 | if (!dentry->d_inode) | 1988 | if (!dentry->d_inode) |
2071 | printk(KERN_WARNING "VFS: moving negative dcache entry\n"); | 1989 | printk(KERN_WARNING "VFS: moving negative dcache entry\n"); |
@@ -2114,22 +2032,6 @@ static void d_move_locked(struct dentry * dentry, struct dentry * target) | |||
2114 | spin_unlock(&dentry->d_lock); | 2032 | spin_unlock(&dentry->d_lock); |
2115 | write_sequnlock(&rename_lock); | 2033 | write_sequnlock(&rename_lock); |
2116 | } | 2034 | } |
2117 | |||
2118 | /** | ||
2119 | * d_move - move a dentry | ||
2120 | * @dentry: entry to move | ||
2121 | * @target: new dentry | ||
2122 | * | ||
2123 | * Update the dcache to reflect the move of a file name. Negative | ||
2124 | * dcache entries should not be moved in this way. | ||
2125 | */ | ||
2126 | |||
2127 | void d_move(struct dentry * dentry, struct dentry * target) | ||
2128 | { | ||
2129 | spin_lock(&dcache_lock); | ||
2130 | d_move_locked(dentry, target); | ||
2131 | spin_unlock(&dcache_lock); | ||
2132 | } | ||
2133 | EXPORT_SYMBOL(d_move); | 2035 | EXPORT_SYMBOL(d_move); |
2134 | 2036 | ||
2135 | /** | 2037 | /** |
@@ -2155,13 +2057,12 @@ struct dentry *d_ancestor(struct dentry *p1, struct dentry *p2) | |||
2155 | * This helper attempts to cope with remotely renamed directories | 2057 | * This helper attempts to cope with remotely renamed directories |
2156 | * | 2058 | * |
2157 | * It assumes that the caller is already holding | 2059 | * It assumes that the caller is already holding |
2158 | * dentry->d_parent->d_inode->i_mutex and the dcache_lock | 2060 | * dentry->d_parent->d_inode->i_mutex and the dcache_inode_lock |
2159 | * | 2061 | * |
2160 | * Note: If ever the locking in lock_rename() changes, then please | 2062 | * Note: If ever the locking in lock_rename() changes, then please |
2161 | * remember to update this too... | 2063 | * remember to update this too... |
2162 | */ | 2064 | */ |
2163 | static struct dentry *__d_unalias(struct dentry *dentry, struct dentry *alias) | 2065 | static struct dentry *__d_unalias(struct dentry *dentry, struct dentry *alias) |
2164 | __releases(dcache_lock) | ||
2165 | __releases(dcache_inode_lock) | 2066 | __releases(dcache_inode_lock) |
2166 | { | 2067 | { |
2167 | struct mutex *m1 = NULL, *m2 = NULL; | 2068 | struct mutex *m1 = NULL, *m2 = NULL; |
@@ -2185,11 +2086,10 @@ static struct dentry *__d_unalias(struct dentry *dentry, struct dentry *alias) | |||
2185 | goto out_err; | 2086 | goto out_err; |
2186 | m2 = &alias->d_parent->d_inode->i_mutex; | 2087 | m2 = &alias->d_parent->d_inode->i_mutex; |
2187 | out_unalias: | 2088 | out_unalias: |
2188 | d_move_locked(alias, dentry); | 2089 | d_move(alias, dentry); |
2189 | ret = alias; | 2090 | ret = alias; |
2190 | out_err: | 2091 | out_err: |
2191 | spin_unlock(&dcache_inode_lock); | 2092 | spin_unlock(&dcache_inode_lock); |
2192 | spin_unlock(&dcache_lock); | ||
2193 | if (m2) | 2093 | if (m2) |
2194 | mutex_unlock(m2); | 2094 | mutex_unlock(m2); |
2195 | if (m1) | 2095 | if (m1) |
@@ -2249,7 +2149,6 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode) | |||
2249 | 2149 | ||
2250 | BUG_ON(!d_unhashed(dentry)); | 2150 | BUG_ON(!d_unhashed(dentry)); |
2251 | 2151 | ||
2252 | spin_lock(&dcache_lock); | ||
2253 | spin_lock(&dcache_inode_lock); | 2152 | spin_lock(&dcache_inode_lock); |
2254 | 2153 | ||
2255 | if (!inode) { | 2154 | if (!inode) { |
@@ -2295,7 +2194,6 @@ found: | |||
2295 | spin_unlock(&dcache_hash_lock); | 2194 | spin_unlock(&dcache_hash_lock); |
2296 | spin_unlock(&actual->d_lock); | 2195 | spin_unlock(&actual->d_lock); |
2297 | spin_unlock(&dcache_inode_lock); | 2196 | spin_unlock(&dcache_inode_lock); |
2298 | spin_unlock(&dcache_lock); | ||
2299 | out_nolock: | 2197 | out_nolock: |
2300 | if (actual == dentry) { | 2198 | if (actual == dentry) { |
2301 | security_d_instantiate(dentry, inode); | 2199 | security_d_instantiate(dentry, inode); |
@@ -2307,7 +2205,6 @@ out_nolock: | |||
2307 | 2205 | ||
2308 | shouldnt_be_hashed: | 2206 | shouldnt_be_hashed: |
2309 | spin_unlock(&dcache_inode_lock); | 2207 | spin_unlock(&dcache_inode_lock); |
2310 | spin_unlock(&dcache_lock); | ||
2311 | BUG(); | 2208 | BUG(); |
2312 | } | 2209 | } |
2313 | EXPORT_SYMBOL_GPL(d_materialise_unique); | 2210 | EXPORT_SYMBOL_GPL(d_materialise_unique); |
@@ -2421,11 +2318,9 @@ char *__d_path(const struct path *path, struct path *root, | |||
2421 | int error; | 2318 | int error; |
2422 | 2319 | ||
2423 | prepend(&res, &buflen, "\0", 1); | 2320 | prepend(&res, &buflen, "\0", 1); |
2424 | spin_lock(&dcache_lock); | ||
2425 | write_seqlock(&rename_lock); | 2321 | write_seqlock(&rename_lock); |
2426 | error = prepend_path(path, root, &res, &buflen); | 2322 | error = prepend_path(path, root, &res, &buflen); |
2427 | write_sequnlock(&rename_lock); | 2323 | write_sequnlock(&rename_lock); |
2428 | spin_unlock(&dcache_lock); | ||
2429 | 2324 | ||
2430 | if (error) | 2325 | if (error) |
2431 | return ERR_PTR(error); | 2326 | return ERR_PTR(error); |
@@ -2487,14 +2382,12 @@ char *d_path(const struct path *path, char *buf, int buflen) | |||
2487 | return path->dentry->d_op->d_dname(path->dentry, buf, buflen); | 2382 | return path->dentry->d_op->d_dname(path->dentry, buf, buflen); |
2488 | 2383 | ||
2489 | get_fs_root(current->fs, &root); | 2384 | get_fs_root(current->fs, &root); |
2490 | spin_lock(&dcache_lock); | ||
2491 | write_seqlock(&rename_lock); | 2385 | write_seqlock(&rename_lock); |
2492 | tmp = root; | 2386 | tmp = root; |
2493 | error = path_with_deleted(path, &tmp, &res, &buflen); | 2387 | error = path_with_deleted(path, &tmp, &res, &buflen); |
2494 | if (error) | 2388 | if (error) |
2495 | res = ERR_PTR(error); | 2389 | res = ERR_PTR(error); |
2496 | write_sequnlock(&rename_lock); | 2390 | write_sequnlock(&rename_lock); |
2497 | spin_unlock(&dcache_lock); | ||
2498 | path_put(&root); | 2391 | path_put(&root); |
2499 | return res; | 2392 | return res; |
2500 | } | 2393 | } |
@@ -2520,14 +2413,12 @@ char *d_path_with_unreachable(const struct path *path, char *buf, int buflen) | |||
2520 | return path->dentry->d_op->d_dname(path->dentry, buf, buflen); | 2413 | return path->dentry->d_op->d_dname(path->dentry, buf, buflen); |
2521 | 2414 | ||
2522 | get_fs_root(current->fs, &root); | 2415 | get_fs_root(current->fs, &root); |
2523 | spin_lock(&dcache_lock); | ||
2524 | write_seqlock(&rename_lock); | 2416 | write_seqlock(&rename_lock); |
2525 | tmp = root; | 2417 | tmp = root; |
2526 | error = path_with_deleted(path, &tmp, &res, &buflen); | 2418 | error = path_with_deleted(path, &tmp, &res, &buflen); |
2527 | if (!error && !path_equal(&tmp, &root)) | 2419 | if (!error && !path_equal(&tmp, &root)) |
2528 | error = prepend_unreachable(&res, &buflen); | 2420 | error = prepend_unreachable(&res, &buflen); |
2529 | write_sequnlock(&rename_lock); | 2421 | write_sequnlock(&rename_lock); |
2530 | spin_unlock(&dcache_lock); | ||
2531 | path_put(&root); | 2422 | path_put(&root); |
2532 | if (error) | 2423 | if (error) |
2533 | res = ERR_PTR(error); | 2424 | res = ERR_PTR(error); |
@@ -2594,11 +2485,9 @@ char *dentry_path_raw(struct dentry *dentry, char *buf, int buflen) | |||
2594 | { | 2485 | { |
2595 | char *retval; | 2486 | char *retval; |
2596 | 2487 | ||
2597 | spin_lock(&dcache_lock); | ||
2598 | write_seqlock(&rename_lock); | 2488 | write_seqlock(&rename_lock); |
2599 | retval = __dentry_path(dentry, buf, buflen); | 2489 | retval = __dentry_path(dentry, buf, buflen); |
2600 | write_sequnlock(&rename_lock); | 2490 | write_sequnlock(&rename_lock); |
2601 | spin_unlock(&dcache_lock); | ||
2602 | 2491 | ||
2603 | return retval; | 2492 | return retval; |
2604 | } | 2493 | } |
@@ -2609,7 +2498,6 @@ char *dentry_path(struct dentry *dentry, char *buf, int buflen) | |||
2609 | char *p = NULL; | 2498 | char *p = NULL; |
2610 | char *retval; | 2499 | char *retval; |
2611 | 2500 | ||
2612 | spin_lock(&dcache_lock); | ||
2613 | write_seqlock(&rename_lock); | 2501 | write_seqlock(&rename_lock); |
2614 | if (d_unlinked(dentry)) { | 2502 | if (d_unlinked(dentry)) { |
2615 | p = buf + buflen; | 2503 | p = buf + buflen; |
@@ -2619,12 +2507,10 @@ char *dentry_path(struct dentry *dentry, char *buf, int buflen) | |||
2619 | } | 2507 | } |
2620 | retval = __dentry_path(dentry, buf, buflen); | 2508 | retval = __dentry_path(dentry, buf, buflen); |
2621 | write_sequnlock(&rename_lock); | 2509 | write_sequnlock(&rename_lock); |
2622 | spin_unlock(&dcache_lock); | ||
2623 | if (!IS_ERR(retval) && p) | 2510 | if (!IS_ERR(retval) && p) |
2624 | *p = '/'; /* restore '/' overriden with '\0' */ | 2511 | *p = '/'; /* restore '/' overriden with '\0' */ |
2625 | return retval; | 2512 | return retval; |
2626 | Elong: | 2513 | Elong: |
2627 | spin_unlock(&dcache_lock); | ||
2628 | return ERR_PTR(-ENAMETOOLONG); | 2514 | return ERR_PTR(-ENAMETOOLONG); |
2629 | } | 2515 | } |
2630 | 2516 | ||
@@ -2658,7 +2544,6 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size) | |||
2658 | get_fs_root_and_pwd(current->fs, &root, &pwd); | 2544 | get_fs_root_and_pwd(current->fs, &root, &pwd); |
2659 | 2545 | ||
2660 | error = -ENOENT; | 2546 | error = -ENOENT; |
2661 | spin_lock(&dcache_lock); | ||
2662 | write_seqlock(&rename_lock); | 2547 | write_seqlock(&rename_lock); |
2663 | if (!d_unlinked(pwd.dentry)) { | 2548 | if (!d_unlinked(pwd.dentry)) { |
2664 | unsigned long len; | 2549 | unsigned long len; |
@@ -2669,7 +2554,6 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size) | |||
2669 | prepend(&cwd, &buflen, "\0", 1); | 2554 | prepend(&cwd, &buflen, "\0", 1); |
2670 | error = prepend_path(&pwd, &tmp, &cwd, &buflen); | 2555 | error = prepend_path(&pwd, &tmp, &cwd, &buflen); |
2671 | write_sequnlock(&rename_lock); | 2556 | write_sequnlock(&rename_lock); |
2672 | spin_unlock(&dcache_lock); | ||
2673 | 2557 | ||
2674 | if (error) | 2558 | if (error) |
2675 | goto out; | 2559 | goto out; |
@@ -2690,7 +2574,6 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size) | |||
2690 | } | 2574 | } |
2691 | } else { | 2575 | } else { |
2692 | write_sequnlock(&rename_lock); | 2576 | write_sequnlock(&rename_lock); |
2693 | spin_unlock(&dcache_lock); | ||
2694 | } | 2577 | } |
2695 | 2578 | ||
2696 | out: | 2579 | out: |
@@ -2776,7 +2659,6 @@ void d_genocide(struct dentry *root) | |||
2776 | rename_retry: | 2659 | rename_retry: |
2777 | this_parent = root; | 2660 | this_parent = root; |
2778 | seq = read_seqbegin(&rename_lock); | 2661 | seq = read_seqbegin(&rename_lock); |
2779 | spin_lock(&dcache_lock); | ||
2780 | spin_lock(&this_parent->d_lock); | 2662 | spin_lock(&this_parent->d_lock); |
2781 | repeat: | 2663 | repeat: |
2782 | next = this_parent->d_subdirs.next; | 2664 | next = this_parent->d_subdirs.next; |
@@ -2823,7 +2705,6 @@ resume: | |||
2823 | if (this_parent != child->d_parent || | 2705 | if (this_parent != child->d_parent || |
2824 | read_seqretry(&rename_lock, seq)) { | 2706 | read_seqretry(&rename_lock, seq)) { |
2825 | spin_unlock(&this_parent->d_lock); | 2707 | spin_unlock(&this_parent->d_lock); |
2826 | spin_unlock(&dcache_lock); | ||
2827 | rcu_read_unlock(); | 2708 | rcu_read_unlock(); |
2828 | goto rename_retry; | 2709 | goto rename_retry; |
2829 | } | 2710 | } |
@@ -2832,7 +2713,6 @@ resume: | |||
2832 | goto resume; | 2713 | goto resume; |
2833 | } | 2714 | } |
2834 | spin_unlock(&this_parent->d_lock); | 2715 | spin_unlock(&this_parent->d_lock); |
2835 | spin_unlock(&dcache_lock); | ||
2836 | if (read_seqretry(&rename_lock, seq)) | 2716 | if (read_seqretry(&rename_lock, seq)) |
2837 | goto rename_retry; | 2717 | goto rename_retry; |
2838 | } | 2718 | } |
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c index 84b8c460a781..53a5c08fb63c 100644 --- a/fs/exportfs/expfs.c +++ b/fs/exportfs/expfs.c | |||
@@ -47,24 +47,20 @@ find_acceptable_alias(struct dentry *result, | |||
47 | if (acceptable(context, result)) | 47 | if (acceptable(context, result)) |
48 | return result; | 48 | return result; |
49 | 49 | ||
50 | spin_lock(&dcache_lock); | ||
51 | spin_lock(&dcache_inode_lock); | 50 | spin_lock(&dcache_inode_lock); |
52 | list_for_each_entry(dentry, &result->d_inode->i_dentry, d_alias) { | 51 | list_for_each_entry(dentry, &result->d_inode->i_dentry, d_alias) { |
53 | dget_locked(dentry); | 52 | dget_locked(dentry); |
54 | spin_unlock(&dcache_inode_lock); | 53 | spin_unlock(&dcache_inode_lock); |
55 | spin_unlock(&dcache_lock); | ||
56 | if (toput) | 54 | if (toput) |
57 | dput(toput); | 55 | dput(toput); |
58 | if (dentry != result && acceptable(context, dentry)) { | 56 | if (dentry != result && acceptable(context, dentry)) { |
59 | dput(result); | 57 | dput(result); |
60 | return dentry; | 58 | return dentry; |
61 | } | 59 | } |
62 | spin_lock(&dcache_lock); | ||
63 | spin_lock(&dcache_inode_lock); | 60 | spin_lock(&dcache_inode_lock); |
64 | toput = dentry; | 61 | toput = dentry; |
65 | } | 62 | } |
66 | spin_unlock(&dcache_inode_lock); | 63 | spin_unlock(&dcache_inode_lock); |
67 | spin_unlock(&dcache_lock); | ||
68 | 64 | ||
69 | if (toput) | 65 | if (toput) |
70 | dput(toput); | 66 | dput(toput); |
diff --git a/fs/libfs.c b/fs/libfs.c index cc4794914b52..28b36663c44e 100644 --- a/fs/libfs.c +++ b/fs/libfs.c | |||
@@ -100,7 +100,6 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin) | |||
100 | struct dentry *cursor = file->private_data; | 100 | struct dentry *cursor = file->private_data; |
101 | loff_t n = file->f_pos - 2; | 101 | loff_t n = file->f_pos - 2; |
102 | 102 | ||
103 | spin_lock(&dcache_lock); | ||
104 | spin_lock(&dentry->d_lock); | 103 | spin_lock(&dentry->d_lock); |
105 | /* d_lock not required for cursor */ | 104 | /* d_lock not required for cursor */ |
106 | list_del(&cursor->d_u.d_child); | 105 | list_del(&cursor->d_u.d_child); |
@@ -116,7 +115,6 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin) | |||
116 | } | 115 | } |
117 | list_add_tail(&cursor->d_u.d_child, p); | 116 | list_add_tail(&cursor->d_u.d_child, p); |
118 | spin_unlock(&dentry->d_lock); | 117 | spin_unlock(&dentry->d_lock); |
119 | spin_unlock(&dcache_lock); | ||
120 | } | 118 | } |
121 | } | 119 | } |
122 | mutex_unlock(&dentry->d_inode->i_mutex); | 120 | mutex_unlock(&dentry->d_inode->i_mutex); |
@@ -159,7 +157,6 @@ int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
159 | i++; | 157 | i++; |
160 | /* fallthrough */ | 158 | /* fallthrough */ |
161 | default: | 159 | default: |
162 | spin_lock(&dcache_lock); | ||
163 | spin_lock(&dentry->d_lock); | 160 | spin_lock(&dentry->d_lock); |
164 | if (filp->f_pos == 2) | 161 | if (filp->f_pos == 2) |
165 | list_move(q, &dentry->d_subdirs); | 162 | list_move(q, &dentry->d_subdirs); |
@@ -175,13 +172,11 @@ int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
175 | 172 | ||
176 | spin_unlock(&next->d_lock); | 173 | spin_unlock(&next->d_lock); |
177 | spin_unlock(&dentry->d_lock); | 174 | spin_unlock(&dentry->d_lock); |
178 | spin_unlock(&dcache_lock); | ||
179 | if (filldir(dirent, next->d_name.name, | 175 | if (filldir(dirent, next->d_name.name, |
180 | next->d_name.len, filp->f_pos, | 176 | next->d_name.len, filp->f_pos, |
181 | next->d_inode->i_ino, | 177 | next->d_inode->i_ino, |
182 | dt_type(next->d_inode)) < 0) | 178 | dt_type(next->d_inode)) < 0) |
183 | return 0; | 179 | return 0; |
184 | spin_lock(&dcache_lock); | ||
185 | spin_lock(&dentry->d_lock); | 180 | spin_lock(&dentry->d_lock); |
186 | spin_lock_nested(&next->d_lock, DENTRY_D_LOCK_NESTED); | 181 | spin_lock_nested(&next->d_lock, DENTRY_D_LOCK_NESTED); |
187 | /* next is still alive */ | 182 | /* next is still alive */ |
@@ -191,7 +186,6 @@ int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
191 | filp->f_pos++; | 186 | filp->f_pos++; |
192 | } | 187 | } |
193 | spin_unlock(&dentry->d_lock); | 188 | spin_unlock(&dentry->d_lock); |
194 | spin_unlock(&dcache_lock); | ||
195 | } | 189 | } |
196 | return 0; | 190 | return 0; |
197 | } | 191 | } |
@@ -285,7 +279,6 @@ int simple_empty(struct dentry *dentry) | |||
285 | struct dentry *child; | 279 | struct dentry *child; |
286 | int ret = 0; | 280 | int ret = 0; |
287 | 281 | ||
288 | spin_lock(&dcache_lock); | ||
289 | spin_lock(&dentry->d_lock); | 282 | spin_lock(&dentry->d_lock); |
290 | list_for_each_entry(child, &dentry->d_subdirs, d_u.d_child) { | 283 | list_for_each_entry(child, &dentry->d_subdirs, d_u.d_child) { |
291 | spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED); | 284 | spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED); |
@@ -298,7 +291,6 @@ int simple_empty(struct dentry *dentry) | |||
298 | ret = 1; | 291 | ret = 1; |
299 | out: | 292 | out: |
300 | spin_unlock(&dentry->d_lock); | 293 | spin_unlock(&dentry->d_lock); |
301 | spin_unlock(&dcache_lock); | ||
302 | return ret; | 294 | return ret; |
303 | } | 295 | } |
304 | 296 | ||
diff --git a/fs/namei.c b/fs/namei.c index cbfa5fb31072..5642bc2be418 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -612,8 +612,8 @@ int follow_up(struct path *path) | |||
612 | return 1; | 612 | return 1; |
613 | } | 613 | } |
614 | 614 | ||
615 | /* no need for dcache_lock, as serialization is taken care in | 615 | /* |
616 | * namespace.c | 616 | * serialization is taken care of in namespace.c |
617 | */ | 617 | */ |
618 | static int __follow_mount(struct path *path) | 618 | static int __follow_mount(struct path *path) |
619 | { | 619 | { |
@@ -645,9 +645,6 @@ static void follow_mount(struct path *path) | |||
645 | } | 645 | } |
646 | } | 646 | } |
647 | 647 | ||
648 | /* no need for dcache_lock, as serialization is taken care in | ||
649 | * namespace.c | ||
650 | */ | ||
651 | int follow_down(struct path *path) | 648 | int follow_down(struct path *path) |
652 | { | 649 | { |
653 | struct vfsmount *mounted; | 650 | struct vfsmount *mounted; |
@@ -2131,12 +2128,10 @@ void dentry_unhash(struct dentry *dentry) | |||
2131 | { | 2128 | { |
2132 | dget(dentry); | 2129 | dget(dentry); |
2133 | shrink_dcache_parent(dentry); | 2130 | shrink_dcache_parent(dentry); |
2134 | spin_lock(&dcache_lock); | ||
2135 | spin_lock(&dentry->d_lock); | 2131 | spin_lock(&dentry->d_lock); |
2136 | if (dentry->d_count == 2) | 2132 | if (dentry->d_count == 2) |
2137 | __d_drop(dentry); | 2133 | __d_drop(dentry); |
2138 | spin_unlock(&dentry->d_lock); | 2134 | spin_unlock(&dentry->d_lock); |
2139 | spin_unlock(&dcache_lock); | ||
2140 | } | 2135 | } |
2141 | 2136 | ||
2142 | int vfs_rmdir(struct inode *dir, struct dentry *dentry) | 2137 | int vfs_rmdir(struct inode *dir, struct dentry *dentry) |
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index 102278ed38bd..de15c533311c 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c | |||
@@ -391,7 +391,6 @@ ncp_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos) | |||
391 | } | 391 | } |
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); | ||
395 | spin_lock(&parent->d_lock); | 394 | spin_lock(&parent->d_lock); |
396 | next = parent->d_subdirs.next; | 395 | next = parent->d_subdirs.next; |
397 | while (next != &parent->d_subdirs) { | 396 | while (next != &parent->d_subdirs) { |
@@ -402,13 +401,11 @@ ncp_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos) | |||
402 | else | 401 | else |
403 | dent = NULL; | 402 | dent = NULL; |
404 | spin_unlock(&parent->d_lock); | 403 | spin_unlock(&parent->d_lock); |
405 | spin_unlock(&dcache_lock); | ||
406 | goto out; | 404 | goto out; |
407 | } | 405 | } |
408 | next = next->next; | 406 | next = next->next; |
409 | } | 407 | } |
410 | spin_unlock(&parent->d_lock); | 408 | spin_unlock(&parent->d_lock); |
411 | spin_unlock(&dcache_lock); | ||
412 | return NULL; | 409 | return NULL; |
413 | 410 | ||
414 | out: | 411 | out: |
diff --git a/fs/ncpfs/ncplib_kernel.h b/fs/ncpfs/ncplib_kernel.h index c4b718ff9a6b..1220df75ff22 100644 --- a/fs/ncpfs/ncplib_kernel.h +++ b/fs/ncpfs/ncplib_kernel.h | |||
@@ -193,7 +193,6 @@ ncp_renew_dentries(struct dentry *parent) | |||
193 | struct list_head *next; | 193 | struct list_head *next; |
194 | struct dentry *dentry; | 194 | struct dentry *dentry; |
195 | 195 | ||
196 | spin_lock(&dcache_lock); | ||
197 | spin_lock(&parent->d_lock); | 196 | spin_lock(&parent->d_lock); |
198 | next = parent->d_subdirs.next; | 197 | next = parent->d_subdirs.next; |
199 | while (next != &parent->d_subdirs) { | 198 | while (next != &parent->d_subdirs) { |
@@ -207,7 +206,6 @@ ncp_renew_dentries(struct dentry *parent) | |||
207 | next = next->next; | 206 | next = next->next; |
208 | } | 207 | } |
209 | spin_unlock(&parent->d_lock); | 208 | spin_unlock(&parent->d_lock); |
210 | spin_unlock(&dcache_lock); | ||
211 | } | 209 | } |
212 | 210 | ||
213 | static inline void | 211 | static inline void |
@@ -217,7 +215,6 @@ ncp_invalidate_dircache_entries(struct dentry *parent) | |||
217 | struct list_head *next; | 215 | struct list_head *next; |
218 | struct dentry *dentry; | 216 | struct dentry *dentry; |
219 | 217 | ||
220 | spin_lock(&dcache_lock); | ||
221 | spin_lock(&parent->d_lock); | 218 | spin_lock(&parent->d_lock); |
222 | next = parent->d_subdirs.next; | 219 | next = parent->d_subdirs.next; |
223 | while (next != &parent->d_subdirs) { | 220 | while (next != &parent->d_subdirs) { |
@@ -227,7 +224,6 @@ ncp_invalidate_dircache_entries(struct dentry *parent) | |||
227 | next = next->next; | 224 | next = next->next; |
228 | } | 225 | } |
229 | spin_unlock(&parent->d_lock); | 226 | spin_unlock(&parent->d_lock); |
230 | spin_unlock(&dcache_lock); | ||
231 | } | 227 | } |
232 | 228 | ||
233 | struct ncp_cache_head { | 229 | struct ncp_cache_head { |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 12de824edb5c..eb77471b8823 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -1718,11 +1718,9 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry) | |||
1718 | dfprintk(VFS, "NFS: unlink(%s/%ld, %s)\n", dir->i_sb->s_id, | 1718 | dfprintk(VFS, "NFS: unlink(%s/%ld, %s)\n", dir->i_sb->s_id, |
1719 | dir->i_ino, dentry->d_name.name); | 1719 | dir->i_ino, dentry->d_name.name); |
1720 | 1720 | ||
1721 | spin_lock(&dcache_lock); | ||
1722 | spin_lock(&dentry->d_lock); | 1721 | spin_lock(&dentry->d_lock); |
1723 | if (dentry->d_count > 1) { | 1722 | if (dentry->d_count > 1) { |
1724 | spin_unlock(&dentry->d_lock); | 1723 | spin_unlock(&dentry->d_lock); |
1725 | spin_unlock(&dcache_lock); | ||
1726 | /* Start asynchronous writeout of the inode */ | 1724 | /* Start asynchronous writeout of the inode */ |
1727 | write_inode_now(dentry->d_inode, 0); | 1725 | write_inode_now(dentry->d_inode, 0); |
1728 | error = nfs_sillyrename(dir, dentry); | 1726 | error = nfs_sillyrename(dir, dentry); |
@@ -1733,7 +1731,6 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry) | |||
1733 | need_rehash = 1; | 1731 | need_rehash = 1; |
1734 | } | 1732 | } |
1735 | spin_unlock(&dentry->d_lock); | 1733 | spin_unlock(&dentry->d_lock); |
1736 | spin_unlock(&dcache_lock); | ||
1737 | error = nfs_safe_remove(dentry); | 1734 | error = nfs_safe_remove(dentry); |
1738 | if (!error || error == -ENOENT) { | 1735 | if (!error || error == -ENOENT) { |
1739 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); | 1736 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); |
diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c index 850f67d5f0ac..b3e36c3430de 100644 --- a/fs/nfs/getroot.c +++ b/fs/nfs/getroot.c | |||
@@ -63,13 +63,11 @@ static int nfs_superblock_set_dummy_root(struct super_block *sb, struct inode *i | |||
63 | * This again causes shrink_dcache_for_umount_subtree() to | 63 | * This again causes shrink_dcache_for_umount_subtree() to |
64 | * Oops, since the test for IS_ROOT() will fail. | 64 | * Oops, since the test for IS_ROOT() will fail. |
65 | */ | 65 | */ |
66 | spin_lock(&dcache_lock); | ||
67 | spin_lock(&dcache_inode_lock); | 66 | spin_lock(&dcache_inode_lock); |
68 | spin_lock(&sb->s_root->d_lock); | 67 | spin_lock(&sb->s_root->d_lock); |
69 | list_del_init(&sb->s_root->d_alias); | 68 | list_del_init(&sb->s_root->d_alias); |
70 | spin_unlock(&sb->s_root->d_lock); | 69 | spin_unlock(&sb->s_root->d_lock); |
71 | spin_unlock(&dcache_inode_lock); | 70 | spin_unlock(&dcache_inode_lock); |
72 | spin_unlock(&dcache_lock); | ||
73 | } | 71 | } |
74 | return 0; | 72 | return 0; |
75 | } | 73 | } |
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c index 78c0ebb0b07c..74aaf3963c10 100644 --- a/fs/nfs/namespace.c +++ b/fs/nfs/namespace.c | |||
@@ -60,7 +60,6 @@ rename_retry: | |||
60 | 60 | ||
61 | seq = read_seqbegin(&rename_lock); | 61 | seq = read_seqbegin(&rename_lock); |
62 | rcu_read_lock(); | 62 | rcu_read_lock(); |
63 | spin_lock(&dcache_lock); | ||
64 | while (!IS_ROOT(dentry) && dentry != droot) { | 63 | while (!IS_ROOT(dentry) && dentry != droot) { |
65 | namelen = dentry->d_name.len; | 64 | namelen = dentry->d_name.len; |
66 | buflen -= namelen + 1; | 65 | buflen -= namelen + 1; |
@@ -71,7 +70,6 @@ rename_retry: | |||
71 | *--end = '/'; | 70 | *--end = '/'; |
72 | dentry = dentry->d_parent; | 71 | dentry = dentry->d_parent; |
73 | } | 72 | } |
74 | spin_unlock(&dcache_lock); | ||
75 | rcu_read_unlock(); | 73 | rcu_read_unlock(); |
76 | if (read_seqretry(&rename_lock, seq)) | 74 | if (read_seqretry(&rename_lock, seq)) |
77 | goto rename_retry; | 75 | goto rename_retry; |
@@ -91,7 +89,6 @@ rename_retry: | |||
91 | memcpy(end, base, namelen); | 89 | memcpy(end, base, namelen); |
92 | return end; | 90 | return end; |
93 | Elong_unlock: | 91 | Elong_unlock: |
94 | spin_unlock(&dcache_lock); | ||
95 | rcu_read_unlock(); | 92 | rcu_read_unlock(); |
96 | if (read_seqretry(&rename_lock, seq)) | 93 | if (read_seqretry(&rename_lock, seq)) |
97 | goto rename_retry; | 94 | goto rename_retry; |
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index ae769fc9b66c..9be6ec1f36d8 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c | |||
@@ -59,7 +59,6 @@ void __fsnotify_update_child_dentry_flags(struct inode *inode) | |||
59 | /* determine if the children should tell inode about their events */ | 59 | /* determine if the children should tell inode about their events */ |
60 | watched = fsnotify_inode_watches_children(inode); | 60 | watched = fsnotify_inode_watches_children(inode); |
61 | 61 | ||
62 | spin_lock(&dcache_lock); | ||
63 | spin_lock(&dcache_inode_lock); | 62 | spin_lock(&dcache_inode_lock); |
64 | /* run all of the dentries associated with this inode. Since this is a | 63 | /* run all of the dentries associated with this inode. Since this is a |
65 | * directory, there damn well better only be one item on this list */ | 64 | * directory, there damn well better only be one item on this list */ |
@@ -84,7 +83,6 @@ void __fsnotify_update_child_dentry_flags(struct inode *inode) | |||
84 | spin_unlock(&alias->d_lock); | 83 | spin_unlock(&alias->d_lock); |
85 | } | 84 | } |
86 | spin_unlock(&dcache_inode_lock); | 85 | spin_unlock(&dcache_inode_lock); |
87 | spin_unlock(&dcache_lock); | ||
88 | } | 86 | } |
89 | 87 | ||
90 | /* Notify this dentry's parent about a child's events. */ | 88 | /* Notify this dentry's parent about a child's events. */ |
diff --git a/fs/ocfs2/dcache.c b/fs/ocfs2/dcache.c index c31b5c647ac7..b7de749bdd12 100644 --- a/fs/ocfs2/dcache.c +++ b/fs/ocfs2/dcache.c | |||
@@ -169,7 +169,6 @@ struct dentry *ocfs2_find_local_alias(struct inode *inode, | |||
169 | struct list_head *p; | 169 | struct list_head *p; |
170 | struct dentry *dentry = NULL; | 170 | struct dentry *dentry = NULL; |
171 | 171 | ||
172 | spin_lock(&dcache_lock); | ||
173 | spin_lock(&dcache_inode_lock); | 172 | spin_lock(&dcache_inode_lock); |
174 | list_for_each(p, &inode->i_dentry) { | 173 | list_for_each(p, &inode->i_dentry) { |
175 | dentry = list_entry(p, struct dentry, d_alias); | 174 | dentry = list_entry(p, struct dentry, d_alias); |
@@ -189,7 +188,6 @@ struct dentry *ocfs2_find_local_alias(struct inode *inode, | |||
189 | } | 188 | } |
190 | 189 | ||
191 | spin_unlock(&dcache_inode_lock); | 190 | spin_unlock(&dcache_inode_lock); |
192 | spin_unlock(&dcache_lock); | ||
193 | 191 | ||
194 | return dentry; | 192 | return dentry; |
195 | } | 193 | } |
diff --git a/include/linux/dcache.h b/include/linux/dcache.h index c963ebada922..a2ceb94b0e38 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h | |||
@@ -183,7 +183,6 @@ struct dentry_operations { | |||
183 | #define DCACHE_GENOCIDE 0x0200 | 183 | #define DCACHE_GENOCIDE 0x0200 |
184 | 184 | ||
185 | extern spinlock_t dcache_inode_lock; | 185 | extern spinlock_t dcache_inode_lock; |
186 | extern spinlock_t dcache_lock; | ||
187 | extern seqlock_t rename_lock; | 186 | extern seqlock_t rename_lock; |
188 | 187 | ||
189 | static inline int dname_external(struct dentry *dentry) | 188 | static inline int dname_external(struct dentry *dentry) |
@@ -296,8 +295,8 @@ extern char *dentry_path(struct dentry *, char *, int); | |||
296 | * destroyed when it has references. dget() should never be | 295 | * destroyed when it has references. dget() should never be |
297 | * called for dentries with zero reference counter. For these cases | 296 | * called for dentries with zero reference counter. For these cases |
298 | * (preferably none, functions in dcache.c are sufficient for normal | 297 | * (preferably none, functions in dcache.c are sufficient for normal |
299 | * needs and they take necessary precautions) you should hold dcache_lock | 298 | * needs and they take necessary precautions) you should hold d_lock |
300 | * and call dget_locked() instead of dget(). | 299 | * and call dget_dlock() instead of dget(). |
301 | */ | 300 | */ |
302 | static inline struct dentry *dget_dlock(struct dentry *dentry) | 301 | static inline struct dentry *dget_dlock(struct dentry *dentry) |
303 | { | 302 | { |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 090f0eacde29..296cf2fde945 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -1378,7 +1378,7 @@ struct super_block { | |||
1378 | #else | 1378 | #else |
1379 | struct list_head s_files; | 1379 | struct list_head s_files; |
1380 | #endif | 1380 | #endif |
1381 | /* s_dentry_lru and s_nr_dentry_unused are protected by dcache_lock */ | 1381 | /* s_dentry_lru, s_nr_dentry_unused protected by dcache.c lru locks */ |
1382 | struct list_head s_dentry_lru; /* unused dentry lru */ | 1382 | struct list_head s_dentry_lru; /* unused dentry lru */ |
1383 | int s_nr_dentry_unused; /* # of dentry on lru */ | 1383 | int s_nr_dentry_unused; /* # of dentry on lru */ |
1384 | 1384 | ||
@@ -2446,6 +2446,10 @@ static inline ino_t parent_ino(struct dentry *dentry) | |||
2446 | { | 2446 | { |
2447 | ino_t res; | 2447 | ino_t res; |
2448 | 2448 | ||
2449 | /* | ||
2450 | * Don't strictly need d_lock here? If the parent ino could change | ||
2451 | * then surely we'd have a deeper race in the caller? | ||
2452 | */ | ||
2449 | spin_lock(&dentry->d_lock); | 2453 | spin_lock(&dentry->d_lock); |
2450 | res = dentry->d_parent->d_inode->i_ino; | 2454 | res = dentry->d_parent->d_inode->i_ino; |
2451 | spin_unlock(&dentry->d_lock); | 2455 | spin_unlock(&dentry->d_lock); |
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index b10bcdeaef76..2a53f10712b3 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h | |||
@@ -17,7 +17,6 @@ | |||
17 | 17 | ||
18 | /* | 18 | /* |
19 | * fsnotify_d_instantiate - instantiate a dentry for inode | 19 | * fsnotify_d_instantiate - instantiate a dentry for inode |
20 | * Called with dcache_lock held. | ||
21 | */ | 20 | */ |
22 | static inline void fsnotify_d_instantiate(struct dentry *dentry, | 21 | static inline void fsnotify_d_instantiate(struct dentry *dentry, |
23 | struct inode *inode) | 22 | struct inode *inode) |
@@ -62,7 +61,6 @@ static inline int fsnotify_perm(struct file *file, int mask) | |||
62 | 61 | ||
63 | /* | 62 | /* |
64 | * fsnotify_d_move - dentry has been moved | 63 | * fsnotify_d_move - dentry has been moved |
65 | * Called with dcache_lock and dentry->d_lock held. | ||
66 | */ | 64 | */ |
67 | static inline void fsnotify_d_move(struct dentry *dentry) | 65 | static inline void fsnotify_d_move(struct dentry *dentry) |
68 | { | 66 | { |
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 7380763595d3..69ad89b50489 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h | |||
@@ -329,9 +329,15 @@ static inline void __fsnotify_update_dcache_flags(struct dentry *dentry) | |||
329 | { | 329 | { |
330 | struct dentry *parent; | 330 | struct dentry *parent; |
331 | 331 | ||
332 | assert_spin_locked(&dcache_lock); | ||
333 | assert_spin_locked(&dentry->d_lock); | 332 | assert_spin_locked(&dentry->d_lock); |
334 | 333 | ||
334 | /* | ||
335 | * Serialisation of setting PARENT_WATCHED on the dentries is provided | ||
336 | * by d_lock. If inotify_inode_watched changes after we have taken | ||
337 | * d_lock, the following __fsnotify_update_child_dentry_flags call will | ||
338 | * find our entry, so it will spin until we complete here, and update | ||
339 | * us with the new state. | ||
340 | */ | ||
335 | parent = dentry->d_parent; | 341 | parent = dentry->d_parent; |
336 | if (parent->d_inode && fsnotify_inode_watches_children(parent->d_inode)) | 342 | if (parent->d_inode && fsnotify_inode_watches_children(parent->d_inode)) |
337 | dentry->d_flags |= DCACHE_FSNOTIFY_PARENT_WATCHED; | 343 | dentry->d_flags |= DCACHE_FSNOTIFY_PARENT_WATCHED; |
@@ -341,15 +347,12 @@ static inline void __fsnotify_update_dcache_flags(struct dentry *dentry) | |||
341 | 347 | ||
342 | /* | 348 | /* |
343 | * fsnotify_d_instantiate - instantiate a dentry for inode | 349 | * fsnotify_d_instantiate - instantiate a dentry for inode |
344 | * Called with dcache_lock held. | ||
345 | */ | 350 | */ |
346 | static inline void __fsnotify_d_instantiate(struct dentry *dentry, struct inode *inode) | 351 | static inline void __fsnotify_d_instantiate(struct dentry *dentry, struct inode *inode) |
347 | { | 352 | { |
348 | if (!inode) | 353 | if (!inode) |
349 | return; | 354 | return; |
350 | 355 | ||
351 | assert_spin_locked(&dcache_lock); | ||
352 | |||
353 | spin_lock(&dentry->d_lock); | 356 | spin_lock(&dentry->d_lock); |
354 | __fsnotify_update_dcache_flags(dentry); | 357 | __fsnotify_update_dcache_flags(dentry); |
355 | spin_unlock(&dentry->d_lock); | 358 | spin_unlock(&dentry->d_lock); |
diff --git a/include/linux/namei.h b/include/linux/namei.h index 05b441d93642..aec730b53935 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h | |||
@@ -41,7 +41,6 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND}; | |||
41 | * - require a directory | 41 | * - require a directory |
42 | * - ending slashes ok even for nonexistent files | 42 | * - ending slashes ok even for nonexistent files |
43 | * - internal "there are more path components" flag | 43 | * - internal "there are more path components" flag |
44 | * - locked when lookup done with dcache_lock held | ||
45 | * - dentry cache is untrusted; force a real lookup | 44 | * - dentry cache is untrusted; force a real lookup |
46 | */ | 45 | */ |
47 | #define LOOKUP_FOLLOW 1 | 46 | #define LOOKUP_FOLLOW 1 |
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 7b4705b51d4a..1864cb6a6a59 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -876,7 +876,6 @@ static void cgroup_clear_directory(struct dentry *dentry) | |||
876 | struct list_head *node; | 876 | struct list_head *node; |
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); | ||
880 | spin_lock(&dentry->d_lock); | 879 | spin_lock(&dentry->d_lock); |
881 | node = dentry->d_subdirs.next; | 880 | node = dentry->d_subdirs.next; |
882 | while (node != &dentry->d_subdirs) { | 881 | while (node != &dentry->d_subdirs) { |
@@ -891,18 +890,15 @@ static void cgroup_clear_directory(struct dentry *dentry) | |||
891 | dget_locked_dlock(d); | 890 | dget_locked_dlock(d); |
892 | spin_unlock(&d->d_lock); | 891 | spin_unlock(&d->d_lock); |
893 | spin_unlock(&dentry->d_lock); | 892 | spin_unlock(&dentry->d_lock); |
894 | spin_unlock(&dcache_lock); | ||
895 | d_delete(d); | 893 | d_delete(d); |
896 | simple_unlink(dentry->d_inode, d); | 894 | simple_unlink(dentry->d_inode, d); |
897 | dput(d); | 895 | dput(d); |
898 | spin_lock(&dcache_lock); | ||
899 | spin_lock(&dentry->d_lock); | 896 | spin_lock(&dentry->d_lock); |
900 | } else | 897 | } else |
901 | spin_unlock(&d->d_lock); | 898 | spin_unlock(&d->d_lock); |
902 | node = dentry->d_subdirs.next; | 899 | node = dentry->d_subdirs.next; |
903 | } | 900 | } |
904 | spin_unlock(&dentry->d_lock); | 901 | spin_unlock(&dentry->d_lock); |
905 | spin_unlock(&dcache_lock); | ||
906 | } | 902 | } |
907 | 903 | ||
908 | /* | 904 | /* |
@@ -914,14 +910,12 @@ static void cgroup_d_remove_dir(struct dentry *dentry) | |||
914 | 910 | ||
915 | cgroup_clear_directory(dentry); | 911 | cgroup_clear_directory(dentry); |
916 | 912 | ||
917 | spin_lock(&dcache_lock); | ||
918 | parent = dentry->d_parent; | 913 | parent = dentry->d_parent; |
919 | spin_lock(&parent->d_lock); | 914 | spin_lock(&parent->d_lock); |
920 | spin_lock(&dentry->d_lock); | 915 | spin_lock(&dentry->d_lock); |
921 | list_del_init(&dentry->d_u.d_child); | 916 | list_del_init(&dentry->d_u.d_child); |
922 | spin_unlock(&dentry->d_lock); | 917 | spin_unlock(&dentry->d_lock); |
923 | spin_unlock(&parent->d_lock); | 918 | spin_unlock(&parent->d_lock); |
924 | spin_unlock(&dcache_lock); | ||
925 | remove_dir(dentry); | 919 | remove_dir(dentry); |
926 | } | 920 | } |
927 | 921 | ||
diff --git a/mm/filemap.c b/mm/filemap.c index 6b9aee20f242..ca389394fa2a 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -102,9 +102,6 @@ | |||
102 | * ->inode_lock (zap_pte_range->set_page_dirty) | 102 | * ->inode_lock (zap_pte_range->set_page_dirty) |
103 | * ->private_lock (zap_pte_range->__set_page_dirty_buffers) | 103 | * ->private_lock (zap_pte_range->__set_page_dirty_buffers) |
104 | * | 104 | * |
105 | * ->task->proc_lock | ||
106 | * ->dcache_lock (proc_pid_lookup) | ||
107 | * | ||
108 | * (code doesn't rely on that order, so you could switch it around) | 105 | * (code doesn't rely on that order, so you could switch it around) |
109 | * ->tasklist_lock (memory_failure, collect_procs_ao) | 106 | * ->tasklist_lock (memory_failure, collect_procs_ao) |
110 | * ->i_mmap_lock | 107 | * ->i_mmap_lock |
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 017ec096446e..2285d693f296 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c | |||
@@ -1145,7 +1145,6 @@ static void sel_remove_entries(struct dentry *de) | |||
1145 | { | 1145 | { |
1146 | struct list_head *node; | 1146 | struct list_head *node; |
1147 | 1147 | ||
1148 | spin_lock(&dcache_lock); | ||
1149 | spin_lock(&de->d_lock); | 1148 | spin_lock(&de->d_lock); |
1150 | node = de->d_subdirs.next; | 1149 | node = de->d_subdirs.next; |
1151 | while (node != &de->d_subdirs) { | 1150 | while (node != &de->d_subdirs) { |
@@ -1158,11 +1157,9 @@ static void sel_remove_entries(struct dentry *de) | |||
1158 | dget_locked_dlock(d); | 1157 | dget_locked_dlock(d); |
1159 | spin_unlock(&de->d_lock); | 1158 | spin_unlock(&de->d_lock); |
1160 | spin_unlock(&d->d_lock); | 1159 | spin_unlock(&d->d_lock); |
1161 | spin_unlock(&dcache_lock); | ||
1162 | d_delete(d); | 1160 | d_delete(d); |
1163 | simple_unlink(de->d_inode, d); | 1161 | simple_unlink(de->d_inode, d); |
1164 | dput(d); | 1162 | dput(d); |
1165 | spin_lock(&dcache_lock); | ||
1166 | spin_lock(&de->d_lock); | 1163 | spin_lock(&de->d_lock); |
1167 | } else | 1164 | } else |
1168 | spin_unlock(&d->d_lock); | 1165 | spin_unlock(&d->d_lock); |
@@ -1170,7 +1167,6 @@ static void sel_remove_entries(struct dentry *de) | |||
1170 | } | 1167 | } |
1171 | 1168 | ||
1172 | spin_unlock(&de->d_lock); | 1169 | spin_unlock(&de->d_lock); |
1173 | spin_unlock(&dcache_lock); | ||
1174 | } | 1170 | } |
1175 | 1171 | ||
1176 | #define BOOL_DIR_NAME "booleans" | 1172 | #define BOOL_DIR_NAME "booleans" |