typedef void (*cache_node_relse_t)(struct cache_node *);
typedef unsigned int (*cache_node_hash_t)(cache_key_t, unsigned int);
typedef int (*cache_node_compare_t)(struct cache_node *, cache_key_t);
+typedef unsigned int (*cache_bulk_relse_t)(struct cache *, struct list_head *);
struct cache_operations {
cache_node_hash_t hash;
cache_node_alloc_t alloc;
cache_node_relse_t relse;
cache_node_compare_t compare;
+ cache_bulk_relse_t bulkrelse; /* optional */
};
struct cache {
cache_node_alloc_t alloc; /* allocation function */
cache_node_relse_t relse; /* memory free function */
cache_node_compare_t compare; /* comparison routine */
+ cache_bulk_relse_t bulkrelse; /* bulk release routine */
unsigned int c_hashsize; /* hash bucket count */
struct cache_hash *c_hash; /* hash table buckets */
};
#define CACHE_DEBUG 1
+static unsigned int cache_generic_bulkrelse(struct cache *, struct list_head *);
+
struct cache *
cache_init(
unsigned int hashsize,
cache->alloc = cache_operations->alloc;
cache->relse = cache_operations->relse;
cache->compare = cache_operations->compare;
+ cache->bulkrelse = cache_operations->bulkrelse ?
+ cache_operations->bulkrelse : cache_generic_bulkrelse;
pthread_mutex_init(&cache->c_mutex, NULL);
for (i = 0; i < hashsize; i++) {
struct list_head * n;
struct cache_node * node;
unsigned int inuse = 0;
- unsigned int count = 0;
list_head_init(&temp);
head = &hash->ch_list;
break;
}
pthread_mutex_unlock(&hash->ch_mutex);
- while (!list_empty(&temp)) {
- node = (struct cache_node *)temp.next;
+ return cache->bulkrelse(cache, &temp);
+}
+
+/*
+ * Generic implementation of bulk release, which just iterates over
+ * the list calling the single node relse routine for each node.
+ */
+static unsigned int
+cache_generic_bulkrelse(
+ struct cache * cache,
+ struct list_head * list)
+{
+ struct cache_node * node;
+ unsigned int count = 0;
+
+ while (!list_empty(list)) {
+ node = (struct cache_node *)list->next;
pthread_mutex_destroy(&node->cn_mutex);
list_del_init(&node->cn_list);
cache->relse(node);
/* .alloc */ libxfs_balloc,
/* .relse */ libxfs_brelse,
/* .compare */ libxfs_bcompare,
+ /* .bulkrelse */ NULL /* TODO: lio_listio64 interface? */
};
/* .alloc */ libxfs_ialloc,
/* .relse */ libxfs_irelse,
/* .compare */ libxfs_icompare,
+ /* .bulkrelse */ NULL
};