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/dcache.c | |
parent | 7406b0a326f2d70ade2671c37d1beef62249db97 (diff) |
Merge with 2.3.99-pre6.
Diffstat (limited to 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 71 |
1 files changed, 51 insertions, 20 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 24e2f2568..3caf950eb 100644 --- a/fs/dcache.c +++ b/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 @@ kmem_cache_t *dentry_cache; * 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 @@ static inline void dentry_iput(struct dentry * dentry) } /* - * 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 @@ int shrink_dcache_memory(int priority, unsigned int gfp_mask, zone_t * zone) * @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 @@ struct dentry * d_alloc(struct dentry * parent, const struct qstr *name) /** * 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 @@ struct dentry * d_alloc(struct dentry * parent, const struct qstr *name) * * 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 @@ void d_instantiate(struct dentry *entry, struct inode * inode) * 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 @@ struct dentry * d_alloc_root(struct inode * root_inode) 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 @@ static inline struct list_head * d_hash(struct dentry * parent, unsigned long ha * 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 @@ void d_delete(struct dentry * dentry) * 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 @@ void d_move(struct dentry * dentry, struct dentry * target) * @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 @@ out: 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 @@ void __init dcache_init(void) 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++; |