• Home
  • Raw
  • Download

Lines Matching full:cache

21  * cache.c
28 * This file implements a generic cache implementation used for both caches,
29 * plus functions layered ontop of the generic cache implementation to
32 * To avoid out of memory and fragmentation issues with vmalloc the cache
35 * It should be noted that the cache is not used for file datablocks, these
36 * are decompressed and cached in the page-cache in the normal way. The
37 * cache is only used to temporarily cache fragment and metadata blocks
62 * Look-up block in cache, and increment usage count. If not in cache, read
66 struct squashfs_cache *cache, u64 block, int length) in squashfs_cache_get() argument
71 spin_lock(&cache->lock); in squashfs_cache_get()
74 for (i = cache->curr_blk, n = 0; n < cache->entries; n++) { in squashfs_cache_get()
75 if (cache->entry[i].block == block) { in squashfs_cache_get()
76 cache->curr_blk = i; in squashfs_cache_get()
79 i = (i + 1) % cache->entries; in squashfs_cache_get()
82 if (n == cache->entries) { in squashfs_cache_get()
84 * Block not in cache, if all cache entries are used in squashfs_cache_get()
87 if (cache->unused == 0) { in squashfs_cache_get()
88 cache->num_waiters++; in squashfs_cache_get()
89 spin_unlock(&cache->lock); in squashfs_cache_get()
90 wait_event(cache->wait_queue, cache->unused); in squashfs_cache_get()
91 spin_lock(&cache->lock); in squashfs_cache_get()
92 cache->num_waiters--; in squashfs_cache_get()
97 * At least one unused cache entry. A simple in squashfs_cache_get()
99 * be evicted from the cache. in squashfs_cache_get()
101 i = cache->next_blk; in squashfs_cache_get()
102 for (n = 0; n < cache->entries; n++) { in squashfs_cache_get()
103 if (cache->entry[i].refcount == 0) in squashfs_cache_get()
105 i = (i + 1) % cache->entries; in squashfs_cache_get()
108 cache->next_blk = (i + 1) % cache->entries; in squashfs_cache_get()
109 entry = &cache->entry[i]; in squashfs_cache_get()
112 * Initialise chosen cache entry, and fill it in from in squashfs_cache_get()
115 cache->unused--; in squashfs_cache_get()
121 spin_unlock(&cache->lock); in squashfs_cache_get()
126 spin_lock(&cache->lock); in squashfs_cache_get()
135 * have looked it up in the cache, and have slept in squashfs_cache_get()
139 spin_unlock(&cache->lock); in squashfs_cache_get()
142 spin_unlock(&cache->lock); in squashfs_cache_get()
148 * Block already in cache. Increment refcount so it doesn't in squashfs_cache_get()
150 * previously unused there's one less cache entry available in squashfs_cache_get()
153 entry = &cache->entry[i]; in squashfs_cache_get()
155 cache->unused--; in squashfs_cache_get()
164 spin_unlock(&cache->lock); in squashfs_cache_get()
167 spin_unlock(&cache->lock); in squashfs_cache_get()
174 cache->name, i, entry->block, entry->refcount, entry->error); in squashfs_cache_get()
177 ERROR("Unable to read %s cache entry [%llx]\n", cache->name, in squashfs_cache_get()
184 * Release cache entry, once usage count is zero it can be reused.
188 struct squashfs_cache *cache = entry->cache; in squashfs_cache_put() local
190 spin_lock(&cache->lock); in squashfs_cache_put()
193 cache->unused++; in squashfs_cache_put()
198 if (cache->num_waiters) { in squashfs_cache_put()
199 spin_unlock(&cache->lock); in squashfs_cache_put()
200 wake_up(&cache->wait_queue); in squashfs_cache_put()
204 spin_unlock(&cache->lock); in squashfs_cache_put()
208 * Delete cache reclaiming all kmalloced buffers.
210 void squashfs_cache_delete(struct squashfs_cache *cache) in squashfs_cache_delete() argument
214 if (cache == NULL) in squashfs_cache_delete()
217 for (i = 0; i < cache->entries; i++) { in squashfs_cache_delete()
218 if (cache->entry[i].data) { in squashfs_cache_delete()
219 for (j = 0; j < cache->pages; j++) in squashfs_cache_delete()
220 kfree(cache->entry[i].data[j]); in squashfs_cache_delete()
221 kfree(cache->entry[i].data); in squashfs_cache_delete()
223 kfree(cache->entry[i].actor); in squashfs_cache_delete()
226 kfree(cache->entry); in squashfs_cache_delete()
227 kfree(cache); in squashfs_cache_delete()
232 * Initialise cache allocating the specified number of entries, each of
240 struct squashfs_cache *cache = kzalloc(sizeof(*cache), GFP_KERNEL); in squashfs_cache_init() local
242 if (cache == NULL) { in squashfs_cache_init()
243 ERROR("Failed to allocate %s cache\n", name); in squashfs_cache_init()
247 cache->entry = kcalloc(entries, sizeof(*(cache->entry)), GFP_KERNEL); in squashfs_cache_init()
248 if (cache->entry == NULL) { in squashfs_cache_init()
249 ERROR("Failed to allocate %s cache\n", name); in squashfs_cache_init()
253 cache->curr_blk = 0; in squashfs_cache_init()
254 cache->next_blk = 0; in squashfs_cache_init()
255 cache->unused = entries; in squashfs_cache_init()
256 cache->entries = entries; in squashfs_cache_init()
257 cache->block_size = block_size; in squashfs_cache_init()
258 cache->pages = block_size >> PAGE_SHIFT; in squashfs_cache_init()
259 cache->pages = cache->pages ? cache->pages : 1; in squashfs_cache_init()
260 cache->name = name; in squashfs_cache_init()
261 cache->num_waiters = 0; in squashfs_cache_init()
262 spin_lock_init(&cache->lock); in squashfs_cache_init()
263 init_waitqueue_head(&cache->wait_queue); in squashfs_cache_init()
266 struct squashfs_cache_entry *entry = &cache->entry[i]; in squashfs_cache_init()
268 init_waitqueue_head(&cache->entry[i].wait_queue); in squashfs_cache_init()
269 entry->cache = cache; in squashfs_cache_init()
271 entry->data = kcalloc(cache->pages, sizeof(void *), GFP_KERNEL); in squashfs_cache_init()
273 ERROR("Failed to allocate %s cache entry\n", name); in squashfs_cache_init()
277 for (j = 0; j < cache->pages; j++) { in squashfs_cache_init()
286 cache->pages, 0); in squashfs_cache_init()
288 ERROR("Failed to allocate %s cache entry\n", name); in squashfs_cache_init()
293 return cache; in squashfs_cache_init()
296 squashfs_cache_delete(cache); in squashfs_cache_init()
302 * Copy up to length bytes from cache entry to buffer starting at offset bytes
303 * into the cache entry. If there's not length bytes then copy the number of
389 * Look-up in the fragmment cache the fragment located at <start_block> in the
404 * filesystem. The cache is used here to avoid duplicating locking and