|
@@ -257,24 +257,10 @@ static void __d_free(struct rcu_head *head)
|
|
|
kmem_cache_free(dentry_cache, dentry);
|
|
|
}
|
|
|
|
|
|
-static void __d_free_external_name(struct rcu_head *head)
|
|
|
-{
|
|
|
- struct external_name *name = container_of(head, struct external_name,
|
|
|
- u.head);
|
|
|
-
|
|
|
- mod_node_page_state(page_pgdat(virt_to_page(name)),
|
|
|
- NR_INDIRECTLY_RECLAIMABLE_BYTES,
|
|
|
- -ksize(name));
|
|
|
-
|
|
|
- kfree(name);
|
|
|
-}
|
|
|
-
|
|
|
static void __d_free_external(struct rcu_head *head)
|
|
|
{
|
|
|
struct dentry *dentry = container_of(head, struct dentry, d_u.d_rcu);
|
|
|
-
|
|
|
- __d_free_external_name(&external_name(dentry)->u.head);
|
|
|
-
|
|
|
+ kfree(external_name(dentry));
|
|
|
kmem_cache_free(dentry_cache, dentry);
|
|
|
}
|
|
|
|
|
@@ -306,7 +292,7 @@ void release_dentry_name_snapshot(struct name_snapshot *name)
|
|
|
struct external_name *p;
|
|
|
p = container_of(name->name, struct external_name, name[0]);
|
|
|
if (unlikely(atomic_dec_and_test(&p->u.count)))
|
|
|
- call_rcu(&p->u.head, __d_free_external_name);
|
|
|
+ kfree_rcu(p, u.head);
|
|
|
}
|
|
|
}
|
|
|
EXPORT_SYMBOL(release_dentry_name_snapshot);
|
|
@@ -1606,7 +1592,6 @@ EXPORT_SYMBOL(d_invalidate);
|
|
|
|
|
|
struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name)
|
|
|
{
|
|
|
- struct external_name *ext = NULL;
|
|
|
struct dentry *dentry;
|
|
|
char *dname;
|
|
|
int err;
|
|
@@ -1627,14 +1612,15 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name)
|
|
|
dname = dentry->d_iname;
|
|
|
} else if (name->len > DNAME_INLINE_LEN-1) {
|
|
|
size_t size = offsetof(struct external_name, name[1]);
|
|
|
-
|
|
|
- ext = kmalloc(size + name->len, GFP_KERNEL_ACCOUNT);
|
|
|
- if (!ext) {
|
|
|
+ struct external_name *p = kmalloc(size + name->len,
|
|
|
+ GFP_KERNEL_ACCOUNT |
|
|
|
+ __GFP_RECLAIMABLE);
|
|
|
+ if (!p) {
|
|
|
kmem_cache_free(dentry_cache, dentry);
|
|
|
return NULL;
|
|
|
}
|
|
|
- atomic_set(&ext->u.count, 1);
|
|
|
- dname = ext->name;
|
|
|
+ atomic_set(&p->u.count, 1);
|
|
|
+ dname = p->name;
|
|
|
} else {
|
|
|
dname = dentry->d_iname;
|
|
|
}
|
|
@@ -1673,12 +1659,6 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (unlikely(ext)) {
|
|
|
- pg_data_t *pgdat = page_pgdat(virt_to_page(ext));
|
|
|
- mod_node_page_state(pgdat, NR_INDIRECTLY_RECLAIMABLE_BYTES,
|
|
|
- ksize(ext));
|
|
|
- }
|
|
|
-
|
|
|
this_cpu_inc(nr_dentry);
|
|
|
|
|
|
return dentry;
|
|
@@ -2707,7 +2687,7 @@ static void copy_name(struct dentry *dentry, struct dentry *target)
|
|
|
dentry->d_name.hash_len = target->d_name.hash_len;
|
|
|
}
|
|
|
if (old_name && likely(atomic_dec_and_test(&old_name->u.count)))
|
|
|
- call_rcu(&old_name->u.head, __d_free_external_name);
|
|
|
+ kfree_rcu(old_name, u.head);
|
|
|
}
|
|
|
|
|
|
/*
|