Whamcloud - gitweb
port snapfs to 2.4
[fs/lustre-release.git] / lustre / snapfs / cache.c
1 /*  
2  *  snapfs/cache.c
3  */
4
5 #define DEBUG_SUBSYSTEM S_SNAP
6
7 #include <linux/kmod.h>
8 #include <linux/init.h>
9 #include <linux/fs.h>
10 #include <linux/slab.h>
11 #include <linux/string.h>
12 #include <linux/jbd.h>
13 #include <linux/ext3_fs.h>
14 #include <linux/snap.h>
15 #include <portals/list.h>
16 #include "snapfs_internal.h" 
17 /*
18  * XXX - Not sure for snapfs that the cache functions are even needed.
19  * Can't all lookups be done by an inode->superblock->u.generic_sbp
20  * lookup?
21  */
22
23 extern struct snap_table snap_tables[SNAP_MAX_TABLES];
24
25 /* the intent of this hash is to have collision chains of length 1 */
26 #define CACHES_BITS 8
27 #define CACHES_SIZE (1 << CACHES_BITS)
28 #define CACHES_MASK CACHES_SIZE - 1
29
30 static struct list_head snap_caches[CACHES_SIZE];
31
32
33 static inline int snap_cache_hash(kdev_t dev)
34 {
35         return (CACHES_MASK) & ((0x000F & (dev)) + ((0x0F00 & (dev)) >>8));
36 }
37
38 inline void snap_cache_add(struct snap_cache *cache, kdev_t dev)
39 {
40         list_add(&cache->cache_chain,
41                  &snap_caches[snap_cache_hash(dev)]);
42         cache->cache_dev = dev;
43 }
44
45 inline void snap_init_cache_hash(void)
46 {
47         int i;
48         for ( i = 0; i < CACHES_SIZE; i++ ) {
49                 INIT_LIST_HEAD(&snap_caches[i]);
50         }
51 }
52
53 /* map a device to a cache */
54 struct snap_cache *snap_find_cache(kdev_t dev)
55 {
56         struct snap_cache *cache;
57         struct list_head *lh, *tmp;
58
59         lh = tmp = &(snap_caches[snap_cache_hash(dev)]);
60         list_for_each_entry(cache, lh, cache_chain) { 
61                 if ( cache->cache_dev == dev )
62                         return cache;
63         }
64         return NULL;
65 }
66
67 /* setup a cache structure when we need one */
68 struct snap_cache *snap_init_cache(void)
69 {
70         struct snap_cache *cache;
71
72         /* make a snap_cache structure for the hash */
73         SNAP_ALLOC(cache,  sizeof(struct snap_cache));
74         if ( cache ) {
75                 int i;
76                 
77                 memset(cache, 0, sizeof(struct snap_cache));
78                 INIT_LIST_HEAD(&cache->cache_chain);
79                 INIT_LIST_HEAD(&cache->cache_clone_list);
80                                 
81                 for (i = 0; i < SNAP_MAX_TABLES; i++) {
82                         init_MUTEX(&snap_tables[i].tbl_sema); 
83                 }
84         }
85         return cache;
86 }
87
88 /* free a cache structure and all of the memory it is pointing to */
89 inline void snap_free_cache(struct snap_cache *cache)
90 {
91         if (!cache)
92                 return;
93         SNAP_FREE(cache, sizeof(struct snap_cache));
94 }
95