diff options
Diffstat (limited to 'fs/squashfs/cache.c')
-rw-r--r-- | fs/squashfs/cache.c | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/fs/squashfs/cache.c b/fs/squashfs/cache.c index 4b5a3fbb1f1..f744be98cd5 100644 --- a/fs/squashfs/cache.c +++ b/fs/squashfs/cache.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * Squashfs - a compressed read only filesystem for Linux | 2 | * Squashfs - a compressed read only filesystem for Linux |
3 | * | 3 | * |
4 | * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 | 4 | * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 |
5 | * Phillip Lougher <phillip@lougher.demon.co.uk> | 5 | * Phillip Lougher <phillip@squashfs.org.uk> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or | 7 | * This program is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU General Public License | 8 | * modify it under the terms of the GNU General Public License |
@@ -393,19 +393,36 @@ struct squashfs_cache_entry *squashfs_get_datablock(struct super_block *sb, | |||
393 | /* | 393 | /* |
394 | * Read a filesystem table (uncompressed sequence of bytes) from disk | 394 | * Read a filesystem table (uncompressed sequence of bytes) from disk |
395 | */ | 395 | */ |
396 | int squashfs_read_table(struct super_block *sb, void *buffer, u64 block, | 396 | void *squashfs_read_table(struct super_block *sb, u64 block, int length) |
397 | int length) | ||
398 | { | 397 | { |
399 | int pages = (length + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | 398 | int pages = (length + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; |
400 | int i, res; | 399 | int i, res; |
401 | void **data = kcalloc(pages, sizeof(void *), GFP_KERNEL); | 400 | void *table, *buffer, **data; |
402 | if (data == NULL) | 401 | |
403 | return -ENOMEM; | 402 | table = buffer = kmalloc(length, GFP_KERNEL); |
403 | if (table == NULL) | ||
404 | return ERR_PTR(-ENOMEM); | ||
405 | |||
406 | data = kcalloc(pages, sizeof(void *), GFP_KERNEL); | ||
407 | if (data == NULL) { | ||
408 | res = -ENOMEM; | ||
409 | goto failed; | ||
410 | } | ||
404 | 411 | ||
405 | for (i = 0; i < pages; i++, buffer += PAGE_CACHE_SIZE) | 412 | for (i = 0; i < pages; i++, buffer += PAGE_CACHE_SIZE) |
406 | data[i] = buffer; | 413 | data[i] = buffer; |
414 | |||
407 | res = squashfs_read_data(sb, data, block, length | | 415 | res = squashfs_read_data(sb, data, block, length | |
408 | SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length, pages); | 416 | SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length, pages); |
417 | |||
409 | kfree(data); | 418 | kfree(data); |
410 | return res; | 419 | |
420 | if (res < 0) | ||
421 | goto failed; | ||
422 | |||
423 | return table; | ||
424 | |||
425 | failed: | ||
426 | kfree(table); | ||
427 | return ERR_PTR(res); | ||
411 | } | 428 | } |