2008-08-21 05:48:44

by Jared Hulbert

[permalink] [raw]
Subject: [PATCH 10/10] AXFS: axfs_uncompress.c

Handles the decompression for axfs, modeled after fs/cramfs/uncompress.c.

Signed-off-by: Jared Hulbert <[email protected]>
---
diff --git a/fs/axfs/axfs_uncompress.c b/fs/axfs/axfs_uncompress.c
new file mode 100644
index 0000000..b7a2060
--- /dev/null
+++ b/fs/axfs/axfs_uncompress.c
@@ -0,0 +1,97 @@
+/*
+ * Advanced XIP File System for Linux - AXFS
+ * Readonly, compressed, and XIP filesystem for Linux systems big and small
+ *
+ * Modified in 2006 by Eric Anderson
+ * from the cramfs sources fs/cramfs/uncompress.c
+ *
+ * (C) Copyright 1999 Linus Torvalds
+ *
+ * axfs_uncompress.c -
+ * axfs interfaces to the uncompression library. There's really just
+ * three entrypoints:
+ *
+ * - axfs_uncompress_init() - called to initialize the thing.
+ * - axfs_uncompress_exit() - tell me when you're done
+ * - axfs_uncompress_block() - uncompress a block.
+ *
+ * NOTE NOTE NOTE! The uncompression is entirely single-threaded. We
+ * only have one stream, and we'll initialize it only once even if it
+ * then is used by multiple filesystems.
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/vmalloc.h>
+#include <linux/zlib.h>
+#include <linux/mutex.h>
+
+static z_stream stream;
+static int initialized;
+static struct mutex axfs_uncmp_mutex;
+
+int axfs_uncompress_block(void *dst, int dstlen, void *src, int srclen)
+{
+ int err;
+ int out;
+
+ mutex_lock(&axfs_uncmp_mutex);
+
+ stream.next_in = src;
+ stream.avail_in = srclen;
+
+ stream.next_out = dst;
+ stream.avail_out = dstlen;
+
+ err = zlib_inflateReset(&stream);
+ if (err != Z_OK) {
+ printk(KERN_ERR "zlib_inflateReset error %d\n", err);
+ zlib_inflateEnd(&stream);
+ zlib_inflateInit(&stream);
+ }
+
+ err = zlib_inflate(&stream, Z_FINISH);
+ if (err != Z_STREAM_END)
+ goto err;
+
+ out = stream.total_out;
+
+ mutex_unlock(&axfs_uncmp_mutex);
+
+ return out;
+
+err:
+
+ mutex_unlock(&axfs_uncmp_mutex);
+
+ printk(KERN_ERR "Error %d while decompressing!\n", err);
+ printk(KERN_ERR "%p(%d)->%p(%d)\n", src, srclen, dst, dstlen);
+ return 0;
+}
+
+int axfs_uncompress_init(void)
+{
+ if (!initialized++) {
+
+ mutex_init(&axfs_uncmp_mutex);
+
+ stream.workspace = vmalloc(zlib_inflate_workspacesize());
+ if (!stream.workspace) {
+ initialized = 0;
+ return -ENOMEM;
+ }
+ stream.next_in = NULL;
+ stream.avail_in = 0;
+ zlib_inflateInit(&stream);
+ }
+ return 0;
+}
+
+int axfs_uncompress_exit(void)
+{
+ if (!--initialized) {
+ zlib_inflateEnd(&stream);
+ vfree(stream.workspace);
+ }
+ return 0;
+}


2008-08-21 09:03:20

by Sven Wegener

[permalink] [raw]
Subject: Re: [PATCH 10/10] AXFS: axfs_uncompress.c

On Wed, 20 Aug 2008, Jared Hulbert wrote:

> Handles the decompression for axfs, modeled after fs/cramfs/uncompress.c.
>
> Signed-off-by: Jared Hulbert <[email protected]>
> ---
> diff --git a/fs/axfs/axfs_uncompress.c b/fs/axfs/axfs_uncompress.c
> new file mode 100644
> index 0000000..b7a2060
> --- /dev/null
> +++ b/fs/axfs/axfs_uncompress.c
> @@ -0,0 +1,97 @@
> +/*
> + * Advanced XIP File System for Linux - AXFS
> + * Readonly, compressed, and XIP filesystem for Linux systems big and small
> + *
> + * Modified in 2006 by Eric Anderson
> + * from the cramfs sources fs/cramfs/uncompress.c
> + *
> + * (C) Copyright 1999 Linus Torvalds
> + *
> + * axfs_uncompress.c -
> + * axfs interfaces to the uncompression library. There's really just
> + * three entrypoints:
> + *
> + * - axfs_uncompress_init() - called to initialize the thing.
> + * - axfs_uncompress_exit() - tell me when you're done
> + * - axfs_uncompress_block() - uncompress a block.
> + *
> + * NOTE NOTE NOTE! The uncompression is entirely single-threaded. We
> + * only have one stream, and we'll initialize it only once even if it
> + * then is used by multiple filesystems.
> + *
> + */
> +
> +#include <linux/errno.h>
> +#include <linux/vmalloc.h>
> +#include <linux/zlib.h>
> +#include <linux/mutex.h>
> +
> +static z_stream stream;
> +static int initialized;
> +static struct mutex axfs_uncmp_mutex;

Use DEFINE_MUTEX and drop the mutex_init() down in the init function.

> +
> +int axfs_uncompress_block(void *dst, int dstlen, void *src, int srclen)
> +{
> + int err;
> + int out;
> +
> + mutex_lock(&axfs_uncmp_mutex);
> +
> + stream.next_in = src;
> + stream.avail_in = srclen;
> +
> + stream.next_out = dst;
> + stream.avail_out = dstlen;
> +
> + err = zlib_inflateReset(&stream);
> + if (err != Z_OK) {
> + printk(KERN_ERR "zlib_inflateReset error %d\n", err);
> + zlib_inflateEnd(&stream);
> + zlib_inflateInit(&stream);
> + }
> +
> + err = zlib_inflate(&stream, Z_FINISH);
> + if (err != Z_STREAM_END)
> + goto err;
> +
> + out = stream.total_out;
> +
> + mutex_unlock(&axfs_uncmp_mutex);
> +
> + return out;
> +
> +err:
> +
> + mutex_unlock(&axfs_uncmp_mutex);
> +
> + printk(KERN_ERR "Error %d while decompressing!\n", err);
> + printk(KERN_ERR "%p(%d)->%p(%d)\n", src, srclen, dst, dstlen);
> + return 0;
> +}
> +
> +int axfs_uncompress_init(void)
> +{
> + if (!initialized++) {
> +
> + mutex_init(&axfs_uncmp_mutex);
> +
> + stream.workspace = vmalloc(zlib_inflate_workspacesize());
> + if (!stream.workspace) {
> + initialized = 0;
> + return -ENOMEM;
> + }
> + stream.next_in = NULL;
> + stream.avail_in = 0;
> + zlib_inflateInit(&stream);
> + }
> + return 0;
> +}
> +
> +int axfs_uncompress_exit(void)
> +{
> + if (!--initialized) {
> + zlib_inflateEnd(&stream);
> + vfree(stream.workspace);
> + }
> + return 0;
> +}

axfs_uncompress_init() and axfs_uncompress_exit() are only called during
init and exit of the module, no need for the initialized variable and the
functions can be annotated with __init and __exit.

2008-08-21 11:45:13

by Artem Bityutskiy

[permalink] [raw]
Subject: Re: [PATCH 10/10] AXFS: axfs_uncompress.c

On Wed, 2008-08-20 at 22:46 -0700, Jared Hulbert wrote:
> + err = zlib_inflateReset(&stream);
> + if (err != Z_OK) {
> + printk(KERN_ERR "zlib_inflateReset error %d\n", err);
> + zlib_inflateEnd(&stream);
> + zlib_inflateInit(&stream);
> + }

Jared,

just FYI, are you aware that LZO which is also present in the kernel is
much faster on decompress than zlib, while its compression is only
slightly worse?

I do not remember the digits, but last time I tested UBIFS, LZO
decompression was about 3 times faster than zlib on OMAP3. This depends
on architecture, etc of course. This may matter a lot if one is fighting
for faster system boot-up. So you might consider supporting LZO as well.

--
Best regards,
Artem Bityutskiy (Битюцкий Артём)

2008-08-21 12:29:08

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH 10/10] AXFS: axfs_uncompress.c

On Thu, 21 Aug 2008, Artem Bityutskiy wrote:
> On Wed, 2008-08-20 at 22:46 -0700, Jared Hulbert wrote:
> > + err = zlib_inflateReset(&stream);
> > + if (err != Z_OK) {
> > + printk(KERN_ERR "zlib_inflateReset error %d\n", err);
> > + zlib_inflateEnd(&stream);
> > + zlib_inflateInit(&stream);
> > + }
>
> just FYI, are you aware that LZO which is also present in the kernel is
> much faster on decompress than zlib, while its compression is only
> slightly worse?

If you want support for multiple decompression algorithms, you can switch
from using zlib_inflate*() directly to calling zlib through the crypto API.
Then you can call crypto_alloc_comp() with the correct decompression algorithm
name.

For squashfs, I had to modify only ca. 40 lines of code.

You do need a new zlib crypto module, as the existing deflate crypto module
uses the raw deflate format instead of the zlib format, and has some parameters
tuned for its use in IPSec.

I hope to have some patches ready next week...

With kind regards,

Geert Uytterhoeven
Software Architect

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

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

A division of Sony Europe (Belgium) N.V.
VAT BE 0413.825.160 · RPR Brussels
Fortis · BIC GEBABEBB · IBAN BE41293037680010

2008-08-21 14:35:47

by Jared Hulbert

[permalink] [raw]
Subject: Re: [PATCH 10/10] AXFS: axfs_uncompress.c

> If you want support for multiple decompression algorithms, you can switch
> from using zlib_inflate*() directly to calling zlib through the crypto API.
> Then you can call crypto_alloc_comp() with the correct decompression algorithm
> name.
>
> For squashfs, I had to modify only ca. 40 lines of code.

I definately want to support multiple formats. I have a flag in the
superblock all ready to go for that. One problem. I'm not sure how
to do it. Can you point us to some reference code?

2008-08-21 14:37:40

by Jared Hulbert

[permalink] [raw]
Subject: Re: [PATCH 10/10] AXFS: axfs_uncompress.c

> Use DEFINE_MUTEX and drop the mutex_init() down in the init function.

okay. by drop you mean delete?

> axfs_uncompress_init() and axfs_uncompress_exit() are only called during
> init and exit of the module, no need for the initialized variable and the
> functions can be annotated with __init and __exit.

can be annotated or should be?

2008-08-21 14:57:26

by Sven Wegener

[permalink] [raw]
Subject: Re: [PATCH 10/10] AXFS: axfs_uncompress.c

On Thu, 21 Aug 2008, Jared Hulbert wrote:

> > Use DEFINE_MUTEX and drop the mutex_init() down in the init function.
>
> okay. by drop you mean delete?

Yes.

> > axfs_uncompress_init() and axfs_uncompress_exit() are only called during
> > init and exit of the module, no need for the initialized variable and the
> > functions can be annotated with __init and __exit.
>
> can be annotated or should be?

Should be. We only need them once during init and cleanup. If you want to
call axfs_uncompress_exit() from init_axfs_fs() to clean up in case of
register_filesystem failing, you can't annotate axfs_uncompress_exit()
with __exit.

Sven

2008-08-29 13:48:21

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH 10/10] AXFS: axfs_uncompress.c

Hi Jared,

On Thu, 21 Aug 2008, Jared Hulbert wrote:
> > If you want support for multiple decompression algorithms, you can switch
> > from using zlib_inflate*() directly to calling zlib through the crypto API.
> > Then you can call crypto_alloc_comp() with the correct decompression algorithm
> > name.
> >
> > For squashfs, I had to modify only ca. 40 lines of code.
>
> I definately want to support multiple formats. I have a flag in the
> superblock all ready to go for that. One problem. I'm not sure how
> to do it. Can you point us to some reference code?

Please take a look at the email with subject

[patch 3/3] squashfs: Switch from zlib/inflate to "zlib" crypto module

With kind regards,

Geert Uytterhoeven
Software Architect

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

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

A division of Sony Europe (Belgium) N.V.
VAT BE 0413.825.160 · RPR Brussels
Fortis · BIC GEBABEBB · IBAN BE41293037680010