@@ -103,13 +103,25 @@ EXPORT_SYMBOL(slash_name);
static unsigned int d_hash_shift __read_mostly;
-static struct hlist_bl_head *dentry_hashtable __read_mostly;
+struct _hlist_bl_head {
+ struct hlist_bl_head head;
+ int count;
+};
-static inline struct hlist_bl_head *d_hash(unsigned int hash)
+static int nentries, nbuckets, maxcount;
+
+static struct _hlist_bl_head *dentry_hashtable __read_mostly;
+
+static inline struct _hlist_bl_head *_d_hash(unsigned int hash)
{
return dentry_hashtable + (hash >> d_hash_shift);
}
+static inline struct hlist_bl_head *d_hash(unsigned int hash)
+{
+ return &_d_hash(hash)->head;
+}
+
#define IN_LOOKUP_SHIFT 10
static struct hlist_bl_head in_lookup_hashtable[1 << IN_LOOKUP_SHIFT];
@@ -174,7 +186,7 @@ int proc_nr_dentry(struct ctl_table *table, int write, void __user *buffer,
* Compare 2 name strings, return 0 if they match, otherwise non-zero.
* The strings are both count bytes long, and count is non-zero.
*/
-#ifdef CONFIG_DCACHE_WORD_ACCESS
+#if 0//def CONFIG_DCACHE_WORD_ACCESS
#include <asm/word-at-a-time.h>
/*
@@ -471,19 +483,28 @@ static void dentry_lru_add(struct dentry *dentry)
static void ___d_drop(struct dentry *dentry)
{
if (!d_unhashed(dentry)) {
+ struct _hlist_bl_head *_b;
struct hlist_bl_head *b;
/*
* Hashed dentries are normally on the dentry hashtable,
* with the exception of those newly allocated by
* d_obtain_root, which are always IS_ROOT:
*/
- if (unlikely(IS_ROOT(dentry)))
+ if (unlikely(IS_ROOT(dentry))) {
+ _b = NULL;
b = &dentry->d_sb->s_roots;
- else
- b = d_hash(dentry->d_name.hash);
-
+ } else {
+ _b = _d_hash(dentry->d_name.hash);
+ b = &_b->head;
+ }
hlist_bl_lock(b);
__hlist_bl_del(&dentry->d_hash);
+ if (_b) {
+ _b->count--;
+ if (!_b->count)
+ nbuckets--;
+ nentries--;
+ }
hlist_bl_unlock(b);
/* After this call, in-progress rcu-walk path lookup will fail. */
write_seqcount_invalidate(&dentry->d_seq);
@@ -2406,10 +2427,20 @@ EXPORT_SYMBOL(d_delete);
static void __d_rehash(struct dentry *entry)
{
- struct hlist_bl_head *b = d_hash(entry->d_name.hash);
+ struct _hlist_bl_head *_b = _d_hash(entry->d_name.hash);
+ struct hlist_bl_head *b = &_b->head;
hlist_bl_lock(b);
hlist_bl_add_head_rcu(&entry->d_hash, b);
+ if (!_b->count)
+ nbuckets++;
+ _b->count++;
+ nentries++;
+ if (_b->count > maxcount) {
+ maxcount = _b->count;
+ pr_info("dcache: d_hash_shift = %d, nentries = %d, nbuckets = %d, maxcount = %d\n",
+ d_hash_shift, nentries, nbuckets, maxcount);
+ }
hlist_bl_unlock(b);
}
@@ -3610,7 +3641,7 @@ static void __init dcache_init_early(void)
dentry_hashtable =
alloc_large_system_hash("Dentry cache",
- sizeof(struct hlist_bl_head),
+ sizeof(struct _hlist_bl_head),
dhash_entries,
13,
HASH_EARLY | HASH_ZERO,
@@ -3618,7 +3649,7 @@ static void __init dcache_init_early(void)
NULL,
0,
0);
- d_hash_shift = 32 - d_hash_shift;
+ d_hash_shift = 32 - 12;//d_hash_shift;
}
static void __init dcache_init(void)
@@ -3638,7 +3669,7 @@ static void __init dcache_init(void)
dentry_hashtable =
alloc_large_system_hash("Dentry cache",
- sizeof(struct hlist_bl_head),
+ sizeof(struct _hlist_bl_head),
dhash_entries,
13,
HASH_ZERO,
@@ -3646,7 +3677,7 @@ static void __init dcache_init(void)
NULL,
0,
0);
- d_hash_shift = 32 - d_hash_shift;
+ d_hash_shift = 32 - 12;//d_hash_shift;
}
/* SLAB cache for __getname() consumers */
@@ -1798,7 +1798,7 @@ static int walk_component(struct nameidata *nd, int flags)
* the final mask". Again, that could be replaced with a
* efficient population count instruction or similar.
*/
-#ifdef CONFIG_DCACHE_WORD_ACCESS
+#if 0//def CONFIG_DCACHE_WORD_ACCESS
#include <asm/word-at-a-time.h>
@@ -1985,6 +1985,9 @@ unsigned long full_name_long_hash(const void *salt, const char *name,
}
EXPORT_SYMBOL(full_name_long_hash);
+// define end_name_hash to NOOP
+//#define end_name_hash (unsigned int)
+
unsigned int full_name_hash(const void *salt, const char *name,
unsigned int len)
{