diff options
Diffstat (limited to 'target/linux/generic-2.6/patches-2.6.30/051-squashfs_pcomp.patch')
-rw-r--r-- | target/linux/generic-2.6/patches-2.6.30/051-squashfs_pcomp.patch | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/target/linux/generic-2.6/patches-2.6.30/051-squashfs_pcomp.patch b/target/linux/generic-2.6/patches-2.6.30/051-squashfs_pcomp.patch new file mode 100644 index 0000000..271c4e5 --- /dev/null +++ b/target/linux/generic-2.6/patches-2.6.30/051-squashfs_pcomp.patch @@ -0,0 +1,234 @@ +--- a/fs/squashfs/Kconfig ++++ b/fs/squashfs/Kconfig +@@ -1,7 +1,8 @@ + config SQUASHFS + tristate "SquashFS 4.0 - Squashed file system support" + depends on BLOCK +- select ZLIB_INFLATE ++ select CRYPTO ++ select CRYPTO_ZLIB + help + Saying Y here includes support for SquashFS 4.0 (a Compressed + Read-Only File System). Squashfs is a highly compressed read-only +--- a/fs/squashfs/block.c ++++ b/fs/squashfs/block.c +@@ -32,7 +32,8 @@ + #include <linux/mutex.h> + #include <linux/string.h> + #include <linux/buffer_head.h> +-#include <linux/zlib.h> ++ ++#include <crypto/compress.h> + + #include "squashfs_fs.h" + #include "squashfs_fs_sb.h" +@@ -153,7 +154,8 @@ int squashfs_read_data(struct super_bloc + } + + if (compressed) { +- int zlib_err = 0, zlib_init = 0; ++ int res = 0, decomp_init = 0; ++ struct comp_request req; + + /* + * Uncompress block. +@@ -161,12 +163,13 @@ int squashfs_read_data(struct super_bloc + + mutex_lock(&msblk->read_data_mutex); + +- msblk->stream.avail_out = 0; +- msblk->stream.avail_in = 0; ++ req.avail_out = 0; ++ req.avail_in = 0; + + bytes = length; ++ length = 0; + do { +- if (msblk->stream.avail_in == 0 && k < b) { ++ if (req.avail_in == 0 && k < b) { + avail = min(bytes, msblk->devblksize - offset); + bytes -= avail; + wait_on_buffer(bh[k]); +@@ -179,45 +182,47 @@ int squashfs_read_data(struct super_bloc + continue; + } + +- msblk->stream.next_in = bh[k]->b_data + offset; +- msblk->stream.avail_in = avail; ++ req.next_in = bh[k]->b_data + offset; ++ req.avail_in = avail; + offset = 0; + } + +- if (msblk->stream.avail_out == 0 && page < pages) { +- msblk->stream.next_out = buffer[page++]; +- msblk->stream.avail_out = PAGE_CACHE_SIZE; ++ if (req.avail_out == 0 && page < pages) { ++ req.next_out = buffer[page++]; ++ req.avail_out = PAGE_CACHE_SIZE; + } + +- if (!zlib_init) { +- zlib_err = zlib_inflateInit(&msblk->stream); +- if (zlib_err != Z_OK) { +- ERROR("zlib_inflateInit returned" +- " unexpected result 0x%x," +- " srclength %d\n", zlib_err, +- srclength); ++ if (!decomp_init) { ++ res = crypto_decompress_init(msblk->tfm); ++ if (res) { ++ ERROR("crypto_decompress_init " ++ "returned %d, srclength %d\n", ++ res, srclength); + goto release_mutex; + } +- zlib_init = 1; ++ decomp_init = 1; + } + +- zlib_err = zlib_inflate(&msblk->stream, Z_SYNC_FLUSH); ++ res = crypto_decompress_update(msblk->tfm, &req); ++ if (res < 0) { ++ ERROR("crypto_decompress_update returned %d, " ++ "data probably corrupt\n", res); ++ goto release_mutex; ++ } ++ length += res; + +- if (msblk->stream.avail_in == 0 && k < b) ++ if (req.avail_in == 0 && k < b) + put_bh(bh[k++]); +- } while (zlib_err == Z_OK); ++ } while (bytes || res); + +- if (zlib_err != Z_STREAM_END) { +- ERROR("zlib_inflate error, data probably corrupt\n"); ++ res = crypto_decompress_final(msblk->tfm, &req); ++ if (res < 0) { ++ ERROR("crypto_decompress_final returned %d, data " ++ "probably corrupt\n", res); + goto release_mutex; + } ++ length += res; + +- zlib_err = zlib_inflateEnd(&msblk->stream); +- if (zlib_err != Z_OK) { +- ERROR("zlib_inflate error, data probably corrupt\n"); +- goto release_mutex; +- } +- length = msblk->stream.total_out; + mutex_unlock(&msblk->read_data_mutex); + } else { + /* +--- a/fs/squashfs/squashfs_fs_sb.h ++++ b/fs/squashfs/squashfs_fs_sb.h +@@ -64,7 +64,7 @@ struct squashfs_sb_info { + struct mutex read_data_mutex; + struct mutex meta_index_mutex; + struct meta_index *meta_index; +- z_stream stream; ++ struct crypto_pcomp *tfm; + __le64 *inode_lookup_table; + u64 inode_table; + u64 directory_table; +--- a/fs/squashfs/super.c ++++ b/fs/squashfs/super.c +@@ -37,11 +37,19 @@ + #include <linux/zlib.h> + #include <linux/magic.h> + ++#include <crypto/compress.h> ++ ++#include <net/netlink.h> ++ + #include "squashfs_fs.h" + #include "squashfs_fs_sb.h" + #include "squashfs_fs_i.h" + #include "squashfs.h" + ++ ++#define SQUASHFS_CRYPTO_ALG "zlib" ++ ++ + static struct file_system_type squashfs_fs_type; + static struct super_operations squashfs_super_ops; + +@@ -75,6 +83,16 @@ static int squashfs_fill_super(struct su + unsigned short flags; + unsigned int fragments; + u64 lookup_table_start; ++ struct { ++ struct nlattr nla; ++ int val; ++ } params = { ++ .nla = { ++ .nla_len = nla_attr_size(sizeof(int)), ++ .nla_type = ZLIB_DECOMP_WINDOWBITS, ++ }, ++ .val = DEF_WBITS, ++ }; + int err; + + TRACE("Entered squashfs_fill_superblock\n"); +@@ -86,16 +104,25 @@ static int squashfs_fill_super(struct su + } + msblk = sb->s_fs_info; + +- msblk->stream.workspace = kmalloc(zlib_inflate_workspacesize(), +- GFP_KERNEL); +- if (msblk->stream.workspace == NULL) { +- ERROR("Failed to allocate zlib workspace\n"); ++ msblk->tfm = crypto_alloc_pcomp(SQUASHFS_CRYPTO_ALG, 0, ++ CRYPTO_ALG_ASYNC); ++ if (IS_ERR(msblk->tfm)) { ++ ERROR("Failed to load %s crypto module\n", ++ SQUASHFS_CRYPTO_ALG); ++ err = PTR_ERR(msblk->tfm); ++ goto failed_pcomp; ++ } ++ ++ err = crypto_decompress_setup(msblk->tfm, ¶ms, sizeof(params)); ++ if (err) { ++ ERROR("Failed to set up decompression parameters\n"); + goto failure; + } + + sblk = kzalloc(sizeof(*sblk), GFP_KERNEL); + if (sblk == NULL) { + ERROR("Failed to allocate squashfs_super_block\n"); ++ err = -ENOMEM; + goto failure; + } + +@@ -284,17 +311,18 @@ failed_mount: + kfree(msblk->inode_lookup_table); + kfree(msblk->fragment_index); + kfree(msblk->id_table); +- kfree(msblk->stream.workspace); ++ crypto_free_pcomp(msblk->tfm); + kfree(sb->s_fs_info); + sb->s_fs_info = NULL; + kfree(sblk); + return err; + + failure: +- kfree(msblk->stream.workspace); ++ crypto_free_pcomp(msblk->tfm); ++failed_pcomp: + kfree(sb->s_fs_info); + sb->s_fs_info = NULL; +- return -ENOMEM; ++ return err; + } + + +@@ -333,7 +361,7 @@ static void squashfs_put_super(struct su + kfree(sbi->id_table); + kfree(sbi->fragment_index); + kfree(sbi->meta_index); +- kfree(sbi->stream.workspace); ++ crypto_free_pcomp(sbi->tfm); + kfree(sb->s_fs_info); + sb->s_fs_info = NULL; + } |