diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-04-28 01:09:25 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-04-28 01:09:25 +0000 |
commit | b9ba7aeb165cffecdffb60aec8c3fa8d590d9ca9 (patch) | |
tree | 42d07b0c7246ae2536a702e7c5de9e2732341116 /fs/inode.c | |
parent | 7406b0a326f2d70ade2671c37d1beef62249db97 (diff) |
Merge with 2.3.99-pre6.
Diffstat (limited to 'fs/inode.c')
-rw-r--r-- | fs/inode.c | 68 |
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) |