AXFS: axfs_uncompress.c
PATCH 10/10 AXFS: axfs_uncompress.c
Handles the decompression for axfs, modeled after fs/cramfs/uncompress.c.
---
fs/axfs/axfs_uncompress.c new file +97 -0
@@ -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 ; +}
Quoted 31 lines · Jared Hulbert
Handles the decompression for axfs, modeled after
fs/cramfs/uncompress.c.Signed-off-by Jared Hulbert <[email protected]>---
fs/axfs/axfs_uncompress.c new file +21
-0@@ -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. +*
fs/axfs/axfs_uncompress.c line 31
Quoted 10 lines
fs/axfs/axfs_uncompress.c new file +10
-0+*/ + +#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.
Quoted 56 lines
fs/axfs/axfs_uncompress.c new file +56
-0+ +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 ;
fs/axfs/axfs_uncompress.c line 97
Quoted 10 lines
fs/axfs/axfs_uncompress.c new file +10
-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.
Quoted 1 line
Use
DEFINE_MUTEXand drop themutex_init()down in the init function.
okay. by drop you mean delete?
Quoted 3 lines
axfs_uncompress_init()andaxfs_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__initand__exit.
can be annotated or should be?
Quoted 3 lines · Jared Hulbert
Quoted 1 line
Use
DEFINE_MUTEXand drop themutex_init()down in the init function.okay. by drop you mean delete?
Yes.
Quoted 5 lines
Quoted 3 lines
axfs_uncompress_init()andaxfs_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__initand__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
fs/axfs/axfs_uncompress.c line 51
Quoted 6 lines · Jared Hulbert
fs/axfs/axfs_uncompress.c new file +6
-0+ 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.
Signature · 2 lines
Best regards, Artem Bityutskiy (Битюцкий Артём)
Quoted 11 lines · Artem Bityutskiy
fs/axfs/axfs_uncompress.c line 51
Quoted 6 lines · Jared Hulbert
fs/axfs/axfs_uncompress.c new file +6
-0+ 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
Quoted 6 lines
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?
Hi Jared,
Quoted 10 lines · Jared Hulbert
Quoted 6 lines
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