4 * Copyright (C) 2000 Stelias Computing, Inc.
5 * Copyright (C) 2000 Red Hat, Inc.
13 #include <asm/bitops.h>
14 #include <asm/uaccess.h>
15 #include <asm/system.h>
17 #include <linux/errno.h>
19 #include <linux/ext2_fs.h>
20 #include <linux/malloc.h>
21 #include <linux/vmalloc.h>
22 #include <linux/sched.h>
23 #include <linux/stat.h>
24 #include <linux/string.h>
25 #include <linux/locks.h>
26 #include <linux/blkdev.h>
27 #include <linux/init.h>
28 #define __NO_VERSION__
29 #include <linux/module.h>
31 #include <linux/filter.h>
32 #include <linux/snapfs.h>
33 #include <linux/snapsupport.h>
36 * XXX - Not sure for snapfs that the cache functions are even needed.
37 * Can't all lookups be done by an inode->superblock->u.generic_sbp
42 This file contains the routines associated with managing a
43 cache of files . These caches need to be found
44 fast so they are hashed by the device, with an attempt to have
45 collision chains of length 1.
48 /* the intent of this hash is to have collision chains of length 1 */
50 #define CACHES_SIZE (1 << CACHES_BITS)
51 #define CACHES_MASK CACHES_SIZE - 1
52 static struct list_head snap_caches[CACHES_SIZE];
54 static inline int snap_cache_hash(kdev_t dev)
56 return (CACHES_MASK) & ((0x000F & (dev)) + ((0x0F00 & (dev)) >>8));
59 inline void snap_cache_add(struct snap_cache *cache, kdev_t dev)
61 list_add(&cache->cache_chain,
62 &snap_caches[snap_cache_hash(dev)]);
63 cache->cache_dev = dev;
66 inline void snap_init_cache_hash(void)
69 for ( i = 0; i < CACHES_SIZE; i++ ) {
70 INIT_LIST_HEAD(&snap_caches[i]);
74 /* map a device to a cache */
75 struct snap_cache *snap_find_cache(kdev_t dev)
77 struct snap_cache *cache;
78 struct list_head *lh, *tmp;
80 lh = tmp = &(snap_caches[snap_cache_hash(dev)]);
81 while ( (tmp = lh->next) != lh ) {
82 cache = list_entry(tmp, struct snap_cache, cache_chain);
83 if ( cache->cache_dev == dev )
90 /* map an inode to a cache */
91 struct snap_cache *snap_get_cache(struct inode *inode)
93 struct snap_cache *cache;
95 /* find the correct snap_cache here, based on the device */
96 cache = snap_find_cache(inode->i_dev);
98 printk("WARNING: no cache for dev %d, ino %ld\n",
99 inode->i_dev, inode->i_ino);
107 /* another debugging routine: check fs is InterMezzo fs */
108 int snap_ispresto(struct inode *inode)
110 struct snap_cache *cache;
114 cache = snap_get_cache(inode);
117 return (inode->i_dev == cache->cache_dev);
120 /* setup a cache structure when we need one */
121 struct snap_cache *snap_init_cache(void)
123 struct snap_cache *cache;
125 /* make a snap_cache structure for the hash */
126 SNAP_ALLOC(cache, struct snap_cache *, sizeof(struct snap_cache));
128 memset(cache, 0, sizeof(struct snap_cache));
129 INIT_LIST_HEAD(&cache->cache_chain);
130 INIT_LIST_HEAD(&cache->cache_clone_list);
136 /* free a cache structure and all of the memory it is pointing to */
137 inline void snap_free_cache(struct snap_cache *cache)
143 SNAP_FREE(cache, sizeof(struct snap_cache));