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

Next file: linux/fs/isofs/inode.c
Previous file: linux/fs/hpfs/namei.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.99-pre5/linux/fs/inode.c linux/fs/inode.c
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/quotaops.h>
 #include <linux/slab.h>
+#include <linux/cache.h>
 
 /*
  * New inode.c implementation.
@@ -32,9 +33,11 @@
  * 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	14
-#define HASH_SIZE	(1UL << HASH_BITS)
-#define HASH_MASK	(HASH_SIZE-1)
+#define I_HASHBITS	i_hash_shift
+#define I_HASHMASK	i_hash_mask
+
+static unsigned int i_hash_mask;
+static unsigned int i_hash_shift;
 
 /*
  * Each inode can be on two separate lists. One is
@@ -50,7 +53,7 @@
 
 static LIST_HEAD(inode_in_use);
 static LIST_HEAD(inode_unused);
-static struct list_head inode_hashtable[HASH_SIZE];
+static struct list_head *inode_hashtable;
 static LIST_HEAD(anon_hash_chain); /* for inodes with NULL i_sb */
 
 /*
@@ -116,7 +119,7 @@
  *	__mark_inode_dirty -	internal function
  *	@inode: inode to mark
  *
- *	Mark an inode as dirty. Callers should use mark_inode_dirty
+ *	Mark an inode as dirty. Callers should use mark_inode_dirty.
  */
  
 void __mark_inode_dirty(struct inode *inode)
@@ -530,7 +533,7 @@
  * no pre-existing information.
  *
  * On a successful return the inode pointer is returned. On a failure
- * a NULL pointer is returned. The returned inode is not on any superblock
+ * a %NULL pointer is returned. The returned inode is not on any superblock
  * lists.
  */
  
@@ -617,9 +620,9 @@
 
 static inline unsigned long hash(struct super_block *sb, unsigned long i_ino)
 {
-	unsigned long tmp = i_ino | (unsigned long) sb;
-	tmp = tmp + (tmp >> HASH_BITS) + (tmp >> HASH_BITS*2);
-	return tmp & HASH_MASK;
+	unsigned long tmp = i_ino | ((unsigned long) sb / L1_CACHE_BYTES);
+	tmp = tmp + (tmp >> I_HASHBITS) + (tmp >> I_HASHBITS*2);
+	return tmp & I_HASHMASK;
 }
 
 /* Yeah, I know about quadratic hash. Maybe, later. */
@@ -707,7 +710,7 @@
  *	@inode: unhashed inode
  *
  *	Add an inode to the inode hash for this superblock. If the inode
- *	has no superblock it is added to a seperate anonymous chain
+ *	has no superblock it is added to a separate anonymous chain.
  */
  
 void insert_inode_hash(struct inode *inode)
@@ -724,7 +727,7 @@
  *	remove_inode_hash - remove an inode from the hash
  *	@inode: inode to unhash
  *
- *	Remove an inode from the superblock or anonymous hash
+ *	Remove an inode from the superblock or anonymous hash.
  */
  
 void remove_inode_hash(struct inode *inode)
@@ -829,9 +832,9 @@
  *
  *	Returns the block number on the device holding the inode that
  *	is the disk block number for the block of the file requested.
- *	That is asked for block 4 of inode 1 the function will return the
+ *	That is, asked for block 4 of inode 1 the function will return the
  *	disk block relative to the disk start that holds that block of the 
- *	file
+ *	file.
  */
  
 int bmap(struct inode * inode, int block)
@@ -845,12 +848,41 @@
 /*
  * Initialize the hash tables.
  */
-void __init inode_init(void)
+void __init inode_init(unsigned long mempages)
 {
+	struct list_head *head;
+	unsigned long order;
+	unsigned int nr_hash;
 	int i;
-	struct list_head *head = inode_hashtable;
 
-	i = HASH_SIZE;
+	mempages >>= (14 - 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);
+		i_hash_mask = (nr_hash - 1);
+
+		tmp = nr_hash;
+		i_hash_shift = 0;
+		while ((tmp >>= 1UL) != 0UL)
+			i_hash_shift++;
+
+		inode_hashtable = (struct list_head *)
+			__get_free_pages(GFP_ATOMIC, order);
+	} while (inode_hashtable == NULL && --order >= 0);
+
+	if (!inode_hashtable)
+		panic("Failed to allocate inode hash table\n");
+
+	printk("VFS: INODE hash table configured to %d entries\n", nr_hash);
+
+	head = inode_hashtable;
+	i = nr_hash;
 	do {
 		INIT_LIST_HEAD(head);
 		head++;
@@ -869,9 +901,9 @@
  *	update_atime	-	update the access time
  *	@inode: inode accessed
  *
- *	Update the accessed time on an inode and mark it for  writeback.
+ *	Update the accessed time on an inode and mark it for writeback.
  *	This function automatically handles read only file systems and media,
- *	as well as the noatime flag and inode specific noatime markers
+ *	as well as the "noatime" flag and inode specific "noatime" markers.
  */
  
 void update_atime (struct inode *inode)

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