summaryrefslogtreecommitdiff
path: root/target/linux/generic-2.6/patches-2.6.31/051-squashfs_pcomp.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/generic-2.6/patches-2.6.31/051-squashfs_pcomp.patch')
-rw-r--r--target/linux/generic-2.6/patches-2.6.31/051-squashfs_pcomp.patch234
1 files changed, 234 insertions, 0 deletions
diff --git a/target/linux/generic-2.6/patches-2.6.31/051-squashfs_pcomp.patch b/target/linux/generic-2.6/patches-2.6.31/051-squashfs_pcomp.patch
new file mode 100644
index 0000000..086adf6
--- /dev/null
+++ b/target/linux/generic-2.6/patches-2.6.31/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
+@@ -38,11 +38,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;
+
+@@ -76,6 +84,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");
+@@ -87,16 +105,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, &params, 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;
+ }
+
+@@ -295,17 +322,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;
+ }
+
+
+@@ -349,7 +377,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;
+ }