diff options
Diffstat (limited to 'fs/squashfs/cache.c')
-rw-r--r-- | fs/squashfs/cache.c | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/fs/squashfs/cache.c b/fs/squashfs/cache.c index af0b73802592..1cb70a0b2168 100644 --- a/fs/squashfs/cache.c +++ b/fs/squashfs/cache.c | |||
@@ -56,6 +56,7 @@ | |||
56 | #include "squashfs_fs.h" | 56 | #include "squashfs_fs.h" |
57 | #include "squashfs_fs_sb.h" | 57 | #include "squashfs_fs_sb.h" |
58 | #include "squashfs.h" | 58 | #include "squashfs.h" |
59 | #include "page_actor.h" | ||
59 | 60 | ||
60 | /* | 61 | /* |
61 | * Look-up block in cache, and increment usage count. If not in cache, read | 62 | * Look-up block in cache, and increment usage count. If not in cache, read |
@@ -119,9 +120,8 @@ struct squashfs_cache_entry *squashfs_cache_get(struct super_block *sb, | |||
119 | entry->error = 0; | 120 | entry->error = 0; |
120 | spin_unlock(&cache->lock); | 121 | spin_unlock(&cache->lock); |
121 | 122 | ||
122 | entry->length = squashfs_read_data(sb, entry->data, | 123 | entry->length = squashfs_read_data(sb, block, length, |
123 | block, length, &entry->next_index, | 124 | &entry->next_index, entry->actor); |
124 | cache->block_size, cache->pages); | ||
125 | 125 | ||
126 | spin_lock(&cache->lock); | 126 | spin_lock(&cache->lock); |
127 | 127 | ||
@@ -220,6 +220,7 @@ void squashfs_cache_delete(struct squashfs_cache *cache) | |||
220 | kfree(cache->entry[i].data[j]); | 220 | kfree(cache->entry[i].data[j]); |
221 | kfree(cache->entry[i].data); | 221 | kfree(cache->entry[i].data); |
222 | } | 222 | } |
223 | kfree(cache->entry[i].actor); | ||
223 | } | 224 | } |
224 | 225 | ||
225 | kfree(cache->entry); | 226 | kfree(cache->entry); |
@@ -280,6 +281,13 @@ struct squashfs_cache *squashfs_cache_init(char *name, int entries, | |||
280 | goto cleanup; | 281 | goto cleanup; |
281 | } | 282 | } |
282 | } | 283 | } |
284 | |||
285 | entry->actor = squashfs_page_actor_init(entry->data, | ||
286 | cache->pages, 0); | ||
287 | if (entry->actor == NULL) { | ||
288 | ERROR("Failed to allocate %s cache entry\n", name); | ||
289 | goto cleanup; | ||
290 | } | ||
283 | } | 291 | } |
284 | 292 | ||
285 | return cache; | 293 | return cache; |
@@ -410,6 +418,7 @@ void *squashfs_read_table(struct super_block *sb, u64 block, int length) | |||
410 | int pages = (length + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | 418 | int pages = (length + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; |
411 | int i, res; | 419 | int i, res; |
412 | void *table, *buffer, **data; | 420 | void *table, *buffer, **data; |
421 | struct squashfs_page_actor *actor; | ||
413 | 422 | ||
414 | table = buffer = kmalloc(length, GFP_KERNEL); | 423 | table = buffer = kmalloc(length, GFP_KERNEL); |
415 | if (table == NULL) | 424 | if (table == NULL) |
@@ -421,19 +430,28 @@ void *squashfs_read_table(struct super_block *sb, u64 block, int length) | |||
421 | goto failed; | 430 | goto failed; |
422 | } | 431 | } |
423 | 432 | ||
433 | actor = squashfs_page_actor_init(data, pages, length); | ||
434 | if (actor == NULL) { | ||
435 | res = -ENOMEM; | ||
436 | goto failed2; | ||
437 | } | ||
438 | |||
424 | for (i = 0; i < pages; i++, buffer += PAGE_CACHE_SIZE) | 439 | for (i = 0; i < pages; i++, buffer += PAGE_CACHE_SIZE) |
425 | data[i] = buffer; | 440 | data[i] = buffer; |
426 | 441 | ||
427 | res = squashfs_read_data(sb, data, block, length | | 442 | res = squashfs_read_data(sb, block, length | |
428 | SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length, pages); | 443 | SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, actor); |
429 | 444 | ||
430 | kfree(data); | 445 | kfree(data); |
446 | kfree(actor); | ||
431 | 447 | ||
432 | if (res < 0) | 448 | if (res < 0) |
433 | goto failed; | 449 | goto failed; |
434 | 450 | ||
435 | return table; | 451 | return table; |
436 | 452 | ||
453 | failed2: | ||
454 | kfree(data); | ||
437 | failed: | 455 | failed: |
438 | kfree(table); | 456 | kfree(table); |
439 | return ERR_PTR(res); | 457 | return ERR_PTR(res); |