summaryrefslogtreecommitdiffstats
path: root/fs/inode.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-04-28 01:09:25 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-04-28 01:09:25 +0000
commitb9ba7aeb165cffecdffb60aec8c3fa8d590d9ca9 (patch)
tree42d07b0c7246ae2536a702e7c5de9e2732341116 /fs/inode.c
parent7406b0a326f2d70ade2671c37d1beef62249db97 (diff)
Merge with 2.3.99-pre6.
Diffstat (limited to 'fs/inode.c')
-rw-r--r--fs/inode.c68
1 files changed, 50 insertions, 18 deletions
diff --git a/fs/inode.c b/fs/inode.c
index de7267c84..9068498c2 100644
--- a/fs/inode.c
+++ b/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 @@ static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
* __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 @@ static void clean_inode(struct inode *inode)
* 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 struct inode * get_new_inode(struct super_block *sb, unsigned long ino, s
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 @@ struct inode *iget4(struct super_block *sb, unsigned long ino, find_inode_t find
* @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 @@ void insert_inode_hash(struct inode *inode)
* 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 @@ kdevname(inode->i_dev), inode->i_ino, atomic_read(&inode->i_sem.count));
*
* 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 @@ int bmap(struct inode * inode, int block)
/*
* 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 @@ void __init inode_init(void)
* 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)