diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-27 02:27:35 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-27 02:27:35 +0200 |
commit | bc9bc72e2f9bb07384c00604d1a40d0b5f62be6c (patch) | |
tree | 99fc71a5d5889445fb39279d7ff3f0d66c1cca0d /fs/squashfs/cache.c | |
parent | m68knommu: use generic find_next_bit_le() (diff) | |
parent | Squashfs: update email address (diff) | |
download | linux-bc9bc72e2f9bb07384c00604d1a40d0b5f62be6c.tar.xz linux-bc9bc72e2f9bb07384c00604d1a40d0b5f62be6c.zip |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pkl/squashfs-linus
* git://git.kernel.org/pub/scm/linux/kernel/git/pkl/squashfs-linus:
Squashfs: update email address
Squashfs: add extra sanity checks at mount time
Squashfs: add sanity checks to fragment reading at mount time
Squashfs: add sanity checks to lookup table reading at mount time
Squashfs: add sanity checks to id reading at mount time
Squashfs: add sanity checks to xattr reading at mount time
Squashfs: reverse order of filesystem table reading
Squashfs: move table allocation into squashfs_read_table()
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 4b5a3fbb1f1f..f744be98cd5a 100644 --- a/fs/squashfs/cache.c +++ b/fs/squashfs/cache.c @@ -2,7 +2,7 @@ * Squashfs - a compressed read only filesystem for Linux * * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 - * Phillip Lougher <phillip@lougher.demon.co.uk> + * Phillip Lougher <phillip@squashfs.org.uk> * * This program is free software; you can redistribute it and/or * 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, /* * 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); } |