diff options
Diffstat (limited to 'fs/dcache.c')
| -rw-r--r-- | fs/dcache.c | 23 |
1 files changed, 11 insertions, 12 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 3aa8a7e980d8..7376b61269fb 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/string.h> | 19 | #include <linux/string.h> |
| 20 | #include <linux/mm.h> | 20 | #include <linux/mm.h> |
| 21 | #include <linux/fs.h> | 21 | #include <linux/fs.h> |
| 22 | #include <linux/fsnotify.h> | ||
| 22 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
| 23 | #include <linux/init.h> | 24 | #include <linux/init.h> |
| 24 | #include <linux/smp_lock.h> | 25 | #include <linux/smp_lock.h> |
| @@ -101,6 +102,7 @@ static inline void dentry_iput(struct dentry * dentry) | |||
| 101 | list_del_init(&dentry->d_alias); | 102 | list_del_init(&dentry->d_alias); |
| 102 | spin_unlock(&dentry->d_lock); | 103 | spin_unlock(&dentry->d_lock); |
| 103 | spin_unlock(&dcache_lock); | 104 | spin_unlock(&dcache_lock); |
| 105 | fsnotify_inoderemove(inode); | ||
| 104 | if (dentry->d_op && dentry->d_op->d_iput) | 106 | if (dentry->d_op && dentry->d_op->d_iput) |
| 105 | dentry->d_op->d_iput(dentry, inode); | 107 | dentry->d_op->d_iput(dentry, inode); |
| 106 | else | 108 | else |
| @@ -335,12 +337,10 @@ struct dentry * d_find_alias(struct inode *inode) | |||
| 335 | */ | 337 | */ |
| 336 | void d_prune_aliases(struct inode *inode) | 338 | void d_prune_aliases(struct inode *inode) |
| 337 | { | 339 | { |
| 338 | struct list_head *tmp, *head = &inode->i_dentry; | 340 | struct dentry *dentry; |
| 339 | restart: | 341 | restart: |
| 340 | spin_lock(&dcache_lock); | 342 | spin_lock(&dcache_lock); |
| 341 | tmp = head; | 343 | list_for_each_entry(dentry, &inode->i_dentry, d_alias) { |
| 342 | while ((tmp = tmp->next) != head) { | ||
| 343 | struct dentry *dentry = list_entry(tmp, struct dentry, d_alias); | ||
| 344 | spin_lock(&dentry->d_lock); | 344 | spin_lock(&dentry->d_lock); |
| 345 | if (!atomic_read(&dentry->d_count)) { | 345 | if (!atomic_read(&dentry->d_count)) { |
| 346 | __dget_locked(dentry); | 346 | __dget_locked(dentry); |
| @@ -461,10 +461,7 @@ void shrink_dcache_sb(struct super_block * sb) | |||
| 461 | * superblock to the most recent end of the unused list. | 461 | * superblock to the most recent end of the unused list. |
| 462 | */ | 462 | */ |
| 463 | spin_lock(&dcache_lock); | 463 | spin_lock(&dcache_lock); |
| 464 | next = dentry_unused.next; | 464 | list_for_each_safe(tmp, next, &dentry_unused) { |
| 465 | while (next != &dentry_unused) { | ||
| 466 | tmp = next; | ||
| 467 | next = tmp->next; | ||
| 468 | dentry = list_entry(tmp, struct dentry, d_lru); | 465 | dentry = list_entry(tmp, struct dentry, d_lru); |
| 469 | if (dentry->d_sb != sb) | 466 | if (dentry->d_sb != sb) |
| 470 | continue; | 467 | continue; |
| @@ -476,10 +473,7 @@ void shrink_dcache_sb(struct super_block * sb) | |||
| 476 | * Pass two ... free the dentries for this superblock. | 473 | * Pass two ... free the dentries for this superblock. |
| 477 | */ | 474 | */ |
| 478 | repeat: | 475 | repeat: |
| 479 | next = dentry_unused.next; | 476 | list_for_each_safe(tmp, next, &dentry_unused) { |
| 480 | while (next != &dentry_unused) { | ||
| 481 | tmp = next; | ||
| 482 | next = tmp->next; | ||
| 483 | dentry = list_entry(tmp, struct dentry, d_lru); | 477 | dentry = list_entry(tmp, struct dentry, d_lru); |
| 484 | if (dentry->d_sb != sb) | 478 | if (dentry->d_sb != sb) |
| 485 | continue; | 479 | continue; |
| @@ -1165,13 +1159,16 @@ out: | |||
| 1165 | 1159 | ||
| 1166 | void d_delete(struct dentry * dentry) | 1160 | void d_delete(struct dentry * dentry) |
| 1167 | { | 1161 | { |
| 1162 | int isdir = 0; | ||
| 1168 | /* | 1163 | /* |
| 1169 | * Are we the only user? | 1164 | * Are we the only user? |
| 1170 | */ | 1165 | */ |
| 1171 | spin_lock(&dcache_lock); | 1166 | spin_lock(&dcache_lock); |
| 1172 | spin_lock(&dentry->d_lock); | 1167 | spin_lock(&dentry->d_lock); |
| 1168 | isdir = S_ISDIR(dentry->d_inode->i_mode); | ||
| 1173 | if (atomic_read(&dentry->d_count) == 1) { | 1169 | if (atomic_read(&dentry->d_count) == 1) { |
| 1174 | dentry_iput(dentry); | 1170 | dentry_iput(dentry); |
| 1171 | fsnotify_nameremove(dentry, isdir); | ||
| 1175 | return; | 1172 | return; |
| 1176 | } | 1173 | } |
| 1177 | 1174 | ||
| @@ -1180,6 +1177,8 @@ void d_delete(struct dentry * dentry) | |||
| 1180 | 1177 | ||
| 1181 | spin_unlock(&dentry->d_lock); | 1178 | spin_unlock(&dentry->d_lock); |
| 1182 | spin_unlock(&dcache_lock); | 1179 | spin_unlock(&dcache_lock); |
| 1180 | |||
| 1181 | fsnotify_nameremove(dentry, isdir); | ||
| 1183 | } | 1182 | } |
| 1184 | 1183 | ||
| 1185 | static void __d_rehash(struct dentry * entry, struct hlist_head *list) | 1184 | static void __d_rehash(struct dentry * entry, struct hlist_head *list) |
