VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   32 Branches   54 Tags
09c434b8a0047 fs/mbcache.c  (Thomas Gleixner     2019-05-19 13:08:20 +0100   1) // SPDX-License-Identifier: GPL-2.0-only
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500   2) #include <linux/spinlock.h>
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500   3) #include <linux/slab.h>
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500   4) #include <linux/list.h>
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500   5) #include <linux/list_bl.h>
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500   6) #include <linux/module.h>
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500   7) #include <linux/sched.h>
c2f3140fe2ece fs/mbcache2.c (Jan Kara            2016-02-22 12:33:03 -0500   8) #include <linux/workqueue.h>
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500   9) #include <linux/mbcache.h>
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  10) 
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  11) /*
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  12)  * Mbcache is a simple key-value store. Keys need not be unique, however
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  13)  * key-value pairs are expected to be unique (we use this fact in
c07dfcb45877f fs/mbcache.c  (Tahsin Erdogan      2017-06-22 10:29:53 -0400  14)  * mb_cache_entry_delete()).
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  15)  *
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  16)  * Ext2 and ext4 use this cache for deduplication of extended attribute blocks.
dec214d00e0d7 fs/mbcache.c  (Tahsin Erdogan      2017-06-22 11:44:55 -0400  17)  * Ext4 also uses it for deduplication of xattr values stored in inodes.
dec214d00e0d7 fs/mbcache.c  (Tahsin Erdogan      2017-06-22 11:44:55 -0400  18)  * They use hash of data as a key and provide a value that may represent a
dec214d00e0d7 fs/mbcache.c  (Tahsin Erdogan      2017-06-22 11:44:55 -0400  19)  * block or inode number. That's why keys need not be unique (hash of different
dec214d00e0d7 fs/mbcache.c  (Tahsin Erdogan      2017-06-22 11:44:55 -0400  20)  * data may be the same). However user provided value always uniquely
dec214d00e0d7 fs/mbcache.c  (Tahsin Erdogan      2017-06-22 11:44:55 -0400  21)  * identifies a cache entry.
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  22)  *
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  23)  * We provide functions for creation and removal of entries, search by key,
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  24)  * and a special "delete entry with given key-value pair" operation. Fixed
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  25)  * size hash table is used for fast key lookups.
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  26)  */
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  27) 
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500  28) struct mb_cache {
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  29) 	/* Hash table of entries */
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  30) 	struct hlist_bl_head	*c_hash;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  31) 	/* log2 of hash table size */
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  32) 	int			c_bucket_bits;
c2f3140fe2ece fs/mbcache2.c (Jan Kara            2016-02-22 12:33:03 -0500  33) 	/* Maximum entries in cache to avoid degrading hash too much */
132d4e2d55dfd fs/mbcache.c  (Eric Biggers        2016-12-03 15:43:48 -0500  34) 	unsigned long		c_max_entries;
f0c8b46238db9 fs/mbcache2.c (Jan Kara            2016-02-22 18:23:47 -0500  35) 	/* Protects c_list, c_entry_count */
f0c8b46238db9 fs/mbcache2.c (Jan Kara            2016-02-22 18:23:47 -0500  36) 	spinlock_t		c_list_lock;
f0c8b46238db9 fs/mbcache2.c (Jan Kara            2016-02-22 18:23:47 -0500  37) 	struct list_head	c_list;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  38) 	/* Number of entries in cache */
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  39) 	unsigned long		c_entry_count;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  40) 	struct shrinker		c_shrink;
c2f3140fe2ece fs/mbcache2.c (Jan Kara            2016-02-22 12:33:03 -0500  41) 	/* Work for shrinking when the cache has too many entries */
c2f3140fe2ece fs/mbcache2.c (Jan Kara            2016-02-22 12:33:03 -0500  42) 	struct work_struct	c_shrink_work;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  43) };
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  44) 
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500  45) static struct kmem_cache *mb_entry_cache;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  46) 
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500  47) static unsigned long mb_cache_shrink(struct mb_cache *cache,
132d4e2d55dfd fs/mbcache.c  (Eric Biggers        2016-12-03 15:43:48 -0500  48) 				     unsigned long nr_to_scan);
c2f3140fe2ece fs/mbcache2.c (Jan Kara            2016-02-22 12:33:03 -0500  49) 
dc8d5e565f00c fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:42:05 -0500  50) static inline struct hlist_bl_head *mb_cache_entry_head(struct mb_cache *cache,
dc8d5e565f00c fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:42:05 -0500  51) 							u32 key)
f0c8b46238db9 fs/mbcache2.c (Jan Kara            2016-02-22 18:23:47 -0500  52) {
dc8d5e565f00c fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:42:05 -0500  53) 	return &cache->c_hash[hash_32(key, cache->c_bucket_bits)];
f0c8b46238db9 fs/mbcache2.c (Jan Kara            2016-02-22 18:23:47 -0500  54) }
f0c8b46238db9 fs/mbcache2.c (Jan Kara            2016-02-22 18:23:47 -0500  55) 
c2f3140fe2ece fs/mbcache2.c (Jan Kara            2016-02-22 12:33:03 -0500  56) /*
c2f3140fe2ece fs/mbcache2.c (Jan Kara            2016-02-22 12:33:03 -0500  57)  * Number of entries to reclaim synchronously when there are too many entries
c2f3140fe2ece fs/mbcache2.c (Jan Kara            2016-02-22 12:33:03 -0500  58)  * in cache
c2f3140fe2ece fs/mbcache2.c (Jan Kara            2016-02-22 12:33:03 -0500  59)  */
c2f3140fe2ece fs/mbcache2.c (Jan Kara            2016-02-22 12:33:03 -0500  60) #define SYNC_SHRINK_BATCH 64
c2f3140fe2ece fs/mbcache2.c (Jan Kara            2016-02-22 12:33:03 -0500  61) 
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  62) /*
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500  63)  * mb_cache_entry_create - create entry in cache
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  64)  * @cache - cache where the entry should be created
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  65)  * @mask - gfp mask with which the entry should be allocated
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  66)  * @key - key of the entry
c07dfcb45877f fs/mbcache.c  (Tahsin Erdogan      2017-06-22 10:29:53 -0400  67)  * @value - value of the entry
c07dfcb45877f fs/mbcache.c  (Tahsin Erdogan      2017-06-22 10:29:53 -0400  68)  * @reusable - is the entry reusable by others?
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  69)  *
c07dfcb45877f fs/mbcache.c  (Tahsin Erdogan      2017-06-22 10:29:53 -0400  70)  * Creates entry in @cache with key @key and value @value. The function returns
c07dfcb45877f fs/mbcache.c  (Tahsin Erdogan      2017-06-22 10:29:53 -0400  71)  * -EBUSY if entry with the same key and value already exists in cache.
c07dfcb45877f fs/mbcache.c  (Tahsin Erdogan      2017-06-22 10:29:53 -0400  72)  * Otherwise 0 is returned.
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  73)  */
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500  74) int mb_cache_entry_create(struct mb_cache *cache, gfp_t mask, u32 key,
c07dfcb45877f fs/mbcache.c  (Tahsin Erdogan      2017-06-22 10:29:53 -0400  75) 			  u64 value, bool reusable)
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  76) {
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500  77) 	struct mb_cache_entry *entry, *dup;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  78) 	struct hlist_bl_node *dup_node;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  79) 	struct hlist_bl_head *head;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  80) 
c2f3140fe2ece fs/mbcache2.c (Jan Kara            2016-02-22 12:33:03 -0500  81) 	/* Schedule background reclaim if there are too many entries */
c2f3140fe2ece fs/mbcache2.c (Jan Kara            2016-02-22 12:33:03 -0500  82) 	if (cache->c_entry_count >= cache->c_max_entries)
c2f3140fe2ece fs/mbcache2.c (Jan Kara            2016-02-22 12:33:03 -0500  83) 		schedule_work(&cache->c_shrink_work);
c2f3140fe2ece fs/mbcache2.c (Jan Kara            2016-02-22 12:33:03 -0500  84) 	/* Do some sync reclaim if background reclaim cannot keep up */
c2f3140fe2ece fs/mbcache2.c (Jan Kara            2016-02-22 12:33:03 -0500  85) 	if (cache->c_entry_count >= 2*cache->c_max_entries)
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500  86) 		mb_cache_shrink(cache, SYNC_SHRINK_BATCH);
c2f3140fe2ece fs/mbcache2.c (Jan Kara            2016-02-22 12:33:03 -0500  87) 
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500  88) 	entry = kmem_cache_alloc(mb_entry_cache, mask);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  89) 	if (!entry)
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  90) 		return -ENOMEM;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  91) 
f0c8b46238db9 fs/mbcache2.c (Jan Kara            2016-02-22 18:23:47 -0500  92) 	INIT_LIST_HEAD(&entry->e_list);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  93) 	/* One ref for hash, one ref returned */
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  94) 	atomic_set(&entry->e_refcnt, 1);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500  95) 	entry->e_key = key;
c07dfcb45877f fs/mbcache.c  (Tahsin Erdogan      2017-06-22 10:29:53 -0400  96) 	entry->e_value = value;
6048c64b26097 fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:44:04 -0500  97) 	entry->e_reusable = reusable;
3876bbe27d04b fs/mbcache.c  (Alexander Potapenko 2018-01-07 16:22:35 -0500  98) 	entry->e_referenced = 0;
dc8d5e565f00c fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:42:05 -0500  99) 	head = mb_cache_entry_head(cache, key);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 100) 	hlist_bl_lock(head);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 101) 	hlist_bl_for_each_entry(dup, dup_node, head, e_hash_list) {
c07dfcb45877f fs/mbcache.c  (Tahsin Erdogan      2017-06-22 10:29:53 -0400 102) 		if (dup->e_key == key && dup->e_value == value) {
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 103) 			hlist_bl_unlock(head);
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 104) 			kmem_cache_free(mb_entry_cache, entry);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 105) 			return -EBUSY;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 106) 		}
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 107) 	}
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 108) 	hlist_bl_add_head(&entry->e_hash_list, head);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 109) 	hlist_bl_unlock(head);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 110) 
f0c8b46238db9 fs/mbcache2.c (Jan Kara            2016-02-22 18:23:47 -0500 111) 	spin_lock(&cache->c_list_lock);
f0c8b46238db9 fs/mbcache2.c (Jan Kara            2016-02-22 18:23:47 -0500 112) 	list_add_tail(&entry->e_list, &cache->c_list);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 113) 	/* Grab ref for LRU list */
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 114) 	atomic_inc(&entry->e_refcnt);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 115) 	cache->c_entry_count++;
f0c8b46238db9 fs/mbcache2.c (Jan Kara            2016-02-22 18:23:47 -0500 116) 	spin_unlock(&cache->c_list_lock);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 117) 
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 118) 	return 0;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 119) }
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 120) EXPORT_SYMBOL(mb_cache_entry_create);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 121) 
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 122) void __mb_cache_entry_free(struct mb_cache_entry *entry)
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 123) {
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 124) 	kmem_cache_free(mb_entry_cache, entry);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 125) }
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 126) EXPORT_SYMBOL(__mb_cache_entry_free);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 127) 
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 128) static struct mb_cache_entry *__entry_find(struct mb_cache *cache,
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 129) 					   struct mb_cache_entry *entry,
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 130) 					   u32 key)
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 131) {
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 132) 	struct mb_cache_entry *old_entry = entry;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 133) 	struct hlist_bl_node *node;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 134) 	struct hlist_bl_head *head;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 135) 
dc8d5e565f00c fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:42:05 -0500 136) 	head = mb_cache_entry_head(cache, key);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 137) 	hlist_bl_lock(head);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 138) 	if (entry && !hlist_bl_unhashed(&entry->e_hash_list))
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 139) 		node = entry->e_hash_list.next;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 140) 	else
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 141) 		node = hlist_bl_first(head);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 142) 	while (node) {
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 143) 		entry = hlist_bl_entry(node, struct mb_cache_entry,
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 144) 				       e_hash_list);
6048c64b26097 fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 145) 		if (entry->e_key == key && entry->e_reusable) {
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 146) 			atomic_inc(&entry->e_refcnt);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 147) 			goto out;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 148) 		}
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 149) 		node = node->next;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 150) 	}
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 151) 	entry = NULL;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 152) out:
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 153) 	hlist_bl_unlock(head);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 154) 	if (old_entry)
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 155) 		mb_cache_entry_put(cache, old_entry);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 156) 
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 157) 	return entry;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 158) }
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 159) 
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 160) /*
b649668c0bb3f fs/mbcache.c  (Eric Biggers        2016-12-03 15:55:01 -0500 161)  * mb_cache_entry_find_first - find the first reusable entry with the given key
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 162)  * @cache: cache where we should search
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 163)  * @key: key to look for
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 164)  *
b649668c0bb3f fs/mbcache.c  (Eric Biggers        2016-12-03 15:55:01 -0500 165)  * Search in @cache for a reusable entry with key @key. Grabs reference to the
b649668c0bb3f fs/mbcache.c  (Eric Biggers        2016-12-03 15:55:01 -0500 166)  * first reusable entry found and returns the entry.
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 167)  */
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 168) struct mb_cache_entry *mb_cache_entry_find_first(struct mb_cache *cache,
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 169) 						 u32 key)
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 170) {
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 171) 	return __entry_find(cache, NULL, key);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 172) }
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 173) EXPORT_SYMBOL(mb_cache_entry_find_first);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 174) 
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 175) /*
b649668c0bb3f fs/mbcache.c  (Eric Biggers        2016-12-03 15:55:01 -0500 176)  * mb_cache_entry_find_next - find next reusable entry with the same key
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 177)  * @cache: cache where we should search
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 178)  * @entry: entry to start search from
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 179)  *
b649668c0bb3f fs/mbcache.c  (Eric Biggers        2016-12-03 15:55:01 -0500 180)  * Finds next reusable entry in the hash chain which has the same key as @entry.
b649668c0bb3f fs/mbcache.c  (Eric Biggers        2016-12-03 15:55:01 -0500 181)  * If @entry is unhashed (which can happen when deletion of entry races with the
b649668c0bb3f fs/mbcache.c  (Eric Biggers        2016-12-03 15:55:01 -0500 182)  * search), finds the first reusable entry in the hash chain. The function drops
b649668c0bb3f fs/mbcache.c  (Eric Biggers        2016-12-03 15:55:01 -0500 183)  * reference to @entry and returns with a reference to the found entry.
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 184)  */
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 185) struct mb_cache_entry *mb_cache_entry_find_next(struct mb_cache *cache,
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 186) 						struct mb_cache_entry *entry)
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 187) {
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 188) 	return __entry_find(cache, entry, entry->e_key);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 189) }
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 190) EXPORT_SYMBOL(mb_cache_entry_find_next);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 191) 
6048c64b26097 fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 192) /*
c07dfcb45877f fs/mbcache.c  (Tahsin Erdogan      2017-06-22 10:29:53 -0400 193)  * mb_cache_entry_get - get a cache entry by value (and key)
6048c64b26097 fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 194)  * @cache - cache we work with
c07dfcb45877f fs/mbcache.c  (Tahsin Erdogan      2017-06-22 10:29:53 -0400 195)  * @key - key
c07dfcb45877f fs/mbcache.c  (Tahsin Erdogan      2017-06-22 10:29:53 -0400 196)  * @value - value
6048c64b26097 fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 197)  */
6048c64b26097 fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 198) struct mb_cache_entry *mb_cache_entry_get(struct mb_cache *cache, u32 key,
c07dfcb45877f fs/mbcache.c  (Tahsin Erdogan      2017-06-22 10:29:53 -0400 199) 					  u64 value)
6048c64b26097 fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 200) {
6048c64b26097 fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 201) 	struct hlist_bl_node *node;
6048c64b26097 fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 202) 	struct hlist_bl_head *head;
6048c64b26097 fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 203) 	struct mb_cache_entry *entry;
6048c64b26097 fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 204) 
6048c64b26097 fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 205) 	head = mb_cache_entry_head(cache, key);
6048c64b26097 fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 206) 	hlist_bl_lock(head);
6048c64b26097 fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 207) 	hlist_bl_for_each_entry(entry, node, head, e_hash_list) {
c07dfcb45877f fs/mbcache.c  (Tahsin Erdogan      2017-06-22 10:29:53 -0400 208) 		if (entry->e_key == key && entry->e_value == value) {
6048c64b26097 fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 209) 			atomic_inc(&entry->e_refcnt);
6048c64b26097 fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 210) 			goto out;
6048c64b26097 fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 211) 		}
6048c64b26097 fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 212) 	}
6048c64b26097 fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 213) 	entry = NULL;
6048c64b26097 fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 214) out:
6048c64b26097 fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 215) 	hlist_bl_unlock(head);
6048c64b26097 fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 216) 	return entry;
6048c64b26097 fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 217) }
6048c64b26097 fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 218) EXPORT_SYMBOL(mb_cache_entry_get);
6048c64b26097 fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:44:04 -0500 219) 
c07dfcb45877f fs/mbcache.c  (Tahsin Erdogan      2017-06-22 10:29:53 -0400 220) /* mb_cache_entry_delete - remove a cache entry
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 221)  * @cache - cache we work with
c07dfcb45877f fs/mbcache.c  (Tahsin Erdogan      2017-06-22 10:29:53 -0400 222)  * @key - key
c07dfcb45877f fs/mbcache.c  (Tahsin Erdogan      2017-06-22 10:29:53 -0400 223)  * @value - value
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 224)  *
c07dfcb45877f fs/mbcache.c  (Tahsin Erdogan      2017-06-22 10:29:53 -0400 225)  * Remove entry from cache @cache with key @key and value @value.
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 226)  */
c07dfcb45877f fs/mbcache.c  (Tahsin Erdogan      2017-06-22 10:29:53 -0400 227) void mb_cache_entry_delete(struct mb_cache *cache, u32 key, u64 value)
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 228) {
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 229) 	struct hlist_bl_node *node;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 230) 	struct hlist_bl_head *head;
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 231) 	struct mb_cache_entry *entry;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 232) 
dc8d5e565f00c fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:42:05 -0500 233) 	head = mb_cache_entry_head(cache, key);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 234) 	hlist_bl_lock(head);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 235) 	hlist_bl_for_each_entry(entry, node, head, e_hash_list) {
c07dfcb45877f fs/mbcache.c  (Tahsin Erdogan      2017-06-22 10:29:53 -0400 236) 		if (entry->e_key == key && entry->e_value == value) {
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 237) 			/* We keep hash list reference to keep entry alive */
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 238) 			hlist_bl_del_init(&entry->e_hash_list);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 239) 			hlist_bl_unlock(head);
f0c8b46238db9 fs/mbcache2.c (Jan Kara            2016-02-22 18:23:47 -0500 240) 			spin_lock(&cache->c_list_lock);
f0c8b46238db9 fs/mbcache2.c (Jan Kara            2016-02-22 18:23:47 -0500 241) 			if (!list_empty(&entry->e_list)) {
f0c8b46238db9 fs/mbcache2.c (Jan Kara            2016-02-22 18:23:47 -0500 242) 				list_del_init(&entry->e_list);
9ee93ba3c430d fs/mbcache.c  (Jiang Biao          2018-01-09 23:57:52 -0500 243) 				if (!WARN_ONCE(cache->c_entry_count == 0,
9ee93ba3c430d fs/mbcache.c  (Jiang Biao          2018-01-09 23:57:52 -0500 244) 		"mbcache: attempt to decrement c_entry_count past zero"))
9ee93ba3c430d fs/mbcache.c  (Jiang Biao          2018-01-09 23:57:52 -0500 245) 					cache->c_entry_count--;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 246) 				atomic_dec(&entry->e_refcnt);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 247) 			}
f0c8b46238db9 fs/mbcache2.c (Jan Kara            2016-02-22 18:23:47 -0500 248) 			spin_unlock(&cache->c_list_lock);
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 249) 			mb_cache_entry_put(cache, entry);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 250) 			return;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 251) 		}
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 252) 	}
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 253) 	hlist_bl_unlock(head);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 254) }
c07dfcb45877f fs/mbcache.c  (Tahsin Erdogan      2017-06-22 10:29:53 -0400 255) EXPORT_SYMBOL(mb_cache_entry_delete);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 256) 
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 257) /* mb_cache_entry_touch - cache entry got used
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 258)  * @cache - cache the entry belongs to
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 259)  * @entry - entry that got used
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 260)  *
f0c8b46238db9 fs/mbcache2.c (Jan Kara            2016-02-22 18:23:47 -0500 261)  * Marks entry as used to give hit higher chances of surviving in cache.
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 262)  */
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 263) void mb_cache_entry_touch(struct mb_cache *cache,
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 264) 			  struct mb_cache_entry *entry)
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 265) {
dc8d5e565f00c fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:42:05 -0500 266) 	entry->e_referenced = 1;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 267) }
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 268) EXPORT_SYMBOL(mb_cache_entry_touch);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 269) 
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 270) static unsigned long mb_cache_count(struct shrinker *shrink,
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 271) 				    struct shrink_control *sc)
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 272) {
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 273) 	struct mb_cache *cache = container_of(shrink, struct mb_cache,
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 274) 					      c_shrink);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 275) 
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 276) 	return cache->c_entry_count;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 277) }
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 278) 
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 279) /* Shrink number of entries in cache */
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 280) static unsigned long mb_cache_shrink(struct mb_cache *cache,
132d4e2d55dfd fs/mbcache.c  (Eric Biggers        2016-12-03 15:43:48 -0500 281) 				     unsigned long nr_to_scan)
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 282) {
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 283) 	struct mb_cache_entry *entry;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 284) 	struct hlist_bl_head *head;
132d4e2d55dfd fs/mbcache.c  (Eric Biggers        2016-12-03 15:43:48 -0500 285) 	unsigned long shrunk = 0;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 286) 
f0c8b46238db9 fs/mbcache2.c (Jan Kara            2016-02-22 18:23:47 -0500 287) 	spin_lock(&cache->c_list_lock);
f0c8b46238db9 fs/mbcache2.c (Jan Kara            2016-02-22 18:23:47 -0500 288) 	while (nr_to_scan-- && !list_empty(&cache->c_list)) {
f0c8b46238db9 fs/mbcache2.c (Jan Kara            2016-02-22 18:23:47 -0500 289) 		entry = list_first_entry(&cache->c_list,
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 290) 					 struct mb_cache_entry, e_list);
dc8d5e565f00c fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:42:05 -0500 291) 		if (entry->e_referenced) {
dc8d5e565f00c fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:42:05 -0500 292) 			entry->e_referenced = 0;
918b7306edacb fs/mbcache.c  (Eric Biggers        2016-12-03 15:13:15 -0500 293) 			list_move_tail(&entry->e_list, &cache->c_list);
f0c8b46238db9 fs/mbcache2.c (Jan Kara            2016-02-22 18:23:47 -0500 294) 			continue;
f0c8b46238db9 fs/mbcache2.c (Jan Kara            2016-02-22 18:23:47 -0500 295) 		}
f0c8b46238db9 fs/mbcache2.c (Jan Kara            2016-02-22 18:23:47 -0500 296) 		list_del_init(&entry->e_list);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 297) 		cache->c_entry_count--;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 298) 		/*
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 299) 		 * We keep LRU list reference so that entry doesn't go away
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 300) 		 * from under us.
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 301) 		 */
f0c8b46238db9 fs/mbcache2.c (Jan Kara            2016-02-22 18:23:47 -0500 302) 		spin_unlock(&cache->c_list_lock);
dc8d5e565f00c fs/mbcache.c  (Andreas Gruenbacher 2016-02-22 22:42:05 -0500 303) 		head = mb_cache_entry_head(cache, entry->e_key);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 304) 		hlist_bl_lock(head);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 305) 		if (!hlist_bl_unhashed(&entry->e_hash_list)) {
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 306) 			hlist_bl_del_init(&entry->e_hash_list);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 307) 			atomic_dec(&entry->e_refcnt);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 308) 		}
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 309) 		hlist_bl_unlock(head);
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 310) 		if (mb_cache_entry_put(cache, entry))
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 311) 			shrunk++;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 312) 		cond_resched();
f0c8b46238db9 fs/mbcache2.c (Jan Kara            2016-02-22 18:23:47 -0500 313) 		spin_lock(&cache->c_list_lock);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 314) 	}
f0c8b46238db9 fs/mbcache2.c (Jan Kara            2016-02-22 18:23:47 -0500 315) 	spin_unlock(&cache->c_list_lock);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 316) 
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 317) 	return shrunk;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 318) }
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 319) 
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 320) static unsigned long mb_cache_scan(struct shrinker *shrink,
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 321) 				   struct shrink_control *sc)
c2f3140fe2ece fs/mbcache2.c (Jan Kara            2016-02-22 12:33:03 -0500 322) {
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 323) 	struct mb_cache *cache = container_of(shrink, struct mb_cache,
c2f3140fe2ece fs/mbcache2.c (Jan Kara            2016-02-22 12:33:03 -0500 324) 					      c_shrink);
132d4e2d55dfd fs/mbcache.c  (Eric Biggers        2016-12-03 15:43:48 -0500 325) 	return mb_cache_shrink(cache, sc->nr_to_scan);
c2f3140fe2ece fs/mbcache2.c (Jan Kara            2016-02-22 12:33:03 -0500 326) }
c2f3140fe2ece fs/mbcache2.c (Jan Kara            2016-02-22 12:33:03 -0500 327) 
c2f3140fe2ece fs/mbcache2.c (Jan Kara            2016-02-22 12:33:03 -0500 328) /* We shrink 1/X of the cache when we have too many entries in it */
c2f3140fe2ece fs/mbcache2.c (Jan Kara            2016-02-22 12:33:03 -0500 329) #define SHRINK_DIVISOR 16
c2f3140fe2ece fs/mbcache2.c (Jan Kara            2016-02-22 12:33:03 -0500 330) 
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 331) static void mb_cache_shrink_worker(struct work_struct *work)
c2f3140fe2ece fs/mbcache2.c (Jan Kara            2016-02-22 12:33:03 -0500 332) {
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 333) 	struct mb_cache *cache = container_of(work, struct mb_cache,
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 334) 					      c_shrink_work);
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 335) 	mb_cache_shrink(cache, cache->c_max_entries / SHRINK_DIVISOR);
c2f3140fe2ece fs/mbcache2.c (Jan Kara            2016-02-22 12:33:03 -0500 336) }
c2f3140fe2ece fs/mbcache2.c (Jan Kara            2016-02-22 12:33:03 -0500 337) 
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 338) /*
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 339)  * mb_cache_create - create cache
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 340)  * @bucket_bits: log2 of the hash table size
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 341)  *
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 342)  * Create cache for keys with 2^bucket_bits hash entries.
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 343)  */
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 344) struct mb_cache *mb_cache_create(int bucket_bits)
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 345) {
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 346) 	struct mb_cache *cache;
132d4e2d55dfd fs/mbcache.c  (Eric Biggers        2016-12-03 15:43:48 -0500 347) 	unsigned long bucket_count = 1UL << bucket_bits;
132d4e2d55dfd fs/mbcache.c  (Eric Biggers        2016-12-03 15:43:48 -0500 348) 	unsigned long i;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 349) 
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 350) 	cache = kzalloc(sizeof(struct mb_cache), GFP_KERNEL);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 351) 	if (!cache)
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 352) 		goto err_out;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 353) 	cache->c_bucket_bits = bucket_bits;
c2f3140fe2ece fs/mbcache2.c (Jan Kara            2016-02-22 12:33:03 -0500 354) 	cache->c_max_entries = bucket_count << 4;
f0c8b46238db9 fs/mbcache2.c (Jan Kara            2016-02-22 18:23:47 -0500 355) 	INIT_LIST_HEAD(&cache->c_list);
f0c8b46238db9 fs/mbcache2.c (Jan Kara            2016-02-22 18:23:47 -0500 356) 	spin_lock_init(&cache->c_list_lock);
6da2ec56059c3 fs/mbcache.c  (Kees Cook           2018-06-12 13:55:00 -0700 357) 	cache->c_hash = kmalloc_array(bucket_count,
6da2ec56059c3 fs/mbcache.c  (Kees Cook           2018-06-12 13:55:00 -0700 358) 				      sizeof(struct hlist_bl_head),
6da2ec56059c3 fs/mbcache.c  (Kees Cook           2018-06-12 13:55:00 -0700 359) 				      GFP_KERNEL);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 360) 	if (!cache->c_hash) {
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 361) 		kfree(cache);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 362) 		goto err_out;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 363) 	}
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 364) 	for (i = 0; i < bucket_count; i++)
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 365) 		INIT_HLIST_BL_HEAD(&cache->c_hash[i]);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 366) 
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 367) 	cache->c_shrink.count_objects = mb_cache_count;
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 368) 	cache->c_shrink.scan_objects = mb_cache_scan;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 369) 	cache->c_shrink.seeks = DEFAULT_SEEKS;
8913f343cdb56 fs/mbcache.c  (Chao Yu             2016-08-31 11:44:36 -0400 370) 	if (register_shrinker(&cache->c_shrink)) {
8913f343cdb56 fs/mbcache.c  (Chao Yu             2016-08-31 11:44:36 -0400 371) 		kfree(cache->c_hash);
8913f343cdb56 fs/mbcache.c  (Chao Yu             2016-08-31 11:44:36 -0400 372) 		kfree(cache);
8913f343cdb56 fs/mbcache.c  (Chao Yu             2016-08-31 11:44:36 -0400 373) 		goto err_out;
8913f343cdb56 fs/mbcache.c  (Chao Yu             2016-08-31 11:44:36 -0400 374) 	}
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 375) 
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 376) 	INIT_WORK(&cache->c_shrink_work, mb_cache_shrink_worker);
c2f3140fe2ece fs/mbcache2.c (Jan Kara            2016-02-22 12:33:03 -0500 377) 
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 378) 	return cache;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 379) 
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 380) err_out:
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 381) 	return NULL;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 382) }
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 383) EXPORT_SYMBOL(mb_cache_create);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 384) 
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 385) /*
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 386)  * mb_cache_destroy - destroy cache
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 387)  * @cache: the cache to destroy
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 388)  *
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 389)  * Free all entries in cache and cache itself. Caller must make sure nobody
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 390)  * (except shrinker) can reach @cache when calling this.
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 391)  */
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 392) void mb_cache_destroy(struct mb_cache *cache)
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 393) {
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 394) 	struct mb_cache_entry *entry, *next;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 395) 
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 396) 	unregister_shrinker(&cache->c_shrink);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 397) 
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 398) 	/*
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 399) 	 * We don't bother with any locking. Cache must not be used at this
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 400) 	 * point.
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 401) 	 */
f0c8b46238db9 fs/mbcache2.c (Jan Kara            2016-02-22 18:23:47 -0500 402) 	list_for_each_entry_safe(entry, next, &cache->c_list, e_list) {
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 403) 		if (!hlist_bl_unhashed(&entry->e_hash_list)) {
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 404) 			hlist_bl_del_init(&entry->e_hash_list);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 405) 			atomic_dec(&entry->e_refcnt);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 406) 		} else
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 407) 			WARN_ON(1);
f0c8b46238db9 fs/mbcache2.c (Jan Kara            2016-02-22 18:23:47 -0500 408) 		list_del(&entry->e_list);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 409) 		WARN_ON(atomic_read(&entry->e_refcnt) != 1);
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 410) 		mb_cache_entry_put(cache, entry);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 411) 	}
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 412) 	kfree(cache->c_hash);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 413) 	kfree(cache);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 414) }
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 415) EXPORT_SYMBOL(mb_cache_destroy);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 416) 
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 417) static int __init mbcache_init(void)
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 418) {
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 419) 	mb_entry_cache = kmem_cache_create("mbcache",
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 420) 				sizeof(struct mb_cache_entry), 0,
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 421) 				SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, NULL);
21d0f4fa8e7b0 fs/mbcache.c  (Eric Biggers        2016-12-03 15:28:53 -0500 422) 	if (!mb_entry_cache)
21d0f4fa8e7b0 fs/mbcache.c  (Eric Biggers        2016-12-03 15:28:53 -0500 423) 		return -ENOMEM;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 424) 	return 0;
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 425) }
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 426) 
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 427) static void __exit mbcache_exit(void)
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 428) {
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 429) 	kmem_cache_destroy(mb_entry_cache);
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 430) }
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 431) 
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 432) module_init(mbcache_init)
7a2508e1b657c fs/mbcache.c  (Jan Kara            2016-02-22 22:35:22 -0500 433) module_exit(mbcache_exit)
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 434) 
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 435) MODULE_AUTHOR("Jan Kara <jack@suse.cz>");
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 436) MODULE_DESCRIPTION("Meta block cache (for extended attributes)");
f9a61eb4e2471 fs/mbcache2.c (Jan Kara            2016-02-22 11:49:09 -0500 437) MODULE_LICENSE("GPL");