Modify SquashFS 4 to use the new "zlib" crypto module as a proof-of-concept for
the partial decompression CRYPTO API enhancements.

Note: Patch against squashfs-2.6.git, as SquashFS is not yet in mainline

Signed-off-by: Geert Uytterhoeven <[EMAIL PROTECTED]>
---
 Kconfig                   |    3 +-
 squashfs/block.c          |   67 +++++++++++++++++++++++++++-------------------
 squashfs/squashfs_fs_sb.h |    4 ++
 squashfs/super.c          |   20 ++++++++-----
 4 files changed, 58 insertions(+), 36 deletions(-)

diff --git a/fs/Kconfig b/fs/Kconfig
index 1d7a5f9..8eebe53 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -934,7 +934,8 @@ config CRAMFS
 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
diff --git a/fs/squashfs/block.c b/fs/squashfs/block.c
index da5f88b..9a681cb 100644
--- a/fs/squashfs/block.c
+++ b/fs/squashfs/block.c
@@ -32,7 +32,7 @@
 #include <linux/mutex.h>
 #include <linux/string.h>
 #include <linux/buffer_head.h>
-#include <linux/zlib.h>
+#include <linux/crypto.h>
 
 #include "squashfs_fs.h"
 #include "squashfs_fs_sb.h"
@@ -150,7 +150,8 @@ int squashfs_read_data(struct super_block *sb, void *buffer,
        }
 
        if (compressed) {
-               int zlib_err = 0;
+               int error = 0;
+               struct comp_request req;
 
                /*
                 * Uncompress block.
@@ -158,8 +159,8 @@ int squashfs_read_data(struct super_block *sb, void *buffer,
 
                mutex_lock(&msblk->read_data_mutex);
 
-               msblk->stream.next_out = buffer;
-               msblk->stream.avail_out = srclength;
+               req.next_out = buffer;
+               req.avail_out = srclength;
 
                for (bytes = 0; k < b; k++) {
                        avail = min(c_byte - bytes, msblk->devblksize - offset);
@@ -168,16 +169,19 @@ int squashfs_read_data(struct super_block *sb, void 
*buffer,
                        if (!buffer_uptodate(bh[k]))
                                goto release_mutex;
 
-                       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;
 
                        if (k == 0) {
-                               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);
+                               error = crypto_comp_decompress_init(msblk->tfm,
+                                                                   &req);
+                               if (error && error != -EAGAIN) {
+                                       ERROR("crypto_comp_decompress_init "
+                                             "returned unexpected result %d, "
+                                             "srclength %d, avail_in %u, "
+                                             "avail_out %u\n",
+                                             error, srclength, req.avail_in,
+                                             req.avail_out);
                                        goto release_mutex;
                                }
 
@@ -186,15 +190,25 @@ int squashfs_read_data(struct super_block *sb, void 
*buffer,
                                        brelse(bh[k]);
                                        continue;
                                }
+
+                       } else {
+                               error = 
crypto_comp_decompress_update(msblk->tfm,
+                                                                     &req);
+                               if (error) {
+                                       ERROR("crypto_comp_decompress_update "
+                                             "returned unexpected result %d, "
+                                             "srclength %d, avail_in %u, "
+                                             "avail_out %u\n",
+                                             error, srclength, req.avail_in,
+                                             req.avail_out);
+                                       goto release_mutex;
+                               }
                        }
 
-                       zlib_err = zlib_inflate(&msblk->stream, Z_NO_FLUSH);
-                       if (zlib_err != Z_OK && zlib_err != Z_STREAM_END) {
-                               ERROR("zlib_inflate returned unexpected result"
-                                       " 0x%x, srclength %d, avail_in %d,"
-                                       " avail_out %d\n", zlib_err, srclength,
-                                       msblk->stream.avail_in,
-                                       msblk->stream.avail_out);
+                       if (req.avail_in) {
+                               ERROR("crypto_comp_decompress_* did not "
+                                     "consume all input data (%u left)\n",
+                                     req.avail_in);
                                goto release_mutex;
                        }
 
@@ -203,16 +217,15 @@ int squashfs_read_data(struct super_block *sb, void 
*buffer,
                        brelse(bh[k]);
                }
 
-               if (zlib_err != Z_STREAM_END)
-                       goto release_mutex;
-
-               zlib_err = zlib_inflateEnd(&msblk->stream);
-               if (zlib_err != Z_OK) {
-                       ERROR("zlib_inflateEnd returned unexpected result 0x%x,"
-                               " srclength %d\n", zlib_err, srclength);
+               error = crypto_comp_decompress_final(msblk->tfm, &req);
+               if (error) {
+                       ERROR("crypto_comp_decompress_final returned "
+                             "unexpected result %d, srclength %d, avail_in "
+                             "%u, avail_out %u\n",
+                             error, srclength, req.avail_in, req.avail_out);
                        goto release_mutex;
                }
-               bytes = msblk->stream.total_out;
+               bytes = req.next_out - buffer;
                mutex_unlock(&msblk->read_data_mutex);
        } else {
                /*
diff --git a/fs/squashfs/squashfs_fs_sb.h b/fs/squashfs/squashfs_fs_sb.h
index 18e5af4..769bbef 100644
--- a/fs/squashfs/squashfs_fs_sb.h
+++ b/fs/squashfs/squashfs_fs_sb.h
@@ -23,6 +23,8 @@
  * squashfs_fs_sb.h
  */
 
+#include <linux/crypto.h>
+
 #include "squashfs_fs.h"
 
 struct squashfs_cache_entry {
@@ -63,7 +65,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_comp      *tfm;
        __le64                  *inode_lookup_table;
        long long               inode_table;
        long long               directory_table;
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c
index 44f94aa..38e0535 100644
--- a/fs/squashfs/super.c
+++ b/fs/squashfs/super.c
@@ -35,13 +35,17 @@
 #include <linux/pagemap.h>
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/zlib.h>
+#include <linux/crypto.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;
 
@@ -86,9 +90,11 @@ static int squashfs_fill_super(struct super_block *sb, void 
*data, int silent)
        }
        msblk = sb->s_fs_info;
 
-       msblk->stream.workspace = vmalloc(zlib_inflate_workspacesize());
-       if (msblk->stream.workspace == NULL) {
-               ERROR("Failed to allocate zlib workspace\n");
+       msblk->tfm = crypto_alloc_comp(SQUASHFS_CRYPTO_ALG, 0,
+                                      CRYPTO_ALG_ASYNC);
+       if (IS_ERR(msblk->tfm)) {
+               ERROR("Failed to load %s crypto module\n", SQUASHFS_CRYPTO_ALG);
+               msblk->tfm = NULL;
                goto failure;
        }
 
@@ -284,14 +290,14 @@ failed_mount:
        kfree(msblk->inode_lookup_table);
        kfree(msblk->fragment_index);
        kfree(msblk->id_table);
-       vfree(msblk->stream.workspace);
+       crypto_free_comp(msblk->tfm);
        kfree(sb->s_fs_info);
        sb->s_fs_info = NULL;
        kfree(sblk);
        return err;
 
 failure:
-       vfree(msblk->stream.workspace);
+       crypto_free_comp(msblk->tfm);
        kfree(sb->s_fs_info);
        sb->s_fs_info = NULL;
        return -ENOMEM;
@@ -333,7 +339,7 @@ static void squashfs_put_super(struct super_block *sb)
                kfree(sbi->id_table);
                kfree(sbi->fragment_index);
                kfree(sbi->meta_index);
-               vfree(sbi->stream.workspace);
+               crypto_free_comp(sbi->tfm);
                kfree(sb->s_fs_info);
                sb->s_fs_info = NULL;
        }

With kind regards,

Geert Uytterhoeven
Software Architect

Sony Techsoft Centre Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium

Phone:    +32 (0)2 700 8453
Fax:      +32 (0)2 700 8622
E-mail:   [EMAIL PROTECTED]
Internet: http://www.sony-europe.com/

A division of Sony Europe (Belgium) N.V.
VAT BE 0413.825.160 · RPR Brussels
Fortis · BIC GEBABEBB · IBAN BE41293037680010
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to