Re: [PATCH 1/9] Squashfs: move zlib decompression wrapper code into a separate file

2009-12-10 Thread Geert Uytterhoeven
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)

2009-12-10 Thread Simon Kagstrom
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

2009-12-10 Thread Phillip Lougher

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

2009-12-10 Thread Felix Fietkau
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

2009-12-10 Thread Phillip Lougher

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

2009-12-10 Thread Phillip Lougher
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

2009-12-10 Thread Phillip Lougher

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

2009-12-10 Thread Phillip Lougher

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

2009-12-10 Thread Phillip Lougher

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

2009-12-10 Thread Phillip Lougher

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 +=