1 diff -Nru a/fs/squashfs/decompressor.c b/fs/squashfs/decompressor.c
2 --- a/fs/squashfs/decompressor.c 2010-05-16 23:17:36.000000000 +0200
3 +++ b/fs/squashfs/decompressor.c 2010-05-17 14:57:45.271547099 +0200
6 static const struct squashfs_decompressor *decompressor[] = {
7 &squashfs_zlib_comp_ops,
8 +#ifdef CONFIG_SQUASHFS_LZMA
9 + &squashfs_lzma_comp_ops,
11 &squashfs_lzma_unsupported_comp_ops,
13 #ifdef CONFIG_SQUASHFS_LZO
14 &squashfs_lzo_comp_ops,
16 diff -Nru a/fs/squashfs/Kconfig b/fs/squashfs/Kconfig
17 --- a/fs/squashfs/Kconfig 2010-05-16 23:17:36.000000000 +0200
18 +++ b/fs/squashfs/Kconfig 2010-05-17 15:13:49.807545765 +0200
24 + bool "Include support for LZMA compressed file systems"
26 + select DECOMPRESS_LZMA
27 + select DECOMPRESS_LZMA_NEEDED
29 config SQUASHFS_EMBEDDED
31 bool "Additional option for memory-constrained systems"
32 diff -Nru a/fs/squashfs/lzma_wrapper.c b/fs/squashfs/lzma_wrapper.c
33 --- a/fs/squashfs/lzma_wrapper.c 1970-01-01 01:00:00.000000000 +0100
34 +++ b/fs/squashfs/lzma_wrapper.c 2010-05-17 15:15:12.637552661 +0200
37 + * Squashfs - a compressed read only filesystem for Linux
39 + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
40 + * Phillip Lougher <phillip@lougher.demon.co.uk>
42 + * This program is free software; you can redistribute it and/or
43 + * modify it under the terms of the GNU General Public License
44 + * as published by the Free Software Foundation; either version 2,
45 + * or (at your option) any later version.
47 + * This program is distributed in the hope that it will be useful,
48 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
49 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
50 + * GNU General Public License for more details.
52 + * You should have received a copy of the GNU General Public License
53 + * along with this program; if not, write to the Free Software
54 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
59 +#include <asm/unaligned.h>
60 +#include <linux/slab.h>
61 +#include <linux/buffer_head.h>
62 +#include <linux/mutex.h>
63 +#include <linux/vmalloc.h>
64 +#include <linux/decompress/unlzma.h>
66 +#include "squashfs_fs.h"
67 +#include "squashfs_fs_sb.h"
68 +#include "squashfs_fs_i.h"
69 +#include "squashfs.h"
70 +#include "decompressor.h"
72 +struct squashfs_lzma {
77 +/* decompress_unlzma.c is currently non re-entrant... */
78 +DEFINE_MUTEX(lzma_mutex);
80 +/* decompress_unlzma.c doesn't provide any context in its callbacks... */
81 +static int lzma_error;
83 +static void error(char *m)
85 + ERROR("unlzma error: %s\n", m);
90 +static void *lzma_init(struct squashfs_sb_info *msblk)
92 + struct squashfs_lzma *stream = kzalloc(sizeof(*stream), GFP_KERNEL);
95 + stream->input = vmalloc(msblk->block_size);
96 + if (stream->input == NULL)
98 + stream->output = vmalloc(msblk->block_size);
99 + if (stream->output == NULL)
105 + vfree(stream->input);
107 + ERROR("failed to allocate lzma workspace\n");
113 +static void lzma_free(void *strm)
115 + struct squashfs_lzma *stream = strm;
118 + vfree(stream->input);
119 + vfree(stream->output);
125 +static int lzma_uncompress(struct squashfs_sb_info *msblk, void **buffer,
126 + struct buffer_head **bh, int b, int offset, int length, int srclength,
129 + struct squashfs_lzma *stream = msblk->stream;
130 + void *buff = stream->input;
131 + int avail, i, bytes = length, res;
133 + mutex_lock(&lzma_mutex);
135 + for (i = 0; i < b; i++) {
136 + wait_on_buffer(bh[i]);
137 + if (!buffer_uptodate(bh[i]))
138 + goto block_release;
140 + avail = min(bytes, msblk->devblksize - offset);
141 + memcpy(buff, bh[i]->b_data + offset, avail);
149 + res = unlzma(stream->input, length, NULL, NULL, stream->output, NULL,
151 + if (res || lzma_error)
154 + /* uncompressed size is stored in the LZMA header (5 byte offset) */
155 + res = bytes = get_unaligned_le32(stream->input + 5);
156 + for (i = 0, buff = stream->output; bytes && i < pages; i++) {
157 + avail = min_t(int, bytes, PAGE_CACHE_SIZE);
158 + memcpy(buffer[i], buff, avail);
165 + mutex_unlock(&lzma_mutex);
173 + mutex_unlock(&lzma_mutex);
175 + ERROR("lzma decompression failed, data probably corrupt\n");
179 +const struct squashfs_decompressor squashfs_lzma_comp_ops = {
182 + .decompress = lzma_uncompress,
183 + .id = LZMA_COMPRESSION,
188 diff -Nru a/fs/squashfs/Makefile b/fs/squashfs/Makefile
189 --- a/fs/squashfs/Makefile 2010-05-16 23:17:36.000000000 +0200
190 +++ b/fs/squashfs/Makefile 2010-05-17 14:57:45.270554026 +0200
192 squashfs-y += block.o cache.o dir.o export.o file.o fragment.o id.o inode.o
193 squashfs-y += namei.o super.o symlink.o zlib_wrapper.o decompressor.o
194 squashfs-$(CONFIG_SQUASHFS_XATTR) += xattr.o xattr_id.o
195 +squashfs-$(CONFIG_SQUASHFS_LZMA) += lzma_wrapper.o
196 squashfs-$(CONFIG_SQUASHFS_LZO) += lzo_wrapper.o
197 diff -Nru a/fs/squashfs/squashfs.h b/fs/squashfs/squashfs.h
198 --- a/fs/squashfs/squashfs.h 2010-05-16 23:17:36.000000000 +0200
199 +++ b/fs/squashfs/squashfs.h 2010-05-17 14:57:45.310795600 +0200
202 extern const struct squashfs_decompressor squashfs_zlib_comp_ops;
204 +/* lzma wrapper.c */
205 +extern const struct squashfs_decompressor squashfs_lzma_comp_ops;
208 extern const struct squashfs_decompressor squashfs_lzo_comp_ops;
209 diff -Nru a/include/linux/decompress/bunzip2_mm.h b/include/linux/decompress/bunzip2_mm.h
210 --- a/include/linux/decompress/bunzip2_mm.h 1970-01-01 01:00:00.000000000 +0100
211 +++ b/include/linux/decompress/bunzip2_mm.h 2010-05-17 15:14:15.255545839 +0200
213 +#ifndef BUNZIP2_MM_H
214 +#define BUNZIP2_MM_H
217 +/* Code active when included from pre-boot environment: */
220 +/* Compile for initramfs/initrd code only */
222 +static void(*error)(char *m);
226 diff -Nru a/include/linux/decompress/inflate_mm.h b/include/linux/decompress/inflate_mm.h
227 --- a/include/linux/decompress/inflate_mm.h 1970-01-01 01:00:00.000000000 +0100
228 +++ b/include/linux/decompress/inflate_mm.h 2010-05-17 15:14:15.255545839 +0200
230 +#ifndef INFLATE_MM_H
231 +#define INFLATE_MM_H
234 +/* Code active when included from pre-boot environment: */
237 +/* Compile for initramfs/initrd code only */
239 +static void(*error)(char *m);
243 diff -Nru a/include/linux/decompress/mm.h b/include/linux/decompress/mm.h
244 --- a/include/linux/decompress/mm.h 2010-05-16 23:17:36.000000000 +0200
245 +++ b/include/linux/decompress/mm.h 2010-05-17 15:14:15.259546209 +0200
248 #define set_error_fn(x)
254 /* Code active when compiled standalone for use when loading ramdisk: */
256 #define large_malloc(a) vmalloc(a)
257 #define large_free(a) vfree(a)
259 -static void(*error)(char *m);
260 #define set_error_fn(x) error = x;
265 #include <linux/init.h>
266 diff -Nru a/include/linux/decompress/unlzma_mm.h b/include/linux/decompress/unlzma_mm.h
267 --- a/include/linux/decompress/unlzma_mm.h 1970-01-01 01:00:00.000000000 +0100
268 +++ b/include/linux/decompress/unlzma_mm.h 2010-05-17 15:13:10.802553245 +0200
275 +/* Code active when included from pre-boot environment: */
278 +#elif defined(CONFIG_DECOMPRESS_LZMA_NEEDED)
280 +/* Make it available to non initramfs/initrd code */
282 +#include <linux/module.h>
285 +/* Compile for initramfs/initrd code only */
290 diff -Nru a/include/linux/decompress/unlzo_mm.h b/include/linux/decompress/unlzo_mm.h
291 --- a/include/linux/decompress/unlzo_mm.h 1970-01-01 01:00:00.000000000 +0100
292 +++ b/include/linux/decompress/unlzo_mm.h 2010-05-17 15:14:15.259546209 +0200
298 +/* Code active when included from pre-boot environment: */
301 +/* Compile for initramfs/initrd code only */
303 +static void(*error)(char *m);
307 diff -Nru a/lib/decompress_bunzip2.c b/lib/decompress_bunzip2.c
308 --- a/lib/decompress_bunzip2.c 2010-05-16 23:17:36.000000000 +0200
309 +++ b/lib/decompress_bunzip2.c 2010-05-17 15:13:10.812574144 +0200
311 #include <linux/slab.h>
314 +#include <linux/decompress/bunzip2_mm.h>
315 #include <linux/decompress/mm.h>
318 diff -Nru a/lib/decompress_inflate.c b/lib/decompress_inflate.c
319 --- a/lib/decompress_inflate.c 2010-05-16 23:17:36.000000000 +0200
320 +++ b/lib/decompress_inflate.c 2010-05-17 15:13:10.815573687 +0200
325 +#include <linux/decompress/inflate_mm.h>
326 #include <linux/decompress/mm.h>
328 #define GZIP_IOBUF_SIZE (16*1024)
329 diff -Nru a/lib/decompress_unlzma.c b/lib/decompress_unlzma.c
330 --- a/lib/decompress_unlzma.c 2010-05-16 23:17:36.000000000 +0200
331 +++ b/lib/decompress_unlzma.c 2010-05-17 15:14:15.260574202 +0200
333 #include <linux/slab.h>
336 +#include <linux/decompress/unlzma_mm.h>
337 #include <linux/decompress/mm.h>
339 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
343 /* Called twice: once at startup and once in rc_normalize() */
344 -static void INIT rc_read(struct rc *rc)
345 +static void INIT rc_read(struct rc *rc, void(*error)(char *x))
347 rc->buffer_size = rc->fill((char *)rc->buffer, LZMA_IOBUF_SIZE);
348 if (rc->buffer_size <= 0)
349 @@ -115,13 +116,13 @@
350 rc->range = 0xFFFFFFFF;
353 -static inline void INIT rc_init_code(struct rc *rc)
354 +static inline void INIT rc_init_code(struct rc *rc, void(*error)(char *x))
358 for (i = 0; i < 5; i++) {
359 if (rc->ptr >= rc->buffer_end)
361 + rc_read(rc, error);
362 rc->code = (rc->code << 8) | *rc->ptr++;
365 @@ -134,32 +135,33 @@
368 /* Called twice, but one callsite is in inline'd rc_is_bit_0_helper() */
369 -static void INIT rc_do_normalize(struct rc *rc)
370 +static void INIT rc_do_normalize(struct rc *rc, void(*error)(char *x))
372 if (rc->ptr >= rc->buffer_end)
374 + rc_read(rc, error);
376 rc->code = (rc->code << 8) | *rc->ptr++;
378 -static inline void INIT rc_normalize(struct rc *rc)
379 +static inline void INIT rc_normalize(struct rc *rc, void(*error)(char *x))
381 if (rc->range < (1 << RC_TOP_BITS))
382 - rc_do_normalize(rc);
383 + rc_do_normalize(rc, error);
387 /* Why rc_is_bit_0_helper exists?
388 *Because we want to always expose (rc->code < rc->bound) to optimizer
390 -static inline uint32_t INIT rc_is_bit_0_helper(struct rc *rc, uint16_t *p)
391 +static inline uint32_t INIT rc_is_bit_0_helper(struct rc *rc, uint16_t *p,
392 + void (*error)(char *x))
395 + rc_normalize(rc, error);
396 rc->bound = *p * (rc->range >> RC_MODEL_TOTAL_BITS);
399 -static inline int INIT rc_is_bit_0(struct rc *rc, uint16_t *p)
400 +static inline int INIT rc_is_bit_0(struct rc *rc, uint16_t *p, void(*error)(char *x))
402 - uint32_t t = rc_is_bit_0_helper(rc, p);
403 + uint32_t t = rc_is_bit_0_helper(rc, p, error);
410 /* Called 4 times in unlzma loop */
411 -static int INIT rc_get_bit(struct rc *rc, uint16_t *p, int *symbol)
412 +static int INIT rc_get_bit(struct rc *rc, uint16_t *p, int *symbol, void(*error)(char *x))
414 - if (rc_is_bit_0(rc, p)) {
415 + if (rc_is_bit_0(rc, p, error)) {
416 rc_update_bit_0(rc, p);
423 -static inline int INIT rc_direct_bit(struct rc *rc)
424 +static inline int INIT rc_direct_bit(struct rc *rc , void(*error)(char *x))
427 + rc_normalize(rc, error);
429 if (rc->code >= rc->range) {
430 rc->code -= rc->range;
431 @@ -204,13 +206,14 @@
434 static inline void INIT
435 -rc_bit_tree_decode(struct rc *rc, uint16_t *p, int num_levels, int *symbol)
436 +rc_bit_tree_decode(struct rc *rc, uint16_t *p, int num_levels, int *symbol,
437 + void(*error)(char *x))
443 - rc_get_bit(rc, p + *symbol, symbol);
444 + rc_get_bit(rc, p + *symbol, symbol, error);
445 *symbol -= 1 << num_levels;
449 static inline void INIT process_bit0(struct writer *wr, struct rc *rc,
450 struct cstate *cst, uint16_t *p,
451 int pos_state, uint16_t *prob,
452 - int lc, uint32_t literal_pos_mask) {
453 + int lc, uint32_t literal_pos_mask,
454 + void(*error)(char *x)) {
456 rc_update_bit_0(rc, prob);
457 prob = (p + LZMA_LITERAL +
460 bit = match_byte & 0x100;
461 prob_lit = prob + 0x100 + bit + mi;
462 - if (rc_get_bit(rc, prob_lit, &mi)) {
463 + if (rc_get_bit(rc, prob_lit, &mi, error)) {
470 uint16_t *prob_lit = prob + mi;
471 - rc_get_bit(rc, prob_lit, &mi);
472 + rc_get_bit(rc, prob_lit, &mi, error);
478 static inline void INIT process_bit1(struct writer *wr, struct rc *rc,
479 struct cstate *cst, uint16_t *p,
480 - int pos_state, uint16_t *prob) {
481 + int pos_state, uint16_t *prob,
482 + void(*error)(char *x)) {
488 rc_update_bit_1(rc, prob);
489 prob = p + LZMA_IS_REP + cst->state;
490 - if (rc_is_bit_0(rc, prob)) {
491 + if (rc_is_bit_0(rc, prob, error)) {
492 rc_update_bit_0(rc, prob);
493 cst->rep3 = cst->rep2;
494 cst->rep2 = cst->rep1;
495 @@ -407,13 +412,13 @@
497 rc_update_bit_1(rc, prob);
498 prob = p + LZMA_IS_REP_G0 + cst->state;
499 - if (rc_is_bit_0(rc, prob)) {
500 + if (rc_is_bit_0(rc, prob, error)) {
501 rc_update_bit_0(rc, prob);
502 prob = (p + LZMA_IS_REP_0_LONG
504 LZMA_NUM_POS_BITS_MAX) +
506 - if (rc_is_bit_0(rc, prob)) {
507 + if (rc_is_bit_0(rc, prob, error)) {
508 rc_update_bit_0(rc, prob);
510 cst->state = cst->state < LZMA_NUM_LIT_STATES ?
511 @@ -428,13 +433,13 @@
513 rc_update_bit_1(rc, prob);
514 prob = p + LZMA_IS_REP_G1 + cst->state;
515 - if (rc_is_bit_0(rc, prob)) {
516 + if (rc_is_bit_0(rc, prob, error)) {
517 rc_update_bit_0(rc, prob);
518 distance = cst->rep1;
520 rc_update_bit_1(rc, prob);
521 prob = p + LZMA_IS_REP_G2 + cst->state;
522 - if (rc_is_bit_0(rc, prob)) {
523 + if (rc_is_bit_0(rc, prob, error)) {
524 rc_update_bit_0(rc, prob);
525 distance = cst->rep2;
530 prob_len = prob + LZMA_LEN_CHOICE;
531 - if (rc_is_bit_0(rc, prob_len)) {
532 + if (rc_is_bit_0(rc, prob_len, error)) {
533 rc_update_bit_0(rc, prob_len);
534 prob_len = (prob + LZMA_LEN_LOW
538 rc_update_bit_1(rc, prob_len);
539 prob_len = prob + LZMA_LEN_CHOICE_2;
540 - if (rc_is_bit_0(rc, prob_len)) {
541 + if (rc_is_bit_0(rc, prob_len, error)) {
542 rc_update_bit_0(rc, prob_len);
543 prob_len = (prob + LZMA_LEN_MID
549 - rc_bit_tree_decode(rc, prob_len, num_bits, &len);
550 + rc_bit_tree_decode(rc, prob_len, num_bits, &len, error);
553 if (cst->state < 4) {
555 << LZMA_NUM_POS_SLOT_BITS);
556 rc_bit_tree_decode(rc, prob,
557 LZMA_NUM_POS_SLOT_BITS,
560 if (pos_slot >= LZMA_START_POS_MODEL_INDEX) {
562 num_bits = (pos_slot >> 1) - 1;
564 num_bits -= LZMA_NUM_ALIGN_BITS;
566 cst->rep0 = (cst->rep0 << 1) |
568 + rc_direct_bit(rc, error);
569 prob = p + LZMA_ALIGN;
570 cst->rep0 <<= LZMA_NUM_ALIGN_BITS;
571 num_bits = LZMA_NUM_ALIGN_BITS;
576 - if (rc_get_bit(rc, prob + mi, &mi))
577 + if (rc_get_bit(rc, prob + mi, &mi, error))
581 @@ -531,12 +536,12 @@
585 -STATIC inline int INIT unlzma(unsigned char *buf, int in_len,
586 +STATIC int INIT unlzma(unsigned char *buf, int in_len,
587 int(*fill)(void*, unsigned int),
588 int(*flush)(void*, unsigned int),
589 unsigned char *output,
591 - void(*error_fn)(char *x)
592 + void(*error)(char *x)
595 struct lzma_header header;
597 unsigned char *inbuf;
600 - set_error_fn(error_fn);
607 for (i = 0; i < sizeof(header); i++) {
608 if (rc.ptr >= rc.buffer_end)
610 + rc_read(&rc, error);
611 ((unsigned char *)&header)[i] = *rc.ptr++;
614 @@ -621,17 +624,17 @@
615 for (i = 0; i < num_probs; i++)
616 p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1;
619 + rc_init_code(&rc, error);
621 while (get_pos(&wr) < header.dst_size) {
622 int pos_state = get_pos(&wr) & pos_state_mask;
623 uint16_t *prob = p + LZMA_IS_MATCH +
624 (cst.state << LZMA_NUM_POS_BITS_MAX) + pos_state;
625 - if (rc_is_bit_0(&rc, prob))
626 + if (rc_is_bit_0(&rc, prob, error))
627 process_bit0(&wr, &rc, &cst, p, pos_state, prob,
628 - lc, literal_pos_mask);
629 + lc, literal_pos_mask, error);
631 - process_bit1(&wr, &rc, &cst, p, pos_state, prob);
632 + process_bit1(&wr, &rc, &cst, p, pos_state, prob, error);
640 +#if defined(CONFIG_DECOMPRESS_LZMA_NEEDED) && !defined(PREBOOT)
641 +EXPORT_SYMBOL(unlzma);
645 STATIC int INIT decompress(unsigned char *buf, int in_len,
646 diff -Nru a/lib/decompress_unlzo.c b/lib/decompress_unlzo.c
647 --- a/lib/decompress_unlzo.c 2010-05-16 23:17:36.000000000 +0200
648 +++ b/lib/decompress_unlzo.c 2010-05-17 15:13:10.820554001 +0200
651 #include <linux/types.h>
652 #include <linux/lzo.h>
653 +#include <linux/decompress/unlzo_mm.h>
654 #include <linux/decompress/mm.h>
656 #include <linux/compiler.h>
657 diff -Nru a/lib/Kconfig b/lib/Kconfig
658 --- a/lib/Kconfig 2010-05-16 23:17:36.000000000 +0200
659 +++ b/lib/Kconfig 2010-05-17 15:13:10.809574529 +0200
661 select LZO_DECOMPRESS
664 +config DECOMPRESS_LZMA_NEEDED
668 # Generic allocator support is selected if needed
670 diff -Nru a/lib/Makefile b/lib/Makefile
671 --- a/lib/Makefile 2010-05-16 23:17:36.000000000 +0200
672 +++ b/lib/Makefile 2010-05-17 15:14:36.312796051 +0200
675 lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o
676 lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o
677 -lib-$(CONFIG_DECOMPRESS_LZMA) += decompress_unlzma.o
678 +obj-$(CONFIG_DECOMPRESS_LZMA) += decompress_unlzma.o
679 lib-$(CONFIG_DECOMPRESS_LZO) += decompress_unlzo.o
681 obj-$(CONFIG_TEXTSEARCH) += textsearch.o