Re: [PATCH 1/9] Squashfs: move zlib decompression wrapper code into a separate file
Hi Phillip, On Thu, Dec 10, 2009 at 01:38, Phillip Lougher phil...@lougher.demon.co.uk wrote: Artem Bityutskiy wrote: Did you consider using cryptoapi? UBIFS uses zlib/lzo in cryptoapi - it is a very clean way. Exactly my question, as that's why the Crypto API was extended with support for partial (de)compression in the first place ;-) In addition, using the Crypto API has the advantage that Squashfs will use hardware decompression if/when available. Yes I did consider using the cryptoapi, but this doesn't have support for lzma in mainline. IIRC, Felix Fietkau added support for that for OpenWRT... My aim is add lzma filesystem support to Squashfs using the existing kernel lzma iplementation, and to make as few changes to that as necessary. Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say programmer or something like that. -- Linus Torvalds -- To unsubscribe from this list: send the line unsubscribe linux-embedded in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Squashfs performance (3.3 vs 4.0 in mainline)
Hi! I'm running 2.6.31 on a slow ARM platform and using squashfs 4.0 as shipped with the kernel. It's a Sharp LH79524, so the architecture itself isn't mainlined yet. Squashfs works well, but I've noted a performance regression compared to the out-of-tree squashfs 3.3 which we ran on 2.6.23. The new kernel is faster until the squashfs root filesystem is mounted, but after that it goes downhill. Especially mounting takes a lot more time with the new: 2.6.23 / 3.3: [ 0.01]: [1.25] RAMDISK: squashfs filesystem found at block 0 [ 0.01]: [1.26] RAMDISK: Loading 2156KiB [1 disk] into ram disk... done. [ 1.39]: [2.65] VFS: Mounted root (squashfs filesystem) readonly. [ 0.01]: [2.66] Freeing init memory: 80K 2.6.31 / 4.0: [ 0.00]: [1.08] RAMDISK: squashfs filesystem found at block 0 [ 0.01]: [1.09] RAMDISK: Loading 2372KiB [1 disk] into ram disk... done. [ 2.79]: [3.88] VFS: Mounted root (squashfs filesystem) readonly on device 1:0. [ 0.01]: [3.89] Freeing init memory: 80K (The first column is the time difference compared to last timestamp). Are there any general changes which could have caused this difference? I've tried with various mksquashfs options, and -noI makes it somewhat faster (and larger), but not near the old version. // Simon -- To unsubscribe from this list: send the line unsubscribe linux-embedded in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/9] Squashfs: move zlib decompression wrapper code into a separate file
Geert Uytterhoeven wrote: Yes I did consider using the cryptoapi, but this doesn't have support for lzma in mainline. IIRC, Felix Fietkau added support for that for OpenWRT... Yes, but it isn't in mainline, and OpenWRT don't appear to have tried to submit it. IMHO the major problem with their patch is it uses a second private copy of lzma, rather than being a wrapper around the pre-existing lzma implementation. I don't think it's going to be easy to get a second lzma implementation accepted into mainline, when it took so long to get one accepted. I have nothing against the cryptoapi, but it doesn't seem likely to be getting lzma support anytime soon. As I previously said my aim is to use the pre-existing lzma implementation. Unless it is stupendously bad (which it isn't), that seems to be the quickest, easiest and best way to get lzma support into Squashfs. Phillip -- To unsubscribe from this list: send the line unsubscribe linux-embedded in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/9] Squashfs: move zlib decompression wrapper code into a separate file
On 2009-12-10 10:17 PM, Phillip Lougher wrote: Geert Uytterhoeven wrote: Yes I did consider using the cryptoapi, but this doesn't have support for lzma in mainline. IIRC, Felix Fietkau added support for that for OpenWRT... Yes, but it isn't in mainline, and OpenWRT don't appear to have tried to submit it. IMHO the major problem with their patch is it uses a second private copy of lzma, rather than being a wrapper around the pre-existing lzma implementation. I don't think it's going to be easy to get a second lzma implementation accepted into mainline, when it took so long to get one accepted. I have nothing against the cryptoapi, but it doesn't seem likely to be getting lzma support anytime soon. As I previously said my aim is to use the pre-existing lzma implementation. Unless it is stupendously bad (which it isn't), that seems to be the quickest, easiest and best way to get lzma support into Squashfs. The main reason why my implementation couldn't be done as a simple wrapper around the existing implementation is that it reuses the caller's split output buffers instead wasting precious RAM by allocating a contiguous buffer big enough to cover the entire block. Especially at bigger block sizes (which provide better compression), this probably has noticeable effects on tiny embedded systems with little RAM. - Felix -- To unsubscribe from this list: send the line unsubscribe linux-embedded in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/9] Squashfs: move zlib decompression wrapper code into a separate file
Geert Uytterhoeven wrote: Hi Phillip, On Thu, Dec 10, 2009 at 01:38, Phillip Lougher phil...@lougher.demon.co.uk wrote: Artem Bityutskiy wrote: Did you consider using cryptoapi? UBIFS uses zlib/lzo in cryptoapi - it is a very clean way. Exactly my question, as that's why the Crypto API was extended with support for partial (de)compression in the first place ;-) Your cryptoapi patches are on my must do something about them list, I've not forgotten them :-) The lack of lzma in the crypotapi made moving solely to the cryptoapi difficult, when I wanted to add lzma decompression support. The decompressor framework is my _solution_ to this problem. This allows cryptoapi support to be added as additional decompression_wrapper, with multiple compression types using the crptoapi wrapper as appropriate. This has the advantage it allows Squashfs to use the cryptoapi (with its advantages), without needlessly restricting Squashfs to the compression algorithms supported by the cryptoapi. Let's get this mainlined, and then we can work on getting your cryptoapi patches integrated into that. That'll make me happy, and hopefully you'll be happy too? Thanks Phillip -- To unsubscribe from this list: send the line unsubscribe linux-embedded in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V2 0/9] Squashfs: Add support for LZMA compressed filesystems
Hi, This a respin of my LZMA decompression support patches, taking into account Andrew Morton's comments regarding poorly named globals: Changes: 1. zlib_uncompress() renamed to squashfs_zlib_uncompress() (patch 1) 2. zlib_init() and zlib_free() renamed to squashfs_zlib_init() and squashfs_zlib_free() (patch 2) 3. Merged patch 7 (make decompressor init function pass superblock info) into patch 3. This was a development commit which should not have been a separate patch for review Original patch series info: The following patches add LZMA decompression support to Squashfs, using the in-kernel LZMA decompression library. The patches also add a decompression framework to Squashfs. This allows LZMA decompression to be added cleanly, and it allows additional decompressors to be easily added in the future. To enable the in-kernel LZMA decompression code to be used by Squashfs, there are two patches to the lzma code itself: one to make lzma available to non-init code, and one to make lzma reentrant. These are obviously not restricted to Squashfs, but are needed by any non-init code that may wish to use lzma compression. These patches are available in my squashfs-devel git tree in a slightly different format (these patches have been refactored for posting, they'll be put into a git tree ASAP). http://git.kernel.org/?p=linux/kernel/git/pkl/squashfs-devel.git;a=summary I would like to thank the CE Linux Forum (CELF) for supporting this work. Thanks Phillip -- To unsubscribe from this list: send the line unsubscribe linux-embedded in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V2 3/8] Squashfs: add a decompressor framework
This adds a decompressor framework which allows multiple compression algorithms to be cleanly supported. Also update zlib wrapper and other code to use the new framework. Signed-off-by: Phillip Lougher phil...@lougher.demon.co.uk --- fs/squashfs/Makefile |2 +- fs/squashfs/block.c |3 +- fs/squashfs/decompressor.c | 58 ++ fs/squashfs/decompressor.h | 55 +++ fs/squashfs/squashfs.h | 14 +- fs/squashfs/squashfs_fs_sb.h | 41 +++-- fs/squashfs/super.c | 45 ++- fs/squashfs/zlib_wrapper.c | 17 ++-- 8 files changed, 184 insertions(+), 51 deletions(-) create mode 100644 fs/squashfs/decompressor.c create mode 100644 fs/squashfs/decompressor.h diff --git a/fs/squashfs/Makefile b/fs/squashfs/Makefile index a397e6f..df8a19e 100644 --- a/fs/squashfs/Makefile +++ b/fs/squashfs/Makefile @@ -4,4 +4,4 @@ obj-$(CONFIG_SQUASHFS) += squashfs.o squashfs-y += block.o cache.o dir.o export.o file.o fragment.o id.o inode.o -squashfs-y += namei.o super.o symlink.o zlib_wrapper.o +squashfs-y += namei.o super.o symlink.o zlib_wrapper.o decompressor.o diff --git a/fs/squashfs/block.c b/fs/squashfs/block.c index 3f836e1..1cb0d81 100644 --- a/fs/squashfs/block.c +++ b/fs/squashfs/block.c @@ -36,6 +36,7 @@ #include squashfs_fs_sb.h #include squashfs_fs_i.h #include squashfs.h +#include decompressor.h /* * Read the metadata block length, this is stored in the first two @@ -151,7 +152,7 @@ int squashfs_read_data(struct super_block *sb, void **buffer, u64 index, } if (compressed) { - length = squashfs_zlib_uncompress(msblk, buffer, bh, b, offset, + length = squashfs_decompress(msblk, buffer, bh, b, offset, length, srclength, pages); if (length 0) goto read_failure; diff --git a/fs/squashfs/decompressor.c b/fs/squashfs/decompressor.c new file mode 100644 index 000..0072ccd --- /dev/null +++ b/fs/squashfs/decompressor.c @@ -0,0 +1,58 @@ +/* + * Squashfs - a compressed read only filesystem for Linux + * + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + * Phillip Lougher phil...@lougher.demon.co.uk + * + * 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, + * or (at your option) any later version. + * + * 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, write to the Free Software + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * decompressor.c + */ + +#include linux/types.h +#include linux/mutex.h +#include linux/buffer_head.h + +#include squashfs_fs.h +#include squashfs_fs_sb.h +#include squashfs_fs_i.h +#include decompressor.h +#include squashfs.h + +/* + * This file (and decompressor.h) implements a decompressor framework for + * Squashfs, allowing multiple decompressors to be easily supported + */ + +static const struct squashfs_decompressor squashfs_unknown_comp_ops = { + NULL, NULL, NULL, 0, unknown, 0 +}; + +static const struct squashfs_decompressor *decompressor[] = { + squashfs_zlib_comp_ops, + squashfs_unknown_comp_ops +}; + + +const struct squashfs_decompressor *squashfs_lookup_decompressor(int id) +{ + int i; + + for (i = 0; decompressor[i]-id; i++) + if (id == decompressor[i]-id) + break; + + return decompressor[i]; +} diff --git a/fs/squashfs/decompressor.h b/fs/squashfs/decompressor.h new file mode 100644 index 000..7425f80 --- /dev/null +++ b/fs/squashfs/decompressor.h @@ -0,0 +1,55 @@ +#ifndef DECOMPRESSOR_H +#define DECOMPRESSOR_H +/* + * Squashfs - a compressed read only filesystem for Linux + * + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + * Phillip Lougher phil...@lougher.demon.co.uk + * + * 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, + * or (at your option) any later version. + * + * 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, write to the
[PATCH V2 7/8] Squashfs: select DECOMPRESS_LZMA_NEEDED when including support for lzma
Signed-off-by: Phillip Lougher phil...@lougher.demon.co.uk --- fs/squashfs/Kconfig |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/fs/squashfs/Kconfig b/fs/squashfs/Kconfig index 0294aa2..7ec5d7e 100644 --- a/fs/squashfs/Kconfig +++ b/fs/squashfs/Kconfig @@ -30,6 +30,7 @@ config SQUASHFS_LZMA bool Include support for LZMA compressed file systems depends on SQUASHFS select DECOMPRESS_LZMA + select DECOMPRESS_LZMA_NEEDED config SQUASHFS_EMBEDDED -- 1.6.3.3 -- To unsubscribe from this list: send the line unsubscribe linux-embedded in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V2 1/8] Squashfs: move zlib decompression wrapper code into a separate file
Signed-off-by: Phillip Lougher phil...@lougher.demon.co.uk --- fs/squashfs/Makefile |2 +- fs/squashfs/block.c| 74 ++ fs/squashfs/squashfs.h |4 ++ fs/squashfs/zlib_wrapper.c | 109 4 files changed, 118 insertions(+), 71 deletions(-) create mode 100644 fs/squashfs/zlib_wrapper.c diff --git a/fs/squashfs/Makefile b/fs/squashfs/Makefile index 70e3244..a397e6f 100644 --- a/fs/squashfs/Makefile +++ b/fs/squashfs/Makefile @@ -4,4 +4,4 @@ obj-$(CONFIG_SQUASHFS) += squashfs.o squashfs-y += block.o cache.o dir.o export.o file.o fragment.o id.o inode.o -squashfs-y += namei.o super.o symlink.o +squashfs-y += namei.o super.o symlink.o zlib_wrapper.o diff --git a/fs/squashfs/block.c b/fs/squashfs/block.c index 2a79603..b8addfd 100644 --- a/fs/squashfs/block.c +++ b/fs/squashfs/block.c @@ -29,7 +29,6 @@ #include linux/fs.h #include linux/vfs.h #include linux/slab.h -#include linux/mutex.h #include linux/string.h #include linux/buffer_head.h #include linux/zlib.h @@ -153,72 +152,10 @@ int squashfs_read_data(struct super_block *sb, void **buffer, u64 index, } if (compressed) { - int zlib_err = 0, zlib_init = 0; - - /* -* Uncompress block. -*/ - - mutex_lock(msblk-read_data_mutex); - - msblk-stream.avail_out = 0; - msblk-stream.avail_in = 0; - - bytes = length; - do { - if (msblk-stream.avail_in == 0 k b) { - avail = min(bytes, msblk-devblksize - offset); - bytes -= avail; - wait_on_buffer(bh[k]); - if (!buffer_uptodate(bh[k])) - goto release_mutex; - - if (avail == 0) { - offset = 0; - put_bh(bh[k++]); - continue; - } - - msblk-stream.next_in = bh[k]-b_data + offset; - msblk-stream.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 (!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); - goto release_mutex; - } - zlib_init = 1; - } - - zlib_err = zlib_inflate(msblk-stream, Z_SYNC_FLUSH); - - if (msblk-stream.avail_in == 0 k b) - put_bh(bh[k++]); - } while (zlib_err == Z_OK); - - if (zlib_err != Z_STREAM_END) { - ERROR(zlib_inflate error, data probably corrupt\n); - goto release_mutex; - } - - 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); + length = squashfs_zlib_uncompress(msblk, buffer, bh, b, offset, +length, srclength, pages); + if (length 0) + goto read_failure; } else { /* * Block is uncompressed. @@ -255,9 +192,6 @@ int squashfs_read_data(struct super_block *sb, void **buffer, u64 index, kfree(bh); return length; -release_mutex: - mutex_unlock(msblk-read_data_mutex); - block_release: for (; k b; k++) put_bh(bh[k]); diff --git a/fs/squashfs/squashfs.h b/fs/squashfs/squashfs.h index 0e9feb6..ba87db6 100644 --- a/fs/squashfs/squashfs.h +++ b/fs/squashfs/squashfs.h @@ -70,6 +70,10 @@ extern struct inode *squashfs_iget(struct super_block *, long long, unsigned int); extern int squashfs_read_inode(struct inode *, long long); +/* zlib_wrapper.c */ +extern int squashfs_zlib_uncompress(struct squashfs_sb_info *, void **, +
[PATCH V2 5/8] Squashfs: add support for LZMA compressed filesystems
Signed-off-by: Phillip Lougher phil...@lougher.demon.co.uk --- fs/squashfs/Kconfig|5 ++ fs/squashfs/Makefile |1 + fs/squashfs/decompressor.c |4 + fs/squashfs/lzma_wrapper.c | 151 fs/squashfs/squashfs.h |3 + 5 files changed, 164 insertions(+), 0 deletions(-) create mode 100644 fs/squashfs/lzma_wrapper.c diff --git a/fs/squashfs/Kconfig b/fs/squashfs/Kconfig index 25a00d1..0294aa2 100644 --- a/fs/squashfs/Kconfig +++ b/fs/squashfs/Kconfig @@ -26,6 +26,11 @@ config SQUASHFS If unsure, say N. +config SQUASHFS_LZMA + bool Include support for LZMA compressed file systems + depends on SQUASHFS + select DECOMPRESS_LZMA + config SQUASHFS_EMBEDDED bool Additional option for memory-constrained systems diff --git a/fs/squashfs/Makefile b/fs/squashfs/Makefile index df8a19e..45aaefd 100644 --- a/fs/squashfs/Makefile +++ b/fs/squashfs/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_SQUASHFS) += squashfs.o squashfs-y += block.o cache.o dir.o export.o file.o fragment.o id.o inode.o squashfs-y += namei.o super.o symlink.o zlib_wrapper.o decompressor.o +squashfs-$(CONFIG_SQUASHFS_LZMA) += lzma_wrapper.o diff --git a/fs/squashfs/decompressor.c b/fs/squashfs/decompressor.c index 157478d..0b6ad9b 100644 --- a/fs/squashfs/decompressor.c +++ b/fs/squashfs/decompressor.c @@ -50,7 +50,11 @@ static const struct squashfs_decompressor squashfs_unknown_comp_ops = { static const struct squashfs_decompressor *decompressor[] = { squashfs_zlib_comp_ops, +#ifdef CONFIG_SQUASHFS_LZMA + squashfs_lzma_comp_ops, +#else squashfs_lzma_unsupported_comp_ops, +#endif squashfs_lzo_unsupported_comp_ops, squashfs_unknown_comp_ops }; diff --git a/fs/squashfs/lzma_wrapper.c b/fs/squashfs/lzma_wrapper.c new file mode 100644 index 000..cef06d6 --- /dev/null +++ b/fs/squashfs/lzma_wrapper.c @@ -0,0 +1,151 @@ +/* + * Squashfs - a compressed read only filesystem for Linux + * + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + * Phillip Lougher phil...@lougher.demon.co.uk + * + * 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, + * or (at your option) any later version. + * + * 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, write to the Free Software + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * lzma_wrapper.c + */ + +#include asm/unaligned.h +#include linux/buffer_head.h +#include linux/mutex.h +#include linux/vmalloc.h +#include linux/decompress/unlzma.h + +#include squashfs_fs.h +#include squashfs_fs_sb.h +#include squashfs_fs_i.h +#include squashfs.h +#include decompressor.h + +struct squashfs_lzma { + void*input; + void*output; +}; + +/* decompress_unlzma.c is currently non re-entrant... */ +DEFINE_MUTEX(lzma_mutex); + +/* decompress_unlzma.c doesn't provide any context in its callbacks... */ +static int lzma_error; + +static void error(char *m) +{ + ERROR(unlzma error: %s\n, m); + lzma_error = 1; +} + + +static void *lzma_init(struct squashfs_sb_info *msblk) +{ + struct squashfs_lzma *stream = kzalloc(sizeof(*stream), GFP_KERNEL); + if (stream == NULL) + goto failed; + stream-input = vmalloc(msblk-block_size); + if (stream-input == NULL) + goto failed; + stream-output = vmalloc(msblk-block_size); + if (stream-output == NULL) + goto failed2; + + return stream; + +failed2: + vfree(stream-input); +failed: + ERROR(failed to allocate lzma workspace\n); + kfree(stream); + return NULL; +} + + +static void lzma_free(void *strm) +{ + struct squashfs_lzma *stream = strm; + + if (stream) { + vfree(stream-input); + vfree(stream-output); + } + kfree(stream); +} + + +static int lzma_uncompress(struct squashfs_sb_info *msblk, void **buffer, + struct buffer_head **bh, int b, int offset, int length, int srclength, + int pages) +{ + struct squashfs_lzma *stream = msblk-stream; + void *buff = stream-input; + int avail, i, bytes = length, res; + + mutex_lock(lzma_mutex); + + for (i = 0; i b; i++) { + wait_on_buffer(bh[i]); + if (!buffer_uptodate(bh[i])) + goto block_release; + + avail = min(bytes, msblk-devblksize - offset); + memcpy(buff, bh[i]-b_data + offset, avail); + buff +=