Re: [PATCH] crypto: compress - Add pcomp interface
From: Geert Uytterhoeven
Date: Mon Feb 23 2009 - 12:32:37 EST
Hi Herbert,
On Thu, 19 Feb 2009, Herbert Xu wrote:
> On Thu, Feb 19, 2009 at 10:12:18AM +0100, Geert Uytterhoeven wrote:
> > IIUC, my setup() routines should decode the parameters using nla_parse()?
>
> Right.
>
> > And the caller of a setup() routine should encode the data. But how? All the
> > nla_put*() routines seem to be targeted at skb's.
>
> The callers in the kernel should just lay it out on the stack, e.g.,
>
> struct {
> struct nlattr foo;
> u32 foo_val;
> struct nlattr bar;
> u32 bar_val;
> ...
> };
>
> Note that the netlink alignment is 4 so u32 doesn't need any padding
> though u8/u16 would need padding before the next nlattr. Although
> for our purposes u32 should be sufficient.
>
> > The only place where nla_parse() is called with a void */length pair is
> > net/sched/em_meta.c:em_meta_change(). But I can find no place where the actual
> > TCA_EM_META_* fields are encoded.
>
> For simple things like u32 the format is just header followed by
> the u32. See nla_get_u32 for details.
Is the below (on top of my last patch series) what you have in mind?
Notes:
- I had to drop the `const' from the `params' pointers of
pcomp_alg.{,de}compress_setup().
Trying to make nla_parse() take const nlattr structures instead seems to
open a big can of worms...
- I should add a dependency of CONFIG_CRYPTO_ZLIB on CONFIG_NET (due to the
need for nla_parse()). However, I don't like that.
Thanks for your comments!
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 4703137..b50c3c6 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -919,7 +919,8 @@ static int test_pcomp(struct crypto_pcomp *tfm,
for (i = 0; i < ctcount; i++) {
struct comp_request req;
- error = crypto_compress_setup(tfm, ctemplate[i].params);
+ 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);
@@ -986,7 +987,8 @@ static int test_pcomp(struct crypto_pcomp *tfm,
for (i = 0; i < dtcount; i++) {
struct comp_request req;
- error = crypto_decompress_setup(tfm, dtemplate[i].params);
+ 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,
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index 098c033..526f00a 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -15,7 +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
@@ -8351,7 +8353,8 @@ struct comp_testvec {
};
struct pcomp_testvec {
- const void *params;
+ void *params;
+ unsigned int paramsize;
int inlen, outlen;
char input[COMP_BUF_SIZE];
char output[COMP_BUF_SIZE];
@@ -8440,21 +8443,60 @@ static struct comp_testvec deflate_decomp_tv_template[] = {
#define ZLIB_COMP_TEST_VECTORS 2
#define ZLIB_DECOMP_TEST_VECTORS 2
-static const struct zlib_comp_params deflate_comp_params = {
- .level = Z_DEFAULT_COMPRESSION,
- .method = Z_DEFLATED,
- .windowBits = -11,
- .memLevel = MAX_MEM_LEVEL,
- .strategy = Z_DEFAULT_STRATEGY
+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 zlib_decomp_params deflate_decomp_params = {
- .windowBits = -11,
+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 "
@@ -8466,6 +8508,7 @@ static struct pcomp_testvec zlib_comp_tv_template[] = {
"\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"
@@ -8493,6 +8536,7 @@ static struct pcomp_testvec zlib_comp_tv_template[] = {
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"
@@ -8516,6 +8560,7 @@ static struct pcomp_testvec zlib_decomp_tv_template[] = {
"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"
diff --git a/crypto/zlib.c b/crypto/zlib.c
index 77b865d..33609ba 100644
--- a/crypto/zlib.c
+++ b/crypto/zlib.c
@@ -33,11 +33,13 @@
#include <crypto/internal/compress.h>
+#include <net/netlink.h>
+
struct zlib_ctx {
- struct zlib_decomp_params decomp_params;
struct z_stream_s comp_stream;
struct z_stream_s decomp_stream;
+ int decomp_windowBits;
};
@@ -77,13 +79,18 @@ static void zlib_exit(struct crypto_tfm *tfm)
}
-static int zlib_compress_setup(struct crypto_pcomp *tfm, const void *params)
+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));
- const struct zlib_comp_params *zparams = params;
struct z_stream_s *stream = &ctx->comp_stream;
+ struct nlattr *tb[ZLIB_COMP_MAX + 1];
size_t workspacesize;
- int ret = 0;
+ int ret;
+
+ ret = nla_parse(tb, ZLIB_COMP_MAX, params, len, NULL);
+ if (ret)
+ return ret;
zlib_comp_exit(ctx);
@@ -93,9 +100,22 @@ static int zlib_compress_setup(struct crypto_pcomp *tfm, const void *params)
return -ENOMEM;
memset(stream->workspace, 0, workspacesize);
- ret = zlib_deflateInit2(stream, zparams->level, zparams->method,
- zparams->windowBits, zparams->memLevel,
- zparams->strategy);
+ 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;
@@ -187,22 +207,29 @@ static int zlib_compress_final(struct crypto_pcomp *tfm,
}
-static int zlib_decompress_setup(struct crypto_pcomp *tfm, const void *params)
+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));
- const struct zlib_decomp_params *zparams = params;
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_params = *zparams;
+ 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, zparams->windowBits);
+ ret = zlib_inflateInit2(stream, ctx->decomp_windowBits);
if (ret != Z_OK) {
kfree(stream->workspace);
stream->workspace = NULL;
@@ -277,7 +304,7 @@ static int zlib_decompress_final(struct crypto_pcomp *tfm,
stream->next_out = req->next_out;
stream->avail_out = req->avail_out;
- if (dctx->decomp_params.windowBits < 0) {
+ if (dctx->decomp_windowBits < 0) {
ret = zlib_inflate(stream, Z_SYNC_FLUSH);
/*
* Work around a bug in zlib, which sometimes wants to taste an
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c
index 12ed86d..62be5ae 100644
--- a/fs/squashfs/super.c
+++ b/fs/squashfs/super.c
@@ -39,6 +39,8 @@
#include <crypto/compress.h>
+#include <net/netlink.h>
+
#include "squashfs_fs.h"
#include "squashfs_fs_sb.h"
#include "squashfs_fs_i.h"
@@ -81,7 +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 zlib_decomp_params params = { .windowBits = DEF_WBITS };
+ 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");
@@ -102,7 +113,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
goto failed_pcomp;
}
- err = crypto_decompress_setup(msblk->tfm, ¶ms);
+ err = crypto_decompress_setup(msblk->tfm, ¶ms, sizeof(params));
if (err) {
ERROR("Failed to set up decompression parameters\n");
goto failure;
diff --git a/include/crypto/compress.h b/include/crypto/compress.h
index 67ba57d..86163ef 100644
--- a/include/crypto/compress.h
+++ b/include/crypto/compress.h
@@ -30,30 +30,40 @@ struct comp_request {
unsigned int avail_out; /* bytes available at next_out */
};
-struct zlib_comp_params {
- int level; /* e.g. Z_DEFAULT_COMPRESSION */
- int method; /* e.g. Z_DEFLATED */
- int windowBits; /* e.g. MAX_WBITS */
- int memLevel; /* e.g. DEF_MEM_LEVEL */
- int strategy; /* e.g. Z_DEFAULT_STRATEGY */
+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,
};
-struct zlib_decomp_params {
- int windowBits; /* e.g. DEF_WBITS */
+#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;
};
struct pcomp_alg {
- int (*compress_setup)(struct crypto_pcomp *tfm, const void *params);
+ 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, const void *params);
+ 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);
@@ -87,9 +97,9 @@ static inline struct pcomp_alg *crypto_pcomp_alg(struct crypto_pcomp *tfm)
}
static inline int crypto_compress_setup(struct crypto_pcomp *tfm,
- const void *params)
+ void *params, unsigned int len)
{
- return crypto_pcomp_alg(tfm)->compress_setup(tfm, params);
+ return crypto_pcomp_alg(tfm)->compress_setup(tfm, params, len);
}
static inline int crypto_compress_init(struct crypto_pcomp *tfm)
@@ -110,9 +120,9 @@ static inline int crypto_compress_final(struct crypto_pcomp *tfm,
}
static inline int crypto_decompress_setup(struct crypto_pcomp *tfm,
- const void *params)
+ void *params, unsigned int len)
{
- return crypto_pcomp_alg(tfm)->decompress_setup(tfm, params);
+ return crypto_pcomp_alg(tfm)->decompress_setup(tfm, params, len);
}
static inline int crypto_decompress_init(struct crypto_pcomp *tfm)
With kind regards,
Geert Uytterhoeven
Software Architect
Sony Techsoft Centre Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
Phone: +32 (0)2 700 8453
Fax: +32 (0)2 700 8622
E-mail: Geert.Uytterhoeven@xxxxxxxxxxx
Internet: http://www.sony-europe.com/
A division of Sony Europe (Belgium) N.V.
VAT BE 0413.825.160 · RPR Brussels
Fortis · BIC GEBABEBB · IBAN BE41293037680010
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/