linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/6] Partial (de)compression Crypto API
@ 2009-02-25 13:43 Geert Uytterhoeven
  2009-02-25 13:43 ` [PATCH 1/6] netlink: Move netlink attribute parsing support to lib/ Geert Uytterhoeven
  0 siblings, 1 reply; 25+ messages in thread
From: Geert Uytterhoeven @ 2009-02-25 13:43 UTC (permalink / raw)
  To: Herbert Xu; +Cc: linux-crypto, linux-kernel


	Hi Herbert,

The following patch series adds support for partial (de)compression to the
CRYPTO API, and modifies SquashFS 4 to use this:

  - [1] netlink: Move netlink attribute parsing support to lib/
  - [2] crypto: compress - Add pcomp interface
  - [3] crypto: testmgr - Add support for the pcomp interface
  - [4] crypto: new zlib crypto module, using pcomp
  - [5] crypto: testmgr - add zlib test
  - [6] squashfs: Make SquashFS 4 use the new pcomp crypto interface

The patches are based on:
  linux-2.6.git + cryptodev-2.6.git

Changes since last version (2009-02-18):
  - Use netlink attributes for the (de)compression setup parameters
  - Move netlink attribute parsing support to lib/, enabled by CONFIG_NLATTR

David, Phillip: can I please have your ack?

If nobody objects, please apply.

Thanks!

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@sonycom.com
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

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH 1/6] netlink: Move netlink attribute parsing support to lib/
  2009-02-25 13:43 [PATCH 0/6] Partial (de)compression Crypto API Geert Uytterhoeven
@ 2009-02-25 13:43 ` Geert Uytterhoeven
  2009-02-25 13:43   ` [PATCH 2/6] crypto: compress - Add pcomp interface Geert Uytterhoeven
  2009-02-25 21:59   ` [PATCH 1/6] netlink: Move netlink attribute parsing support to lib/ David Miller
  0 siblings, 2 replies; 25+ messages in thread
From: Geert Uytterhoeven @ 2009-02-25 13:43 UTC (permalink / raw)
  To: Herbert Xu
  Cc: linux-crypto, linux-kernel, Geert Uytterhoeven, David S. Miller, netdev

Netlink attribute parsing may be used even if CONFIG_NET is not set.
Move it from net/netlink to lib and control its inclusion based on the new
config symbol CONFIG_NLATTR, which is selected by CONFIG_NET.

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: netdev@vger.kernel.org
---
 lib/Kconfig                        |    6 ++++++
 lib/Makefile                       |    2 ++
 net/netlink/attr.c => lib/nlattr.c |    0
 net/Kconfig                        |    1 +
 net/netlink/Makefile               |    2 +-
 5 files changed, 10 insertions(+), 1 deletions(-)
 rename net/netlink/attr.c => lib/nlattr.c (100%)

diff --git a/lib/Kconfig b/lib/Kconfig
index 03c2c24..cea9e30 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -174,4 +174,10 @@ config DISABLE_OBSOLETE_CPUMASK_FUNCTIONS
        bool "Disable obsolete cpumask functions" if DEBUG_PER_CPU_MAPS
        depends on EXPERIMENTAL && BROKEN
 
+#
+# Netlink attribute parsing support is select'ed if needed
+#
+config NLATTR
+	bool
+
 endmenu
diff --git a/lib/Makefile b/lib/Makefile
index 32b0e64..b2c09da 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -84,6 +84,8 @@ obj-$(CONFIG_HAVE_ARCH_TRACEHOOK) += syscall.o
 
 obj-$(CONFIG_DYNAMIC_PRINTK_DEBUG) += dynamic_printk.o
 
+obj-$(CONFIG_NLATTR) += nlattr.o
+
 hostprogs-y	:= gen_crc32table
 clean-files	:= crc32table.h
 
diff --git a/net/netlink/attr.c b/lib/nlattr.c
similarity index 100%
rename from net/netlink/attr.c
rename to lib/nlattr.c
diff --git a/net/Kconfig b/net/Kconfig
index cdb8fde..eab40a4 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -4,6 +4,7 @@
 
 menuconfig NET
 	bool "Networking support"
+	select NLATTR
 	---help---
 	  Unless you really know what you are doing, you should say Y here.
 	  The reason is that some programs need kernel networking support even
diff --git a/net/netlink/Makefile b/net/netlink/Makefile
index e3589c2..bdd6ddf 100644
--- a/net/netlink/Makefile
+++ b/net/netlink/Makefile
@@ -2,4 +2,4 @@
 # Makefile for the netlink driver.
 #
 
-obj-y  				:= af_netlink.o attr.o genetlink.o
+obj-y  				:= af_netlink.o genetlink.o
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 2/6] crypto: compress - Add pcomp interface
  2009-02-25 13:43 ` [PATCH 1/6] netlink: Move netlink attribute parsing support to lib/ Geert Uytterhoeven
@ 2009-02-25 13:43   ` Geert Uytterhoeven
  2009-02-25 13:43     ` [PATCH 3/6] crypto: testmgr - Add support for the " Geert Uytterhoeven
  2009-02-25 21:59   ` [PATCH 1/6] netlink: Move netlink attribute parsing support to lib/ David Miller
  1 sibling, 1 reply; 25+ messages in thread
From: Geert Uytterhoeven @ 2009-02-25 13:43 UTC (permalink / raw)
  To: Herbert Xu; +Cc: linux-crypto, linux-kernel, Geert Uytterhoeven

The current "comp" crypto interface supports one-shot (de)compression only,
i.e. the whole data buffer to be (de)compressed must be passed at once, and
the whole (de)compressed data buffer will be received at once.
In several use-cases (e.g. compressed file systems that store files in big
compressed blocks), this workflow is not suitable.
Furthermore, the "comp" type doesn't provide for the configuration of
(de)compression parameters, and always allocates workspace memory for both
compression and decompression, which may waste memory.

To solve this, add a "pcomp" partial (de)compression interface that provides
the following operations:
  - crypto_compress_{init,update,final}() for compression,
  - crypto_decompress_{init,update,final}() for decompression,
  - crypto_{,de}compress_setup(), to configure (de)compression parameters
    (incl. allocating workspace memory).

The (de)compression methods take a struct comp_request, which was mimicked
after the z_stream object in zlib, and contains buffer pointer and length
pairs for input and output.

The setup methods take an opaque parameter pointer and length pair. Parameters
are supposed to be encoded using netlink attributes, whose meanings depend on
the actual (name of the) (de)compression algorithm.

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
---
 crypto/Kconfig                     |    4 +
 crypto/Makefile                    |    2 +
 crypto/pcompress.c                 |   97 ++++++++++++++++++++++++++++
 include/crypto/compress.h          |  125 ++++++++++++++++++++++++++++++++++++
 include/crypto/internal/compress.h |   28 ++++++++
 include/linux/crypto.h             |    1 +
 6 files changed, 257 insertions(+), 0 deletions(-)
 create mode 100644 crypto/pcompress.c
 create mode 100644 include/crypto/compress.h
 create mode 100644 include/crypto/internal/compress.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index a83ce04..c00c985 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -75,6 +75,10 @@ config CRYPTO_RNG2
 	tristate
 	select CRYPTO_ALGAPI2
 
+config CRYPTO_PCOMP
+	tristate
+	select CRYPTO_ALGAPI2
+
 config CRYPTO_MANAGER
 	tristate "Cryptographic algorithm manager"
 	select CRYPTO_MANAGER2
diff --git a/crypto/Makefile b/crypto/Makefile
index 46b08bf..8de194f 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -25,6 +25,8 @@ crypto_hash-objs += ahash.o
 crypto_hash-objs += shash.o
 obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
 
+obj-$(CONFIG_CRYPTO_PCOMP) += pcompress.o
+
 cryptomgr-objs := algboss.o testmgr.o
 
 obj-$(CONFIG_CRYPTO_MANAGER2) += cryptomgr.o
diff --git a/crypto/pcompress.c b/crypto/pcompress.c
new file mode 100644
index 0000000..ca9a4af
--- /dev/null
+++ b/crypto/pcompress.c
@@ -0,0 +1,97 @@
+/*
+ * Cryptographic API.
+ *
+ * Partial (de)compression operations.
+ *
+ * Copyright 2008 Sony Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ * If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/crypto.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/seq_file.h>
+#include <linux/string.h>
+
+#include <crypto/compress.h>
+
+#include "internal.h"
+
+
+static int crypto_pcomp_init(struct crypto_tfm *tfm, u32 type, u32 mask)
+{
+	return 0;
+}
+
+static unsigned int crypto_pcomp_extsize(struct crypto_alg *alg,
+					 const struct crypto_type *frontend)
+{
+	return alg->cra_ctxsize;
+}
+
+static int crypto_pcomp_init_tfm(struct crypto_tfm *tfm,
+				 const struct crypto_type *frontend)
+{
+	return 0;
+}
+
+static void crypto_pcomp_show(struct seq_file *m, struct crypto_alg *alg)
+	__attribute__ ((unused));
+static void crypto_pcomp_show(struct seq_file *m, struct crypto_alg *alg)
+{
+	seq_printf(m, "type         : pcomp\n");
+}
+
+static const struct crypto_type crypto_pcomp_type = {
+	.extsize	= crypto_pcomp_extsize,
+	.init		= crypto_pcomp_init,
+	.init_tfm	= crypto_pcomp_init_tfm,
+#ifdef CONFIG_PROC_FS
+	.show		= crypto_pcomp_show,
+#endif
+	.maskclear	= ~CRYPTO_ALG_TYPE_MASK,
+	.maskset	= CRYPTO_ALG_TYPE_MASK,
+	.type		= CRYPTO_ALG_TYPE_PCOMPRESS,
+	.tfmsize	= offsetof(struct crypto_pcomp, base),
+};
+
+struct crypto_pcomp *crypto_alloc_pcomp(const char *alg_name, u32 type,
+					u32 mask)
+{
+	return crypto_alloc_tfm(alg_name, &crypto_pcomp_type, type, mask);
+}
+EXPORT_SYMBOL_GPL(crypto_alloc_pcomp);
+
+int crypto_register_pcomp(struct pcomp_alg *alg)
+{
+	struct crypto_alg *base = &alg->base;
+
+	base->cra_type = &crypto_pcomp_type;
+	base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK;
+	base->cra_flags |= CRYPTO_ALG_TYPE_PCOMPRESS;
+
+	return crypto_register_alg(base);
+}
+EXPORT_SYMBOL_GPL(crypto_register_pcomp);
+
+int crypto_unregister_pcomp(struct pcomp_alg *alg)
+{
+	return crypto_unregister_alg(&alg->base);
+}
+EXPORT_SYMBOL_GPL(crypto_unregister_pcomp);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Partial (de)compression type");
+MODULE_AUTHOR("Sony Corporation");
diff --git a/include/crypto/compress.h b/include/crypto/compress.h
new file mode 100644
index 0000000..b7d2287
--- /dev/null
+++ b/include/crypto/compress.h
@@ -0,0 +1,125 @@
+/*
+ * Compress: Compression algorithms under the cryptographic API.
+ *
+ * Copyright 2008 Sony Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ * If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _CRYPTO_COMPRESS_H
+#define _CRYPTO_COMPRESS_H
+
+#include <linux/crypto.h>
+
+
+struct comp_request {
+	const void *next_in;		/* next input byte */
+	void *next_out;			/* next output byte */
+	unsigned int avail_in;		/* bytes available at next_in */
+	unsigned int avail_out;		/* bytes available at next_out */
+};
+
+struct crypto_pcomp {
+	struct crypto_tfm base;
+};
+
+struct pcomp_alg {
+	int (*compress_setup)(struct crypto_pcomp *tfm, void *params,
+			      unsigned int len);
+	int (*compress_init)(struct crypto_pcomp *tfm);
+	int (*compress_update)(struct crypto_pcomp *tfm,
+			       struct comp_request *req);
+	int (*compress_final)(struct crypto_pcomp *tfm,
+			      struct comp_request *req);
+	int (*decompress_setup)(struct crypto_pcomp *tfm, void *params,
+				unsigned int len);
+	int (*decompress_init)(struct crypto_pcomp *tfm);
+	int (*decompress_update)(struct crypto_pcomp *tfm,
+				 struct comp_request *req);
+	int (*decompress_final)(struct crypto_pcomp *tfm,
+				struct comp_request *req);
+
+	struct crypto_alg base;
+};
+
+extern struct crypto_pcomp *crypto_alloc_pcomp(const char *alg_name, u32 type,
+					       u32 mask);
+
+static inline struct crypto_tfm *crypto_pcomp_tfm(struct crypto_pcomp *tfm)
+{
+	return &tfm->base;
+}
+
+static inline void crypto_free_pcomp(struct crypto_pcomp *tfm)
+{
+	crypto_destroy_tfm(tfm, crypto_pcomp_tfm(tfm));
+}
+
+static inline struct pcomp_alg *__crypto_pcomp_alg(struct crypto_alg *alg)
+{
+	return container_of(alg, struct pcomp_alg, base);
+}
+
+static inline struct pcomp_alg *crypto_pcomp_alg(struct crypto_pcomp *tfm)
+{
+	return __crypto_pcomp_alg(crypto_pcomp_tfm(tfm)->__crt_alg);
+}
+
+static inline int crypto_compress_setup(struct crypto_pcomp *tfm,
+					void *params, unsigned int len)
+{
+	return crypto_pcomp_alg(tfm)->compress_setup(tfm, params, len);
+}
+
+static inline int crypto_compress_init(struct crypto_pcomp *tfm)
+{
+	return crypto_pcomp_alg(tfm)->compress_init(tfm);
+}
+
+static inline int crypto_compress_update(struct crypto_pcomp *tfm,
+					 struct comp_request *req)
+{
+	return crypto_pcomp_alg(tfm)->compress_update(tfm, req);
+}
+
+static inline int crypto_compress_final(struct crypto_pcomp *tfm,
+					struct comp_request *req)
+{
+	return crypto_pcomp_alg(tfm)->compress_final(tfm, req);
+}
+
+static inline int crypto_decompress_setup(struct crypto_pcomp *tfm,
+					  void *params, unsigned int len)
+{
+	return crypto_pcomp_alg(tfm)->decompress_setup(tfm, params, len);
+}
+
+static inline int crypto_decompress_init(struct crypto_pcomp *tfm)
+{
+	return crypto_pcomp_alg(tfm)->decompress_init(tfm);
+}
+
+static inline int crypto_decompress_update(struct crypto_pcomp *tfm,
+					   struct comp_request *req)
+{
+	return crypto_pcomp_alg(tfm)->decompress_update(tfm, req);
+}
+
+static inline int crypto_decompress_final(struct crypto_pcomp *tfm,
+					  struct comp_request *req)
+{
+	return crypto_pcomp_alg(tfm)->decompress_final(tfm, req);
+}
+
+#endif	/* _CRYPTO_COMPRESS_H */
diff --git a/include/crypto/internal/compress.h b/include/crypto/internal/compress.h
new file mode 100644
index 0000000..178a888
--- /dev/null
+++ b/include/crypto/internal/compress.h
@@ -0,0 +1,28 @@
+/*
+ * Compress: Compression algorithms under the cryptographic API.
+ *
+ * Copyright 2008 Sony Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ * If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _CRYPTO_INTERNAL_COMPRESS_H
+#define _CRYPTO_INTERNAL_COMPRESS_H
+
+#include <crypto/compress.h>
+
+extern int crypto_register_pcomp(struct pcomp_alg *alg);
+extern int crypto_unregister_pcomp(struct pcomp_alg *alg);
+
+#endif	/* _CRYPTO_INTERNAL_COMPRESS_H */
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index 29729b8..ec29fa2 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -40,6 +40,7 @@
 #define CRYPTO_ALG_TYPE_SHASH		0x00000009
 #define CRYPTO_ALG_TYPE_AHASH		0x0000000a
 #define CRYPTO_ALG_TYPE_RNG		0x0000000c
+#define CRYPTO_ALG_TYPE_PCOMPRESS	0x0000000f
 
 #define CRYPTO_ALG_TYPE_HASH_MASK	0x0000000e
 #define CRYPTO_ALG_TYPE_AHASH_MASK	0x0000000c
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 3/6] crypto: testmgr - Add support for the pcomp interface
  2009-02-25 13:43   ` [PATCH 2/6] crypto: compress - Add pcomp interface Geert Uytterhoeven
@ 2009-02-25 13:43     ` Geert Uytterhoeven
  2009-02-25 13:43       ` [PATCH 4/6] crypto: new zlib crypto module, using pcomp Geert Uytterhoeven
  0 siblings, 1 reply; 25+ messages in thread
From: Geert Uytterhoeven @ 2009-02-25 13:43 UTC (permalink / raw)
  To: Herbert Xu; +Cc: linux-crypto, linux-kernel, Geert Uytterhoeven

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
---
 crypto/testmgr.c |  183 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 crypto/testmgr.h |   10 +++
 2 files changed, 193 insertions(+), 0 deletions(-)

diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index a75f11f..e750357 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -72,6 +72,13 @@ struct comp_test_suite {
 	} comp, decomp;
 };
 
+struct pcomp_test_suite {
+	struct {
+		struct pcomp_testvec *vecs;
+		unsigned int count;
+	} comp, decomp;
+};
+
 struct hash_test_suite {
 	struct hash_testvec *vecs;
 	unsigned int count;
@@ -86,6 +93,7 @@ struct alg_test_desc {
 		struct aead_test_suite aead;
 		struct cipher_test_suite cipher;
 		struct comp_test_suite comp;
+		struct pcomp_test_suite pcomp;
 		struct hash_test_suite hash;
 	} suite;
 };
@@ -898,6 +906,159 @@ out:
 	return ret;
 }
 
+static int test_pcomp(struct crypto_pcomp *tfm,
+		      struct pcomp_testvec *ctemplate,
+		      struct pcomp_testvec *dtemplate, int ctcount,
+		      int dtcount)
+{
+	const char *algo = crypto_tfm_alg_driver_name(crypto_pcomp_tfm(tfm));
+	unsigned int i;
+	char result[COMP_BUF_SIZE];
+	int error;
+
+	for (i = 0; i < ctcount; i++) {
+		struct comp_request req;
+
+		error = crypto_compress_setup(tfm, ctemplate[i].params,
+					      ctemplate[i].paramsize);
+		if (error) {
+			pr_err("alg: pcomp: compression setup failed on test "
+			       "%d for %s: error=%d\n", i + 1, algo, error);
+			return error;
+		}
+
+		error = crypto_compress_init(tfm);
+		if (error) {
+			pr_err("alg: pcomp: compression init failed on test "
+			       "%d for %s: error=%d\n", i + 1, algo, error);
+			return error;
+		}
+
+		memset(result, 0, sizeof(result));
+
+		req.next_in = ctemplate[i].input;
+		req.avail_in = ctemplate[i].inlen / 2;
+		req.next_out = result;
+		req.avail_out = ctemplate[i].outlen / 2;
+
+		error = crypto_compress_update(tfm, &req);
+		if (error && (error != -EAGAIN || req.avail_in)) {
+			pr_err("alg: pcomp: compression update failed on test "
+			       "%d for %s: error=%d\n", i + 1, algo, error);
+			return error;
+		}
+
+		/* Add remaining input data */
+		req.avail_in += (ctemplate[i].inlen + 1) / 2;
+
+		error = crypto_compress_update(tfm, &req);
+		if (error && (error != -EAGAIN || req.avail_in)) {
+			pr_err("alg: pcomp: compression update failed on test "
+			       "%d for %s: error=%d\n", i + 1, algo, error);
+			return error;
+		}
+
+		/* Provide remaining output space */
+		req.avail_out += COMP_BUF_SIZE - ctemplate[i].outlen / 2;
+
+		error = crypto_compress_final(tfm, &req);
+		if (error) {
+			pr_err("alg: pcomp: compression final failed on test "
+			       "%d for %s: error=%d\n", i + 1, algo, error);
+			return error;
+		}
+
+		if (COMP_BUF_SIZE - req.avail_out != ctemplate[i].outlen) {
+			pr_err("alg: comp: Compression test %d failed for %s: "
+			       "output len = %d (expected %d)\n", i + 1, algo,
+			       COMP_BUF_SIZE - req.avail_out,
+			       ctemplate[i].outlen);
+			return -EINVAL;
+		}
+
+		if (memcmp(result, ctemplate[i].output, ctemplate[i].outlen)) {
+			pr_err("alg: pcomp: Compression test %d failed for "
+			       "%s\n", i + 1, algo);
+			hexdump(result, ctemplate[i].outlen);
+			return -EINVAL;
+		}
+	}
+
+	for (i = 0; i < dtcount; i++) {
+		struct comp_request req;
+
+		error = crypto_decompress_setup(tfm, dtemplate[i].params,
+						dtemplate[i].paramsize);
+		if (error) {
+			pr_err("alg: pcomp: decompression setup failed on "
+			       "test %d for %s: error=%d\n", i + 1, algo,
+			       error);
+			return error;
+		}
+
+		error = crypto_decompress_init(tfm);
+		if (error) {
+			pr_err("alg: pcomp: decompression init failed on test "
+			       "%d for %s: error=%d\n", i + 1, algo, error);
+			return error;
+		}
+
+		memset(result, 0, sizeof(result));
+
+		req.next_in = dtemplate[i].input;
+		req.avail_in = dtemplate[i].inlen / 2;
+		req.next_out = result;
+		req.avail_out = dtemplate[i].outlen / 2;
+
+		error = crypto_decompress_update(tfm, &req);
+		if (error  && (error != -EAGAIN || req.avail_in)) {
+			pr_err("alg: pcomp: decompression update failed on "
+			       "test %d for %s: error=%d\n", i + 1, algo,
+			       error);
+			return error;
+		}
+
+		/* Add remaining input data */
+		req.avail_in += (dtemplate[i].inlen + 1) / 2;
+
+		error = crypto_decompress_update(tfm, &req);
+		if (error  && (error != -EAGAIN || req.avail_in)) {
+			pr_err("alg: pcomp: decompression update failed on "
+			       "test %d for %s: error=%d\n", i + 1, algo,
+			       error);
+			return error;
+		}
+
+		/* Provide remaining output space */
+		req.avail_out += COMP_BUF_SIZE - dtemplate[i].outlen / 2;
+
+		error = crypto_decompress_final(tfm, &req);
+		if (error  && (error != -EAGAIN || req.avail_in)) {
+			pr_err("alg: pcomp: decompression final failed on "
+			       "test %d for %s: error=%d\n", i + 1, algo,
+			       error);
+			return error;
+		}
+
+		if (COMP_BUF_SIZE - req.avail_out != dtemplate[i].outlen) {
+			pr_err("alg: comp: Decompression test %d failed for "
+			       "%s: output len = %d (expected %d)\n", i + 1,
+			       algo, COMP_BUF_SIZE - req.avail_out,
+			       dtemplate[i].outlen);
+			return -EINVAL;
+		}
+
+		if (memcmp(result, dtemplate[i].output, dtemplate[i].outlen)) {
+			pr_err("alg: pcomp: Decompression test %d failed for "
+			       "%s\n", i + 1, algo);
+			hexdump(result, dtemplate[i].outlen);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
 static int alg_test_aead(const struct alg_test_desc *desc, const char *driver,
 			 u32 type, u32 mask)
 {
@@ -1007,6 +1168,28 @@ static int alg_test_comp(const struct alg_test_desc *desc, const char *driver,
 	return err;
 }
 
+static int alg_test_pcomp(const struct alg_test_desc *desc, const char *driver,
+			  u32 type, u32 mask)
+{
+	struct crypto_pcomp *tfm;
+	int err;
+
+	tfm = crypto_alloc_pcomp(driver, type, mask);
+	if (IS_ERR(tfm)) {
+		pr_err("alg: pcomp: Failed to load transform for %s: %ld\n",
+		       driver, PTR_ERR(tfm));
+		return PTR_ERR(tfm);
+	}
+
+	err = test_pcomp(tfm, desc->suite.pcomp.comp.vecs,
+			 desc->suite.pcomp.decomp.vecs,
+			 desc->suite.pcomp.comp.count,
+			 desc->suite.pcomp.decomp.count);
+
+	crypto_free_pcomp(tfm);
+	return err;
+}
+
 static int alg_test_hash(const struct alg_test_desc *desc, const char *driver,
 			 u32 type, u32 mask)
 {
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index 132953e..c517e43 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -15,6 +15,8 @@
 #ifndef _CRYPTO_TESTMGR_H
 #define _CRYPTO_TESTMGR_H
 
+#include <crypto/compress.h>
+
 #define MAX_DIGEST_SIZE		64
 #define MAX_TAP			8
 
@@ -8347,6 +8349,14 @@ struct comp_testvec {
 	char output[COMP_BUF_SIZE];
 };
 
+struct pcomp_testvec {
+	void *params;
+	unsigned int paramsize;
+	int inlen, outlen;
+	char input[COMP_BUF_SIZE];
+	char output[COMP_BUF_SIZE];
+};
+
 /*
  * Deflate test vectors (null-terminated strings).
  * Params: winbits=-11, Z_DEFAULT_COMPRESSION, MAX_MEM_LEVEL.
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 4/6] crypto: new zlib crypto module, using pcomp
  2009-02-25 13:43     ` [PATCH 3/6] crypto: testmgr - Add support for the " Geert Uytterhoeven
@ 2009-02-25 13:43       ` Geert Uytterhoeven
  2009-02-25 13:43         ` [PATCH 5/6] crypto: testmgr - add zlib test Geert Uytterhoeven
  0 siblings, 1 reply; 25+ messages in thread
From: Geert Uytterhoeven @ 2009-02-25 13:43 UTC (permalink / raw)
  To: Herbert Xu; +Cc: linux-crypto, linux-kernel, Geert Uytterhoeven, James Morris

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
Cc: James Morris <jmorris@namei.org>
---
 crypto/Kconfig            |    9 +
 crypto/Makefile           |    1 +
 crypto/zlib.c             |  378 +++++++++++++++++++++++++++++++++++++++++++++
 include/crypto/compress.h |   20 +++
 4 files changed, 408 insertions(+), 0 deletions(-)
 create mode 100644 crypto/zlib.c

diff --git a/crypto/Kconfig b/crypto/Kconfig
index c00c985..8845eff 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -743,6 +743,15 @@ config CRYPTO_DEFLATE
 
 	  You will most probably want this if using IPSec.
 
+config CRYPTO_ZLIB
+	tristate "Zlib compression algorithm"
+	select CRYPTO_PCOMP
+	select ZLIB_INFLATE
+	select ZLIB_DEFLATE
+	select NLATTR
+	help
+	  This is the zlib algorithm.
+
 config CRYPTO_LZO
 	tristate "LZO compression algorithm"
 	select CRYPTO_ALGAPI
diff --git a/crypto/Makefile b/crypto/Makefile
index 8de194f..836a764 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -72,6 +72,7 @@ obj-$(CONFIG_CRYPTO_ANUBIS) += anubis.o
 obj-$(CONFIG_CRYPTO_SEED) += seed.o
 obj-$(CONFIG_CRYPTO_SALSA20) += salsa20_generic.o
 obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o
+obj-$(CONFIG_CRYPTO_ZLIB) += zlib.o
 obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o
 obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o
 obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o
diff --git a/crypto/zlib.c b/crypto/zlib.c
new file mode 100644
index 0000000..33609ba
--- /dev/null
+++ b/crypto/zlib.c
@@ -0,0 +1,378 @@
+/*
+ * Cryptographic API.
+ *
+ * Zlib algorithm
+ *
+ * Copyright 2008 Sony Corporation
+ *
+ * Based on deflate.c, which is
+ * Copyright (c) 2003 James Morris <jmorris@intercode.com.au>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * FIXME: deflate transforms will require up to a total of about 436k of kernel
+ * memory on i386 (390k for compression, the rest for decompression), as the
+ * current zlib kernel code uses a worst case pre-allocation system by default.
+ * This needs to be fixed so that the amount of memory required is properly
+ * related to the winbits and memlevel parameters.
+ */
+
+#define pr_fmt(fmt)	"%s: " fmt, __func__
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/zlib.h>
+#include <linux/vmalloc.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/net.h>
+#include <linux/slab.h>
+
+#include <crypto/internal/compress.h>
+
+#include <net/netlink.h>
+
+
+struct zlib_ctx {
+	struct z_stream_s comp_stream;
+	struct z_stream_s decomp_stream;
+	int decomp_windowBits;
+};
+
+
+static void zlib_comp_exit(struct zlib_ctx *ctx)
+{
+	struct z_stream_s *stream = &ctx->comp_stream;
+
+	if (stream->workspace) {
+		zlib_deflateEnd(stream);
+		vfree(stream->workspace);
+		stream->workspace = NULL;
+	}
+}
+
+static void zlib_decomp_exit(struct zlib_ctx *ctx)
+{
+	struct z_stream_s *stream = &ctx->decomp_stream;
+
+	if (stream->workspace) {
+		zlib_inflateEnd(stream);
+		kfree(stream->workspace);
+		stream->workspace = NULL;
+	}
+}
+
+static int zlib_init(struct crypto_tfm *tfm)
+{
+	return 0;
+}
+
+static void zlib_exit(struct crypto_tfm *tfm)
+{
+	struct zlib_ctx *ctx = crypto_tfm_ctx(tfm);
+
+	zlib_comp_exit(ctx);
+	zlib_decomp_exit(ctx);
+}
+
+
+static int zlib_compress_setup(struct crypto_pcomp *tfm, void *params,
+			       unsigned int len)
+{
+	struct zlib_ctx *ctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
+	struct z_stream_s *stream = &ctx->comp_stream;
+	struct nlattr *tb[ZLIB_COMP_MAX + 1];
+	size_t workspacesize;
+	int ret;
+
+	ret = nla_parse(tb, ZLIB_COMP_MAX, params, len, NULL);
+	if (ret)
+		return ret;
+
+	zlib_comp_exit(ctx);
+
+	workspacesize = zlib_deflate_workspacesize();
+	stream->workspace = vmalloc(workspacesize);
+	if (!stream->workspace)
+		return -ENOMEM;
+
+	memset(stream->workspace, 0, workspacesize);
+	ret = zlib_deflateInit2(stream,
+				tb[ZLIB_COMP_LEVEL]
+					? nla_get_u32(tb[ZLIB_COMP_LEVEL])
+					: Z_DEFAULT_COMPRESSION,
+				tb[ZLIB_COMP_METHOD]
+					? nla_get_u32(tb[ZLIB_COMP_METHOD])
+					: Z_DEFLATED,
+				tb[ZLIB_COMP_WINDOWBITS]
+					? nla_get_u32(tb[ZLIB_COMP_WINDOWBITS])
+					: MAX_WBITS,
+				tb[ZLIB_COMP_MEMLEVEL]
+					? nla_get_u32(tb[ZLIB_COMP_MEMLEVEL])
+					: DEF_MEM_LEVEL,
+				tb[ZLIB_COMP_STRATEGY]
+					? nla_get_u32(tb[ZLIB_COMP_STRATEGY])
+					: Z_DEFAULT_STRATEGY);
+	if (ret != Z_OK) {
+		vfree(stream->workspace);
+		stream->workspace = NULL;
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int zlib_compress_init(struct crypto_pcomp *tfm)
+{
+	int ret;
+	struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
+	struct z_stream_s *stream = &dctx->comp_stream;
+
+	ret = zlib_deflateReset(stream);
+	if (ret != Z_OK)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int zlib_compress_update(struct crypto_pcomp *tfm,
+				struct comp_request *req)
+{
+	int ret;
+	struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
+	struct z_stream_s *stream = &dctx->comp_stream;
+
+	pr_debug("avail_in %u, avail_out %u\n", req->avail_in, req->avail_out);
+	stream->next_in = req->next_in;
+	stream->avail_in = req->avail_in;
+	stream->next_out = req->next_out;
+	stream->avail_out = req->avail_out;
+
+	ret = zlib_deflate(stream, Z_NO_FLUSH);
+	switch (ret) {
+	case Z_OK:
+		break;
+
+	case Z_BUF_ERROR:
+		pr_debug("zlib_deflate could not make progress\n");
+		return -EAGAIN;
+
+	default:
+		pr_debug("zlib_deflate failed %d\n", ret);
+		return -EINVAL;
+	}
+
+	pr_debug("avail_in %u, avail_out %u (consumed %u, produced %u)\n",
+		 stream->avail_in, stream->avail_out,
+		 req->avail_in - stream->avail_in,
+		 req->avail_out - stream->avail_out);
+	req->next_in = stream->next_in;
+	req->avail_in = stream->avail_in;
+	req->next_out = stream->next_out;
+	req->avail_out = stream->avail_out;
+	return 0;
+}
+
+static int zlib_compress_final(struct crypto_pcomp *tfm,
+			       struct comp_request *req)
+{
+	int ret;
+	struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
+	struct z_stream_s *stream = &dctx->comp_stream;
+
+	pr_debug("avail_in %u, avail_out %u\n", req->avail_in, req->avail_out);
+	stream->next_in = req->next_in;
+	stream->avail_in = req->avail_in;
+	stream->next_out = req->next_out;
+	stream->avail_out = req->avail_out;
+
+	ret = zlib_deflate(stream, Z_FINISH);
+	if (ret != Z_STREAM_END) {
+		pr_debug("zlib_deflate failed %d\n", ret);
+		return -EINVAL;
+	}
+
+	pr_debug("avail_in %u, avail_out %u (consumed %u, produced %u)\n",
+		 stream->avail_in, stream->avail_out,
+		 req->avail_in - stream->avail_in,
+		 req->avail_out - stream->avail_out);
+	req->next_in = stream->next_in;
+	req->avail_in = stream->avail_in;
+	req->next_out = stream->next_out;
+	req->avail_out = stream->avail_out;
+	return 0;
+}
+
+
+static int zlib_decompress_setup(struct crypto_pcomp *tfm, void *params,
+				 unsigned int len)
+{
+	struct zlib_ctx *ctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
+	struct z_stream_s *stream = &ctx->decomp_stream;
+	struct nlattr *tb[ZLIB_DECOMP_MAX + 1];
+	int ret = 0;
+
+	ret = nla_parse(tb, ZLIB_DECOMP_MAX, params, len, NULL);
+	if (ret)
+		return ret;
+
+	zlib_decomp_exit(ctx);
+
+	ctx->decomp_windowBits = tb[ZLIB_DECOMP_WINDOWBITS]
+				 ? nla_get_u32(tb[ZLIB_DECOMP_WINDOWBITS])
+				 : DEF_WBITS;
+
+	stream->workspace = kzalloc(zlib_inflate_workspacesize(), GFP_KERNEL);
+	if (!stream->workspace)
+		return -ENOMEM;
+
+	ret = zlib_inflateInit2(stream, ctx->decomp_windowBits);
+	if (ret != Z_OK) {
+		kfree(stream->workspace);
+		stream->workspace = NULL;
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int zlib_decompress_init(struct crypto_pcomp *tfm)
+{
+	int ret;
+	struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
+	struct z_stream_s *stream = &dctx->decomp_stream;
+
+	ret = zlib_inflateReset(stream);
+	if (ret != Z_OK)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int zlib_decompress_update(struct crypto_pcomp *tfm,
+				  struct comp_request *req)
+{
+	int ret;
+	struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
+	struct z_stream_s *stream = &dctx->decomp_stream;
+
+	pr_debug("avail_in %u, avail_out %u\n", req->avail_in, req->avail_out);
+	stream->next_in = req->next_in;
+	stream->avail_in = req->avail_in;
+	stream->next_out = req->next_out;
+	stream->avail_out = req->avail_out;
+
+	ret = zlib_inflate(stream, Z_SYNC_FLUSH);
+	switch (ret) {
+	case Z_OK:
+	case Z_STREAM_END:
+		break;
+
+	case Z_BUF_ERROR:
+		pr_debug("zlib_inflate could not make progress\n");
+		return -EAGAIN;
+
+	default:
+		pr_debug("zlib_inflate failed %d\n", ret);
+		return -EINVAL;
+	}
+
+	pr_debug("avail_in %u, avail_out %u (consumed %u, produced %u)\n",
+		 stream->avail_in, stream->avail_out,
+		 req->avail_in - stream->avail_in,
+		 req->avail_out - stream->avail_out);
+	req->next_in = stream->next_in;
+	req->avail_in = stream->avail_in;
+	req->next_out = stream->next_out;
+	req->avail_out = stream->avail_out;
+	return 0;
+}
+
+static int zlib_decompress_final(struct crypto_pcomp *tfm,
+				 struct comp_request *req)
+{
+	int ret;
+	struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
+	struct z_stream_s *stream = &dctx->decomp_stream;
+
+	pr_debug("avail_in %u, avail_out %u\n", req->avail_in, req->avail_out);
+	stream->next_in = req->next_in;
+	stream->avail_in = req->avail_in;
+	stream->next_out = req->next_out;
+	stream->avail_out = req->avail_out;
+
+	if (dctx->decomp_windowBits < 0) {
+		ret = zlib_inflate(stream, Z_SYNC_FLUSH);
+		/*
+		 * Work around a bug in zlib, which sometimes wants to taste an
+		 * extra byte when being used in the (undocumented) raw deflate
+		 * mode. (From USAGI).
+		 */
+		if (ret == Z_OK && !stream->avail_in && stream->avail_out) {
+			const void *saved_next_in = stream->next_in;
+			u8 zerostuff = 0;
+
+			stream->next_in = &zerostuff;
+			stream->avail_in = 1;
+			ret = zlib_inflate(stream, Z_FINISH);
+			stream->next_in = saved_next_in;
+			stream->avail_in = 0;
+		}
+	} else
+		ret = zlib_inflate(stream, Z_FINISH);
+	if (ret != Z_STREAM_END) {
+		pr_debug("zlib_inflate failed %d\n", ret);
+		return -EINVAL;
+	}
+
+	pr_debug("avail_in %u, avail_out %u (consumed %u, produced %u)\n",
+		 stream->avail_in, stream->avail_out,
+		 req->avail_in - stream->avail_in,
+		 req->avail_out - stream->avail_out);
+	req->next_in = stream->next_in;
+	req->avail_in = stream->avail_in;
+	req->next_out = stream->next_out;
+	req->avail_out = stream->avail_out;
+	return 0;
+}
+
+
+static struct pcomp_alg zlib_alg = {
+	.compress_setup		= zlib_compress_setup,
+	.compress_init		= zlib_compress_init,
+	.compress_update	= zlib_compress_update,
+	.compress_final		= zlib_compress_final,
+	.decompress_setup	= zlib_decompress_setup,
+	.decompress_init	= zlib_decompress_init,
+	.decompress_update	= zlib_decompress_update,
+	.decompress_final	= zlib_decompress_final,
+
+	.base			= {
+		.cra_name	= "zlib",
+		.cra_flags	= CRYPTO_ALG_TYPE_PCOMPRESS,
+		.cra_ctxsize	= sizeof(struct zlib_ctx),
+		.cra_module	= THIS_MODULE,
+		.cra_init	= zlib_init,
+		.cra_exit	= zlib_exit,
+	}
+};
+
+static int __init zlib_mod_init(void)
+{
+	return crypto_register_pcomp(&zlib_alg);
+}
+
+static void __exit zlib_mod_fini(void)
+{
+	crypto_unregister_pcomp(&zlib_alg);
+}
+
+module_init(zlib_mod_init);
+module_exit(zlib_mod_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Zlib Compression Algorithm");
+MODULE_AUTHOR("Sony Corporation");
diff --git a/include/crypto/compress.h b/include/crypto/compress.h
index b7d2287..86163ef 100644
--- a/include/crypto/compress.h
+++ b/include/crypto/compress.h
@@ -30,6 +30,26 @@ struct comp_request {
 	unsigned int avail_out;		/* bytes available at next_out */
 };
 
+enum zlib_comp_params {
+	ZLIB_COMP_LEVEL = 1,		/* e.g. Z_DEFAULT_COMPRESSION */
+	ZLIB_COMP_METHOD,		/* e.g. Z_DEFLATED */
+	ZLIB_COMP_WINDOWBITS,		/* e.g. MAX_WBITS */
+	ZLIB_COMP_MEMLEVEL,		/* e.g. DEF_MEM_LEVEL */
+	ZLIB_COMP_STRATEGY,		/* e.g. Z_DEFAULT_STRATEGY */
+	__ZLIB_COMP_MAX,
+};
+
+#define ZLIB_COMP_MAX	(__ZLIB_COMP_MAX - 1)
+
+
+enum zlib_decomp_params {
+	ZLIB_DECOMP_WINDOWBITS = 1,	/* e.g. DEF_WBITS */
+	__ZLIB_DECOMP_MAX,
+};
+
+#define ZLIB_DECOMP_MAX	(__ZLIB_DECOMP_MAX - 1)
+
+
 struct crypto_pcomp {
 	struct crypto_tfm base;
 };
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 5/6] crypto: testmgr - add zlib test
  2009-02-25 13:43       ` [PATCH 4/6] crypto: new zlib crypto module, using pcomp Geert Uytterhoeven
@ 2009-02-25 13:43         ` Geert Uytterhoeven
  2009-02-25 13:43           ` [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface Geert Uytterhoeven
  0 siblings, 1 reply; 25+ messages in thread
From: Geert Uytterhoeven @ 2009-02-25 13:43 UTC (permalink / raw)
  To: Herbert Xu; +Cc: linux-crypto, linux-kernel, Geert Uytterhoeven

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
---
 crypto/Kconfig   |    1 +
 crypto/tcrypt.c  |    6 ++-
 crypto/testmgr.c |   15 ++++++
 crypto/testmgr.h |  137 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 158 insertions(+), 1 deletions(-)

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 8845eff..632330d 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -91,6 +91,7 @@ config CRYPTO_MANAGER2
 	select CRYPTO_AEAD2
 	select CRYPTO_HASH2
 	select CRYPTO_BLKCIPHER2
+	select CRYPTO_PCOMP
 
 config CRYPTO_GF128MUL
 	tristate "GF(2^128) multiplication functions (EXPERIMENTAL)"
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 28a45a1..c3c9124 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -53,7 +53,7 @@ static char *check[] = {
 	"cast6", "arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea",
 	"khazad", "wp512", "wp384", "wp256", "tnepres", "xeta",  "fcrypt",
 	"camellia", "seed", "salsa20", "rmd128", "rmd160", "rmd256", "rmd320",
-	"lzo", "cts", NULL
+	"lzo", "cts", "zlib", NULL
 };
 
 static int test_cipher_jiffies(struct blkcipher_desc *desc, int enc,
@@ -661,6 +661,10 @@ static void do_test(int m)
 		tcrypt_test("ecb(seed)");
 		break;
 
+	case 44:
+		tcrypt_test("zlib");
+		break;
+
 	case 100:
 		tcrypt_test("hmac(md5)");
 		break;
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index e750357..b50c3c6 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -2018,6 +2018,21 @@ static const struct alg_test_desc alg_test_descs[] = {
 				}
 			}
 		}
+	}, {
+		.alg = "zlib",
+		.test = alg_test_pcomp,
+		.suite = {
+			.pcomp = {
+				.comp = {
+					.vecs = zlib_comp_tv_template,
+					.count = ZLIB_COMP_TEST_VECTORS
+				},
+				.decomp = {
+					.vecs = zlib_decomp_tv_template,
+					.count = ZLIB_DECOMP_TEST_VECTORS
+				}
+			}
+		}
 	}
 };
 
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index c517e43..526f00a 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -15,6 +15,9 @@
 #ifndef _CRYPTO_TESTMGR_H
 #define _CRYPTO_TESTMGR_H
 
+#include <linux/netlink.h>
+#include <linux/zlib.h>
+
 #include <crypto/compress.h>
 
 #define MAX_DIGEST_SIZE		64
@@ -8361,6 +8364,7 @@ struct pcomp_testvec {
  * Deflate test vectors (null-terminated strings).
  * Params: winbits=-11, Z_DEFAULT_COMPRESSION, MAX_MEM_LEVEL.
  */
+
 #define DEFLATE_COMP_TEST_VECTORS 2
 #define DEFLATE_DECOMP_TEST_VECTORS 2
 
@@ -8436,6 +8440,139 @@ static struct comp_testvec deflate_decomp_tv_template[] = {
 	},
 };
 
+#define ZLIB_COMP_TEST_VECTORS 2
+#define ZLIB_DECOMP_TEST_VECTORS 2
+
+static const struct {
+	struct nlattr nla;
+	int val;
+} deflate_comp_params[] = {
+	{
+		.nla = {
+			.nla_len	= NLA_HDRLEN + sizeof(int),
+			.nla_type	= ZLIB_COMP_LEVEL,
+		},
+		.val			= Z_DEFAULT_COMPRESSION,
+	}, {
+		.nla = {
+			.nla_len	= NLA_HDRLEN + sizeof(int),
+			.nla_type	= ZLIB_COMP_METHOD,
+		},
+		.val			= Z_DEFLATED,
+	}, {
+		.nla = {
+			.nla_len	= NLA_HDRLEN + sizeof(int),
+			.nla_type	= ZLIB_COMP_WINDOWBITS,
+		},
+		.val			= -11,
+	}, {
+		.nla = {
+			.nla_len	= NLA_HDRLEN + sizeof(int),
+			.nla_type	= ZLIB_COMP_MEMLEVEL,
+		},
+		.val			= MAX_MEM_LEVEL,
+	}, {
+		.nla = {
+			.nla_len	= NLA_HDRLEN + sizeof(int),
+			.nla_type	= ZLIB_COMP_STRATEGY,
+		},
+		.val			= Z_DEFAULT_STRATEGY,
+	}
+};
+
+static const struct {
+	struct nlattr nla;
+	int val;
+} deflate_decomp_params[] = {
+	{
+		.nla = {
+			.nla_len	= NLA_HDRLEN + sizeof(int),
+			.nla_type	= ZLIB_DECOMP_WINDOWBITS,
+		},
+		.val			= -11,
+	}
+};
+
+static struct pcomp_testvec zlib_comp_tv_template[] = {
+	{
+		.params = &deflate_comp_params,
+		.paramsize = sizeof(deflate_comp_params),
+		.inlen	= 70,
+		.outlen	= 38,
+		.input	= "Join us now and share the software "
+			"Join us now and share the software ",
+		.output	= "\xf3\xca\xcf\xcc\x53\x28\x2d\x56"
+			  "\xc8\xcb\x2f\x57\x48\xcc\x4b\x51"
+			  "\x28\xce\x48\x2c\x4a\x55\x28\xc9"
+			  "\x48\x55\x28\xce\x4f\x2b\x29\x07"
+			  "\x71\xbc\x08\x2b\x01\x00",
+	}, {
+		.params = &deflate_comp_params,
+		.paramsize = sizeof(deflate_comp_params),
+		.inlen	= 191,
+		.outlen	= 122,
+		.input	= "This document describes a compression method based on the DEFLATE"
+			"compression algorithm.  This document defines the application of "
+			"the DEFLATE algorithm to the IP Payload Compression Protocol.",
+		.output	= "\x5d\x8d\x31\x0e\xc2\x30\x10\x04"
+			  "\xbf\xb2\x2f\xc8\x1f\x10\x04\x09"
+			  "\x89\xc2\x85\x3f\x70\xb1\x2f\xf8"
+			  "\x24\xdb\x67\xd9\x47\xc1\xef\x49"
+			  "\x68\x12\x51\xae\x76\x67\xd6\x27"
+			  "\x19\x88\x1a\xde\x85\xab\x21\xf2"
+			  "\x08\x5d\x16\x1e\x20\x04\x2d\xad"
+			  "\xf3\x18\xa2\x15\x85\x2d\x69\xc4"
+			  "\x42\x83\x23\xb6\x6c\x89\x71\x9b"
+			  "\xef\xcf\x8b\x9f\xcf\x33\xca\x2f"
+			  "\xed\x62\xa9\x4c\x80\xff\x13\xaf"
+			  "\x52\x37\xed\x0e\x52\x6b\x59\x02"
+			  "\xd9\x4e\xe8\x7a\x76\x1d\x02\x98"
+			  "\xfe\x8a\x87\x83\xa3\x4f\x56\x8a"
+			  "\xb8\x9e\x8e\x5c\x57\xd3\xa0\x79"
+			  "\xfa\x02",
+	},
+};
+
+static struct pcomp_testvec zlib_decomp_tv_template[] = {
+	{
+		.params = &deflate_decomp_params,
+		.paramsize = sizeof(deflate_decomp_params),
+		.inlen	= 122,
+		.outlen	= 191,
+		.input	= "\x5d\x8d\x31\x0e\xc2\x30\x10\x04"
+			  "\xbf\xb2\x2f\xc8\x1f\x10\x04\x09"
+			  "\x89\xc2\x85\x3f\x70\xb1\x2f\xf8"
+			  "\x24\xdb\x67\xd9\x47\xc1\xef\x49"
+			  "\x68\x12\x51\xae\x76\x67\xd6\x27"
+			  "\x19\x88\x1a\xde\x85\xab\x21\xf2"
+			  "\x08\x5d\x16\x1e\x20\x04\x2d\xad"
+			  "\xf3\x18\xa2\x15\x85\x2d\x69\xc4"
+			  "\x42\x83\x23\xb6\x6c\x89\x71\x9b"
+			  "\xef\xcf\x8b\x9f\xcf\x33\xca\x2f"
+			  "\xed\x62\xa9\x4c\x80\xff\x13\xaf"
+			  "\x52\x37\xed\x0e\x52\x6b\x59\x02"
+			  "\xd9\x4e\xe8\x7a\x76\x1d\x02\x98"
+			  "\xfe\x8a\x87\x83\xa3\x4f\x56\x8a"
+			  "\xb8\x9e\x8e\x5c\x57\xd3\xa0\x79"
+			  "\xfa\x02",
+		.output	= "This document describes a compression method based on the DEFLATE"
+			"compression algorithm.  This document defines the application of "
+			"the DEFLATE algorithm to the IP Payload Compression Protocol.",
+	}, {
+		.params = &deflate_decomp_params,
+		.paramsize = sizeof(deflate_decomp_params),
+		.inlen	= 38,
+		.outlen	= 70,
+		.input	= "\xf3\xca\xcf\xcc\x53\x28\x2d\x56"
+			  "\xc8\xcb\x2f\x57\x48\xcc\x4b\x51"
+			  "\x28\xce\x48\x2c\x4a\x55\x28\xc9"
+			  "\x48\x55\x28\xce\x4f\x2b\x29\x07"
+			  "\x71\xbc\x08\x2b\x01\x00",
+		.output	= "Join us now and share the software "
+			"Join us now and share the software ",
+	},
+};
+
 /*
  * LZO test vectors (null-terminated strings).
  */
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface
  2009-02-25 13:43         ` [PATCH 5/6] crypto: testmgr - add zlib test Geert Uytterhoeven
@ 2009-02-25 13:43           ` Geert Uytterhoeven
  2009-03-07 10:46             ` Herbert Xu
  2009-03-17 12:44             ` [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface Geert Uytterhoeven
  0 siblings, 2 replies; 25+ messages in thread
From: Geert Uytterhoeven @ 2009-02-25 13:43 UTC (permalink / raw)
  To: Herbert Xu
  Cc: linux-crypto, linux-kernel, Geert Uytterhoeven, Phillip Lougher

Modify SquashFS 4 to use the new "pcomp" crypto interface for decompression,
instead of calling the underlying zlib library directly. This simplifies e.g.
the addition of support for hardware decompression and different decompression
algorithms.

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
Cc: Phillip Lougher <phillip@lougher.demon.co.uk>
---
 fs/squashfs/Kconfig          |    3 +-
 fs/squashfs/block.c          |   80 +++++++++++++++++++++++------------------
 fs/squashfs/squashfs_fs_sb.h |    2 +-
 fs/squashfs/super.c          |   44 +++++++++++++++++++----
 4 files changed, 84 insertions(+), 45 deletions(-)

diff --git a/fs/squashfs/Kconfig b/fs/squashfs/Kconfig
index 25a00d1..18e33a6 100644
--- 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
diff --git a/fs/squashfs/block.c b/fs/squashfs/block.c
index c837dfc..5a3e628 100644
--- 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,9 @@ int squashfs_read_data(struct super_block *sb, void **buffer, u64 index,
 	}
 
 	if (compressed) {
-		int zlib_err = 0, zlib_init = 0;
+		int error = 0, decomp_init = 0;
+		struct comp_request req;
+		unsigned int produced = 0;
 
 		/*
 		 * Uncompress block.
@@ -161,12 +164,13 @@ int squashfs_read_data(struct super_block *sb, void **buffer, u64 index,
 
 		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,50 +183,56 @@ int squashfs_read_data(struct super_block *sb, void **buffer, u64 index,
 					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) {
-				msblk->stream.next_out = buffer[page++];
-				msblk->stream.avail_out = PAGE_CACHE_SIZE;
+			if (req.avail_out == 0) {
+				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) {
+				error = crypto_decompress_init(msblk->tfm);
+				if (error) {
+					ERROR("crypto_decompress_init "
+						"returned %d, srclength %d\n",
+						error, srclength);
 					goto release_mutex;
 				}
-				zlib_init = 1;
+				decomp_init = 1;
+			}
+
+			produced = req.avail_out;
+			error = crypto_decompress_update(msblk->tfm, &req);
+			if (error) {
+				ERROR("crypto_decompress_update returned %d, "
+					"srclength %d, avail_in %d, avail_out "
+					"%d\n", error, srclength, req.avail_in,
+					req.avail_out);
+				goto release_mutex;
 			}
+			produced -= req.avail_out;
 
-			zlib_err = zlib_inflate(&msblk->stream, Z_NO_FLUSH);
+			length += produced;
 
-			if (msblk->stream.avail_in == 0 && k < b)
+			if (req.avail_in == 0 && k < b)
 				put_bh(bh[k++]);
-		} while (zlib_err == Z_OK);
-
-		if (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);
-			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);
+		} while (bytes || produced);
+
+		produced = req.avail_out;
+		error = crypto_decompress_final(msblk->tfm, &req);
+		if (error) {
+			ERROR("crypto_decompress_final returned %d, srclength "
+				"%d\n", error, srclength);
 			goto release_mutex;
 		}
-		length = msblk->stream.total_out;
+		produced -= req.avail_out;
+
+		length += produced;
+
 		mutex_unlock(&msblk->read_data_mutex);
 	} else {
 		/*
diff --git a/fs/squashfs/squashfs_fs_sb.h b/fs/squashfs/squashfs_fs_sb.h
index c8c6561..4eae75b 100644
--- 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;
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c
index 071df5b..62be5ae 100644
--- 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 super_block *sb, void *data, int silent)
 	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 super_block *sb, void *data, int silent)
 	}
 	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;
 	}
 
@@ -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 super_block *sb)
 		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;
 	}
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [PATCH 1/6] netlink: Move netlink attribute parsing support to lib/
  2009-02-25 13:43 ` [PATCH 1/6] netlink: Move netlink attribute parsing support to lib/ Geert Uytterhoeven
  2009-02-25 13:43   ` [PATCH 2/6] crypto: compress - Add pcomp interface Geert Uytterhoeven
@ 2009-02-25 21:59   ` David Miller
  1 sibling, 0 replies; 25+ messages in thread
From: David Miller @ 2009-02-25 21:59 UTC (permalink / raw)
  To: Geert.Uytterhoeven; +Cc: herbert, linux-crypto, linux-kernel, netdev

From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
Date: Wed, 25 Feb 2009 14:43:09 +0100

> Netlink attribute parsing may be used even if CONFIG_NET is not set.
> Move it from net/netlink to lib and control its inclusion based on the new
> config symbol CONFIG_NLATTR, which is selected by CONFIG_NET.
> 
> Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>

Acked-by: David S. Miller <davem@davemloft.net>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface
  2009-02-25 13:43           ` [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface Geert Uytterhoeven
@ 2009-03-07 10:46             ` Herbert Xu
  2009-03-08  6:47               ` Phillip Lougher
  2009-03-17 12:44             ` [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface Geert Uytterhoeven
  1 sibling, 1 reply; 25+ messages in thread
From: Herbert Xu @ 2009-03-07 10:46 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: linux-crypto, linux-kernel, Phillip Lougher

On Wed, Feb 25, 2009 at 02:43:14PM +0100, Geert Uytterhoeven wrote:
> Modify SquashFS 4 to use the new "pcomp" crypto interface for decompression,
> instead of calling the underlying zlib library directly. This simplifies e.g.
> the addition of support for hardware decompression and different decompression
> algorithms.
> 
> Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
> Cc: Phillip Lougher <phillip@lougher.demon.co.uk>

I've applied patches 1-5.  I'd like to see an ack on this before
applying it.

Thanks,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface
  2009-03-07 10:46             ` Herbert Xu
@ 2009-03-08  6:47               ` Phillip Lougher
  2009-03-11 17:59                 ` Geert Uytterhoeven
  0 siblings, 1 reply; 25+ messages in thread
From: Phillip Lougher @ 2009-03-08  6:47 UTC (permalink / raw)
  To: Herbert Xu; +Cc: Geert Uytterhoeven, linux-crypto, linux-kernel

Herbert Xu wrote:
> On Wed, Feb 25, 2009 at 02:43:14PM +0100, Geert Uytterhoeven wrote:
>> Modify SquashFS 4 to use the new "pcomp" crypto interface for decompression,
>> instead of calling the underlying zlib library directly. This simplifies e.g.
>> the addition of support for hardware decompression and different decompression
>> algorithms.
>>
>> Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
>> Cc: Phillip Lougher <phillip@lougher.demon.co.uk>
> 
> I've applied patches 1-5.  I'd like to see an ack on this before
> applying it.
> 

I've not acked it because I've not yet made any decisions as to whether 
I want it in Squashfs.  Also as Squashfs maintainer I maintain my own 
tree of patches to Squashfs, and so I'll prefer to add it to my tree for 
subsequent feeding into 2.6.30 once the merge window opens.

I'm fairly agnostic about what decompression library Squashfs uses.  The 
only thing I care about is cleanliness and usability of the API and 
performance.  If the crypto API is cleaner or the cryto zlib 
implementation is faster than the current zlib implementation then I see 
no reason not to move over to it.  But, I've seen no performance figures 
and the API seems clumsier.

Two API issues of concern (one major, one minor).  Both of these relate 
to the way Squashfs drives the decompression code, where it repeatedly 
calls it supplying additional input/output buffers, rather than using a 
"single-shot" approach where it calls the decompression code once 
supplying all the necessary input and output buffer space.

1. Minor issue -the lack of a stream.total_out field.  The current 
zlib_inflate code collects the total number of bytes decompressed over 
the multiple calls into the stream.total_out field.

    There is clearly no such field available in the cryto API, leading 
to the somewhat clumsy need to track it, i.e. it leads to the following 
additional code.

+		unsigned int produced = 0;

[snip]

 > +		length = 0;

[snip]
 > +			produced = req.avail_out;
 > +			error = crypto_decompress_update(msblk->tfm, &req);

 > +			produced -= req.avail_out;
 >
 > +			length += produced;
 >

[snip]
 > +		produced = req.avail_out;
 > +		error = crypto_decompress_final(msblk->tfm, &req);

 > +		produced -= req.avail_out;
 > +
 > +		length += produced;


Whereas previously, only the following single line was required:

 > -		length = msblk->stream.total_out;

2. Major issue - working out loop termination.

It transpires when decompressing from multiple input buffers into 
multiple output buffers, determining when the decompressor has consumed 
all input buffers and has flushed all output to the output buffers is 
difficult.

One might assume loop termination can take place once the decompressor 
has consumed all the input data - however, this is insufficient because 
the decompressor may exit having consumed all the input data but it 
still requires additional output buffer space (stream.avail_in == 0, 
stream.avail_out == 0).

This leads to the exit condition (stream.avail_in == 0 && 
stream.avail_out != 0).  However, this still isn't sufficient because 
the majority of blocks in Squashfs decompress to an exact multiple of 
the output buffer, i.e. stream.avail_in == 0 && stream.avail_out == 0 is 
true at the end of decompression.

(stream.avail_in == 0 && stream_avail_out == 0) == true may or may not 
indicate the end of decompression.  In other words the status of the 
input/output buffers doesn't give sufficient information as to whether 
to terminate the loop or not.

With zlib_inflate this is irrelevant because it supplies a suitable exit 
code indicating whether it needs to be called again (Z_OK) or whether 
decompression has finished (Z_STREAM_END).  This makes loop termination 
easy.

My biggest criticism against the cryto changes to Squashfs is 
crypto_decompress_update doesn't seem to give this information, leaving 
to the clumsy introduction of a check to see if crypto_decompress_update 
produced any output data, i.e.:

-		} while (zlib_err == Z_OK);
 > -

is replaced by:

 > +		} while (bytes || produced);
 > +

This is clearly suboptimal, and always leads to an additional iteration 
around the loop.  Only once we've iterated over the loop one last time 
doing nothing do we decide the decompression has completed.

Not only this, but the loop termination also suffers from a major 
unanticipated bug:

The loop termination forces an additional iteration around the loop even 
though we've run out of output buffer space.

Consider the usual scenario where we're decompressing a buffer into two 
4K pages (pages = 2), and the buffer decompresses to 8K.  The final 
"real" iteration will have produced != 0 and req.avail_out == 0 (we've 
consumed all the output bytes in the last output buffer).

Because produced != 0 we will iterate over the loop again.  But because
req.avail_out == 0 we will load req.next_out with a non-existent buffer 
(we will fall off the end of the buffer array), i.e.

+			if (req.avail_out == 0) {
 > +				req.next_out = buffer[page++];
 > +				req.avail_out = PAGE_CACHE_SIZE;
 >  			}
 >

If for any reason crypto_decompress_update produces unexpected output 
(perhaps because of corrupted data), we will trigger a kernel oops.

Obviously in the majority of cases (which is why the code works), the 
"false" additional iteration doesn't produce any output.  But it is 
distinctly bad practice to have code in the kernel that in normal 
operation passes a bad pointer to crypto_decompress_output, and relies 
on its behaviour not to use that bad pointer.

> Thanks,

Currently as it stands I cannot accept the patch into Squashfs for the 
above reasons.  The code is less optimal, suffers from a major bug, and 
has a number of workarounds stemming from what I feel is a less 
"featureful" API.

I'm willing to consider moving Squashfs over to the crypto API once my 
concerns have been addressed.  The promised simplification in the 
"addition of support for hardware decompression and different 
decompression algorithms" seems quite attractive.  But I'm unwilling to 
degrade the zlib support in Squashfs for this future promise.

Phillip


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface
  2009-03-08  6:47               ` Phillip Lougher
@ 2009-03-11 17:59                 ` Geert Uytterhoeven
  2009-03-17 12:54                   ` [PATCH/RFC] crypto: compress - Add comp_request.total_out (was: Re: [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface) Geert Uytterhoeven
  0 siblings, 1 reply; 25+ messages in thread
From: Geert Uytterhoeven @ 2009-03-11 17:59 UTC (permalink / raw)
  To: Phillip Lougher; +Cc: Herbert Xu, linux-crypto, linux-kernel

	Hi Phillip,

On Sun, 8 Mar 2009, Phillip Lougher wrote:
> Herbert Xu wrote:
> > On Wed, Feb 25, 2009 at 02:43:14PM +0100, Geert Uytterhoeven wrote:
> > > Modify SquashFS 4 to use the new "pcomp" crypto interface for
> > > decompression,
> > > instead of calling the underlying zlib library directly. This simplifies
> > > e.g.
> > > the addition of support for hardware decompression and different
> > > decompression
> > > algorithms.
> > >
> > > Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
> > > Cc: Phillip Lougher <phillip@lougher.demon.co.uk>
> > 
> > I've applied patches 1-5.  I'd like to see an ack on this before
> > applying it.
> 
> I've not acked it because I've not yet made any decisions as to whether I want
> it in Squashfs.  Also as Squashfs maintainer I maintain my own tree of patches
> to Squashfs, and so I'll prefer to add it to my tree for subsequent feeding
> into 2.6.30 once the merge window opens.

OK.

> I'm fairly agnostic about what decompression library Squashfs uses.  The only
> thing I care about is cleanliness and usability of the API and performance.
> If the crypto API is cleaner or the cryto zlib implementation is faster than
> the current zlib implementation then I see no reason not to move over to it.
> But, I've seen no performance figures and the API seems clumsier.

I did not see any noticeable performance impact due to my changes.

> Two API issues of concern (one major, one minor).  Both of these relate to the
> way Squashfs drives the decompression code, where it repeatedly calls it
> supplying additional input/output buffers, rather than using a "single-shot"
> approach where it calls the decompression code once supplying all the
> necessary input and output buffer space.
> 
> 1. Minor issue -the lack of a stream.total_out field.  The current
> zlib_inflate code collects the total number of bytes decompressed over the
> multiple calls into the stream.total_out field.
> 
>    There is clearly no such field available in the cryto API, leading to the
> somewhat clumsy need to track it, i.e. it leads to the following additional
> code.

If people feel the need for a total_out field, I can add it to struct
comp_request.

BTW, what about total_in, which is also provided by plain zlib's z_stream?
Do people see a need for a similar field?

> 2. Major issue - working out loop termination.
> 
> It transpires when decompressing from multiple input buffers into multiple
> output buffers, determining when the decompressor has consumed all input
> buffers and has flushed all output to the output buffers is difficult.

    [...]

> With zlib_inflate this is irrelevant because it supplies a suitable exit code
> indicating whether it needs to be called again (Z_OK) or whether decompression
> has finished (Z_STREAM_END).  This makes loop termination easy.

Zlib indeed provides such a flag. Other decompression algorithms may not
provide this, and keep on `decompressing' as long as you feed them data.

So while I could add an output flag indicating decompression has finished, it
cannot be more than a mere hint when considering support for multiple
(de)compression algorithms.

> My biggest criticism against the cryto changes to Squashfs is
> crypto_decompress_update doesn't seem to give this information, leaving to the
> clumsy introduction of a check to see if crypto_decompress_update produced any
> output data, i.e.:
> 
> -		} while (zlib_err == Z_OK);
> > -
> 
> is replaced by:
> 
> > +		} while (bytes || produced);
> > +
> 
> This is clearly suboptimal, and always leads to an additional iteration around
> the loop.  Only once we've iterated over the loop one last time doing nothing
> do we decide the decompression has completed.

Given the difficulty in determining the finishing of decompression in a generic
way, I don't see a better solution. If no data has been consumed nor produced,
and no -EAGAIN is returned, decompression is finished.

BTW, this is also very similar to reading from a file: read() returns a
non-zero count until the end of the file is reached.

The additional loop also doesn't seem to have any noticeable impact on
performance, though.

> Not only this, but the loop termination also suffers from a major
> unanticipated bug:
> 
> The loop termination forces an additional iteration around the loop even
> though we've run out of output buffer space.
> 
> Consider the usual scenario where we're decompressing a buffer into two 4K
> pages (pages = 2), and the buffer decompresses to 8K.  The final "real"
> iteration will have produced != 0 and req.avail_out == 0 (we've consumed all
> the output bytes in the last output buffer).
> 
> Because produced != 0 we will iterate over the loop again.  But because
> req.avail_out == 0 we will load req.next_out with a non-existent buffer (we
> will fall off the end of the buffer array), i.e.
> 
> +			if (req.avail_out == 0) {
> > +				req.next_out = buffer[page++];
> > +				req.avail_out = PAGE_CACHE_SIZE;
> >     }
> >
> 
> If for any reason crypto_decompress_update produces unexpected output (perhaps
> because of corrupted data), we will trigger a kernel oops.
> 
> Obviously in the majority of cases (which is why the code works), the "false"
> additional iteration doesn't produce any output.  But it is distinctly bad
> practice to have code in the kernel that in normal operation passes a bad
> pointer to crypto_decompress_output, and relies on its behaviour not to use
> that bad pointer.

You are right.  Hence this needs a check for page < pages, cfr. your recent fix
to survive corrupted file system images. I'll take care of that.

Thanks for your comments!

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@sonycom.com
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

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface
  2009-02-25 13:43           ` [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface Geert Uytterhoeven
  2009-03-07 10:46             ` Herbert Xu
@ 2009-03-17 12:44             ` Geert Uytterhoeven
  1 sibling, 0 replies; 25+ messages in thread
From: Geert Uytterhoeven @ 2009-03-17 12:44 UTC (permalink / raw)
  To: Herbert Xu; +Cc: linux-crypto, linux-kernel, Phillip Lougher

On Wed, 25 Feb 2009, Geert Uytterhoeven wrote:
> Modify SquashFS 4 to use the new "pcomp" crypto interface for decompression,
> instead of calling the underlying zlib library directly. This simplifies e.g.
> the addition of support for hardware decompression and different decompression
> algorithms.

This is an updated patch, to accomodate for the recent changes in SquashFS.
---
>From 46b8e0ab105e9b414d455c0a7205a7c79f0517e8 Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
Date: Thu, 18 Dec 2008 14:35:22 +0100
Subject: [PATCH] squashfs: Make SquashFS 4 use the new pcomp crypto interface

Modify SquashFS 4 to use the new "pcomp" crypto interface for decompression,
instead of calling the underlying zlib library directly. This simplifies e.g.
the addition of support for hardware decompression and different decompression
algorithms.

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
Cc: Phillip Lougher <phillip@lougher.demon.co.uk>
---
 fs/squashfs/Kconfig          |    3 +-
 fs/squashfs/block.c          |   70 ++++++++++++++++++++++++-----------------
 fs/squashfs/squashfs_fs_sb.h |    2 +-
 fs/squashfs/super.c          |   44 +++++++++++++++++++++-----
 4 files changed, 80 insertions(+), 39 deletions(-)

diff --git a/fs/squashfs/Kconfig b/fs/squashfs/Kconfig
index 25a00d1..18e33a6 100644
--- 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
diff --git a/fs/squashfs/block.c b/fs/squashfs/block.c
index 2a79603..6196821 100644
--- 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,9 @@ int squashfs_read_data(struct super_block *sb, void **buffer, u64 index,
 	}
 
 	if (compressed) {
-		int zlib_err = 0, zlib_init = 0;
+		int error = 0, decomp_init = 0;
+		struct comp_request req;
+		unsigned int produced = 0;
 
 		/*
 		 * Uncompress block.
@@ -161,12 +164,13 @@ int squashfs_read_data(struct super_block *sb, void **buffer, u64 index,
 
 		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 +183,53 @@ int squashfs_read_data(struct super_block *sb, void **buffer, u64 index,
 					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) {
+				error = crypto_decompress_init(msblk->tfm);
+				if (error) {
+					ERROR("crypto_decompress_init "
+						"returned %d, srclength %d\n",
+						error, srclength);
 					goto release_mutex;
 				}
-				zlib_init = 1;
+				decomp_init = 1;
+			}
+
+			produced = req.avail_out;
+			error = crypto_decompress_update(msblk->tfm, &req);
+			if (error) {
+				ERROR("crypto_decompress_update returned %d, "
+					"data probably corrupt\n", error);
+				goto release_mutex;
 			}
+			produced -= req.avail_out;
 
-			zlib_err = zlib_inflate(&msblk->stream, Z_SYNC_FLUSH);
+			length += produced;
 
-			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 || produced);
 
-		if (zlib_err != Z_STREAM_END) {
-			ERROR("zlib_inflate error, data probably corrupt\n");
+		produced = req.avail_out;
+		error = crypto_decompress_final(msblk->tfm, &req);
+		if (error) {
+			ERROR("crypto_decompress_final returned %d, data "
+				"probably corrupt\n", error);
 			goto release_mutex;
 		}
+		produced -= req.avail_out;
+
+		length += produced;
 
-		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 {
 		/*
diff --git a/fs/squashfs/squashfs_fs_sb.h b/fs/squashfs/squashfs_fs_sb.h
index c8c6561..4eae75b 100644
--- 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;
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c
index 681ec0d..2b63f54 100644
--- 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 super_block *sb, void *data, int silent)
 	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 super_block *sb, void *data, int silent)
 	}
 	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;
 	}
 
@@ -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 super_block *sb)
 		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;
 	}
-- 
1.6.0.4


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@sonycom.com
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

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH/RFC] crypto: compress - Add comp_request.total_out (was: Re: [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface)
  2009-03-11 17:59                 ` Geert Uytterhoeven
@ 2009-03-17 12:54                   ` Geert Uytterhoeven
  2009-03-24 16:33                     ` [PATCH/RFC] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}() (was: Re: [PATCH/RFC] crypto: compress - Add comp_request.total_out (was: Re: [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface)) Geert Uytterhoeven
  0 siblings, 1 reply; 25+ messages in thread
From: Geert Uytterhoeven @ 2009-03-17 12:54 UTC (permalink / raw)
  To: Phillip Lougher; +Cc: Herbert Xu, linux-crypto, linux-kernel

On Wed, 11 Mar 2009, Geert Uytterhoeven wrote:
> On Sun, 8 Mar 2009, Phillip Lougher wrote:
> > Two API issues of concern (one major, one minor).  Both of these relate to the
> > way Squashfs drives the decompression code, where it repeatedly calls it
> > supplying additional input/output buffers, rather than using a "single-shot"
> > approach where it calls the decompression code once supplying all the
> > necessary input and output buffer space.
> > 
> > 1. Minor issue -the lack of a stream.total_out field.  The current
> > zlib_inflate code collects the total number of bytes decompressed over the
> > multiple calls into the stream.total_out field.
> > 
> >    There is clearly no such field available in the cryto API, leading to the
> > somewhat clumsy need to track it, i.e. it leads to the following additional
> > code.
> 
> If people feel the need for a total_out field, I can add it to struct
> comp_request.
> 
> BTW, what about total_in, which is also provided by plain zlib's z_stream?
> Do people see a need for a similar field?

The patch below (on top of the updated one to convert SquashFS to pcomp) adds
comp_request.total_out, so you don't have to calculate and accumulate the
decompressed output sizes in SquashFS.

Notes:
  - This required the addition of a `struct comp_request *' parameter to
    crypto_{,de}compress_init()
  - Still, there's one of the 

	produced = req.avail_out;
	...
	produced -= req.avail_out;

    left, as this is part of the logic to discover the end of decompression
    (no bytes produced, no error returned).

Perhaps it's better to instead make crypto_{,de}compress_{update,final}()
return the (positive) number of output bytes (of the current step)?

Currently it returns zero (no error) or a negative error value.
That would allow to get rid of both `produced = ... / produced -= ...'
constructs, but the user would have to accumulate the total output size again
(which is not such a big deal, IMHO).

Thanks for your comments!

>From e43f85baa75668be4cce340ae98a3b76e66a452a Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
Date: Mon, 16 Mar 2009 15:53:30 +0100
Subject: [PATCH] crypto: compress - Add comp_request.total_out

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
---
 crypto/testmgr.c          |    4 ++--
 crypto/zlib.c             |   12 ++++++++++--
 fs/squashfs/block.c       |   10 +++-------
 include/crypto/compress.h |   17 +++++++++++------
 4 files changed, 26 insertions(+), 17 deletions(-)

diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index b50c3c6..2b112ae 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -927,7 +927,7 @@ static int test_pcomp(struct crypto_pcomp *tfm,
 			return error;
 		}
 
-		error = crypto_compress_init(tfm);
+		error = crypto_compress_init(tfm, &req);
 		if (error) {
 			pr_err("alg: pcomp: compression init failed on test "
 			       "%d for %s: error=%d\n", i + 1, algo, error);
@@ -996,7 +996,7 @@ static int test_pcomp(struct crypto_pcomp *tfm,
 			return error;
 		}
 
-		error = crypto_decompress_init(tfm);
+		error = crypto_decompress_init(tfm, &req);
 		if (error) {
 			pr_err("alg: pcomp: decompression init failed on test "
 			       "%d for %s: error=%d\n", i + 1, algo, error);
diff --git a/crypto/zlib.c b/crypto/zlib.c
index 33609ba..93ec380 100644
--- a/crypto/zlib.c
+++ b/crypto/zlib.c
@@ -125,7 +125,8 @@ static int zlib_compress_setup(struct crypto_pcomp *tfm, void *params,
 	return 0;
 }
 
-static int zlib_compress_init(struct crypto_pcomp *tfm)
+static int zlib_compress_init(struct crypto_pcomp *tfm,
+			      struct comp_request *req)
 {
 	int ret;
 	struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
@@ -135,6 +136,7 @@ static int zlib_compress_init(struct crypto_pcomp *tfm)
 	if (ret != Z_OK)
 		return -EINVAL;
 
+	req->total_out = 0;
 	return 0;
 }
 
@@ -173,6 +175,7 @@ static int zlib_compress_update(struct crypto_pcomp *tfm,
 	req->avail_in = stream->avail_in;
 	req->next_out = stream->next_out;
 	req->avail_out = stream->avail_out;
+	req->total_out = stream->total_out;
 	return 0;
 }
 
@@ -203,6 +206,7 @@ static int zlib_compress_final(struct crypto_pcomp *tfm,
 	req->avail_in = stream->avail_in;
 	req->next_out = stream->next_out;
 	req->avail_out = stream->avail_out;
+	req->total_out = stream->total_out;
 	return 0;
 }
 
@@ -239,7 +243,8 @@ static int zlib_decompress_setup(struct crypto_pcomp *tfm, void *params,
 	return 0;
 }
 
-static int zlib_decompress_init(struct crypto_pcomp *tfm)
+static int zlib_decompress_init(struct crypto_pcomp *tfm,
+				struct comp_request *req)
 {
 	int ret;
 	struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
@@ -249,6 +254,7 @@ static int zlib_decompress_init(struct crypto_pcomp *tfm)
 	if (ret != Z_OK)
 		return -EINVAL;
 
+	req->total_out = 0;
 	return 0;
 }
 
@@ -288,6 +294,7 @@ static int zlib_decompress_update(struct crypto_pcomp *tfm,
 	req->avail_in = stream->avail_in;
 	req->next_out = stream->next_out;
 	req->avail_out = stream->avail_out;
+	req->total_out = stream->total_out;
 	return 0;
 }
 
@@ -336,6 +343,7 @@ static int zlib_decompress_final(struct crypto_pcomp *tfm,
 	req->avail_in = stream->avail_in;
 	req->next_out = stream->next_out;
 	req->avail_out = stream->avail_out;
+	req->total_out = stream->total_out;
 	return 0;
 }
 
diff --git a/fs/squashfs/block.c b/fs/squashfs/block.c
index 6196821..11e19b6 100644
--- a/fs/squashfs/block.c
+++ b/fs/squashfs/block.c
@@ -168,7 +168,6 @@ int squashfs_read_data(struct super_block *sb, void **buffer, u64 index,
 		req.avail_in = 0;
 
 		bytes = length;
-		length = 0;
 		do {
 			if (req.avail_in == 0 && k < b) {
 				avail = min(bytes, msblk->devblksize - offset);
@@ -194,7 +193,8 @@ int squashfs_read_data(struct super_block *sb, void **buffer, u64 index,
 			}
 
 			if (!decomp_init) {
-				error = crypto_decompress_init(msblk->tfm);
+				error = crypto_decompress_init(msblk->tfm,
+							       &req);
 				if (error) {
 					ERROR("crypto_decompress_init "
 						"returned %d, srclength %d\n",
@@ -213,22 +213,18 @@ int squashfs_read_data(struct super_block *sb, void **buffer, u64 index,
 			}
 			produced -= req.avail_out;
 
-			length += produced;
-
 			if (req.avail_in == 0 && k < b)
 				put_bh(bh[k++]);
 		} while (bytes || produced);
 
-		produced = req.avail_out;
 		error = crypto_decompress_final(msblk->tfm, &req);
 		if (error) {
 			ERROR("crypto_decompress_final returned %d, data "
 				"probably corrupt\n", error);
 			goto release_mutex;
 		}
-		produced -= req.avail_out;
 
-		length += produced;
+		length = req.total_out;
 
 		mutex_unlock(&msblk->read_data_mutex);
 	} else {
diff --git a/include/crypto/compress.h b/include/crypto/compress.h
index 86163ef..d872c06 100644
--- a/include/crypto/compress.h
+++ b/include/crypto/compress.h
@@ -28,6 +28,7 @@ struct comp_request {
 	void *next_out;			/* next output byte */
 	unsigned int avail_in;		/* bytes available at next_in */
 	unsigned int avail_out;		/* bytes available at next_out */
+	size_t total_out;		/* total bytes output so far */
 };
 
 enum zlib_comp_params {
@@ -57,14 +58,16 @@ struct crypto_pcomp {
 struct pcomp_alg {
 	int (*compress_setup)(struct crypto_pcomp *tfm, void *params,
 			      unsigned int len);
-	int (*compress_init)(struct crypto_pcomp *tfm);
+	int (*compress_init)(struct crypto_pcomp *tfm,
+			     struct comp_request *req);
 	int (*compress_update)(struct crypto_pcomp *tfm,
 			       struct comp_request *req);
 	int (*compress_final)(struct crypto_pcomp *tfm,
 			      struct comp_request *req);
 	int (*decompress_setup)(struct crypto_pcomp *tfm, void *params,
 				unsigned int len);
-	int (*decompress_init)(struct crypto_pcomp *tfm);
+	int (*decompress_init)(struct crypto_pcomp *tfm,
+			       struct comp_request *req);
 	int (*decompress_update)(struct crypto_pcomp *tfm,
 				 struct comp_request *req);
 	int (*decompress_final)(struct crypto_pcomp *tfm,
@@ -102,9 +105,10 @@ static inline int crypto_compress_setup(struct crypto_pcomp *tfm,
 	return crypto_pcomp_alg(tfm)->compress_setup(tfm, params, len);
 }
 
-static inline int crypto_compress_init(struct crypto_pcomp *tfm)
+static inline int crypto_compress_init(struct crypto_pcomp *tfm,
+				       struct comp_request *req)
 {
-	return crypto_pcomp_alg(tfm)->compress_init(tfm);
+	return crypto_pcomp_alg(tfm)->compress_init(tfm, req);
 }
 
 static inline int crypto_compress_update(struct crypto_pcomp *tfm,
@@ -125,9 +129,10 @@ static inline int crypto_decompress_setup(struct crypto_pcomp *tfm,
 	return crypto_pcomp_alg(tfm)->decompress_setup(tfm, params, len);
 }
 
-static inline int crypto_decompress_init(struct crypto_pcomp *tfm)
+static inline int crypto_decompress_init(struct crypto_pcomp *tfm,
+					 struct comp_request *req)
 {
-	return crypto_pcomp_alg(tfm)->decompress_init(tfm);
+	return crypto_pcomp_alg(tfm)->decompress_init(tfm, req);
 }
 
 static inline int crypto_decompress_update(struct crypto_pcomp *tfm,
-- 
1.6.0.4

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@sonycom.com
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

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH/RFC] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}() (was: Re: [PATCH/RFC] crypto: compress - Add comp_request.total_out (was: Re: [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface))
  2009-03-17 12:54                   ` [PATCH/RFC] crypto: compress - Add comp_request.total_out (was: Re: [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface) Geert Uytterhoeven
@ 2009-03-24 16:33                     ` Geert Uytterhoeven
  2009-03-25 10:12                       ` [PATCH/RFC] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}() (was: Re: [PATCH/RFC] crypto: compress - Add comp_request.total_out Phillip Lougher
  2009-04-20  6:03                       ` [PATCH/RFC] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}() (was: Re: [PATCH/RFC] crypto: compress - Add comp_request.total_out (was: Re: [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface)) Herbert Xu
  0 siblings, 2 replies; 25+ messages in thread
From: Geert Uytterhoeven @ 2009-03-24 16:33 UTC (permalink / raw)
  To: Phillip Lougher; +Cc: Herbert Xu, linux-crypto, linux-kernel

On Tue, 17 Mar 2009, Geert Uytterhoeven wrote:
> On Wed, 11 Mar 2009, Geert Uytterhoeven wrote:
> > On Sun, 8 Mar 2009, Phillip Lougher wrote:
> > > Two API issues of concern (one major, one minor).  Both of these relate to the
> > > way Squashfs drives the decompression code, where it repeatedly calls it
> > > supplying additional input/output buffers, rather than using a "single-shot"
> > > approach where it calls the decompression code once supplying all the
> > > necessary input and output buffer space.
> > > 
> > > 1. Minor issue -the lack of a stream.total_out field.  The current
> > > zlib_inflate code collects the total number of bytes decompressed over the
> > > multiple calls into the stream.total_out field.
> > > 
> > >    There is clearly no such field available in the cryto API, leading to the
> > > somewhat clumsy need to track it, i.e. it leads to the following additional
> > > code.
> > 
> > If people feel the need for a total_out field, I can add it to struct
> > comp_request.
> > 
> > BTW, what about total_in, which is also provided by plain zlib's z_stream?
> > Do people see a need for a similar field?
> 
> The patch below (on top of the updated one to convert SquashFS to pcomp) adds
> comp_request.total_out, so you don't have to calculate and accumulate the
> decompressed output sizes in SquashFS.
> 
> Notes:
>   - This required the addition of a `struct comp_request *' parameter to
>     crypto_{,de}compress_init()
>   - Still, there's one of the 
> 
> 	produced = req.avail_out;
> 	...
> 	produced -= req.avail_out;
> 
>     left, as this is part of the logic to discover the end of decompression
>     (no bytes produced, no error returned).
> 
> Perhaps it's better to instead make crypto_{,de}compress_{update,final}()
> return the (positive) number of output bytes (of the current step)?
> 
> Currently it returns zero (no error) or a negative error value.
> That would allow to get rid of both `produced = ... / produced -= ...'
> constructs, but the user would have to accumulate the total output size again
> (which is not such a big deal, IMHO).

Here's an alternative patch, which does exactly that.
Phillip, what do you think?

Thanks for your comments!

>From be7d630f96a85d3ce48716b8e328563ba217647b Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
Date: Tue, 24 Mar 2009 17:19:05 +0100
Subject: [PATCH] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}()

If crypto_{,de}compress_{update,final}() succeed, return the actual number of
bytes produced instead of zero, so their users don't have to calculate that
theirselves.

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
---
 crypto/testmgr.c    |  117 ++++++++++++++++++++++++++++++--------------------
 crypto/zlib.c       |   24 +++++-----
 fs/squashfs/block.c |   33 ++++++---------
 3 files changed, 95 insertions(+), 79 deletions(-)

diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index b50c3c6..9cee018 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -914,24 +914,25 @@ static int test_pcomp(struct crypto_pcomp *tfm,
 	const char *algo = crypto_tfm_alg_driver_name(crypto_pcomp_tfm(tfm));
 	unsigned int i;
 	char result[COMP_BUF_SIZE];
-	int error;
+	int res;
 
 	for (i = 0; i < ctcount; i++) {
 		struct comp_request req;
+		unsigned int produced = 0;
 
-		error = crypto_compress_setup(tfm, ctemplate[i].params,
-					      ctemplate[i].paramsize);
-		if (error) {
+		res = crypto_compress_setup(tfm, ctemplate[i].params,
+					    ctemplate[i].paramsize);
+		if (res) {
 			pr_err("alg: pcomp: compression setup failed on test "
-			       "%d for %s: error=%d\n", i + 1, algo, error);
-			return error;
+			       "%d for %s: error=%d\n", i + 1, algo, res);
+			return res;
 		}
 
-		error = crypto_compress_init(tfm);
-		if (error) {
+		res = crypto_compress_init(tfm);
+		if (res) {
 			pr_err("alg: pcomp: compression init failed on test "
-			       "%d for %s: error=%d\n", i + 1, algo, error);
-			return error;
+			       "%d for %s: error=%d\n", i + 1, algo, res);
+			return res;
 		}
 
 		memset(result, 0, sizeof(result));
@@ -941,32 +942,37 @@ static int test_pcomp(struct crypto_pcomp *tfm,
 		req.next_out = result;
 		req.avail_out = ctemplate[i].outlen / 2;
 
-		error = crypto_compress_update(tfm, &req);
-		if (error && (error != -EAGAIN || req.avail_in)) {
+		res = crypto_compress_update(tfm, &req);
+		if (res < 0 && (res != -EAGAIN || req.avail_in)) {
 			pr_err("alg: pcomp: compression update failed on test "
-			       "%d for %s: error=%d\n", i + 1, algo, error);
-			return error;
+			       "%d for %s: error=%d\n", i + 1, algo, res);
+			return res;
 		}
+		if (res > 0)
+			produced += res;
 
 		/* Add remaining input data */
 		req.avail_in += (ctemplate[i].inlen + 1) / 2;
 
-		error = crypto_compress_update(tfm, &req);
-		if (error && (error != -EAGAIN || req.avail_in)) {
+		res = crypto_compress_update(tfm, &req);
+		if (res < 0 && (res != -EAGAIN || req.avail_in)) {
 			pr_err("alg: pcomp: compression update failed on test "
-			       "%d for %s: error=%d\n", i + 1, algo, error);
-			return error;
+			       "%d for %s: error=%d\n", i + 1, algo, res);
+			return res;
 		}
+		if (res > 0)
+			produced += res;
 
 		/* Provide remaining output space */
 		req.avail_out += COMP_BUF_SIZE - ctemplate[i].outlen / 2;
 
-		error = crypto_compress_final(tfm, &req);
-		if (error) {
+		res = crypto_compress_final(tfm, &req);
+		if (res < 0) {
 			pr_err("alg: pcomp: compression final failed on test "
-			       "%d for %s: error=%d\n", i + 1, algo, error);
-			return error;
+			       "%d for %s: error=%d\n", i + 1, algo, res);
+			return res;
 		}
+		produced += res;
 
 		if (COMP_BUF_SIZE - req.avail_out != ctemplate[i].outlen) {
 			pr_err("alg: comp: Compression test %d failed for %s: "
@@ -976,6 +982,13 @@ static int test_pcomp(struct crypto_pcomp *tfm,
 			return -EINVAL;
 		}
 
+		if (produced != ctemplate[i].outlen) {
+			pr_err("alg: comp: Compression test %d failed for %s: "
+			       "returned len = %u (expected %d)\n", i + 1,
+			       algo, produced, ctemplate[i].outlen);
+			return -EINVAL;
+		}
+
 		if (memcmp(result, ctemplate[i].output, ctemplate[i].outlen)) {
 			pr_err("alg: pcomp: Compression test %d failed for "
 			       "%s\n", i + 1, algo);
@@ -986,21 +999,21 @@ static int test_pcomp(struct crypto_pcomp *tfm,
 
 	for (i = 0; i < dtcount; i++) {
 		struct comp_request req;
+		unsigned int produced = 0;
 
-		error = crypto_decompress_setup(tfm, dtemplate[i].params,
-						dtemplate[i].paramsize);
-		if (error) {
+		res = crypto_decompress_setup(tfm, dtemplate[i].params,
+					      dtemplate[i].paramsize);
+		if (res) {
 			pr_err("alg: pcomp: decompression setup failed on "
-			       "test %d for %s: error=%d\n", i + 1, algo,
-			       error);
-			return error;
+			       "test %d for %s: error=%d\n", i + 1, algo, res);
+			return res;
 		}
 
-		error = crypto_decompress_init(tfm);
-		if (error) {
+		res = crypto_decompress_init(tfm);
+		if (res) {
 			pr_err("alg: pcomp: decompression init failed on test "
-			       "%d for %s: error=%d\n", i + 1, algo, error);
-			return error;
+			       "%d for %s: error=%d\n", i + 1, algo, res);
+			return res;
 		}
 
 		memset(result, 0, sizeof(result));
@@ -1010,35 +1023,38 @@ static int test_pcomp(struct crypto_pcomp *tfm,
 		req.next_out = result;
 		req.avail_out = dtemplate[i].outlen / 2;
 
-		error = crypto_decompress_update(tfm, &req);
-		if (error  && (error != -EAGAIN || req.avail_in)) {
+		res = crypto_decompress_update(tfm, &req);
+		if (res < 0 && (res != -EAGAIN || req.avail_in)) {
 			pr_err("alg: pcomp: decompression update failed on "
-			       "test %d for %s: error=%d\n", i + 1, algo,
-			       error);
-			return error;
+			       "test %d for %s: error=%d\n", i + 1, algo, res);
+			return res;
 		}
+		if (res > 0)
+			produced += res;
 
 		/* Add remaining input data */
 		req.avail_in += (dtemplate[i].inlen + 1) / 2;
 
-		error = crypto_decompress_update(tfm, &req);
-		if (error  && (error != -EAGAIN || req.avail_in)) {
+		res = crypto_decompress_update(tfm, &req);
+		if (res < 0 && (res != -EAGAIN || req.avail_in)) {
 			pr_err("alg: pcomp: decompression update failed on "
-			       "test %d for %s: error=%d\n", i + 1, algo,
-			       error);
-			return error;
+			       "test %d for %s: error=%d\n", i + 1, algo, res);
+			return res;
 		}
+		if (res > 0)
+			produced += res;
 
 		/* Provide remaining output space */
 		req.avail_out += COMP_BUF_SIZE - dtemplate[i].outlen / 2;
 
-		error = crypto_decompress_final(tfm, &req);
-		if (error  && (error != -EAGAIN || req.avail_in)) {
+		res = crypto_decompress_final(tfm, &req);
+		if (res < 0 && (res != -EAGAIN || req.avail_in)) {
 			pr_err("alg: pcomp: decompression final failed on "
-			       "test %d for %s: error=%d\n", i + 1, algo,
-			       error);
-			return error;
+			       "test %d for %s: error=%d\n", i + 1, algo, res);
+			return res;
 		}
+		if (res > 0)
+			produced += res;
 
 		if (COMP_BUF_SIZE - req.avail_out != dtemplate[i].outlen) {
 			pr_err("alg: comp: Decompression test %d failed for "
@@ -1048,6 +1064,13 @@ static int test_pcomp(struct crypto_pcomp *tfm,
 			return -EINVAL;
 		}
 
+		if (produced != dtemplate[i].outlen) {
+			pr_err("alg: comp: Decompression test %d failed for "
+			       "%s: returned len = %u (expected %d)\n", i + 1,
+			       algo, produced, dtemplate[i].outlen);
+			return -EINVAL;
+		}
+
 		if (memcmp(result, dtemplate[i].output, dtemplate[i].outlen)) {
 			pr_err("alg: pcomp: Decompression test %d failed for "
 			       "%s\n", i + 1, algo);
diff --git a/crypto/zlib.c b/crypto/zlib.c
index 33609ba..c301573 100644
--- a/crypto/zlib.c
+++ b/crypto/zlib.c
@@ -165,15 +165,15 @@ static int zlib_compress_update(struct crypto_pcomp *tfm,
 		return -EINVAL;
 	}
 
+	ret = req->avail_out - stream->avail_out;
 	pr_debug("avail_in %u, avail_out %u (consumed %u, produced %u)\n",
 		 stream->avail_in, stream->avail_out,
-		 req->avail_in - stream->avail_in,
-		 req->avail_out - stream->avail_out);
+		 req->avail_in - stream->avail_in, ret);
 	req->next_in = stream->next_in;
 	req->avail_in = stream->avail_in;
 	req->next_out = stream->next_out;
 	req->avail_out = stream->avail_out;
-	return 0;
+	return ret;
 }
 
 static int zlib_compress_final(struct crypto_pcomp *tfm,
@@ -195,15 +195,15 @@ static int zlib_compress_final(struct crypto_pcomp *tfm,
 		return -EINVAL;
 	}
 
+	ret = req->avail_out - stream->avail_out;
 	pr_debug("avail_in %u, avail_out %u (consumed %u, produced %u)\n",
 		 stream->avail_in, stream->avail_out,
-		 req->avail_in - stream->avail_in,
-		 req->avail_out - stream->avail_out);
+		 req->avail_in - stream->avail_in, ret);
 	req->next_in = stream->next_in;
 	req->avail_in = stream->avail_in;
 	req->next_out = stream->next_out;
 	req->avail_out = stream->avail_out;
-	return 0;
+	return ret;
 }
 
 
@@ -280,15 +280,15 @@ static int zlib_decompress_update(struct crypto_pcomp *tfm,
 		return -EINVAL;
 	}
 
+	ret = req->avail_out - stream->avail_out;
 	pr_debug("avail_in %u, avail_out %u (consumed %u, produced %u)\n",
 		 stream->avail_in, stream->avail_out,
-		 req->avail_in - stream->avail_in,
-		 req->avail_out - stream->avail_out);
+		 req->avail_in - stream->avail_in, ret);
 	req->next_in = stream->next_in;
 	req->avail_in = stream->avail_in;
 	req->next_out = stream->next_out;
 	req->avail_out = stream->avail_out;
-	return 0;
+	return ret;
 }
 
 static int zlib_decompress_final(struct crypto_pcomp *tfm,
@@ -328,15 +328,15 @@ static int zlib_decompress_final(struct crypto_pcomp *tfm,
 		return -EINVAL;
 	}
 
+	ret = req->avail_out - stream->avail_out;
 	pr_debug("avail_in %u, avail_out %u (consumed %u, produced %u)\n",
 		 stream->avail_in, stream->avail_out,
-		 req->avail_in - stream->avail_in,
-		 req->avail_out - stream->avail_out);
+		 req->avail_in - stream->avail_in, ret);
 	req->next_in = stream->next_in;
 	req->avail_in = stream->avail_in;
 	req->next_out = stream->next_out;
 	req->avail_out = stream->avail_out;
-	return 0;
+	return ret;
 }
 
 
diff --git a/fs/squashfs/block.c b/fs/squashfs/block.c
index 6196821..433f065 100644
--- a/fs/squashfs/block.c
+++ b/fs/squashfs/block.c
@@ -154,9 +154,8 @@ int squashfs_read_data(struct super_block *sb, void **buffer, u64 index,
 	}
 
 	if (compressed) {
-		int error = 0, decomp_init = 0;
+		int res = 0, decomp_init = 0;
 		struct comp_request req;
-		unsigned int produced = 0;
 
 		/*
 		 * Uncompress block.
@@ -194,41 +193,35 @@ int squashfs_read_data(struct super_block *sb, void **buffer, u64 index,
 			}
 
 			if (!decomp_init) {
-				error = crypto_decompress_init(msblk->tfm);
-				if (error) {
+				res = crypto_decompress_init(msblk->tfm);
+				if (res) {
 					ERROR("crypto_decompress_init "
 						"returned %d, srclength %d\n",
-						error, srclength);
+						res, srclength);
 					goto release_mutex;
 				}
 				decomp_init = 1;
 			}
 
-			produced = req.avail_out;
-			error = crypto_decompress_update(msblk->tfm, &req);
-			if (error) {
+			res = crypto_decompress_update(msblk->tfm, &req);
+			if (res < 0) {
 				ERROR("crypto_decompress_update returned %d, "
-					"data probably corrupt\n", error);
+					"data probably corrupt\n", res);
 				goto release_mutex;
 			}
-			produced -= req.avail_out;
-
-			length += produced;
+			length += res;
 
 			if (req.avail_in == 0 && k < b)
 				put_bh(bh[k++]);
-		} while (bytes || produced);
+		} while (bytes || res);
 
-		produced = req.avail_out;
-		error = crypto_decompress_final(msblk->tfm, &req);
-		if (error) {
+		res = crypto_decompress_final(msblk->tfm, &req);
+		if (res < 0) {
 			ERROR("crypto_decompress_final returned %d, data "
-				"probably corrupt\n", error);
+				"probably corrupt\n", res);
 			goto release_mutex;
 		}
-		produced -= req.avail_out;
-
-		length += produced;
+		length += res;
 
 		mutex_unlock(&msblk->read_data_mutex);
 	} else {
-- 
1.6.0.4


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@sonycom.com
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

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [PATCH/RFC] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}() (was: Re: [PATCH/RFC] crypto: compress - Add comp_request.total_out
  2009-03-24 16:33                     ` [PATCH/RFC] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}() (was: Re: [PATCH/RFC] crypto: compress - Add comp_request.total_out (was: Re: [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface)) Geert Uytterhoeven
@ 2009-03-25 10:12                       ` Phillip Lougher
  2009-04-20  6:03                       ` [PATCH/RFC] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}() (was: Re: [PATCH/RFC] crypto: compress - Add comp_request.total_out (was: Re: [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface)) Herbert Xu
  1 sibling, 0 replies; 25+ messages in thread
From: Phillip Lougher @ 2009-03-25 10:12 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: Herbert Xu, linux-crypto, linux-kernel

Geert Uytterhoeven wrote:
> On Tue, 17 Mar 2009, Geert Uytterhoeven wrote:
>> On Wed, 11 Mar 2009, Geert Uytterhoeven wrote:
>>> On Sun, 8 Mar 2009, Phillip Lougher wrote:
>>>> Two API issues of concern (one major, one minor).  Both of these relate to the
>>>> way Squashfs drives the decompression code, where it repeatedly calls it
>>>> supplying additional input/output buffers, rather than using a "single-shot"
>>>> approach where it calls the decompression code once supplying all the
>>>> necessary input and output buffer space.
>>>>
>>>> 1. Minor issue -the lack of a stream.total_out field.  The current
>>>> zlib_inflate code collects the total number of bytes decompressed over the
>>>> multiple calls into the stream.total_out field.
>>>>
>>>>    There is clearly no such field available in the cryto API, leading to the
>>>> somewhat clumsy need to track it, i.e. it leads to the following additional
>>>> code.
>>> If people feel the need for a total_out field, I can add it to struct
>>> comp_request.
>>>
>>> BTW, what about total_in, which is also provided by plain zlib's z_stream?
>>> Do people see a need for a similar field?
>> The patch below (on top of the updated one to convert SquashFS to pcomp) adds
>> comp_request.total_out, so you don't have to calculate and accumulate the
>> decompressed output sizes in SquashFS.
>>
>> Notes:
>>   - This required the addition of a `struct comp_request *' parameter to
>>     crypto_{,de}compress_init()
>>   - Still, there's one of the 
>>
>> 	produced = req.avail_out;
>> 	...
>> 	produced -= req.avail_out;
>>
>>     left, as this is part of the logic to discover the end of decompression
>>     (no bytes produced, no error returned).
>>
>> Perhaps it's better to instead make crypto_{,de}compress_{update,final}()
>> return the (positive) number of output bytes (of the current step)?
>>
>> Currently it returns zero (no error) or a negative error value.
>> That would allow to get rid of both `produced = ... / produced -= ...'
>> constructs, but the user would have to accumulate the total output size again
>> (which is not such a big deal, IMHO).
> 
> Here's an alternative patch, which does exactly that.
> Phillip, what do you think?
> 

 From a quick look, it looks OK :-)  I'm not ignoring this, but I'm trying to get a release of
the 4.0 tools finished ASAP (now 2.6.29 is out).

Phillip

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH/RFC] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}() (was: Re: [PATCH/RFC] crypto: compress - Add comp_request.total_out (was: Re: [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface))
  2009-03-24 16:33                     ` [PATCH/RFC] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}() (was: Re: [PATCH/RFC] crypto: compress - Add comp_request.total_out (was: Re: [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface)) Geert Uytterhoeven
  2009-03-25 10:12                       ` [PATCH/RFC] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}() (was: Re: [PATCH/RFC] crypto: compress - Add comp_request.total_out Phillip Lougher
@ 2009-04-20  6:03                       ` Herbert Xu
  2009-04-20  7:26                         ` Geert Uytterhoeven
  1 sibling, 1 reply; 25+ messages in thread
From: Herbert Xu @ 2009-04-20  6:03 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: Phillip Lougher, linux-crypto, linux-kernel

On Tue, Mar 24, 2009 at 05:33:01PM +0100, Geert Uytterhoeven wrote:
> 
> Here's an alternative patch, which does exactly that.
> Phillip, what do you think?
> 
> Thanks for your comments!
> 
> >From be7d630f96a85d3ce48716b8e328563ba217647b Mon Sep 17 00:00:00 2001
> From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
> Date: Tue, 24 Mar 2009 17:19:05 +0100
> Subject: [PATCH] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}()
> 
> If crypto_{,de}compress_{update,final}() succeed, return the actual number of
> bytes produced instead of zero, so their users don't have to calculate that
> theirselves.
> 
> Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>

I certainly prefer this version over the other one? Do you want to
submit crypto API portion of this?

Thanks,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH/RFC] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}() (was: Re: [PATCH/RFC] crypto: compress - Add comp_request.total_out (was: Re: [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface))
  2009-04-20  6:03                       ` [PATCH/RFC] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}() (was: Re: [PATCH/RFC] crypto: compress - Add comp_request.total_out (was: Re: [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface)) Herbert Xu
@ 2009-04-20  7:26                         ` Geert Uytterhoeven
  2009-04-20 23:45                           ` [PATCH/RFC] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}() (was: Re: [PATCH/RFC] crypto: compress - Add comp_request.total_out Phillip Lougher
  2009-05-05 14:14                           ` [PATCH/RFC] crypto: compress - Return produced bytes in crypto_{, de}compress_{update, final}() (was: Re: [PATCH/RFC] crypto: compress - Add comp_request.total_out (was: Re: [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface)) Geert Uytterhoeven
  0 siblings, 2 replies; 25+ messages in thread
From: Geert Uytterhoeven @ 2009-04-20  7:26 UTC (permalink / raw)
  To: Herbert Xu; +Cc: Phillip Lougher, linux-crypto, linux-kernel

On Mon, 20 Apr 2009, Herbert Xu wrote:
> On Tue, Mar 24, 2009 at 05:33:01PM +0100, Geert Uytterhoeven wrote:
> > Here's an alternative patch, which does exactly that.
> > Phillip, what do you think?
> > 
> > Thanks for your comments!
> > 
> > >From be7d630f96a85d3ce48716b8e328563ba217647b Mon Sep 17 00:00:00 2001
> > From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
> > Date: Tue, 24 Mar 2009 17:19:05 +0100
> > Subject: [PATCH] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}()
> > 
> > If crypto_{,de}compress_{update,final}() succeed, return the actual number of
> > bytes produced instead of zero, so their users don't have to calculate that
> > theirselves.
> > 
> > Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
> 
> I certainly prefer this version over the other one? Do you want to
> submit crypto API portion of this?

If you think I should submit it now, I can do it. But I'm still waiting for
Phillip's comments.

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@sonycom.com
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

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH/RFC] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}() (was: Re: [PATCH/RFC] crypto: compress - Add comp_request.total_out
  2009-04-20  7:26                         ` Geert Uytterhoeven
@ 2009-04-20 23:45                           ` Phillip Lougher
  2009-04-21  0:09                             ` Herbert Xu
  2009-07-28 14:45                             ` [PATCH/RFC] crypto: compress - Return produced bytes in crypto_{, de}compress_{update, final}() " Geert Uytterhoeven
  2009-05-05 14:14                           ` [PATCH/RFC] crypto: compress - Return produced bytes in crypto_{, de}compress_{update, final}() (was: Re: [PATCH/RFC] crypto: compress - Add comp_request.total_out (was: Re: [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface)) Geert Uytterhoeven
  1 sibling, 2 replies; 25+ messages in thread
From: Phillip Lougher @ 2009-04-20 23:45 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: Herbert Xu, linux-crypto, linux-kernel

Geert Uytterhoeven wrote:
> On Mon, 20 Apr 2009, Herbert Xu wrote:
>> On Tue, Mar 24, 2009 at 05:33:01PM +0100, Geert Uytterhoeven wrote:
>>> Here's an alternative patch, which does exactly that.
>>> Phillip, what do you think?
>>>
>>> Thanks for your comments!
>>>
>>> >From be7d630f96a85d3ce48716b8e328563ba217647b Mon Sep 17 00:00:00 2001
>>> From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
>>> Date: Tue, 24 Mar 2009 17:19:05 +0100
>>> Subject: [PATCH] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}()
>>>
>>> If crypto_{,de}compress_{update,final}() succeed, return the actual number of
>>> bytes produced instead of zero, so their users don't have to calculate that
>>> theirselves.
>>>
>>> Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
>> I certainly prefer this version over the other one? Do you want to
>> submit crypto API portion of this?
> 
> If you think I should submit it now, I can do it. But I'm still waiting for
> Phillip's comments.
> 

I think I said they looked OK to me.  But, I want to do performance tests
to see if there's any performance degradation over vanilla zlib, and see
if they cope gracefully with corrupted filesystems.

Herbert, are the other cryto API patches in linux-next (or any other
git repository)?

Thanks

Phillip


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH/RFC] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}() (was: Re: [PATCH/RFC] crypto: compress - Add comp_request.total_out
  2009-04-20 23:45                           ` [PATCH/RFC] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}() (was: Re: [PATCH/RFC] crypto: compress - Add comp_request.total_out Phillip Lougher
@ 2009-04-21  0:09                             ` Herbert Xu
  2009-07-28 14:45                             ` [PATCH/RFC] crypto: compress - Return produced bytes in crypto_{, de}compress_{update, final}() " Geert Uytterhoeven
  1 sibling, 0 replies; 25+ messages in thread
From: Herbert Xu @ 2009-04-21  0:09 UTC (permalink / raw)
  To: Phillip Lougher; +Cc: Geert Uytterhoeven, linux-crypto, linux-kernel

On Tue, Apr 21, 2009 at 12:45:19AM +0100, Phillip Lougher wrote:
>
> Herbert, are the other cryto API patches in linux-next (or any other
> git repository)?

They should be in Linus's tree.

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH/RFC] crypto: compress - Return produced bytes in crypto_{, de}compress_{update, final}() (was: Re: [PATCH/RFC] crypto: compress - Add comp_request.total_out (was: Re: [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface))
  2009-04-20  7:26                         ` Geert Uytterhoeven
  2009-04-20 23:45                           ` [PATCH/RFC] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}() (was: Re: [PATCH/RFC] crypto: compress - Add comp_request.total_out Phillip Lougher
@ 2009-05-05 14:14                           ` Geert Uytterhoeven
  2009-05-11 15:35                             ` [PATCH] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}() Geert Uytterhoeven
  1 sibling, 1 reply; 25+ messages in thread
From: Geert Uytterhoeven @ 2009-05-05 14:14 UTC (permalink / raw)
  To: Herbert Xu, Phillip Lougher; +Cc: linux-crypto, Linux Kernel Development

On Mon, 20 Apr 2009, Geert Uytterhoeven wrote:
> On Mon, 20 Apr 2009, Herbert Xu wrote:
> > On Tue, Mar 24, 2009 at 05:33:01PM +0100, Geert Uytterhoeven wrote:
> > > Here's an alternative patch, which does exactly that.
> > > Phillip, what do you think?
> > > 
> > > Thanks for your comments!
> > > 
> > > >From be7d630f96a85d3ce48716b8e328563ba217647b Mon Sep 17 00:00:00 2001
> > > From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
> > > Date: Tue, 24 Mar 2009 17:19:05 +0100
> > > Subject: [PATCH] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}()
> > > 
> > > If crypto_{,de}compress_{update,final}() succeed, return the actual number of
> > > bytes produced instead of zero, so their users don't have to calculate that
> > > theirselves.
> > > 
> > > Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
> > 
> > I certainly prefer this version over the other one? Do you want to
> > submit crypto API portion of this?
> 
> If you think I should submit it now, I can do it. But I'm still waiting for
> Phillip's comments.

Phillip, any progress?

If we want to change the API of crypto_{,de}compress_{update,final}(), we
should do it before the release of 2.6.30, and we're already at -rc4...

Thanks!

With kind regards,

Geert Uytterhoeven
Software Architect
Techsoft Centre

Technology and Software 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@sonycom.com
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

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}()
  2009-05-05 14:14                           ` [PATCH/RFC] crypto: compress - Return produced bytes in crypto_{, de}compress_{update, final}() (was: Re: [PATCH/RFC] crypto: compress - Add comp_request.total_out (was: Re: [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface)) Geert Uytterhoeven
@ 2009-05-11 15:35                             ` Geert Uytterhoeven
  2009-05-18  7:16                               ` Geert Uytterhoeven
  2009-05-27  5:05                               ` Herbert Xu
  0 siblings, 2 replies; 25+ messages in thread
From: Geert Uytterhoeven @ 2009-05-11 15:35 UTC (permalink / raw)
  To: Herbert Xu; +Cc: Phillip Lougher, linux-crypto, Linux Kernel Development

If crypto_{,de}compress_{update,final}() succeed, return the actual number of
bytes produced instead of zero, so their users don't have to calculate that
theirselves.

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
---
As we're already at 2.6.30-rc5, I do not want to delay any longer this API
change for a new module introduced for 2.6.30.

Herbert, please apply for 2.6.30.
Thanks!

 crypto/testmgr.c |  117 ++++++++++++++++++++++++++++++++----------------------
 crypto/zlib.c    |   24 ++++++------
 2 files changed, 82 insertions(+), 59 deletions(-)

diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index bfee6e9..b55bccc 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -916,24 +916,25 @@ static int test_pcomp(struct crypto_pcomp *tfm,
 	const char *algo = crypto_tfm_alg_driver_name(crypto_pcomp_tfm(tfm));
 	unsigned int i;
 	char result[COMP_BUF_SIZE];
-	int error;
+	int res;
 
 	for (i = 0; i < ctcount; i++) {
 		struct comp_request req;
+		unsigned int produced = 0;
 
-		error = crypto_compress_setup(tfm, ctemplate[i].params,
-					      ctemplate[i].paramsize);
-		if (error) {
+		res = crypto_compress_setup(tfm, ctemplate[i].params,
+					    ctemplate[i].paramsize);
+		if (res) {
 			pr_err("alg: pcomp: compression setup failed on test "
-			       "%d for %s: error=%d\n", i + 1, algo, error);
-			return error;
+			       "%d for %s: error=%d\n", i + 1, algo, res);
+			return res;
 		}
 
-		error = crypto_compress_init(tfm);
-		if (error) {
+		res = crypto_compress_init(tfm);
+		if (res) {
 			pr_err("alg: pcomp: compression init failed on test "
-			       "%d for %s: error=%d\n", i + 1, algo, error);
-			return error;
+			       "%d for %s: error=%d\n", i + 1, algo, res);
+			return res;
 		}
 
 		memset(result, 0, sizeof(result));
@@ -943,32 +944,37 @@ static int test_pcomp(struct crypto_pcomp *tfm,
 		req.next_out = result;
 		req.avail_out = ctemplate[i].outlen / 2;
 
-		error = crypto_compress_update(tfm, &req);
-		if (error && (error != -EAGAIN || req.avail_in)) {
+		res = crypto_compress_update(tfm, &req);
+		if (res < 0 && (res != -EAGAIN || req.avail_in)) {
 			pr_err("alg: pcomp: compression update failed on test "
-			       "%d for %s: error=%d\n", i + 1, algo, error);
-			return error;
+			       "%d for %s: error=%d\n", i + 1, algo, res);
+			return res;
 		}
+		if (res > 0)
+			produced += res;
 
 		/* Add remaining input data */
 		req.avail_in += (ctemplate[i].inlen + 1) / 2;
 
-		error = crypto_compress_update(tfm, &req);
-		if (error && (error != -EAGAIN || req.avail_in)) {
+		res = crypto_compress_update(tfm, &req);
+		if (res < 0 && (res != -EAGAIN || req.avail_in)) {
 			pr_err("alg: pcomp: compression update failed on test "
-			       "%d for %s: error=%d\n", i + 1, algo, error);
-			return error;
+			       "%d for %s: error=%d\n", i + 1, algo, res);
+			return res;
 		}
+		if (res > 0)
+			produced += res;
 
 		/* Provide remaining output space */
 		req.avail_out += COMP_BUF_SIZE - ctemplate[i].outlen / 2;
 
-		error = crypto_compress_final(tfm, &req);
-		if (error) {
+		res = crypto_compress_final(tfm, &req);
+		if (res < 0) {
 			pr_err("alg: pcomp: compression final failed on test "
-			       "%d for %s: error=%d\n", i + 1, algo, error);
-			return error;
+			       "%d for %s: error=%d\n", i + 1, algo, res);
+			return res;
 		}
+		produced += res;
 
 		if (COMP_BUF_SIZE - req.avail_out != ctemplate[i].outlen) {
 			pr_err("alg: comp: Compression test %d failed for %s: "
@@ -978,6 +984,13 @@ static int test_pcomp(struct crypto_pcomp *tfm,
 			return -EINVAL;
 		}
 
+		if (produced != ctemplate[i].outlen) {
+			pr_err("alg: comp: Compression test %d failed for %s: "
+			       "returned len = %u (expected %d)\n", i + 1,
+			       algo, produced, ctemplate[i].outlen);
+			return -EINVAL;
+		}
+
 		if (memcmp(result, ctemplate[i].output, ctemplate[i].outlen)) {
 			pr_err("alg: pcomp: Compression test %d failed for "
 			       "%s\n", i + 1, algo);
@@ -988,21 +1001,21 @@ static int test_pcomp(struct crypto_pcomp *tfm,
 
 	for (i = 0; i < dtcount; i++) {
 		struct comp_request req;
+		unsigned int produced = 0;
 
-		error = crypto_decompress_setup(tfm, dtemplate[i].params,
-						dtemplate[i].paramsize);
-		if (error) {
+		res = crypto_decompress_setup(tfm, dtemplate[i].params,
+					      dtemplate[i].paramsize);
+		if (res) {
 			pr_err("alg: pcomp: decompression setup failed on "
-			       "test %d for %s: error=%d\n", i + 1, algo,
-			       error);
-			return error;
+			       "test %d for %s: error=%d\n", i + 1, algo, res);
+			return res;
 		}
 
-		error = crypto_decompress_init(tfm);
-		if (error) {
+		res = crypto_decompress_init(tfm);
+		if (res) {
 			pr_err("alg: pcomp: decompression init failed on test "
-			       "%d for %s: error=%d\n", i + 1, algo, error);
-			return error;
+			       "%d for %s: error=%d\n", i + 1, algo, res);
+			return res;
 		}
 
 		memset(result, 0, sizeof(result));
@@ -1012,35 +1025,38 @@ static int test_pcomp(struct crypto_pcomp *tfm,
 		req.next_out = result;
 		req.avail_out = dtemplate[i].outlen / 2;
 
-		error = crypto_decompress_update(tfm, &req);
-		if (error  && (error != -EAGAIN || req.avail_in)) {
+		res = crypto_decompress_update(tfm, &req);
+		if (res < 0 && (res != -EAGAIN || req.avail_in)) {
 			pr_err("alg: pcomp: decompression update failed on "
-			       "test %d for %s: error=%d\n", i + 1, algo,
-			       error);
-			return error;
+			       "test %d for %s: error=%d\n", i + 1, algo, res);
+			return res;
 		}
+		if (res > 0)
+			produced += res;
 
 		/* Add remaining input data */
 		req.avail_in += (dtemplate[i].inlen + 1) / 2;
 
-		error = crypto_decompress_update(tfm, &req);
-		if (error  && (error != -EAGAIN || req.avail_in)) {
+		res = crypto_decompress_update(tfm, &req);
+		if (res < 0 && (res != -EAGAIN || req.avail_in)) {
 			pr_err("alg: pcomp: decompression update failed on "
-			       "test %d for %s: error=%d\n", i + 1, algo,
-			       error);
-			return error;
+			       "test %d for %s: error=%d\n", i + 1, algo, res);
+			return res;
 		}
+		if (res > 0)
+			produced += res;
 
 		/* Provide remaining output space */
 		req.avail_out += COMP_BUF_SIZE - dtemplate[i].outlen / 2;
 
-		error = crypto_decompress_final(tfm, &req);
-		if (error  && (error != -EAGAIN || req.avail_in)) {
+		res = crypto_decompress_final(tfm, &req);
+		if (res < 0 && (res != -EAGAIN || req.avail_in)) {
 			pr_err("alg: pcomp: decompression final failed on "
-			       "test %d for %s: error=%d\n", i + 1, algo,
-			       error);
-			return error;
+			       "test %d for %s: error=%d\n", i + 1, algo, res);
+			return res;
 		}
+		if (res > 0)
+			produced += res;
 
 		if (COMP_BUF_SIZE - req.avail_out != dtemplate[i].outlen) {
 			pr_err("alg: comp: Decompression test %d failed for "
@@ -1050,6 +1066,13 @@ static int test_pcomp(struct crypto_pcomp *tfm,
 			return -EINVAL;
 		}
 
+		if (produced != dtemplate[i].outlen) {
+			pr_err("alg: comp: Decompression test %d failed for "
+			       "%s: returned len = %u (expected %d)\n", i + 1,
+			       algo, produced, dtemplate[i].outlen);
+			return -EINVAL;
+		}
+
 		if (memcmp(result, dtemplate[i].output, dtemplate[i].outlen)) {
 			pr_err("alg: pcomp: Decompression test %d failed for "
 			       "%s\n", i + 1, algo);
diff --git a/crypto/zlib.c b/crypto/zlib.c
index 33609ba..c301573 100644
--- a/crypto/zlib.c
+++ b/crypto/zlib.c
@@ -165,15 +165,15 @@ static int zlib_compress_update(struct crypto_pcomp *tfm,
 		return -EINVAL;
 	}
 
+	ret = req->avail_out - stream->avail_out;
 	pr_debug("avail_in %u, avail_out %u (consumed %u, produced %u)\n",
 		 stream->avail_in, stream->avail_out,
-		 req->avail_in - stream->avail_in,
-		 req->avail_out - stream->avail_out);
+		 req->avail_in - stream->avail_in, ret);
 	req->next_in = stream->next_in;
 	req->avail_in = stream->avail_in;
 	req->next_out = stream->next_out;
 	req->avail_out = stream->avail_out;
-	return 0;
+	return ret;
 }
 
 static int zlib_compress_final(struct crypto_pcomp *tfm,
@@ -195,15 +195,15 @@ static int zlib_compress_final(struct crypto_pcomp *tfm,
 		return -EINVAL;
 	}
 
+	ret = req->avail_out - stream->avail_out;
 	pr_debug("avail_in %u, avail_out %u (consumed %u, produced %u)\n",
 		 stream->avail_in, stream->avail_out,
-		 req->avail_in - stream->avail_in,
-		 req->avail_out - stream->avail_out);
+		 req->avail_in - stream->avail_in, ret);
 	req->next_in = stream->next_in;
 	req->avail_in = stream->avail_in;
 	req->next_out = stream->next_out;
 	req->avail_out = stream->avail_out;
-	return 0;
+	return ret;
 }
 
 
@@ -280,15 +280,15 @@ static int zlib_decompress_update(struct crypto_pcomp *tfm,
 		return -EINVAL;
 	}
 
+	ret = req->avail_out - stream->avail_out;
 	pr_debug("avail_in %u, avail_out %u (consumed %u, produced %u)\n",
 		 stream->avail_in, stream->avail_out,
-		 req->avail_in - stream->avail_in,
-		 req->avail_out - stream->avail_out);
+		 req->avail_in - stream->avail_in, ret);
 	req->next_in = stream->next_in;
 	req->avail_in = stream->avail_in;
 	req->next_out = stream->next_out;
 	req->avail_out = stream->avail_out;
-	return 0;
+	return ret;
 }
 
 static int zlib_decompress_final(struct crypto_pcomp *tfm,
@@ -328,15 +328,15 @@ static int zlib_decompress_final(struct crypto_pcomp *tfm,
 		return -EINVAL;
 	}
 
+	ret = req->avail_out - stream->avail_out;
 	pr_debug("avail_in %u, avail_out %u (consumed %u, produced %u)\n",
 		 stream->avail_in, stream->avail_out,
-		 req->avail_in - stream->avail_in,
-		 req->avail_out - stream->avail_out);
+		 req->avail_in - stream->avail_in, ret);
 	req->next_in = stream->next_in;
 	req->avail_in = stream->avail_in;
 	req->next_out = stream->next_out;
 	req->avail_out = stream->avail_out;
-	return 0;
+	return ret;
 }
 
 
-- 
1.6.2.4


With kind regards,

Geert Uytterhoeven
Software Architect
Techsoft Centre

Technology and Software 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@sonycom.com
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

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [PATCH] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}()
  2009-05-11 15:35                             ` [PATCH] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}() Geert Uytterhoeven
@ 2009-05-18  7:16                               ` Geert Uytterhoeven
  2009-05-18  7:22                                 ` Herbert Xu
  2009-05-27  5:05                               ` Herbert Xu
  1 sibling, 1 reply; 25+ messages in thread
From: Geert Uytterhoeven @ 2009-05-18  7:16 UTC (permalink / raw)
  To: Herbert Xu; +Cc: Phillip Lougher, linux-crypto, Linux Kernel Development

	Hi Herbert,

On Mon, 11 May 2009, Geert Uytterhoeven wrote:
> If crypto_{,de}compress_{update,final}() succeed, return the actual number of
> bytes produced instead of zero, so their users don't have to calculate that
> theirselves.
> 
> Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
> ---
> As we're already at 2.6.30-rc5, I do not want to delay any longer this API
> change for a new module introduced for 2.6.30.
> 
> Herbert, please apply for 2.6.30.
> Thanks!

As I just saw your pull request for Linus, which didn't include this change,
I'm wondering if you plan to apply it for 2.6.30?

Thanks again!

With kind regards,

Geert Uytterhoeven
Software Architect
Techsoft Centre

Technology and Software 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@sonycom.com
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

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}()
  2009-05-18  7:16                               ` Geert Uytterhoeven
@ 2009-05-18  7:22                                 ` Herbert Xu
  0 siblings, 0 replies; 25+ messages in thread
From: Herbert Xu @ 2009-05-18  7:22 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Phillip Lougher, linux-crypto, Linux Kernel Development

On Mon, May 18, 2009 at 09:16:49AM +0200, Geert Uytterhoeven wrote:
>
> As I just saw your pull request for Linus, which didn't include this change,
> I'm wondering if you plan to apply it for 2.6.30?

Sorry, this is too late for 2.6.30.
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}()
  2009-05-11 15:35                             ` [PATCH] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}() Geert Uytterhoeven
  2009-05-18  7:16                               ` Geert Uytterhoeven
@ 2009-05-27  5:05                               ` Herbert Xu
  1 sibling, 0 replies; 25+ messages in thread
From: Herbert Xu @ 2009-05-27  5:05 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Phillip Lougher, linux-crypto, Linux Kernel Development

On Mon, May 11, 2009 at 05:35:08PM +0200, Geert Uytterhoeven wrote:
> If crypto_{,de}compress_{update,final}() succeed, return the actual number of
> bytes produced instead of zero, so their users don't have to calculate that
> theirselves.
> 
> Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>

Applied to cryptodev, thanks a lot!
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH/RFC] crypto: compress - Return produced bytes in crypto_{, de}compress_{update, final}() (was: Re: [PATCH/RFC] crypto: compress - Add comp_request.total_out
  2009-04-20 23:45                           ` [PATCH/RFC] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}() (was: Re: [PATCH/RFC] crypto: compress - Add comp_request.total_out Phillip Lougher
  2009-04-21  0:09                             ` Herbert Xu
@ 2009-07-28 14:45                             ` Geert Uytterhoeven
  1 sibling, 0 replies; 25+ messages in thread
From: Geert Uytterhoeven @ 2009-07-28 14:45 UTC (permalink / raw)
  To: Phillip Lougher
  Cc: Herbert Xu, linux-crypto, Linux Kernel Development, squashfs-devel

On Tue, 21 Apr 2009, Phillip Lougher wrote:
> Geert Uytterhoeven wrote:
> > On Mon, 20 Apr 2009, Herbert Xu wrote:
> > > On Tue, Mar 24, 2009 at 05:33:01PM +0100, Geert Uytterhoeven wrote:
> > > > Here's an alternative patch, which does exactly that.
> > > > Phillip, what do you think?
> > > >
> > > > Thanks for your comments!
> > > >
> > > > >From be7d630f96a85d3ce48716b8e328563ba217647b Mon Sep 17 00:00:00 2001
> > > > From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
> > > > Date: Tue, 24 Mar 2009 17:19:05 +0100
> > > > Subject: [PATCH] crypto: compress - Return produced bytes in
> > > > crypto_{,de}compress_{update,final}()
> > > >
> > > > If crypto_{,de}compress_{update,final}() succeed, return the actual
> > > > number of
> > > > bytes produced instead of zero, so their users don't have to calculate
> > > > that
> > > > theirselves.
> > > >
> > > > Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
> > > I certainly prefer this version over the other one? Do you want to
> > > submit crypto API portion of this?
> > 
> > If you think I should submit it now, I can do it. But I'm still waiting for
> > Phillip's comments.
> 
> I think I said they looked OK to me.  But, I want to do performance tests
> to see if there's any performance degradation over vanilla zlib, and see
> if they cope gracefully with corrupted filesystems.
> 
> Herbert, are the other cryto API patches in linux-next (or any other
> git repository)?

(in the mean time, all of this has been in mainline since a while)

Phillip, any news from you?

Thanks!

With kind regards,

Geert Uytterhoeven
Software Architect
Techsoft Centre

Technology and Software 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@sonycom.com
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

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2009-07-28 14:45 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-02-25 13:43 [PATCH 0/6] Partial (de)compression Crypto API Geert Uytterhoeven
2009-02-25 13:43 ` [PATCH 1/6] netlink: Move netlink attribute parsing support to lib/ Geert Uytterhoeven
2009-02-25 13:43   ` [PATCH 2/6] crypto: compress - Add pcomp interface Geert Uytterhoeven
2009-02-25 13:43     ` [PATCH 3/6] crypto: testmgr - Add support for the " Geert Uytterhoeven
2009-02-25 13:43       ` [PATCH 4/6] crypto: new zlib crypto module, using pcomp Geert Uytterhoeven
2009-02-25 13:43         ` [PATCH 5/6] crypto: testmgr - add zlib test Geert Uytterhoeven
2009-02-25 13:43           ` [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface Geert Uytterhoeven
2009-03-07 10:46             ` Herbert Xu
2009-03-08  6:47               ` Phillip Lougher
2009-03-11 17:59                 ` Geert Uytterhoeven
2009-03-17 12:54                   ` [PATCH/RFC] crypto: compress - Add comp_request.total_out (was: Re: [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface) Geert Uytterhoeven
2009-03-24 16:33                     ` [PATCH/RFC] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}() (was: Re: [PATCH/RFC] crypto: compress - Add comp_request.total_out (was: Re: [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface)) Geert Uytterhoeven
2009-03-25 10:12                       ` [PATCH/RFC] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}() (was: Re: [PATCH/RFC] crypto: compress - Add comp_request.total_out Phillip Lougher
2009-04-20  6:03                       ` [PATCH/RFC] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}() (was: Re: [PATCH/RFC] crypto: compress - Add comp_request.total_out (was: Re: [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface)) Herbert Xu
2009-04-20  7:26                         ` Geert Uytterhoeven
2009-04-20 23:45                           ` [PATCH/RFC] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}() (was: Re: [PATCH/RFC] crypto: compress - Add comp_request.total_out Phillip Lougher
2009-04-21  0:09                             ` Herbert Xu
2009-07-28 14:45                             ` [PATCH/RFC] crypto: compress - Return produced bytes in crypto_{, de}compress_{update, final}() " Geert Uytterhoeven
2009-05-05 14:14                           ` [PATCH/RFC] crypto: compress - Return produced bytes in crypto_{, de}compress_{update, final}() (was: Re: [PATCH/RFC] crypto: compress - Add comp_request.total_out (was: Re: [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface)) Geert Uytterhoeven
2009-05-11 15:35                             ` [PATCH] crypto: compress - Return produced bytes in crypto_{,de}compress_{update,final}() Geert Uytterhoeven
2009-05-18  7:16                               ` Geert Uytterhoeven
2009-05-18  7:22                                 ` Herbert Xu
2009-05-27  5:05                               ` Herbert Xu
2009-03-17 12:44             ` [PATCH 6/6] squashfs: Make SquashFS 4 use the new pcomp crypto interface Geert Uytterhoeven
2009-02-25 21:59   ` [PATCH 1/6] netlink: Move netlink attribute parsing support to lib/ David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).