From b8dc57dfdc81739dde89dbc4666924f1838a90cf Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Sat, 5 Dec 2009 19:27:54 +0100 Subject: [PATCH] squashfs: - add support for lzma compression linux: - build with squashfs lzma support project/intel: - build kernel with squashfs lzma support project/ION: - build kernel with squashfs lzma support --- packages/image/install | 2 +- .../patches/linux-2.6.32-squashfs_lzma.diff | 1052 +++++++++++++++++ packages/toolchain/sysutils/squashfs/build | 6 +- packages/toolchain/sysutils/squashfs/install | 2 +- ...zma.diff => squashfs_remove_defaults.diff} | 8 +- projects/ION/linux/linux.i386.conf | 3 + projects/intel/linux/linux.i386.conf | 3 + 7 files changed, 1069 insertions(+), 7 deletions(-) create mode 100644 packages/linux/patches/linux-2.6.32-squashfs_lzma.diff rename packages/toolchain/sysutils/squashfs/patches/{squashfs_disable_lzma.diff => squashfs_remove_defaults.diff} (78%) diff --git a/packages/image/install b/packages/image/install index 62769fe900..8a6d56aa63 100755 --- a/packages/image/install +++ b/packages/image/install @@ -84,7 +84,7 @@ case "$2" in cp -PR $BUILD/linux-*/arch/x86/boot/bzImage $ROOT/target/OpenELEC-$PROJECT-$TARGET_LIBC-$OPENELEC_VERSION.kernel echo "rm -rf $ROOT/target/OpenELEC-$PROJECT-$TARGET_LIBC-$OPENELEC_VERSION.system" >> $ROOT/.fakeroot - echo "$ROOT/$TOOLCHAIN/bin/mksquashfs $INSTALL $ROOT/target/OpenELEC-$PROJECT-$TARGET_LIBC-$OPENELEC_VERSION.system -noappend" >> $ROOT/.fakeroot + echo "$ROOT/$TOOLCHAIN/bin/mksquashfs $INSTALL $ROOT/target/OpenELEC-$PROJECT-$TARGET_LIBC-$OPENELEC_VERSION.system -noappend -comp lzma" >> $ROOT/.fakeroot $ROOT/$TOOLCHAIN/bin/fakeroot -- $ROOT/.fakeroot chmod 0644 $ROOT/target/OpenELEC-$PROJECT-$TARGET_LIBC-$OPENELEC_VERSION.system rm -rf $ROOT/.fakeroot diff --git a/packages/linux/patches/linux-2.6.32-squashfs_lzma.diff b/packages/linux/patches/linux-2.6.32-squashfs_lzma.diff new file mode 100644 index 0000000000..97562928ad --- /dev/null +++ b/packages/linux/patches/linux-2.6.32-squashfs_lzma.diff @@ -0,0 +1,1052 @@ +diff -Naur linux-2.6.32/fs/squashfs/block.c linux-2.6.32.patch/fs/squashfs/block.c +--- linux-2.6.32/fs/squashfs/block.c 2009-12-03 04:51:21.000000000 +0100 ++++ linux-2.6.32.patch/fs/squashfs/block.c 2009-12-05 18:41:38.437304056 +0100 +@@ -29,16 +29,14 @@ + #include + #include + #include +-#include + #include + #include +-#include + + #include "squashfs_fs.h" + #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 + * bytes of the metadata block. +@@ -153,72 +151,10 @@ + } + + 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_decompress(msblk, buffer, bh, b, offset, ++ length, srclength, pages); ++ if (length < 0) ++ goto read_failure; + } else { + /* + * Block is uncompressed. +@@ -255,9 +191,6 @@ + kfree(bh); + return length; + +-release_mutex: +- mutex_unlock(&msblk->read_data_mutex); +- + block_release: + for (; k < b; k++) + put_bh(bh[k]); +diff -Naur linux-2.6.32/fs/squashfs/cache.c linux-2.6.32.patch/fs/squashfs/cache.c +--- linux-2.6.32/fs/squashfs/cache.c 2009-12-03 04:51:21.000000000 +0100 ++++ linux-2.6.32.patch/fs/squashfs/cache.c 2009-12-05 18:41:38.438305640 +0100 +@@ -51,7 +51,6 @@ + #include + #include + #include +-#include + #include + + #include "squashfs_fs.h" +diff -Naur linux-2.6.32/fs/squashfs/decompressor.c linux-2.6.32.patch/fs/squashfs/decompressor.c +--- linux-2.6.32/fs/squashfs/decompressor.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.32.patch/fs/squashfs/decompressor.c 2009-12-05 18:41:38.439304990 +0100 +@@ -0,0 +1,72 @@ ++/* ++ * Squashfs - a compressed read only filesystem for Linux ++ * ++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 ++ * Phillip Lougher ++ * ++ * 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 ++#include ++#include ++ ++#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_lzma_unsupported_comp_ops = { ++ NULL, NULL, NULL, LZMA_COMPRESSION, "lzma", 0 ++}; ++ ++static const struct squashfs_decompressor squashfs_lzo_unsupported_comp_ops = { ++ NULL, NULL, NULL, LZO_COMPRESSION, "lzo", 0 ++}; ++ ++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, ++#ifdef CONFIG_SQUASHFS_LZMA ++ &squashfs_lzma_comp_ops, ++#else ++ &squashfs_lzma_unsupported_comp_ops, ++#endif ++ &squashfs_lzo_unsupported_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 -Naur linux-2.6.32/fs/squashfs/decompressor.h linux-2.6.32.patch/fs/squashfs/decompressor.h +--- linux-2.6.32/fs/squashfs/decompressor.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.32.patch/fs/squashfs/decompressor.h 2009-12-05 18:41:38.439304990 +0100 +@@ -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 ++ * ++ * 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.h ++ */ ++ ++struct squashfs_decompressor { ++ void *(*init)(struct squashfs_sb_info *); ++ void (*free)(void *); ++ int (*decompress)(struct squashfs_sb_info *, void **, ++ struct buffer_head **, int, int, int, int, int); ++ int id; ++ char *name; ++ int supported; ++}; ++ ++static inline void *squashfs_decompressor_init(struct squashfs_sb_info *msblk) ++{ ++ return msblk->decompressor->init(msblk); ++} ++ ++static inline void squashfs_decompressor_free(struct squashfs_sb_info *msblk, ++ void *s) ++{ ++ if (msblk->decompressor) ++ msblk->decompressor->free(s); ++} ++ ++static inline int squashfs_decompress(struct squashfs_sb_info *msblk, ++ void **buffer, struct buffer_head **bh, int b, int offset, int length, ++ int srclength, int pages) ++{ ++ return msblk->decompressor->decompress(msblk, buffer, bh, b, offset, ++ length, srclength, pages); ++} ++#endif +diff -Naur linux-2.6.32/fs/squashfs/dir.c linux-2.6.32.patch/fs/squashfs/dir.c +--- linux-2.6.32/fs/squashfs/dir.c 2009-12-03 04:51:21.000000000 +0100 ++++ linux-2.6.32.patch/fs/squashfs/dir.c 2009-12-05 18:41:38.439304990 +0100 +@@ -30,7 +30,6 @@ + #include + #include + #include +-#include + + #include "squashfs_fs.h" + #include "squashfs_fs_sb.h" +diff -Naur linux-2.6.32/fs/squashfs/export.c linux-2.6.32.patch/fs/squashfs/export.c +--- linux-2.6.32/fs/squashfs/export.c 2009-12-03 04:51:21.000000000 +0100 ++++ linux-2.6.32.patch/fs/squashfs/export.c 2009-12-05 18:41:38.440302872 +0100 +@@ -39,7 +39,6 @@ + #include + #include + #include +-#include + #include + + #include "squashfs_fs.h" +diff -Naur linux-2.6.32/fs/squashfs/file.c linux-2.6.32.patch/fs/squashfs/file.c +--- linux-2.6.32/fs/squashfs/file.c 2009-12-03 04:51:21.000000000 +0100 ++++ linux-2.6.32.patch/fs/squashfs/file.c 2009-12-05 18:41:38.493304431 +0100 +@@ -47,7 +47,6 @@ + #include + #include + #include +-#include + + #include "squashfs_fs.h" + #include "squashfs_fs_sb.h" +diff -Naur linux-2.6.32/fs/squashfs/fragment.c linux-2.6.32.patch/fs/squashfs/fragment.c +--- linux-2.6.32/fs/squashfs/fragment.c 2009-12-03 04:51:21.000000000 +0100 ++++ linux-2.6.32.patch/fs/squashfs/fragment.c 2009-12-05 18:41:38.494304967 +0100 +@@ -36,7 +36,6 @@ + #include + #include + #include +-#include + + #include "squashfs_fs.h" + #include "squashfs_fs_sb.h" +diff -Naur linux-2.6.32/fs/squashfs/id.c linux-2.6.32.patch/fs/squashfs/id.c +--- linux-2.6.32/fs/squashfs/id.c 2009-12-03 04:51:21.000000000 +0100 ++++ linux-2.6.32.patch/fs/squashfs/id.c 2009-12-05 18:41:38.495305225 +0100 +@@ -34,7 +34,6 @@ + #include + #include + #include +-#include + + #include "squashfs_fs.h" + #include "squashfs_fs_sb.h" +diff -Naur linux-2.6.32/fs/squashfs/inode.c linux-2.6.32.patch/fs/squashfs/inode.c +--- linux-2.6.32/fs/squashfs/inode.c 2009-12-03 04:51:21.000000000 +0100 ++++ linux-2.6.32.patch/fs/squashfs/inode.c 2009-12-05 18:41:38.496306250 +0100 +@@ -40,7 +40,6 @@ + + #include + #include +-#include + + #include "squashfs_fs.h" + #include "squashfs_fs_sb.h" +diff -Naur linux-2.6.32/fs/squashfs/Kconfig linux-2.6.32.patch/fs/squashfs/Kconfig +--- linux-2.6.32/fs/squashfs/Kconfig 2009-12-03 04:51:21.000000000 +0100 ++++ linux-2.6.32.patch/fs/squashfs/Kconfig 2009-12-05 18:41:38.497305111 +0100 +@@ -26,6 +26,12 @@ + + If unsure, say N. + ++config SQUASHFS_LZMA ++ bool "Include support for LZMA compressed file systems" ++ depends on SQUASHFS ++ select DECOMPRESS_LZMA ++ select DECOMPRESS_LZMA_NEEDED ++ + config SQUASHFS_EMBEDDED + + bool "Additional option for memory-constrained systems" +diff -Naur linux-2.6.32/fs/squashfs/lzma_wrapper.c linux-2.6.32.patch/fs/squashfs/lzma_wrapper.c +--- linux-2.6.32/fs/squashfs/lzma_wrapper.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.32.patch/fs/squashfs/lzma_wrapper.c 2009-12-05 18:41:38.498304460 +0100 +@@ -0,0 +1,151 @@ ++/* ++ * Squashfs - a compressed read only filesystem for Linux ++ * ++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 ++ * Phillip Lougher ++ * ++ * 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 ++#include ++#include ++#include ++#include ++ ++#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 += avail; ++ bytes -= avail; ++ offset = 0; ++ put_bh(bh[i]); ++ } ++ ++ lzma_error = 0; ++ res = unlzma(stream->input, length, NULL, NULL, stream->output, NULL, ++ error); ++ if (res || lzma_error) ++ goto failed; ++ ++ /* uncompressed size is stored in the LZMA header (5 byte offset) */ ++ res = bytes = get_unaligned_le32(stream->input + 5); ++ for (i = 0, buff = stream->output; bytes && i < pages; i++) { ++ avail = min_t(int, bytes, PAGE_CACHE_SIZE); ++ memcpy(buffer[i], buff, avail); ++ buff += avail; ++ bytes -= avail; ++ } ++ if (bytes) ++ goto failed; ++ ++ mutex_unlock(&lzma_mutex); ++ return res; ++ ++block_release: ++ for (; i < b; i++) ++ put_bh(bh[i]); ++ ++failed: ++ mutex_unlock(&lzma_mutex); ++ ++ ERROR("lzma decompression failed, data probably corrupt\n"); ++ return -EIO; ++} ++ ++const struct squashfs_decompressor squashfs_lzma_comp_ops = { ++ .init = lzma_init, ++ .free = lzma_free, ++ .decompress = lzma_uncompress, ++ .id = LZMA_COMPRESSION, ++ .name = "lzma", ++ .supported = 1 ++}; ++ +diff -Naur linux-2.6.32/fs/squashfs/Makefile linux-2.6.32.patch/fs/squashfs/Makefile +--- linux-2.6.32/fs/squashfs/Makefile 2009-12-03 04:51:21.000000000 +0100 ++++ linux-2.6.32.patch/fs/squashfs/Makefile 2009-12-05 18:41:38.498304460 +0100 +@@ -4,4 +4,5 @@ + + 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 decompressor.o ++squashfs-$(CONFIG_SQUASHFS_LZMA) += lzma_wrapper.o +diff -Naur linux-2.6.32/fs/squashfs/namei.c linux-2.6.32.patch/fs/squashfs/namei.c +--- linux-2.6.32/fs/squashfs/namei.c 2009-12-03 04:51:21.000000000 +0100 ++++ linux-2.6.32.patch/fs/squashfs/namei.c 2009-12-05 18:41:38.499304857 +0100 +@@ -57,7 +57,6 @@ + #include + #include + #include +-#include + + #include "squashfs_fs.h" + #include "squashfs_fs_sb.h" +diff -Naur linux-2.6.32/fs/squashfs/squashfs_fs.h linux-2.6.32.patch/fs/squashfs/squashfs_fs.h +--- linux-2.6.32/fs/squashfs/squashfs_fs.h 2009-12-03 04:51:21.000000000 +0100 ++++ linux-2.6.32.patch/fs/squashfs/squashfs_fs.h 2009-12-05 18:41:38.500303299 +0100 +@@ -211,7 +211,9 @@ + /* + * definitions for structures on disk + */ +-#define ZLIB_COMPRESSION 1 ++#define ZLIB_COMPRESSION 1 ++#define LZMA_COMPRESSION 2 ++#define LZO_COMPRESSION 3 + + struct squashfs_super_block { + __le32 s_magic; +diff -Naur linux-2.6.32/fs/squashfs/squashfs_fs_sb.h linux-2.6.32.patch/fs/squashfs/squashfs_fs_sb.h +--- linux-2.6.32/fs/squashfs/squashfs_fs_sb.h 2009-12-03 04:51:21.000000000 +0100 ++++ linux-2.6.32.patch/fs/squashfs/squashfs_fs_sb.h 2009-12-05 18:41:38.500303299 +0100 +@@ -52,25 +52,26 @@ + }; + + struct squashfs_sb_info { +- int devblksize; +- int devblksize_log2; +- struct squashfs_cache *block_cache; +- struct squashfs_cache *fragment_cache; +- struct squashfs_cache *read_page; +- int next_meta_index; +- __le64 *id_table; +- __le64 *fragment_index; +- unsigned int *fragment_index_2; +- struct mutex read_data_mutex; +- struct mutex meta_index_mutex; +- struct meta_index *meta_index; +- z_stream stream; +- __le64 *inode_lookup_table; +- u64 inode_table; +- u64 directory_table; +- unsigned int block_size; +- unsigned short block_log; +- long long bytes_used; +- unsigned int inodes; ++ const struct squashfs_decompressor *decompressor; ++ int devblksize; ++ int devblksize_log2; ++ struct squashfs_cache *block_cache; ++ struct squashfs_cache *fragment_cache; ++ struct squashfs_cache *read_page; ++ int next_meta_index; ++ __le64 *id_table; ++ __le64 *fragment_index; ++ unsigned int *fragment_index_2; ++ struct mutex read_data_mutex; ++ struct mutex meta_index_mutex; ++ struct meta_index *meta_index; ++ void *stream; ++ __le64 *inode_lookup_table; ++ u64 inode_table; ++ u64 directory_table; ++ unsigned int block_size; ++ unsigned short block_log; ++ long long bytes_used; ++ unsigned int inodes; + }; + #endif +diff -Naur linux-2.6.32/fs/squashfs/squashfs.h linux-2.6.32.patch/fs/squashfs/squashfs.h +--- linux-2.6.32/fs/squashfs/squashfs.h 2009-12-03 04:51:21.000000000 +0100 ++++ linux-2.6.32.patch/fs/squashfs/squashfs.h 2009-12-05 18:41:38.500303299 +0100 +@@ -51,6 +51,9 @@ + u64, int); + extern int squashfs_read_table(struct super_block *, void *, u64, int); + ++/* decompressor.c */ ++extern const struct squashfs_decompressor *squashfs_lookup_decompressor(int); ++ + /* export.c */ + extern __le64 *squashfs_read_inode_lookup_table(struct super_block *, u64, + unsigned int); +@@ -71,7 +74,7 @@ + extern int squashfs_read_inode(struct inode *, long long); + + /* +- * Inodes and files operations ++ * Inodes, files and decompressor operations + */ + + /* dir.c */ +@@ -88,3 +91,9 @@ + + /* symlink.c */ + extern const struct address_space_operations squashfs_symlink_aops; ++ ++/* zlib_wrapper.c */ ++extern const struct squashfs_decompressor squashfs_zlib_comp_ops; ++ ++/* lzma wrapper.c */ ++extern const struct squashfs_decompressor squashfs_lzma_comp_ops; +diff -Naur linux-2.6.32/fs/squashfs/super.c linux-2.6.32.patch/fs/squashfs/super.c +--- linux-2.6.32/fs/squashfs/super.c 2009-12-03 04:51:21.000000000 +0100 ++++ linux-2.6.32.patch/fs/squashfs/super.c 2009-12-05 18:57:00.781303859 +0100 +@@ -35,34 +35,41 @@ + #include + #include + #include +-#include + #include + + #include "squashfs_fs.h" + #include "squashfs_fs_sb.h" + #include "squashfs_fs_i.h" + #include "squashfs.h" ++#include "decompressor.h" + + static struct file_system_type squashfs_fs_type; + static const struct super_operations squashfs_super_ops; + +-static int supported_squashfs_filesystem(short major, short minor, short comp) ++static const struct squashfs_decompressor *supported_squashfs_filesystem(short ++ major, short minor, short id) + { ++ const struct squashfs_decompressor *decompressor; ++ + if (major < SQUASHFS_MAJOR) { + ERROR("Major/Minor mismatch, older Squashfs %d.%d " + "filesystems are unsupported\n", major, minor); +- return -EINVAL; ++ return NULL; + } else if (major > SQUASHFS_MAJOR || minor > SQUASHFS_MINOR) { + ERROR("Major/Minor mismatch, trying to mount newer " + "%d.%d filesystem\n", major, minor); + ERROR("Please update your kernel\n"); +- return -EINVAL; ++ return NULL; + } + +- if (comp != ZLIB_COMPRESSION) +- return -EINVAL; ++ decompressor = squashfs_lookup_decompressor(id); ++ if (!decompressor->supported) { ++ ERROR("Filesystem uses \"%s\" compression. This is not " ++ "supported\n", decompressor->name); ++ return NULL; ++ } + +- return 0; ++ return decompressor; + } + + +@@ -87,13 +94,6 @@ + } + msblk = sb->s_fs_info; + +- msblk->stream.workspace = kmalloc(zlib_inflate_workspacesize(), +- GFP_KERNEL); +- if (msblk->stream.workspace == NULL) { +- ERROR("Failed to allocate zlib workspace\n"); +- goto failure; +- } +- + sblk = kzalloc(sizeof(*sblk), GFP_KERNEL); + if (sblk == NULL) { + ERROR("Failed to allocate squashfs_super_block\n"); +@@ -120,25 +120,25 @@ + goto failed_mount; + } + ++ err = -EINVAL; ++ + /* Check it is a SQUASHFS superblock */ + sb->s_magic = le32_to_cpu(sblk->s_magic); + if (sb->s_magic != SQUASHFS_MAGIC) { + if (!silent) + ERROR("Can't find a SQUASHFS superblock on %s\n", + bdevname(sb->s_bdev, b)); +- err = -EINVAL; + goto failed_mount; + } + +- /* Check the MAJOR & MINOR versions and compression type */ +- err = supported_squashfs_filesystem(le16_to_cpu(sblk->s_major), ++ /* Check the MAJOR & MINOR versions and lookup compression type */ ++ msblk->decompressor = supported_squashfs_filesystem( ++ le16_to_cpu(sblk->s_major), + le16_to_cpu(sblk->s_minor), + le16_to_cpu(sblk->compression)); +- if (err < 0) ++ if (msblk->decompressor == NULL) + goto failed_mount; + +- err = -EINVAL; +- + /* + * Check if there's xattrs in the filesystem. These are not + * supported in this version, so warn that they will be ignored. +@@ -205,6 +205,10 @@ + + err = -ENOMEM; + ++ msblk->stream = squashfs_decompressor_init(msblk); ++ if (msblk->stream == NULL) ++ goto failed_mount; ++ + msblk->block_cache = squashfs_cache_init("metadata", + SQUASHFS_CACHED_BLKS, SQUASHFS_METADATA_SIZE); + if (msblk->block_cache == NULL) +@@ -292,17 +296,16 @@ + squashfs_cache_delete(msblk->block_cache); + squashfs_cache_delete(msblk->fragment_cache); + squashfs_cache_delete(msblk->read_page); ++ squashfs_decompressor_free(msblk, msblk->stream); + kfree(msblk->inode_lookup_table); + kfree(msblk->fragment_index); + kfree(msblk->id_table); +- kfree(msblk->stream.workspace); + kfree(sb->s_fs_info); + sb->s_fs_info = NULL; + kfree(sblk); + return err; + + failure: +- kfree(msblk->stream.workspace); + kfree(sb->s_fs_info); + sb->s_fs_info = NULL; + return -ENOMEM; +@@ -346,10 +349,10 @@ + squashfs_cache_delete(sbi->block_cache); + squashfs_cache_delete(sbi->fragment_cache); + squashfs_cache_delete(sbi->read_page); ++ squashfs_decompressor_free(sbi, sbi->stream); + kfree(sbi->id_table); + kfree(sbi->fragment_index); + kfree(sbi->meta_index); +- kfree(sbi->stream.workspace); + kfree(sb->s_fs_info); + sb->s_fs_info = NULL; + } +diff -Naur linux-2.6.32/fs/squashfs/symlink.c linux-2.6.32.patch/fs/squashfs/symlink.c +--- linux-2.6.32/fs/squashfs/symlink.c 2009-12-03 04:51:21.000000000 +0100 ++++ linux-2.6.32.patch/fs/squashfs/symlink.c 2009-12-05 18:41:38.502302976 +0100 +@@ -36,7 +36,6 @@ + #include + #include + #include +-#include + + #include "squashfs_fs.h" + #include "squashfs_fs_sb.h" +diff -Naur linux-2.6.32/fs/squashfs/zlib_wrapper.c linux-2.6.32.patch/fs/squashfs/zlib_wrapper.c +--- linux-2.6.32/fs/squashfs/zlib_wrapper.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.32.patch/fs/squashfs/zlib_wrapper.c 2009-12-05 18:41:38.502302976 +0100 +@@ -0,0 +1,150 @@ ++/* ++ * Squashfs - a compressed read only filesystem for Linux ++ * ++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 ++ * Phillip Lougher ++ * ++ * 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. ++ * ++ * zlib_wrapper.c ++ */ ++ ++ ++#include ++#include ++#include ++ ++#include "squashfs_fs.h" ++#include "squashfs_fs_sb.h" ++#include "squashfs_fs_i.h" ++#include "squashfs.h" ++#include "decompressor.h" ++ ++static void *zlib_init(struct squashfs_sb_info *dummy) ++{ ++ z_stream *stream = kmalloc(sizeof(z_stream), GFP_KERNEL); ++ if (stream == NULL) ++ goto failed; ++ stream->workspace = kmalloc(zlib_inflate_workspacesize(), ++ GFP_KERNEL); ++ if (stream->workspace == NULL) ++ goto failed; ++ ++ return stream; ++ ++failed: ++ ERROR("Failed to allocate zlib workspace\n"); ++ kfree(stream); ++ return NULL; ++} ++ ++ ++static void zlib_free(void *strm) ++{ ++ z_stream *stream = strm; ++ ++ if (stream) ++ kfree(stream->workspace); ++ kfree(stream); ++} ++ ++ ++static int zlib_uncompress(struct squashfs_sb_info *msblk, void **buffer, ++ struct buffer_head **bh, int b, int offset, int length, int srclength, ++ int pages) ++{ ++ int zlib_err = 0, zlib_init = 0; ++ int avail, bytes, k = 0, page = 0; ++ z_stream *stream = msblk->stream; ++ ++ mutex_lock(&msblk->read_data_mutex); ++ ++ stream->avail_out = 0; ++ stream->avail_in = 0; ++ ++ bytes = length; ++ do { ++ if (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; ++ } ++ ++ stream->next_in = bh[k]->b_data + offset; ++ stream->avail_in = avail; ++ offset = 0; ++ } ++ ++ if (stream->avail_out == 0 && page < pages) { ++ stream->next_out = buffer[page++]; ++ stream->avail_out = PAGE_CACHE_SIZE; ++ } ++ ++ if (!zlib_init) { ++ zlib_err = zlib_inflateInit(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(stream, Z_SYNC_FLUSH); ++ ++ if (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(stream); ++ if (zlib_err != Z_OK) { ++ ERROR("zlib_inflate error, data probably corrupt\n"); ++ goto release_mutex; ++ } ++ ++ mutex_unlock(&msblk->read_data_mutex); ++ return stream->total_out; ++ ++release_mutex: ++ mutex_unlock(&msblk->read_data_mutex); ++ ++ for (; k < b; k++) ++ put_bh(bh[k]); ++ ++ return -EIO; ++} ++ ++const struct squashfs_decompressor squashfs_zlib_comp_ops = { ++ .init = zlib_init, ++ .free = zlib_free, ++ .decompress = zlib_uncompress, ++ .id = ZLIB_COMPRESSION, ++ .name = "zlib", ++ .supported = 1 ++}; ++ +diff -Naur linux-2.6.32/include/linux/decompress/bunzip2_mm.h linux-2.6.32.patch/include/linux/decompress/bunzip2_mm.h +--- linux-2.6.32/include/linux/decompress/bunzip2_mm.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.32.patch/include/linux/decompress/bunzip2_mm.h 2009-12-05 18:41:38.502302976 +0100 +@@ -0,0 +1,12 @@ ++#ifndef BUNZIP2_MM_H ++#define BUNZIP2_MM_H ++ ++#ifdef STATIC ++/* Code active when included from pre-boot environment: */ ++#define INIT ++#else ++/* Compile for initramfs/initrd code only */ ++#define INIT __init ++#endif ++ ++#endif +diff -Naur linux-2.6.32/include/linux/decompress/inflate_mm.h linux-2.6.32.patch/include/linux/decompress/inflate_mm.h +--- linux-2.6.32/include/linux/decompress/inflate_mm.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.32.patch/include/linux/decompress/inflate_mm.h 2009-12-05 18:41:38.503302604 +0100 +@@ -0,0 +1,12 @@ ++#ifndef INFLATE_MM_H ++#define INFLATE_MM_H ++ ++#ifdef STATIC ++/* Code active when included from pre-boot environment: */ ++#define INIT ++#else ++/* Compile for initramfs/initrd code only */ ++#define INIT __init ++#endif ++ ++#endif +diff -Naur linux-2.6.32/include/linux/decompress/mm.h linux-2.6.32.patch/include/linux/decompress/mm.h +--- linux-2.6.32/include/linux/decompress/mm.h 2009-12-03 04:51:21.000000000 +0100 ++++ linux-2.6.32.patch/include/linux/decompress/mm.h 2009-12-05 18:41:38.503302604 +0100 +@@ -53,8 +53,6 @@ + + #define set_error_fn(x) + +-#define INIT +- + #else /* STATIC */ + + /* Code active when compiled standalone for use when loading ramdisk: */ +@@ -77,7 +75,6 @@ + static void(*error)(char *m); + #define set_error_fn(x) error = x; + +-#define INIT __init + #define STATIC + + #include +diff -Naur linux-2.6.32/include/linux/decompress/unlzma_mm.h linux-2.6.32.patch/include/linux/decompress/unlzma_mm.h +--- linux-2.6.32/include/linux/decompress/unlzma_mm.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.32.patch/include/linux/decompress/unlzma_mm.h 2009-12-05 18:41:38.503302604 +0100 +@@ -0,0 +1,20 @@ ++#ifndef UNLZMA_MM_H ++#define UNLZMA_MM_H ++ ++#ifdef STATIC ++ ++/* Code active when included from pre-boot environment: */ ++#define INIT ++ ++#elif defined(CONFIG_DECOMPRESS_LZMA_NEEDED) ++ ++/* Make it available to non initramfs/initrd code */ ++#define INIT ++#include ++#else ++ ++/* Compile for initramfs/initrd code only */ ++#define INIT __init ++#endif ++ ++#endif +diff -Naur linux-2.6.32/lib/decompress_bunzip2.c linux-2.6.32.patch/lib/decompress_bunzip2.c +--- linux-2.6.32/lib/decompress_bunzip2.c 2009-12-03 04:51:21.000000000 +0100 ++++ linux-2.6.32.patch/lib/decompress_bunzip2.c 2009-12-05 18:41:38.504178266 +0100 +@@ -52,6 +52,7 @@ + #include + #endif /* STATIC */ + ++#include + #include + + #ifndef INT_MAX +diff -Naur linux-2.6.32/lib/decompress_inflate.c linux-2.6.32.patch/lib/decompress_inflate.c +--- linux-2.6.32/lib/decompress_inflate.c 2009-12-03 04:51:21.000000000 +0100 ++++ linux-2.6.32.patch/lib/decompress_inflate.c 2009-12-05 18:41:38.504178266 +0100 +@@ -23,6 +23,7 @@ + + #endif /* STATIC */ + ++#include + #include + + #define GZIP_IOBUF_SIZE (16*1024) +diff -Naur linux-2.6.32/lib/decompress_unlzma.c linux-2.6.32.patch/lib/decompress_unlzma.c +--- linux-2.6.32/lib/decompress_unlzma.c 2009-12-03 04:51:21.000000000 +0100 ++++ linux-2.6.32.patch/lib/decompress_unlzma.c 2009-12-05 18:41:38.514296914 +0100 +@@ -36,6 +36,7 @@ + #include + #endif /* STATIC */ + ++#include + #include + + #define MIN(a, b) (((a) < (b)) ? (a) : (b)) +@@ -531,7 +532,7 @@ + + + +-STATIC inline int INIT unlzma(unsigned char *buf, int in_len, ++STATIC int INIT unlzma(unsigned char *buf, int in_len, + int(*fill)(void*, unsigned int), + int(*flush)(void*, unsigned int), + unsigned char *output, +@@ -664,4 +665,6 @@ + { + return unlzma(buf, in_len - 4, fill, flush, output, posp, error_fn); + } ++#elif defined(CONFIG_DECOMPRESS_LZMA_NEEDED) ++EXPORT_SYMBOL(unlzma); + #endif +diff -Naur linux-2.6.32/lib/decompress_unlzma.c.orig linux-2.6.32.patch/lib/decompress_unlzma.c.orig +diff -Naur linux-2.6.32/lib/Kconfig linux-2.6.32.patch/lib/Kconfig +--- linux-2.6.32/lib/Kconfig 2009-12-03 04:51:21.000000000 +0100 ++++ linux-2.6.32.patch/lib/Kconfig 2009-12-05 18:41:38.514296914 +0100 +@@ -117,6 +117,9 @@ + config DECOMPRESS_LZMA + tristate + ++config DECOMPRESS_LZMA_NEEDED ++ boolean ++ + # + # Generic allocator support is selected if needed + # diff --git a/packages/toolchain/sysutils/squashfs/build b/packages/toolchain/sysutils/squashfs/build index 7dc6ccfa9d..59c13fd5a8 100755 --- a/packages/toolchain/sysutils/squashfs/build +++ b/packages/toolchain/sysutils/squashfs/build @@ -2,13 +2,15 @@ . config/options -$SCRIPTS/build toolchain +$SCRIPTS/unpack lzma + +LZMA_DIR=`ls -d $ROOT/$BUILD/lzma*` setup_toolchain host cd $BUILD/$1*/squashfs-tools -make mksquashfs +make mksquashfs LZMA_SUPPORT=1 LZMA_DIR=$LZMA_DIR mkdir -p $ROOT/$TOOLCHAIN/bin cp mksquashfs $ROOT/$TOOLCHAIN/bin diff --git a/packages/toolchain/sysutils/squashfs/install b/packages/toolchain/sysutils/squashfs/install index b0f88efb35..6d96198155 100755 --- a/packages/toolchain/sysutils/squashfs/install +++ b/packages/toolchain/sysutils/squashfs/install @@ -3,4 +3,4 @@ . config/options mkdir -p $ROOT/$TOOLCHAIN/bin -cp -rf $BUILD/$1*/squashfs-tools/mksquashfs $ROOT/$TOOLCHAIN/bin + cp -rf $BUILD/$1*/squashfs-tools/mksquashfs $ROOT/$TOOLCHAIN/bin diff --git a/packages/toolchain/sysutils/squashfs/patches/squashfs_disable_lzma.diff b/packages/toolchain/sysutils/squashfs/patches/squashfs_remove_defaults.diff similarity index 78% rename from packages/toolchain/sysutils/squashfs/patches/squashfs_disable_lzma.diff rename to packages/toolchain/sysutils/squashfs/patches/squashfs_remove_defaults.diff index 8c19ae39e4..ef264ccba4 100644 --- a/packages/toolchain/sysutils/squashfs/patches/squashfs_disable_lzma.diff +++ b/packages/toolchain/sysutils/squashfs/patches/squashfs_remove_defaults.diff @@ -1,12 +1,14 @@ diff -Naur squashfs4.0-20091205/squashfs-tools/Makefile squashfs4.0-20091205.patch/squashfs-tools/Makefile --- squashfs4.0-20091205/squashfs-tools/Makefile 2009-10-14 05:32:57.000000000 +0200 -+++ squashfs4.0-20091205.patch/squashfs-tools/Makefile 2009-12-05 14:45:55.389177120 +0100 -@@ -2,7 +2,7 @@ ++++ squashfs4.0-20091205.patch/squashfs-tools/Makefile 2009-12-05 18:24:48.241450813 +0100 +@@ -2,8 +2,8 @@ # Building LZMA support # Download LZMA sdk (4.65 used in development, other versions may work), # set LZMA_DIR to unpacked source, and uncomment next line -LZMA_SUPPORT = 1 +-LZMA_DIR = ../../../LZMA/lzma465 +#LZMA_SUPPORT = 1 - LZMA_DIR = ../../../LZMA/lzma465 ++#LZMA_DIR = ../../../LZMA/lzma465 #Compression default. + COMP_DEFAULT = gzip diff --git a/projects/ION/linux/linux.i386.conf b/projects/ION/linux/linux.i386.conf index d6bef4e256..8bbac86faa 100644 --- a/projects/ION/linux/linux.i386.conf +++ b/projects/ION/linux/linux.i386.conf @@ -1622,6 +1622,7 @@ CONFIG_HFSPLUS_FS=m # CONFIG_EFS_FS is not set # CONFIG_CRAMFS is not set CONFIG_SQUASHFS=y +CONFIG_SQUASHFS_LZMA=y # CONFIG_SQUASHFS_EMBEDDED is not set CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 # CONFIG_VXFS_FS is not set @@ -1902,6 +1903,8 @@ CONFIG_LIBCRC32C=y CONFIG_AUDIT_GENERIC=y CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m +CONFIG_DECOMPRESS_LZMA=y +CONFIG_DECOMPRESS_LZMA_NEEDED=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y diff --git a/projects/intel/linux/linux.i386.conf b/projects/intel/linux/linux.i386.conf index 6c9c212529..ec95f2954f 100644 --- a/projects/intel/linux/linux.i386.conf +++ b/projects/intel/linux/linux.i386.conf @@ -2005,6 +2005,7 @@ CONFIG_HFSPLUS_FS=m # CONFIG_EFS_FS is not set # CONFIG_CRAMFS is not set CONFIG_SQUASHFS=y +CONFIG_SQUASHFS_LZMA=y # CONFIG_SQUASHFS_EMBEDDED is not set CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 # CONFIG_VXFS_FS is not set @@ -2285,6 +2286,8 @@ CONFIG_LIBCRC32C=y CONFIG_AUDIT_GENERIC=y CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m +CONFIG_DECOMPRESS_LZMA=y +CONFIG_DECOMPRESS_LZMA_NEEDED=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y