diff options
Diffstat (limited to 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 48 |
1 files changed, 26 insertions, 22 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 11dc83092d4a..19458d399502 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -34,9 +34,8 @@ | |||
34 | #include <linux/swap.h> | 34 | #include <linux/swap.h> |
35 | #include <linux/bootmem.h> | 35 | #include <linux/bootmem.h> |
36 | 36 | ||
37 | /* #define DCACHE_DEBUG 1 */ | ||
38 | 37 | ||
39 | int sysctl_vfs_cache_pressure = 100; | 38 | int sysctl_vfs_cache_pressure __read_mostly = 100; |
40 | EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure); | 39 | EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure); |
41 | 40 | ||
42 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lock); | 41 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lock); |
@@ -44,7 +43,7 @@ static seqlock_t rename_lock __cacheline_aligned_in_smp = SEQLOCK_UNLOCKED; | |||
44 | 43 | ||
45 | EXPORT_SYMBOL(dcache_lock); | 44 | EXPORT_SYMBOL(dcache_lock); |
46 | 45 | ||
47 | static kmem_cache_t *dentry_cache; | 46 | static kmem_cache_t *dentry_cache __read_mostly; |
48 | 47 | ||
49 | #define DNAME_INLINE_LEN (sizeof(struct dentry)-offsetof(struct dentry,d_iname)) | 48 | #define DNAME_INLINE_LEN (sizeof(struct dentry)-offsetof(struct dentry,d_iname)) |
50 | 49 | ||
@@ -59,9 +58,9 @@ static kmem_cache_t *dentry_cache; | |||
59 | #define D_HASHBITS d_hash_shift | 58 | #define D_HASHBITS d_hash_shift |
60 | #define D_HASHMASK d_hash_mask | 59 | #define D_HASHMASK d_hash_mask |
61 | 60 | ||
62 | static unsigned int d_hash_mask; | 61 | static unsigned int d_hash_mask __read_mostly; |
63 | static unsigned int d_hash_shift; | 62 | static unsigned int d_hash_shift __read_mostly; |
64 | static struct hlist_head *dentry_hashtable; | 63 | static struct hlist_head *dentry_hashtable __read_mostly; |
65 | static LIST_HEAD(dentry_unused); | 64 | static LIST_HEAD(dentry_unused); |
66 | 65 | ||
67 | /* Statistics gathering. */ | 66 | /* Statistics gathering. */ |
@@ -325,10 +324,13 @@ static struct dentry * __d_find_alias(struct inode *inode, int want_discon) | |||
325 | 324 | ||
326 | struct dentry * d_find_alias(struct inode *inode) | 325 | struct dentry * d_find_alias(struct inode *inode) |
327 | { | 326 | { |
328 | struct dentry *de; | 327 | struct dentry *de = NULL; |
329 | spin_lock(&dcache_lock); | 328 | |
330 | de = __d_find_alias(inode, 0); | 329 | if (!list_empty(&inode->i_dentry)) { |
331 | spin_unlock(&dcache_lock); | 330 | spin_lock(&dcache_lock); |
331 | de = __d_find_alias(inode, 0); | ||
332 | spin_unlock(&dcache_lock); | ||
333 | } | ||
332 | return de; | 334 | return de; |
333 | } | 335 | } |
334 | 336 | ||
@@ -486,6 +488,7 @@ repeat: | |||
486 | continue; | 488 | continue; |
487 | } | 489 | } |
488 | prune_one_dentry(dentry); | 490 | prune_one_dentry(dentry); |
491 | cond_resched_lock(&dcache_lock); | ||
489 | goto repeat; | 492 | goto repeat; |
490 | } | 493 | } |
491 | spin_unlock(&dcache_lock); | 494 | spin_unlock(&dcache_lock); |
@@ -599,10 +602,6 @@ resume: | |||
599 | */ | 602 | */ |
600 | if (!list_empty(&dentry->d_subdirs)) { | 603 | if (!list_empty(&dentry->d_subdirs)) { |
601 | this_parent = dentry; | 604 | this_parent = dentry; |
602 | #ifdef DCACHE_DEBUG | ||
603 | printk(KERN_DEBUG "select_parent: descending to %s/%s, found=%d\n", | ||
604 | dentry->d_parent->d_name.name, dentry->d_name.name, found); | ||
605 | #endif | ||
606 | goto repeat; | 605 | goto repeat; |
607 | } | 606 | } |
608 | } | 607 | } |
@@ -612,10 +611,6 @@ dentry->d_parent->d_name.name, dentry->d_name.name, found); | |||
612 | if (this_parent != parent) { | 611 | if (this_parent != parent) { |
613 | next = this_parent->d_u.d_child.next; | 612 | next = this_parent->d_u.d_child.next; |
614 | this_parent = this_parent->d_parent; | 613 | this_parent = this_parent->d_parent; |
615 | #ifdef DCACHE_DEBUG | ||
616 | printk(KERN_DEBUG "select_parent: ascending to %s/%s, found=%d\n", | ||
617 | this_parent->d_parent->d_name.name, this_parent->d_name.name, found); | ||
618 | #endif | ||
619 | goto resume; | 614 | goto resume; |
620 | } | 615 | } |
621 | out: | 616 | out: |
@@ -794,11 +789,12 @@ struct dentry *d_alloc_name(struct dentry *parent, const char *name) | |||
794 | 789 | ||
795 | void d_instantiate(struct dentry *entry, struct inode * inode) | 790 | void d_instantiate(struct dentry *entry, struct inode * inode) |
796 | { | 791 | { |
797 | if (!list_empty(&entry->d_alias)) BUG(); | 792 | BUG_ON(!list_empty(&entry->d_alias)); |
798 | spin_lock(&dcache_lock); | 793 | spin_lock(&dcache_lock); |
799 | if (inode) | 794 | if (inode) |
800 | list_add(&entry->d_alias, &inode->i_dentry); | 795 | list_add(&entry->d_alias, &inode->i_dentry); |
801 | entry->d_inode = inode; | 796 | entry->d_inode = inode; |
797 | fsnotify_d_instantiate(entry, inode); | ||
802 | spin_unlock(&dcache_lock); | 798 | spin_unlock(&dcache_lock); |
803 | security_d_instantiate(entry, inode); | 799 | security_d_instantiate(entry, inode); |
804 | } | 800 | } |
@@ -850,6 +846,7 @@ struct dentry *d_instantiate_unique(struct dentry *entry, struct inode *inode) | |||
850 | list_add(&entry->d_alias, &inode->i_dentry); | 846 | list_add(&entry->d_alias, &inode->i_dentry); |
851 | do_negative: | 847 | do_negative: |
852 | entry->d_inode = inode; | 848 | entry->d_inode = inode; |
849 | fsnotify_d_instantiate(entry, inode); | ||
853 | spin_unlock(&dcache_lock); | 850 | spin_unlock(&dcache_lock); |
854 | security_d_instantiate(entry, inode); | 851 | security_d_instantiate(entry, inode); |
855 | return NULL; | 852 | return NULL; |
@@ -980,6 +977,7 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry) | |||
980 | new = __d_find_alias(inode, 1); | 977 | new = __d_find_alias(inode, 1); |
981 | if (new) { | 978 | if (new) { |
982 | BUG_ON(!(new->d_flags & DCACHE_DISCONNECTED)); | 979 | BUG_ON(!(new->d_flags & DCACHE_DISCONNECTED)); |
980 | fsnotify_d_instantiate(new, inode); | ||
983 | spin_unlock(&dcache_lock); | 981 | spin_unlock(&dcache_lock); |
984 | security_d_instantiate(new, inode); | 982 | security_d_instantiate(new, inode); |
985 | d_rehash(dentry); | 983 | d_rehash(dentry); |
@@ -989,6 +987,7 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry) | |||
989 | /* d_instantiate takes dcache_lock, so we do it by hand */ | 987 | /* d_instantiate takes dcache_lock, so we do it by hand */ |
990 | list_add(&dentry->d_alias, &inode->i_dentry); | 988 | list_add(&dentry->d_alias, &inode->i_dentry); |
991 | dentry->d_inode = inode; | 989 | dentry->d_inode = inode; |
990 | fsnotify_d_instantiate(dentry, inode); | ||
992 | spin_unlock(&dcache_lock); | 991 | spin_unlock(&dcache_lock); |
993 | security_d_instantiate(dentry, inode); | 992 | security_d_instantiate(dentry, inode); |
994 | d_rehash(dentry); | 993 | d_rehash(dentry); |
@@ -1173,6 +1172,9 @@ void d_delete(struct dentry * dentry) | |||
1173 | spin_lock(&dentry->d_lock); | 1172 | spin_lock(&dentry->d_lock); |
1174 | isdir = S_ISDIR(dentry->d_inode->i_mode); | 1173 | isdir = S_ISDIR(dentry->d_inode->i_mode); |
1175 | if (atomic_read(&dentry->d_count) == 1) { | 1174 | if (atomic_read(&dentry->d_count) == 1) { |
1175 | /* remove this and other inotify debug checks after 2.6.18 */ | ||
1176 | dentry->d_flags &= ~DCACHE_INOTIFY_PARENT_WATCHED; | ||
1177 | |||
1176 | dentry_iput(dentry); | 1178 | dentry_iput(dentry); |
1177 | fsnotify_nameremove(dentry, isdir); | 1179 | fsnotify_nameremove(dentry, isdir); |
1178 | return; | 1180 | return; |
@@ -1339,6 +1341,7 @@ already_unhashed: | |||
1339 | 1341 | ||
1340 | list_add(&dentry->d_u.d_child, &dentry->d_parent->d_subdirs); | 1342 | list_add(&dentry->d_u.d_child, &dentry->d_parent->d_subdirs); |
1341 | spin_unlock(&target->d_lock); | 1343 | spin_unlock(&target->d_lock); |
1344 | fsnotify_d_move(dentry); | ||
1342 | spin_unlock(&dentry->d_lock); | 1345 | spin_unlock(&dentry->d_lock); |
1343 | write_sequnlock(&rename_lock); | 1346 | write_sequnlock(&rename_lock); |
1344 | spin_unlock(&dcache_lock); | 1347 | spin_unlock(&dcache_lock); |
@@ -1682,7 +1685,8 @@ static void __init dcache_init(unsigned long mempages) | |||
1682 | dentry_cache = kmem_cache_create("dentry_cache", | 1685 | dentry_cache = kmem_cache_create("dentry_cache", |
1683 | sizeof(struct dentry), | 1686 | sizeof(struct dentry), |
1684 | 0, | 1687 | 0, |
1685 | SLAB_RECLAIM_ACCOUNT|SLAB_PANIC, | 1688 | (SLAB_RECLAIM_ACCOUNT|SLAB_PANIC| |
1689 | SLAB_MEM_SPREAD), | ||
1686 | NULL, NULL); | 1690 | NULL, NULL); |
1687 | 1691 | ||
1688 | set_shrinker(DEFAULT_SEEKS, shrink_dcache_memory); | 1692 | set_shrinker(DEFAULT_SEEKS, shrink_dcache_memory); |
@@ -1706,10 +1710,10 @@ static void __init dcache_init(unsigned long mempages) | |||
1706 | } | 1710 | } |
1707 | 1711 | ||
1708 | /* SLAB cache for __getname() consumers */ | 1712 | /* SLAB cache for __getname() consumers */ |
1709 | kmem_cache_t *names_cachep; | 1713 | kmem_cache_t *names_cachep __read_mostly; |
1710 | 1714 | ||
1711 | /* SLAB cache for file structures */ | 1715 | /* SLAB cache for file structures */ |
1712 | kmem_cache_t *filp_cachep; | 1716 | kmem_cache_t *filp_cachep __read_mostly; |
1713 | 1717 | ||
1714 | EXPORT_SYMBOL(d_genocide); | 1718 | EXPORT_SYMBOL(d_genocide); |
1715 | 1719 | ||