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