]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - include/cache.h
libxfs: plumb in refcount deferred op log items
[thirdparty/xfsprogs-dev.git] / include / cache.h
1 /*
2 * Copyright (c) 2006 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 #ifndef __CACHE_H__
19 #define __CACHE_H__
20
21 /*
22 * initialisation flags
23 */
24 /*
25 * xfs_db always writes changes immediately, and so we need to purge buffers
26 * when we get a buffer lookup mismatch due to reading the same block with a
27 * different buffer configuration.
28 */
29 #define CACHE_MISCOMPARE_PURGE (1 << 0)
30
31 /*
32 * cache object campare return values
33 */
34 enum {
35 CACHE_HIT,
36 CACHE_MISS,
37 CACHE_PURGE,
38 };
39
40 #define HASH_CACHE_RATIO 8
41
42 /*
43 * Cache priorities range from BASE to MAX.
44 *
45 * For prefetch support, the top half of the range starts at
46 * CACHE_PREFETCH_PRIORITY and everytime the buffer is fetched and is at or
47 * above this priority level, it is reduced to below this level (refer to
48 * libxfs_getbuf).
49 *
50 * If we have dirty nodes, we can't recycle them until they've been cleaned. To
51 * keep these out of the reclaimable lists (as there can be lots of them) give
52 * them their own priority that the shaker doesn't attempt to walk.
53 */
54
55 #define CACHE_BASE_PRIORITY 0
56 #define CACHE_PREFETCH_PRIORITY 8
57 #define CACHE_MAX_PRIORITY 15
58 #define CACHE_DIRTY_PRIORITY (CACHE_MAX_PRIORITY + 1)
59 #define CACHE_NR_PRIORITIES CACHE_DIRTY_PRIORITY
60
61 /*
62 * Simple, generic implementation of a cache (arbitrary data).
63 * Provides a hash table with a capped number of cache entries.
64 */
65
66 struct cache;
67 struct cache_node;
68
69 typedef void *cache_key_t;
70
71 typedef void (*cache_walk_t)(struct cache_node *);
72 typedef struct cache_node * (*cache_node_alloc_t)(cache_key_t);
73 typedef int (*cache_node_flush_t)(struct cache_node *);
74 typedef void (*cache_node_relse_t)(struct cache_node *);
75 typedef unsigned int (*cache_node_hash_t)(cache_key_t, unsigned int,
76 unsigned int);
77 typedef int (*cache_node_compare_t)(struct cache_node *, cache_key_t);
78 typedef unsigned int (*cache_bulk_relse_t)(struct cache *, struct list_head *);
79
80 struct cache_operations {
81 cache_node_hash_t hash;
82 cache_node_alloc_t alloc;
83 cache_node_flush_t flush;
84 cache_node_relse_t relse;
85 cache_node_compare_t compare;
86 cache_bulk_relse_t bulkrelse; /* optional */
87 };
88
89 struct cache_hash {
90 struct list_head ch_list; /* hash chain head */
91 unsigned int ch_count; /* hash chain length */
92 pthread_mutex_t ch_mutex; /* hash chain mutex */
93 };
94
95 struct cache_mru {
96 struct list_head cm_list; /* MRU head */
97 unsigned int cm_count; /* MRU length */
98 pthread_mutex_t cm_mutex; /* MRU lock */
99 };
100
101 struct cache_node {
102 struct list_head cn_hash; /* hash chain */
103 struct list_head cn_mru; /* MRU chain */
104 unsigned int cn_count; /* reference count */
105 unsigned int cn_hashidx; /* hash chain index */
106 int cn_priority; /* priority, -1 = free list */
107 int cn_old_priority;/* saved pre-dirty prio */
108 pthread_mutex_t cn_mutex; /* node mutex */
109 };
110
111 struct cache {
112 int c_flags; /* behavioural flags */
113 unsigned int c_maxcount; /* max cache nodes */
114 unsigned int c_count; /* count of nodes */
115 pthread_mutex_t c_mutex; /* node count mutex */
116 cache_node_hash_t hash; /* node hash function */
117 cache_node_alloc_t alloc; /* allocation function */
118 cache_node_flush_t flush; /* flush dirty data function */
119 cache_node_relse_t relse; /* memory free function */
120 cache_node_compare_t compare; /* comparison routine */
121 cache_bulk_relse_t bulkrelse; /* bulk release routine */
122 unsigned int c_hashsize; /* hash bucket count */
123 unsigned int c_hashshift; /* hash key shift */
124 struct cache_hash *c_hash; /* hash table buckets */
125 struct cache_mru c_mrus[CACHE_DIRTY_PRIORITY + 1];
126 unsigned long long c_misses; /* cache misses */
127 unsigned long long c_hits; /* cache hits */
128 unsigned int c_max; /* max nodes ever used */
129 };
130
131 struct cache *cache_init(int, unsigned int, struct cache_operations *);
132 void cache_destroy(struct cache *);
133 void cache_walk(struct cache *, cache_walk_t);
134 void cache_purge(struct cache *);
135 void cache_flush(struct cache *);
136
137 int cache_node_get(struct cache *, cache_key_t, struct cache_node **);
138 void cache_node_put(struct cache *, struct cache_node *);
139 void cache_node_set_priority(struct cache *, struct cache_node *, int);
140 int cache_node_get_priority(struct cache_node *);
141 int cache_node_purge(struct cache *, cache_key_t, struct cache_node *);
142 void cache_report(FILE *fp, const char *, struct cache *);
143 int cache_overflowed(struct cache *);
144
145 #endif /* __CACHE_H__ */