aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dcache.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/dcache.c')
-rw-r--r--fs/dcache.c49
1 files changed, 23 insertions, 26 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index e987ad576a39..cc2b93802179 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -133,37 +133,34 @@ static void dentry_iput(struct dentry * dentry)
133} 133}
134 134
135/* 135/*
136 * dentry_lru_(add|add_tail|del|del_init) must be called with dcache_lock held. 136 * dentry_lru_(add|del|move_tail) must be called with dcache_lock held.
137 */ 137 */
138static void dentry_lru_add(struct dentry *dentry) 138static void dentry_lru_add(struct dentry *dentry)
139{ 139{
140 list_add(&dentry->d_lru, &dentry->d_sb->s_dentry_lru); 140 if (list_empty(&dentry->d_lru)) {
141 dentry->d_sb->s_nr_dentry_unused++; 141 list_add(&dentry->d_lru, &dentry->d_sb->s_dentry_lru);
142 percpu_counter_inc(&nr_dentry_unused); 142 dentry->d_sb->s_nr_dentry_unused++;
143} 143 percpu_counter_inc(&nr_dentry_unused);
144 144 }
145static void dentry_lru_add_tail(struct dentry *dentry)
146{
147 list_add_tail(&dentry->d_lru, &dentry->d_sb->s_dentry_lru);
148 dentry->d_sb->s_nr_dentry_unused++;
149 percpu_counter_inc(&nr_dentry_unused);
150} 145}
151 146
152static void dentry_lru_del(struct dentry *dentry) 147static void dentry_lru_del(struct dentry *dentry)
153{ 148{
154 if (!list_empty(&dentry->d_lru)) { 149 if (!list_empty(&dentry->d_lru)) {
155 list_del(&dentry->d_lru); 150 list_del_init(&dentry->d_lru);
156 dentry->d_sb->s_nr_dentry_unused--; 151 dentry->d_sb->s_nr_dentry_unused--;
157 percpu_counter_dec(&nr_dentry_unused); 152 percpu_counter_dec(&nr_dentry_unused);
158 } 153 }
159} 154}
160 155
161static void dentry_lru_del_init(struct dentry *dentry) 156static void dentry_lru_move_tail(struct dentry *dentry)
162{ 157{
163 if (likely(!list_empty(&dentry->d_lru))) { 158 if (list_empty(&dentry->d_lru)) {
164 list_del_init(&dentry->d_lru); 159 list_add_tail(&dentry->d_lru, &dentry->d_sb->s_dentry_lru);
165 dentry->d_sb->s_nr_dentry_unused--; 160 dentry->d_sb->s_nr_dentry_unused++;
166 percpu_counter_dec(&nr_dentry_unused); 161 percpu_counter_inc(&nr_dentry_unused);
162 } else {
163 list_move_tail(&dentry->d_lru, &dentry->d_sb->s_dentry_lru);
167 } 164 }
168} 165}
169 166
@@ -253,8 +250,7 @@ repeat:
253 250
254 /* Otherwise leave it cached and ensure it's on the LRU */ 251 /* Otherwise leave it cached and ensure it's on the LRU */
255 dentry->d_flags |= DCACHE_REFERENCED; 252 dentry->d_flags |= DCACHE_REFERENCED;
256 if (list_empty(&dentry->d_lru)) 253 dentry_lru_add(dentry);
257 dentry_lru_add(dentry);
258 254
259 spin_unlock(&dentry->d_lock); 255 spin_unlock(&dentry->d_lock);
260 spin_unlock(&dcache_lock); 256 spin_unlock(&dcache_lock);
@@ -333,7 +329,7 @@ EXPORT_SYMBOL(d_invalidate);
333static inline struct dentry * __dget_locked(struct dentry *dentry) 329static inline struct dentry * __dget_locked(struct dentry *dentry)
334{ 330{
335 atomic_inc(&dentry->d_count); 331 atomic_inc(&dentry->d_count);
336 dentry_lru_del_init(dentry); 332 dentry_lru_del(dentry);
337 return dentry; 333 return dentry;
338} 334}
339 335
@@ -452,7 +448,7 @@ static void prune_one_dentry(struct dentry * dentry)
452 448
453 if (dentry->d_op && dentry->d_op->d_delete) 449 if (dentry->d_op && dentry->d_op->d_delete)
454 dentry->d_op->d_delete(dentry); 450 dentry->d_op->d_delete(dentry);
455 dentry_lru_del_init(dentry); 451 dentry_lru_del(dentry);
456 __d_drop(dentry); 452 __d_drop(dentry);
457 dentry = d_kill(dentry); 453 dentry = d_kill(dentry);
458 spin_lock(&dcache_lock); 454 spin_lock(&dcache_lock);
@@ -465,7 +461,7 @@ static void shrink_dentry_list(struct list_head *list)
465 461
466 while (!list_empty(list)) { 462 while (!list_empty(list)) {
467 dentry = list_entry(list->prev, struct dentry, d_lru); 463 dentry = list_entry(list->prev, struct dentry, d_lru);
468 dentry_lru_del_init(dentry); 464 dentry_lru_del(dentry);
469 465
470 /* 466 /*
471 * We found an inuse dentry which was not removed from 467 * We found an inuse dentry which was not removed from
@@ -650,7 +646,7 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
650 646
651 /* detach this root from the system */ 647 /* detach this root from the system */
652 spin_lock(&dcache_lock); 648 spin_lock(&dcache_lock);
653 dentry_lru_del_init(dentry); 649 dentry_lru_del(dentry);
654 __d_drop(dentry); 650 __d_drop(dentry);
655 spin_unlock(&dcache_lock); 651 spin_unlock(&dcache_lock);
656 652
@@ -664,7 +660,7 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
664 spin_lock(&dcache_lock); 660 spin_lock(&dcache_lock);
665 list_for_each_entry(loop, &dentry->d_subdirs, 661 list_for_each_entry(loop, &dentry->d_subdirs,
666 d_u.d_child) { 662 d_u.d_child) {
667 dentry_lru_del_init(loop); 663 dentry_lru_del(loop);
668 __d_drop(loop); 664 __d_drop(loop);
669 cond_resched_lock(&dcache_lock); 665 cond_resched_lock(&dcache_lock);
670 } 666 }
@@ -841,14 +837,15 @@ resume:
841 struct dentry *dentry = list_entry(tmp, struct dentry, d_u.d_child); 837 struct dentry *dentry = list_entry(tmp, struct dentry, d_u.d_child);
842 next = tmp->next; 838 next = tmp->next;
843 839
844 dentry_lru_del_init(dentry);
845 /* 840 /*
846 * move only zero ref count dentries to the end 841 * move only zero ref count dentries to the end
847 * of the unused list for prune_dcache 842 * of the unused list for prune_dcache
848 */ 843 */
849 if (!atomic_read(&dentry->d_count)) { 844 if (!atomic_read(&dentry->d_count)) {
850 dentry_lru_add_tail(dentry); 845 dentry_lru_move_tail(dentry);
851 found++; 846 found++;
847 } else {
848 dentry_lru_del(dentry);
852 } 849 }
853 850
854 /* 851 /*