patch-2.3.99-pre6 linux/fs/dcache.c

Next file: linux/fs/devfs/base.c
Previous file: linux/fs/cramfs/uncompress.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.99-pre5/linux/fs/dcache.c linux/fs/dcache.c
@@ -21,6 +21,7 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/smp_lock.h>
+#include <linux/cache.h>
 
 #include <asm/uaccess.h>
 
@@ -40,11 +41,12 @@
  * This hash-function tries to avoid losing too many bits of hash
  * information, yet avoid using a prime hash-size or similar.
  */
-#define D_HASHBITS     14
-#define D_HASHSIZE     (1UL << D_HASHBITS)
-#define D_HASHMASK     (D_HASHSIZE-1)
+#define D_HASHBITS     d_hash_shift
+#define D_HASHMASK     d_hash_mask
 
-static struct list_head dentry_hashtable[D_HASHSIZE];
+static unsigned int d_hash_mask;
+static unsigned int d_hash_shift;
+static struct list_head *dentry_hashtable;
 static LIST_HEAD(dentry_unused);
 
 struct {
@@ -83,7 +85,7 @@
 }
 
 /* 
- * dput
+ * This is dput
  *
  * This is complicated by the fact that we do not want to put
  * dentries that are no longer on any hash chain on the unused
@@ -534,7 +536,7 @@
  * @parent: parent of entry to allocate
  * @name: qstr of the name
  *
- * Allocates a dentry. It returns NULL if there is insufficient memory
+ * Allocates a dentry. It returns %NULL if there is insufficient memory
  * available. On a success the dentry is returned. The name passed in is
  * copied and the copy passed in may be reused after this call.
  */
@@ -590,7 +592,7 @@
 /**
  * d_instantiate - fill in inode information for a dentry
  * @entry: dentry to complete
- * @inode: inode to attacheto this dentry
+ * @inode: inode to attach to this dentry
  *
  * Fill in inode information in the entry.
  *
@@ -599,7 +601,7 @@
  *
  * NOTE! This assumes that the inode count has been incremented
  * (or otherwise set) by the caller to indicate that it is now
- * in use by the dcache..
+ * in use by the dcache.
  */
  
 void d_instantiate(struct dentry *entry, struct inode * inode)
@@ -613,9 +615,9 @@
  * d_alloc_root - allocate root dentry
  * @root_inode: inode to allocate the root for
  *
- * Allocate a root ('/') dentry for the inode given. The inode is
- * instantiated and returned. NULL is returned if there is insufficient
- * memory or the inode passed is NULL.
+ * Allocate a root ("/") dentry for the inode given. The inode is
+ * instantiated and returned. %NULL is returned if there is insufficient
+ * memory or the inode passed is %NULL.
  */
  
 struct dentry * d_alloc_root(struct inode * root_inode)
@@ -635,7 +637,7 @@
 
 static inline struct list_head * d_hash(struct dentry * parent, unsigned long hash)
 {
-	hash += (unsigned long) parent;
+	hash += (unsigned long) parent / L1_CACHE_BYTES;
 	hash = hash ^ (hash >> D_HASHBITS) ^ (hash >> D_HASHBITS*2);
 	return dentry_hashtable + (hash & D_HASHMASK);
 }
@@ -648,7 +650,7 @@
  * Searches the children of the parent dentry for the name in question. If
  * the dentry is found its reference count is incremented and the dentry
  * is returned. The caller must use d_put to free the entry when it has
- * finished using it. NULL is returned on failure.
+ * finished using it. %NULL is returned on failure.
  */
  
 struct dentry * d_lookup(struct dentry * parent, struct qstr * name)
@@ -780,7 +782,7 @@
  * d_rehash	- add an entry back to the hash
  * @entry: dentry to add to the hash
  *
- * Adds a dentry to the hash according to its name
+ * Adds a dentry to the hash according to its name.
  */
  
 void d_rehash(struct dentry * entry)
@@ -881,11 +883,11 @@
  * @buffer: buffer to return value in
  * @buflen: buffer length
  *
- * Convert a dentry into an ascii path name. If the entry has been deleted
- * the string ' (deleted)' is appended. Note that this is ambiguous. Returns
+ * Convert a dentry into an ASCII path name. If the entry has been deleted
+ * the string " (deleted)" is appended. Note that this is ambiguous. Returns
  * the buffer.
  *
- * "buflen" should be PAGE_SIZE or more.
+ * "buflen" should be %PAGE_SIZE or more.
  */
 char * __d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
 		struct dentry *root, struct vfsmount *rootmnt,
@@ -1054,10 +1056,12 @@
 	return ino;
 }
 
-void __init dcache_init(void)
+void __init dcache_init(unsigned long mempages)
 {
+	struct list_head *d;
+	unsigned long order;
+	unsigned int nr_hash;
 	int i;
-	struct list_head *d = dentry_hashtable;
 
 	/* 
 	 * A constructor could be added for stable state like the lists,
@@ -1075,7 +1079,34 @@
 	if (!dentry_cache)
 		panic("Cannot create dentry cache");
 
-	i = D_HASHSIZE;
+	mempages >>= (13 - PAGE_SHIFT);
+	mempages *= sizeof(struct list_head);
+	for (order = 0; ((1UL << order) << PAGE_SHIFT) < mempages; order++)
+		;
+
+	do {
+		unsigned long tmp;
+
+		nr_hash = (1UL << order) * PAGE_SIZE /
+			sizeof(struct list_head);
+		d_hash_mask = (nr_hash - 1);
+
+		tmp = nr_hash;
+		d_hash_shift = 0;
+		while ((tmp >>= 1UL) != 0UL)
+			d_hash_shift++;
+
+		dentry_hashtable = (struct list_head *)
+			__get_free_pages(GFP_ATOMIC, order);
+	} while (dentry_hashtable == NULL && --order >= 0);
+
+	if (!dentry_hashtable)
+		panic("Failed to allocate dcache hash table\n");
+
+	printk("VFS: DCACHE hash table configured to %d entries\n", nr_hash);
+
+	d = dentry_hashtable;
+	i = nr_hash;
 	do {
 		INIT_LIST_HEAD(d);
 		d++;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)