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