aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dcache.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/dcache.c')
-rw-r--r--fs/dcache.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index a7c67cee5d83..d68631f18df1 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -68,15 +68,19 @@ struct dentry_stat_t dentry_stat = {
68 .age_limit = 45, 68 .age_limit = 45,
69}; 69};
70 70
71static void d_callback(struct rcu_head *head) 71static void __d_free(struct dentry *dentry)
72{ 72{
73 struct dentry * dentry = container_of(head, struct dentry, d_u.d_rcu);
74
75 if (dname_external(dentry)) 73 if (dname_external(dentry))
76 kfree(dentry->d_name.name); 74 kfree(dentry->d_name.name);
77 kmem_cache_free(dentry_cache, dentry); 75 kmem_cache_free(dentry_cache, dentry);
78} 76}
79 77
78static void d_callback(struct rcu_head *head)
79{
80 struct dentry * dentry = container_of(head, struct dentry, d_u.d_rcu);
81 __d_free(dentry);
82}
83
80/* 84/*
81 * no dcache_lock, please. The caller must decrement dentry_stat.nr_dentry 85 * no dcache_lock, please. The caller must decrement dentry_stat.nr_dentry
82 * inside dcache_lock. 86 * inside dcache_lock.
@@ -85,7 +89,11 @@ static void d_free(struct dentry *dentry)
85{ 89{
86 if (dentry->d_op && dentry->d_op->d_release) 90 if (dentry->d_op && dentry->d_op->d_release)
87 dentry->d_op->d_release(dentry); 91 dentry->d_op->d_release(dentry);
88 call_rcu(&dentry->d_u.d_rcu, d_callback); 92 /* if dentry was never inserted into hash, immediate free is OK */
93 if (dentry->d_hash.pprev == NULL)
94 __d_free(dentry);
95 else
96 call_rcu(&dentry->d_u.d_rcu, d_callback);
89} 97}
90 98
91/* 99/*