summaryrefslogtreecommitdiff
path: root/include/linux/mbcache.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/mbcache.h')
-rw-r--r--include/linux/mbcache.h105
1 files changed, 62 insertions, 43 deletions
diff --git a/include/linux/mbcache.h b/include/linux/mbcache.h
index 5525d370701d..97e64184767d 100644
--- a/include/linux/mbcache.h
+++ b/include/linux/mbcache.h
@@ -1,53 +1,72 @@
-/*
- File: linux/mbcache.h
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_MBCACHE_H
+#define _LINUX_MBCACHE_H
- (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
-*/
+#include <linux/hash.h>
+#include <linux/list_bl.h>
+#include <linux/list.h>
+#include <linux/atomic.h>
+#include <linux/fs.h>
-struct mb_cache_entry {
- struct list_head e_lru_list;
- struct mb_cache *e_cache;
- unsigned short e_used;
- unsigned short e_queued;
- struct block_device *e_bdev;
- sector_t e_block;
- struct list_head e_block_list;
- struct {
- struct list_head o_list;
- unsigned int o_key;
- } e_index;
+struct mb_cache;
+
+/* Cache entry flags */
+enum {
+ MBE_REFERENCED_B = 0,
+ MBE_REUSABLE_B
};
-struct mb_cache {
- struct list_head c_cache_list;
- const char *c_name;
- atomic_t c_entry_count;
- int c_max_entries;
- int c_bucket_bits;
- struct kmem_cache *c_entry_cache;
- struct list_head *c_block_hash;
- struct list_head *c_index_hash;
+struct mb_cache_entry {
+ /* List of entries in cache - protected by cache->c_list_lock */
+ struct list_head e_list;
+ /*
+ * Hash table list - protected by hash chain bitlock. The entry is
+ * guaranteed to be hashed while e_refcnt > 0.
+ */
+ struct hlist_bl_node e_hash_list;
+ /*
+ * Entry refcount. Once it reaches zero, entry is unhashed and freed.
+ * While refcount > 0, the entry is guaranteed to stay in the hash and
+ * e.g. mb_cache_entry_try_delete() will fail.
+ */
+ atomic_t e_refcnt;
+ /* Key in hash - stable during lifetime of the entry */
+ u32 e_key;
+ unsigned long e_flags;
+ /* User provided value - stable during lifetime of the entry */
+ u64 e_value;
};
-/* Functions on caches */
+struct mb_cache *mb_cache_create(int bucket_bits);
+void mb_cache_destroy(struct mb_cache *cache);
-struct mb_cache *mb_cache_create(const char *, int);
-void mb_cache_shrink(struct block_device *);
-void mb_cache_destroy(struct mb_cache *);
+int mb_cache_entry_create(struct mb_cache *cache, gfp_t mask, u32 key,
+ u64 value, bool reusable);
+void __mb_cache_entry_free(struct mb_cache *cache,
+ struct mb_cache_entry *entry);
+void mb_cache_entry_wait_unused(struct mb_cache_entry *entry);
+static inline void mb_cache_entry_put(struct mb_cache *cache,
+ struct mb_cache_entry *entry)
+{
+ unsigned int cnt = atomic_dec_return(&entry->e_refcnt);
-/* Functions on cache entries */
+ if (cnt > 0) {
+ if (cnt <= 2)
+ wake_up_var(&entry->e_refcnt);
+ return;
+ }
+ __mb_cache_entry_free(cache, entry);
+}
-struct mb_cache_entry *mb_cache_entry_alloc(struct mb_cache *, gfp_t);
-int mb_cache_entry_insert(struct mb_cache_entry *, struct block_device *,
- sector_t, unsigned int);
-void mb_cache_entry_release(struct mb_cache_entry *);
-void mb_cache_entry_free(struct mb_cache_entry *);
-struct mb_cache_entry *mb_cache_entry_get(struct mb_cache *,
- struct block_device *,
- sector_t);
+struct mb_cache_entry *mb_cache_entry_delete_or_get(struct mb_cache *cache,
+ u32 key, u64 value);
+struct mb_cache_entry *mb_cache_entry_get(struct mb_cache *cache, u32 key,
+ u64 value);
struct mb_cache_entry *mb_cache_entry_find_first(struct mb_cache *cache,
- struct block_device *,
- unsigned int);
-struct mb_cache_entry *mb_cache_entry_find_next(struct mb_cache_entry *,
- struct block_device *,
- unsigned int);
+ u32 key);
+struct mb_cache_entry *mb_cache_entry_find_next(struct mb_cache *cache,
+ struct mb_cache_entry *entry);
+void mb_cache_entry_touch(struct mb_cache *cache,
+ struct mb_cache_entry *entry);
+
+#endif /* _LINUX_MBCACHE_H */