diff -ruN linux-2.2.5/fs/buffer.c linux/fs/buffer.c
--- linux-2.2.5/fs/buffer.c	Mon Apr 19 22:19:22 1999
+++ linux/fs/buffer.c	Wed Apr 28 14:05:52 1999
@@ -420,7 +420,8 @@
 	}
 }
 
-#define _hashfn(dev,block) (((unsigned)(HASHDEV(dev)^block)) & bh_hash_mask)
+#define _hashfn(dev,block) \
+	((((unsigned long)(block) * 2654435761UL) >> 11) & bh_hash_mask)
 #define hash(dev,block) hash_table[_hashfn(dev,block)]
 
 static inline void remove_from_hash_queue(struct buffer_head * bh)
@@ -1528,7 +1529,7 @@
  */
 void __init buffer_init(void)
 {
-	int order = 5;		/* Currently maximum order.. */
+	int order = 4;
 	unsigned int nr_hash;
 
 	nr_hash = (1UL << order) * PAGE_SIZE / sizeof(struct buffer_head *);
diff -ruN linux-2.2.5/fs/dcache.c linux/fs/dcache.c
--- linux-2.2.5/fs/dcache.c	Sat Apr 17 21:03:53 1999
+++ linux/fs/dcache.c	Tue Apr 27 21:56:26 1999
@@ -41,7 +41,7 @@
  * 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     10
+#define D_HASHBITS     13
 #define D_HASHSIZE     (1UL << D_HASHBITS)
 #define D_HASHMASK     (D_HASHSIZE-1)
 
@@ -472,7 +472,7 @@
 void shrink_dcache_memory(int priority, unsigned int gfp_mask)
 {
 	if (gfp_mask & __GFP_IO)
-		prune_dcache(0);
+		prune_dcache(dentry_stat.nr_unused / (priority+1));
 }
 
 #define NAME_ALLOC_LEN(len)	((len+16) & ~15)
@@ -560,7 +560,7 @@
 static inline struct list_head * d_hash(struct dentry * parent, unsigned long hash)
 {
 	hash += (unsigned long) parent;
-	hash = hash ^ (hash >> D_HASHBITS) ^ (hash >> D_HASHBITS*2);
+	hash = hash + (hash >> D_HASHBITS) + (hash >> D_HASHBITS*2);
 	return dentry_hashtable + (hash & D_HASHMASK);
 }
 
diff -ruN linux-2.2.5/fs/inode.c linux/fs/inode.c
--- linux-2.2.5/fs/inode.c	Sat Apr 17 21:03:53 1999
+++ linux/fs/inode.c	Tue Apr 27 22:15:22 1999
@@ -28,7 +28,7 @@
  * Inode lookup is no longer as critical as it used to be:
  * most of the lookups are going to be through the dcache.
  */
-#define HASH_BITS	8
+#define HASH_BITS	11
 #define HASH_SIZE	(1UL << HASH_BITS)
 #define HASH_MASK	(HASH_SIZE-1)
 
@@ -644,7 +644,7 @@
 
 static inline unsigned long hash(struct super_block *sb, unsigned long i_ino)
 {
-	unsigned long tmp = i_ino | (unsigned long) sb;
+	unsigned long tmp = i_ino + (unsigned long) sb;
 	tmp = tmp + (tmp >> HASH_BITS) + (tmp >> HASH_BITS*2);
 	return tmp & HASH_MASK;
 }
diff -ruN linux-2.2.5/include/linux/pagemap.h linux/include/linux/pagemap.h
--- linux-2.2.5/include/linux/pagemap.h	Mon Apr 19 22:19:54 1999
+++ linux/include/linux/pagemap.h	Wed Apr 28 14:07:17 1999
@@ -17,7 +17,7 @@
 	return PAGE_OFFSET + PAGE_SIZE * (page - mem_map);
 }
 
-#define PAGE_HASH_BITS 11
+#define PAGE_HASH_BITS 13
 #define PAGE_HASH_SIZE (1 << PAGE_HASH_BITS)
 
 #define PAGE_AGE_VALUE 16
@@ -36,7 +36,7 @@
 #define i (((unsigned long) inode)/(sizeof(struct inode) & ~ (sizeof(struct inode) - 1)))
 #define o (offset >> PAGE_SHIFT)
 #define s(x) ((x)+((x)>>PAGE_HASH_BITS))
-	return s(i+o) & (PAGE_HASH_SIZE-1);
+	return s(i+o+offset) & (PAGE_HASH_SIZE-1);
 #undef i
 #undef o
 #undef s
diff -ruN linux-2.2.5/mm/vmscan.c linux/mm/vmscan.c
--- linux-2.2.5/mm/vmscan.c	Sat Apr 17 21:03:43 1999
+++ linux/mm/vmscan.c	Tue Apr 27 18:10:29 1999
@@ -393,6 +393,8 @@
 				goto done;
 		}
 
+		shrink_dcache_memory(priority, gfp_mask);
+
 		/* Try to get rid of some shared memory pages.. */
 		if (gfp_mask & __GFP_IO) {
 			while (shm_swap(priority, gfp_mask)) {
@@ -406,8 +408,6 @@
 			if (!--count)
 				goto done;
 		}
-
-		shrink_dcache_memory(priority, gfp_mask);
 	} while (--priority >= 0);
 done:
 	unlock_kernel();
