[PATCH/RFC 4/4] squashfs: Make SquashFS 4 use the new "zlib" crypto module

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 <Geert.Uytterhoeven@xxxxxxxxxxx>
---
 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:   Geert.Uytterhoeven@xxxxxxxxxxx
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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel]     [Gnu Classpath]     [Gnu Crypto]     [DM Crypt]     [Netfilter]     [Bugtraq]

  Powered by Linux