summaryrefslogtreecommitdiffstats
path: root/fs/squashfs/cache.c
diff options
context:
space:
mode:
authorPhillip Lougher <phillip@lougher.demon.co.uk>2011-05-20 02:26:43 +0100
committerPhillip Lougher <phillip@lougher.demon.co.uk>2011-05-25 18:21:31 +0100
commit82de647e1f81fd89afc48608d889dd3b33cb8983 (patch)
tree847b7b40ed273eaa755c27bef6b1a20d201273c2 /fs/squashfs/cache.c
parent117a91e0f25fd7698e20ac3dfa62086be3dc82a3 (diff)
downloadlinux-82de647e1f81fd89afc48608d889dd3b33cb8983.tar.bz2
Squashfs: move table allocation into squashfs_read_table()
This eliminates a lot of duplicate code. Signed-off-by: Phillip Lougher <phillip@lougher.demon.co.uk>
Diffstat (limited to 'fs/squashfs/cache.c')
-rw-r--r--fs/squashfs/cache.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/fs/squashfs/cache.c b/fs/squashfs/cache.c
index 26b15ae34d6f..20c8df1b7efc 100644
--- a/fs/squashfs/cache.c
+++ b/fs/squashfs/cache.c
@@ -393,19 +393,36 @@ struct squashfs_cache_entry *squashfs_get_datablock(struct super_block *sb,
/*
* Read a filesystem table (uncompressed sequence of bytes) from disk
*/
-int squashfs_read_table(struct super_block *sb, void *buffer, u64 block,
- int length)
+void *squashfs_read_table(struct super_block *sb, u64 block, int length)
{
int pages = (length + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
int i, res;
- void **data = kcalloc(pages, sizeof(void *), GFP_KERNEL);
- if (data == NULL)
- return -ENOMEM;
+ void *table, *buffer, **data;
+
+ table = buffer = kmalloc(length, GFP_KERNEL);
+ if (table == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ data = kcalloc(pages, sizeof(void *), GFP_KERNEL);
+ if (data == NULL) {
+ res = -ENOMEM;
+ goto failed;
+ }
for (i = 0; i < pages; i++, buffer += PAGE_CACHE_SIZE)
data[i] = buffer;
+
res = squashfs_read_data(sb, data, block, length |
SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length, pages);
+
kfree(data);
- return res;
+
+ if (res < 0)
+ goto failed;
+
+ return table;
+
+failed:
+ kfree(table);
+ return ERR_PTR(res);
}