wok-current view linux/stuff/linux-squashfs-lzma-2.6.30.6.u @ rev 4738

Remove: file-dev. Replaced by libmagic-dev.
author Eric Joseph-Alexandre <erjo@slitaz.org>
date Thu Jan 07 14:15:11 2010 +0100 (2010-01-07)
parents
children 6359032279ef
line source
1 --- linux-2.6.30.6/fs/squashfs/Kconfig
2 +++ linux-2.6.30.6/fs/squashfs/Kconfig
3 @@ -26,6 +26,12 @@
5 If unsure, say N.
7 +config SQUASHFS_LZMA
8 + bool "Include support for LZMA compressed file systems"
9 + depends on SQUASHFS
10 + select DECOMPRESS_LZMA
11 + select DECOMPRESS_LZMA_NEEDED
12 +
13 config SQUASHFS_EMBEDDED
15 bool "Additional option for memory-constrained systems"
17 --- linux-2.6.30.6/fs/squashfs/Makefile
18 +++ linux-2.6.30.6/fs/squashfs/Makefile
19 @@ -4,4 +4,5 @@
21 obj-$(CONFIG_SQUASHFS) += squashfs.o
22 squashfs-y += block.o cache.o dir.o export.o file.o fragment.o id.o inode.o
23 -squashfs-y += namei.o super.o symlink.o
24 +squashfs-y += namei.o super.o symlink.o zlib_wrapper.o decompressor.o
25 +squashfs-$(CONFIG_SQUASHFS_LZMA) += lzma_wrapper.o
27 --- linux-2.6.30.6/fs/squashfs/block.c
28 +++ linux-2.6.30.6/fs/squashfs/block.c
29 @@ -29,15 +29,14 @@
30 #include <linux/fs.h>
31 #include <linux/vfs.h>
32 #include <linux/slab.h>
33 -#include <linux/mutex.h>
34 #include <linux/string.h>
35 #include <linux/buffer_head.h>
36 -#include <linux/zlib.h>
38 #include "squashfs_fs.h"
39 #include "squashfs_fs_sb.h"
40 #include "squashfs_fs_i.h"
41 #include "squashfs.h"
42 +#include "decompressor.h"
44 /*
45 * Read the metadata block length, this is stored in the first two
46 @@ -153,72 +152,10 @@
47 }
49 if (compressed) {
50 - int zlib_err = 0, zlib_init = 0;
51 -
52 - /*
53 - * Uncompress block.
54 - */
55 -
56 - mutex_lock(&msblk->read_data_mutex);
57 -
58 - msblk->stream.avail_out = 0;
59 - msblk->stream.avail_in = 0;
60 -
61 - bytes = length;
62 - do {
63 - if (msblk->stream.avail_in == 0 && k < b) {
64 - avail = min(bytes, msblk->devblksize - offset);
65 - bytes -= avail;
66 - wait_on_buffer(bh[k]);
67 - if (!buffer_uptodate(bh[k]))
68 - goto release_mutex;
69 -
70 - if (avail == 0) {
71 - offset = 0;
72 - put_bh(bh[k++]);
73 - continue;
74 - }
75 -
76 - msblk->stream.next_in = bh[k]->b_data + offset;
77 - msblk->stream.avail_in = avail;
78 - offset = 0;
79 - }
80 -
81 - if (msblk->stream.avail_out == 0 && page < pages) {
82 - msblk->stream.next_out = buffer[page++];
83 - msblk->stream.avail_out = PAGE_CACHE_SIZE;
84 - }
85 -
86 - if (!zlib_init) {
87 - zlib_err = zlib_inflateInit(&msblk->stream);
88 - if (zlib_err != Z_OK) {
89 - ERROR("zlib_inflateInit returned"
90 - " unexpected result 0x%x,"
91 - " srclength %d\n", zlib_err,
92 - srclength);
93 - goto release_mutex;
94 - }
95 - zlib_init = 1;
96 - }
97 -
98 - zlib_err = zlib_inflate(&msblk->stream, Z_SYNC_FLUSH);
99 -
100 - if (msblk->stream.avail_in == 0 && k < b)
101 - put_bh(bh[k++]);
102 - } while (zlib_err == Z_OK);
103 -
104 - if (zlib_err != Z_STREAM_END) {
105 - ERROR("zlib_inflate error, data probably corrupt\n");
106 - goto release_mutex;
107 - }
108 -
109 - zlib_err = zlib_inflateEnd(&msblk->stream);
110 - if (zlib_err != Z_OK) {
111 - ERROR("zlib_inflate error, data probably corrupt\n");
112 - goto release_mutex;
113 - }
114 - length = msblk->stream.total_out;
115 - mutex_unlock(&msblk->read_data_mutex);
116 + length = squashfs_decompress(msblk, buffer, bh, b, offset,
117 + length, srclength, pages);
118 + if (length < 0)
119 + goto read_failure;
120 } else {
121 /*
122 * Block is uncompressed.
123 @@ -254,9 +191,6 @@
125 kfree(bh);
126 return length;
127 -
128 -release_mutex:
129 - mutex_unlock(&msblk->read_data_mutex);
131 block_release:
132 for (; k < b; k++)
134 --- linux-2.6.30.6/fs/squashfs/cache.c
135 +++ linux-2.6.30.6/fs/squashfs/cache.c
136 @@ -51,7 +51,6 @@
137 #include <linux/sched.h>
138 #include <linux/spinlock.h>
139 #include <linux/wait.h>
140 -#include <linux/zlib.h>
141 #include <linux/pagemap.h>
143 #include "squashfs_fs.h"
145 --- linux-2.6.30.6/fs/squashfs/decompressor.c
146 +++ linux-2.6.30.6/fs/squashfs/decompressor.c
147 @@ -0,0 +1,72 @@
148 +/*
149 + * Squashfs - a compressed read only filesystem for Linux
150 + *
151 + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
152 + * Phillip Lougher <phillip@lougher.demon.co.uk>
153 + *
154 + * This program is free software; you can redistribute it and/or
155 + * modify it under the terms of the GNU General Public License
156 + * as published by the Free Software Foundation; either version 2,
157 + * or (at your option) any later version.
158 + *
159 + * This program is distributed in the hope that it will be useful,
160 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
161 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
162 + * GNU General Public License for more details.
163 + *
164 + * You should have received a copy of the GNU General Public License
165 + * along with this program; if not, write to the Free Software
166 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
167 + *
168 + * decompressor.c
169 + */
170 +
171 +#include <linux/types.h>
172 +#include <linux/mutex.h>
173 +#include <linux/buffer_head.h>
174 +
175 +#include "squashfs_fs.h"
176 +#include "squashfs_fs_sb.h"
177 +#include "squashfs_fs_i.h"
178 +#include "decompressor.h"
179 +#include "squashfs.h"
180 +
181 +/*
182 + * This file (and decompressor.h) implements a decompressor framework for
183 + * Squashfs, allowing multiple decompressors to be easily supported
184 + */
185 +
186 +static const struct squashfs_decompressor squashfs_lzma_unsupported_comp_ops = {
187 + NULL, NULL, NULL, LZMA_COMPRESSION, "lzma", 0
188 +};
189 +
190 +static const struct squashfs_decompressor squashfs_lzo_unsupported_comp_ops = {
191 + NULL, NULL, NULL, LZO_COMPRESSION, "lzo", 0
192 +};
193 +
194 +static const struct squashfs_decompressor squashfs_unknown_comp_ops = {
195 + NULL, NULL, NULL, 0, "unknown", 0
196 +};
197 +
198 +static const struct squashfs_decompressor *decompressor[] = {
199 + &squashfs_zlib_comp_ops,
200 +#ifdef CONFIG_SQUASHFS_LZMA
201 + &squashfs_lzma_comp_ops,
202 +#else
203 + &squashfs_lzma_unsupported_comp_ops,
204 +#endif
205 + &squashfs_lzo_unsupported_comp_ops,
206 + &squashfs_unknown_comp_ops
207 +};
208 +
209 +
210 +const struct squashfs_decompressor *squashfs_lookup_decompressor(int id)
211 +{
212 + int i;
213 +
214 + for (i = 0; decompressor[i]->id; i++)
215 + if (id == decompressor[i]->id)
216 + break;
217 +
218 + return decompressor[i];
219 +}
221 --- linux-2.6.30.6/fs/squashfs/decompressor.h
222 +++ linux-2.6.30.6/fs/squashfs/decompressor.h
223 @@ -0,0 +1,55 @@
224 +#ifndef DECOMPRESSOR_H
225 +#define DECOMPRESSOR_H
226 +/*
227 + * Squashfs - a compressed read only filesystem for Linux
228 + *
229 + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
230 + * Phillip Lougher <phillip@lougher.demon.co.uk>
231 + *
232 + * This program is free software; you can redistribute it and/or
233 + * modify it under the terms of the GNU General Public License
234 + * as published by the Free Software Foundation; either version 2,
235 + * or (at your option) any later version.
236 + *
237 + * This program is distributed in the hope that it will be useful,
238 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
239 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
240 + * GNU General Public License for more details.
241 + *
242 + * You should have received a copy of the GNU General Public License
243 + * along with this program; if not, write to the Free Software
244 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
245 + *
246 + * decompressor.h
247 + */
248 +
249 +struct squashfs_decompressor {
250 + void *(*init)(struct squashfs_sb_info *);
251 + void (*free)(void *);
252 + int (*decompress)(struct squashfs_sb_info *, void **,
253 + struct buffer_head **, int, int, int, int, int);
254 + int id;
255 + char *name;
256 + int supported;
257 +};
258 +
259 +static inline void *squashfs_decompressor_init(struct squashfs_sb_info *msblk)
260 +{
261 + return msblk->decompressor->init(msblk);
262 +}
263 +
264 +static inline void squashfs_decompressor_free(struct squashfs_sb_info *msblk,
265 + void *s)
266 +{
267 + if (msblk->decompressor)
268 + msblk->decompressor->free(s);
269 +}
270 +
271 +static inline int squashfs_decompress(struct squashfs_sb_info *msblk,
272 + void **buffer, struct buffer_head **bh, int b, int offset, int length,
273 + int srclength, int pages)
274 +{
275 + return msblk->decompressor->decompress(msblk, buffer, bh, b, offset,
276 + length, srclength, pages);
277 +}
278 +#endif
280 --- linux-2.6.30.6/fs/squashfs/dir.c
281 +++ linux-2.6.30.6/fs/squashfs/dir.c
282 @@ -30,7 +30,6 @@
283 #include <linux/fs.h>
284 #include <linux/vfs.h>
285 #include <linux/slab.h>
286 -#include <linux/zlib.h>
288 #include "squashfs_fs.h"
289 #include "squashfs_fs_sb.h"
291 --- linux-2.6.30.6/fs/squashfs/export.c
292 +++ linux-2.6.30.6/fs/squashfs/export.c
293 @@ -39,7 +39,6 @@
294 #include <linux/vfs.h>
295 #include <linux/dcache.h>
296 #include <linux/exportfs.h>
297 -#include <linux/zlib.h>
298 #include <linux/slab.h>
300 #include "squashfs_fs.h"
302 --- linux-2.6.30.6/fs/squashfs/file.c
303 +++ linux-2.6.30.6/fs/squashfs/file.c
304 @@ -47,7 +47,6 @@
305 #include <linux/string.h>
306 #include <linux/pagemap.h>
307 #include <linux/mutex.h>
308 -#include <linux/zlib.h>
310 #include "squashfs_fs.h"
311 #include "squashfs_fs_sb.h"
313 --- linux-2.6.30.6/fs/squashfs/fragment.c
314 +++ linux-2.6.30.6/fs/squashfs/fragment.c
315 @@ -36,7 +36,6 @@
316 #include <linux/fs.h>
317 #include <linux/vfs.h>
318 #include <linux/slab.h>
319 -#include <linux/zlib.h>
321 #include "squashfs_fs.h"
322 #include "squashfs_fs_sb.h"
324 --- linux-2.6.30.6/fs/squashfs/id.c
325 +++ linux-2.6.30.6/fs/squashfs/id.c
326 @@ -34,7 +34,6 @@
327 #include <linux/fs.h>
328 #include <linux/vfs.h>
329 #include <linux/slab.h>
330 -#include <linux/zlib.h>
332 #include "squashfs_fs.h"
333 #include "squashfs_fs_sb.h"
335 --- linux-2.6.30.6/fs/squashfs/inode.c
336 +++ linux-2.6.30.6/fs/squashfs/inode.c
337 @@ -40,7 +40,6 @@
339 #include <linux/fs.h>
340 #include <linux/vfs.h>
341 -#include <linux/zlib.h>
343 #include "squashfs_fs.h"
344 #include "squashfs_fs_sb.h"
346 --- linux-2.6.30.6/fs/squashfs/lzma_wrapper.c
347 +++ linux-2.6.30.6/fs/squashfs/lzma_wrapper.c
348 @@ -0,0 +1,151 @@
349 +/*
350 + * Squashfs - a compressed read only filesystem for Linux
351 + *
352 + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
353 + * Phillip Lougher <phillip@lougher.demon.co.uk>
354 + *
355 + * This program is free software; you can redistribute it and/or
356 + * modify it under the terms of the GNU General Public License
357 + * as published by the Free Software Foundation; either version 2,
358 + * or (at your option) any later version.
359 + *
360 + * This program is distributed in the hope that it will be useful,
361 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
362 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
363 + * GNU General Public License for more details.
364 + *
365 + * You should have received a copy of the GNU General Public License
366 + * along with this program; if not, write to the Free Software
367 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
368 + *
369 + * lzma_wrapper.c
370 + */
371 +
372 +#include <asm/unaligned.h>
373 +#include <linux/buffer_head.h>
374 +#include <linux/mutex.h>
375 +#include <linux/vmalloc.h>
376 +#include <linux/decompress/unlzma.h>
377 +
378 +#include "squashfs_fs.h"
379 +#include "squashfs_fs_sb.h"
380 +#include "squashfs_fs_i.h"
381 +#include "squashfs.h"
382 +#include "decompressor.h"
383 +
384 +struct squashfs_lzma {
385 + void *input;
386 + void *output;
387 +};
388 +
389 +/* decompress_unlzma.c is currently non re-entrant... */
390 +DEFINE_MUTEX(lzma_mutex);
391 +
392 +/* decompress_unlzma.c doesn't provide any context in its callbacks... */
393 +static int lzma_error;
394 +
395 +static void error(char *m)
396 +{
397 + ERROR("unlzma error: %s\n", m);
398 + lzma_error = 1;
399 +}
400 +
401 +
402 +static void *lzma_init(struct squashfs_sb_info *msblk)
403 +{
404 + struct squashfs_lzma *stream = kzalloc(sizeof(*stream), GFP_KERNEL);
405 + if (stream == NULL)
406 + goto failed;
407 + stream->input = vmalloc(msblk->block_size);
408 + if (stream->input == NULL)
409 + goto failed;
410 + stream->output = vmalloc(msblk->block_size);
411 + if (stream->output == NULL)
412 + goto failed2;
413 +
414 + return stream;
415 +
416 +failed2:
417 + vfree(stream->input);
418 +failed:
419 + ERROR("failed to allocate lzma workspace\n");
420 + kfree(stream);
421 + return NULL;
422 +}
423 +
424 +
425 +static void lzma_free(void *strm)
426 +{
427 + struct squashfs_lzma *stream = strm;
428 +
429 + if (stream) {
430 + vfree(stream->input);
431 + vfree(stream->output);
432 + }
433 + kfree(stream);
434 +}
435 +
436 +
437 +static int lzma_uncompress(struct squashfs_sb_info *msblk, void **buffer,
438 + struct buffer_head **bh, int b, int offset, int length, int srclength,
439 + int pages)
440 +{
441 + struct squashfs_lzma *stream = msblk->stream;
442 + void *buff = stream->input;
443 + int avail, i, bytes = length, res;
444 +
445 + mutex_lock(&lzma_mutex);
446 +
447 + for (i = 0; i < b; i++) {
448 + wait_on_buffer(bh[i]);
449 + if (!buffer_uptodate(bh[i]))
450 + goto block_release;
451 +
452 + avail = min(bytes, msblk->devblksize - offset);
453 + memcpy(buff, bh[i]->b_data + offset, avail);
454 + buff += avail;
455 + bytes -= avail;
456 + offset = 0;
457 + put_bh(bh[i]);
458 + }
459 +
460 + lzma_error = 0;
461 + res = unlzma(stream->input, length, NULL, NULL, stream->output, NULL,
462 + error);
463 + if (res || lzma_error)
464 + goto failed;
465 +
466 + /* uncompressed size is stored in the LZMA header (5 byte offset) */
467 + res = bytes = get_unaligned_le32(stream->input + 5);
468 + for (i = 0, buff = stream->output; bytes && i < pages; i++) {
469 + avail = min_t(int, bytes, PAGE_CACHE_SIZE);
470 + memcpy(buffer[i], buff, avail);
471 + buff += avail;
472 + bytes -= avail;
473 + }
474 + if (bytes)
475 + goto failed;
476 +
477 + mutex_unlock(&lzma_mutex);
478 + return res;
479 +
480 +block_release:
481 + for (; i < b; i++)
482 + put_bh(bh[i]);
483 +
484 +failed:
485 + mutex_unlock(&lzma_mutex);
486 +
487 + ERROR("lzma decompression failed, data probably corrupt\n");
488 + return -EIO;
489 +}
490 +
491 +const struct squashfs_decompressor squashfs_lzma_comp_ops = {
492 + .init = lzma_init,
493 + .free = lzma_free,
494 + .decompress = lzma_uncompress,
495 + .id = LZMA_COMPRESSION,
496 + .name = "lzma",
497 + .supported = 1
498 +};
499 +
501 --- linux-2.6.30.6/fs/squashfs/namei.c
502 +++ linux-2.6.30.6/fs/squashfs/namei.c
503 @@ -57,7 +57,6 @@
504 #include <linux/slab.h>
505 #include <linux/string.h>
506 #include <linux/dcache.h>
507 -#include <linux/zlib.h>
509 #include "squashfs_fs.h"
510 #include "squashfs_fs_sb.h"
512 --- linux-2.6.30.6/fs/squashfs/squashfs.h
513 +++ linux-2.6.30.6/fs/squashfs/squashfs.h
514 @@ -51,6 +51,9 @@
515 u64, int);
516 extern int squashfs_read_table(struct super_block *, void *, u64, int);
518 +/* decompressor.c */
519 +extern const struct squashfs_decompressor *squashfs_lookup_decompressor(int);
520 +
521 /* export.c */
522 extern __le64 *squashfs_read_inode_lookup_table(struct super_block *, u64,
523 unsigned int);
524 @@ -71,7 +74,7 @@
525 extern int squashfs_read_inode(struct inode *, long long);
527 /*
528 - * Inodes and files operations
529 + * Inodes, files and decompressor operations
530 */
532 /* dir.c */
533 @@ -88,3 +91,9 @@
535 /* symlink.c */
536 extern const struct address_space_operations squashfs_symlink_aops;
537 +
538 +/* zlib_wrapper.c */
539 +extern const struct squashfs_decompressor squashfs_zlib_comp_ops;
540 +
541 +/* lzma wrapper.c */
542 +extern const struct squashfs_decompressor squashfs_lzma_comp_ops;
544 --- linux-2.6.30.6/fs/squashfs/squashfs_fs.h
545 +++ linux-2.6.30.6/fs/squashfs/squashfs_fs.h
546 @@ -211,7 +211,9 @@
547 /*
548 * definitions for structures on disk
549 */
550 -#define ZLIB_COMPRESSION 1
551 +#define ZLIB_COMPRESSION 1
552 +#define LZMA_COMPRESSION 2
553 +#define LZO_COMPRESSION 3
555 struct squashfs_super_block {
556 __le32 s_magic;
558 --- linux-2.6.30.6/fs/squashfs/squashfs_fs_sb.h
559 +++ linux-2.6.30.6/fs/squashfs/squashfs_fs_sb.h
560 @@ -52,25 +52,26 @@
561 };
563 struct squashfs_sb_info {
564 - int devblksize;
565 - int devblksize_log2;
566 - struct squashfs_cache *block_cache;
567 - struct squashfs_cache *fragment_cache;
568 - struct squashfs_cache *read_page;
569 - int next_meta_index;
570 - __le64 *id_table;
571 - __le64 *fragment_index;
572 - unsigned int *fragment_index_2;
573 - struct mutex read_data_mutex;
574 - struct mutex meta_index_mutex;
575 - struct meta_index *meta_index;
576 - z_stream stream;
577 - __le64 *inode_lookup_table;
578 - u64 inode_table;
579 - u64 directory_table;
580 - unsigned int block_size;
581 - unsigned short block_log;
582 - long long bytes_used;
583 - unsigned int inodes;
584 + const struct squashfs_decompressor *decompressor;
585 + int devblksize;
586 + int devblksize_log2;
587 + struct squashfs_cache *block_cache;
588 + struct squashfs_cache *fragment_cache;
589 + struct squashfs_cache *read_page;
590 + int next_meta_index;
591 + __le64 *id_table;
592 + __le64 *fragment_index;
593 + unsigned int *fragment_index_2;
594 + struct mutex read_data_mutex;
595 + struct mutex meta_index_mutex;
596 + struct meta_index *meta_index;
597 + void *stream;
598 + __le64 *inode_lookup_table;
599 + u64 inode_table;
600 + u64 directory_table;
601 + unsigned int block_size;
602 + unsigned short block_log;
603 + long long bytes_used;
604 + unsigned int inodes;
605 };
606 #endif
608 --- linux-2.6.30.6/fs/squashfs/super.c
609 +++ linux-2.6.30.6/fs/squashfs/super.c
610 @@ -30,38 +30,46 @@
611 #include <linux/fs.h>
612 #include <linux/vfs.h>
613 #include <linux/slab.h>
614 +#include <linux/smp_lock.h>
615 #include <linux/mutex.h>
616 #include <linux/pagemap.h>
617 #include <linux/init.h>
618 #include <linux/module.h>
619 -#include <linux/zlib.h>
620 #include <linux/magic.h>
622 #include "squashfs_fs.h"
623 #include "squashfs_fs_sb.h"
624 #include "squashfs_fs_i.h"
625 #include "squashfs.h"
626 +#include "decompressor.h"
628 static struct file_system_type squashfs_fs_type;
629 -static struct super_operations squashfs_super_ops;
630 +static const struct super_operations squashfs_super_ops;
632 -static int supported_squashfs_filesystem(short major, short minor, short comp)
633 +static const struct squashfs_decompressor *supported_squashfs_filesystem(short
634 + major, short minor, short id)
635 {
636 + const struct squashfs_decompressor *decompressor;
637 +
638 if (major < SQUASHFS_MAJOR) {
639 ERROR("Major/Minor mismatch, older Squashfs %d.%d "
640 "filesystems are unsupported\n", major, minor);
641 - return -EINVAL;
642 + return NULL;
643 } else if (major > SQUASHFS_MAJOR || minor > SQUASHFS_MINOR) {
644 ERROR("Major/Minor mismatch, trying to mount newer "
645 "%d.%d filesystem\n", major, minor);
646 ERROR("Please update your kernel\n");
647 - return -EINVAL;
648 + return NULL;
649 }
651 - if (comp != ZLIB_COMPRESSION)
652 - return -EINVAL;
653 + decompressor = squashfs_lookup_decompressor(id);
654 + if (!decompressor->supported) {
655 + ERROR("Filesystem uses \"%s\" compression. This is not "
656 + "supported\n", decompressor->name);
657 + return NULL;
658 + }
660 - return 0;
661 + return decompressor;
662 }
665 @@ -86,13 +94,6 @@
666 }
667 msblk = sb->s_fs_info;
669 - msblk->stream.workspace = kmalloc(zlib_inflate_workspacesize(),
670 - GFP_KERNEL);
671 - if (msblk->stream.workspace == NULL) {
672 - ERROR("Failed to allocate zlib workspace\n");
673 - goto failure;
674 - }
675 -
676 sblk = kzalloc(sizeof(*sblk), GFP_KERNEL);
677 if (sblk == NULL) {
678 ERROR("Failed to allocate squashfs_super_block\n");
679 @@ -119,25 +120,25 @@
680 goto failed_mount;
681 }
683 + err = -EINVAL;
684 +
685 /* Check it is a SQUASHFS superblock */
686 sb->s_magic = le32_to_cpu(sblk->s_magic);
687 if (sb->s_magic != SQUASHFS_MAGIC) {
688 if (!silent)
689 ERROR("Can't find a SQUASHFS superblock on %s\n",
690 bdevname(sb->s_bdev, b));
691 - err = -EINVAL;
692 goto failed_mount;
693 }
695 - /* Check the MAJOR & MINOR versions and compression type */
696 - err = supported_squashfs_filesystem(le16_to_cpu(sblk->s_major),
697 + /* Check the MAJOR & MINOR versions and lookup compression type */
698 + msblk->decompressor = supported_squashfs_filesystem(
699 + le16_to_cpu(sblk->s_major),
700 le16_to_cpu(sblk->s_minor),
701 le16_to_cpu(sblk->compression));
702 - if (err < 0)
703 + if (msblk->decompressor == NULL)
704 goto failed_mount;
706 - err = -EINVAL;
707 -
708 /*
709 * Check if there's xattrs in the filesystem. These are not
710 * supported in this version, so warn that they will be ignored.
711 @@ -204,6 +205,10 @@
713 err = -ENOMEM;
715 + msblk->stream = squashfs_decompressor_init(msblk);
716 + if (msblk->stream == NULL)
717 + goto failed_mount;
718 +
719 msblk->block_cache = squashfs_cache_init("metadata",
720 SQUASHFS_CACHED_BLKS, SQUASHFS_METADATA_SIZE);
721 if (msblk->block_cache == NULL)
722 @@ -291,17 +296,16 @@
723 squashfs_cache_delete(msblk->block_cache);
724 squashfs_cache_delete(msblk->fragment_cache);
725 squashfs_cache_delete(msblk->read_page);
726 + squashfs_decompressor_free(msblk, msblk->stream);
727 kfree(msblk->inode_lookup_table);
728 kfree(msblk->fragment_index);
729 kfree(msblk->id_table);
730 - kfree(msblk->stream.workspace);
731 kfree(sb->s_fs_info);
732 sb->s_fs_info = NULL;
733 kfree(sblk);
734 return err;
736 failure:
737 - kfree(msblk->stream.workspace);
738 kfree(sb->s_fs_info);
739 sb->s_fs_info = NULL;
740 return -ENOMEM;
741 @@ -338,18 +342,22 @@
743 static void squashfs_put_super(struct super_block *sb)
744 {
745 + lock_kernel();
746 +
747 if (sb->s_fs_info) {
748 struct squashfs_sb_info *sbi = sb->s_fs_info;
749 squashfs_cache_delete(sbi->block_cache);
750 squashfs_cache_delete(sbi->fragment_cache);
751 squashfs_cache_delete(sbi->read_page);
752 + squashfs_decompressor_free(sbi, sbi->stream);
753 kfree(sbi->id_table);
754 kfree(sbi->fragment_index);
755 kfree(sbi->meta_index);
756 - kfree(sbi->stream.workspace);
757 kfree(sb->s_fs_info);
758 sb->s_fs_info = NULL;
759 }
760 +
761 + unlock_kernel();
762 }
765 @@ -439,7 +447,7 @@
766 .fs_flags = FS_REQUIRES_DEV
767 };
769 -static struct super_operations squashfs_super_ops = {
770 +static const struct super_operations squashfs_super_ops = {
771 .alloc_inode = squashfs_alloc_inode,
772 .destroy_inode = squashfs_destroy_inode,
773 .statfs = squashfs_statfs,
775 --- linux-2.6.30.6/fs/squashfs/symlink.c
776 +++ linux-2.6.30.6/fs/squashfs/symlink.c
777 @@ -36,7 +36,6 @@
778 #include <linux/slab.h>
779 #include <linux/string.h>
780 #include <linux/pagemap.h>
781 -#include <linux/zlib.h>
783 #include "squashfs_fs.h"
784 #include "squashfs_fs_sb.h"
786 --- linux-2.6.30.6/fs/squashfs/zlib_wrapper.c
787 +++ linux-2.6.30.6/fs/squashfs/zlib_wrapper.c
788 @@ -0,0 +1,150 @@
789 +/*
790 + * Squashfs - a compressed read only filesystem for Linux
791 + *
792 + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
793 + * Phillip Lougher <phillip@lougher.demon.co.uk>
794 + *
795 + * This program is free software; you can redistribute it and/or
796 + * modify it under the terms of the GNU General Public License
797 + * as published by the Free Software Foundation; either version 2,
798 + * or (at your option) any later version.
799 + *
800 + * This program is distributed in the hope that it will be useful,
801 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
802 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
803 + * GNU General Public License for more details.
804 + *
805 + * You should have received a copy of the GNU General Public License
806 + * along with this program; if not, write to the Free Software
807 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
808 + *
809 + * zlib_wrapper.c
810 + */
811 +
812 +
813 +#include <linux/mutex.h>
814 +#include <linux/buffer_head.h>
815 +#include <linux/zlib.h>
816 +
817 +#include "squashfs_fs.h"
818 +#include "squashfs_fs_sb.h"
819 +#include "squashfs_fs_i.h"
820 +#include "squashfs.h"
821 +#include "decompressor.h"
822 +
823 +static void *zlib_init(struct squashfs_sb_info *dummy)
824 +{
825 + z_stream *stream = kmalloc(sizeof(z_stream), GFP_KERNEL);
826 + if (stream == NULL)
827 + goto failed;
828 + stream->workspace = kmalloc(zlib_inflate_workspacesize(),
829 + GFP_KERNEL);
830 + if (stream->workspace == NULL)
831 + goto failed;
832 +
833 + return stream;
834 +
835 +failed:
836 + ERROR("Failed to allocate zlib workspace\n");
837 + kfree(stream);
838 + return NULL;
839 +}
840 +
841 +
842 +static void zlib_free(void *strm)
843 +{
844 + z_stream *stream = strm;
845 +
846 + if (stream)
847 + kfree(stream->workspace);
848 + kfree(stream);
849 +}
850 +
851 +
852 +static int zlib_uncompress(struct squashfs_sb_info *msblk, void **buffer,
853 + struct buffer_head **bh, int b, int offset, int length, int srclength,
854 + int pages)
855 +{
856 + int zlib_err = 0, zlib_init = 0;
857 + int avail, bytes, k = 0, page = 0;
858 + z_stream *stream = msblk->stream;
859 +
860 + mutex_lock(&msblk->read_data_mutex);
861 +
862 + stream->avail_out = 0;
863 + stream->avail_in = 0;
864 +
865 + bytes = length;
866 + do {
867 + if (stream->avail_in == 0 && k < b) {
868 + avail = min(bytes, msblk->devblksize - offset);
869 + bytes -= avail;
870 + wait_on_buffer(bh[k]);
871 + if (!buffer_uptodate(bh[k]))
872 + goto release_mutex;
873 +
874 + if (avail == 0) {
875 + offset = 0;
876 + put_bh(bh[k++]);
877 + continue;
878 + }
879 +
880 + stream->next_in = bh[k]->b_data + offset;
881 + stream->avail_in = avail;
882 + offset = 0;
883 + }
884 +
885 + if (stream->avail_out == 0 && page < pages) {
886 + stream->next_out = buffer[page++];
887 + stream->avail_out = PAGE_CACHE_SIZE;
888 + }
889 +
890 + if (!zlib_init) {
891 + zlib_err = zlib_inflateInit(stream);
892 + if (zlib_err != Z_OK) {
893 + ERROR("zlib_inflateInit returned unexpected "
894 + "result 0x%x, srclength %d\n",
895 + zlib_err, srclength);
896 + goto release_mutex;
897 + }
898 + zlib_init = 1;
899 + }
900 +
901 + zlib_err = zlib_inflate(stream, Z_SYNC_FLUSH);
902 +
903 + if (stream->avail_in == 0 && k < b)
904 + put_bh(bh[k++]);
905 + } while (zlib_err == Z_OK);
906 +
907 + if (zlib_err != Z_STREAM_END) {
908 + ERROR("zlib_inflate error, data probably corrupt\n");
909 + goto release_mutex;
910 + }
911 +
912 + zlib_err = zlib_inflateEnd(stream);
913 + if (zlib_err != Z_OK) {
914 + ERROR("zlib_inflate error, data probably corrupt\n");
915 + goto release_mutex;
916 + }
917 +
918 + mutex_unlock(&msblk->read_data_mutex);
919 + return stream->total_out;
920 +
921 +release_mutex:
922 + mutex_unlock(&msblk->read_data_mutex);
923 +
924 + for (; k < b; k++)
925 + put_bh(bh[k]);
926 +
927 + return -EIO;
928 +}
929 +
930 +const struct squashfs_decompressor squashfs_zlib_comp_ops = {
931 + .init = zlib_init,
932 + .free = zlib_free,
933 + .decompress = zlib_uncompress,
934 + .id = ZLIB_COMPRESSION,
935 + .name = "zlib",
936 + .supported = 1
937 +};
938 +
940 --- linux-2.6.30.6/include/linux/decompress/bunzip2_mm.h
941 +++ linux-2.6.30.6/include/linux/decompress/bunzip2_mm.h
942 @@ -0,0 +1,13 @@
943 +#ifndef BUNZIP2_MM_H
944 +#define BUNZIP2_MM_H
945 +
946 +#ifdef STATIC
947 +/* Code active when included from pre-boot environment: */
948 +#define INIT
949 +#else
950 +/* Compile for initramfs/initrd code only */
951 +#define INIT __init
952 +static void(*error)(char *m);
953 +#endif
954 +
955 +#endif
957 --- linux-2.6.30.6/include/linux/decompress/inflate_mm.h
958 +++ linux-2.6.30.6/include/linux/decompress/inflate_mm.h
959 @@ -0,0 +1,13 @@
960 +#ifndef INFLATE_MM_H
961 +#define INFLATE_MM_H
962 +
963 +#ifdef STATIC
964 +/* Code active when included from pre-boot environment: */
965 +#define INIT
966 +#else
967 +/* Compile for initramfs/initrd code only */
968 +#define INIT __init
969 +static void(*error)(char *m);
970 +#endif
971 +
972 +#endif
974 --- linux-2.6.30.6/include/linux/decompress/mm.h
975 +++ linux-2.6.30.6/include/linux/decompress/mm.h
976 @@ -25,7 +25,7 @@
977 void *p;
979 if (size < 0)
980 - error("Malloc error");
981 + return NULL;
982 if (!malloc_ptr)
983 malloc_ptr = free_mem_ptr;
985 @@ -35,7 +35,7 @@
986 malloc_ptr += size;
988 if (free_mem_end_ptr && malloc_ptr >= free_mem_end_ptr)
989 - error("Out of memory");
990 + return NULL;
992 malloc_count++;
993 return p;
994 @@ -53,8 +53,6 @@
996 #define set_error_fn(x)
998 -#define INIT
999 -
1000 #else /* STATIC */
1002 /* Code active when compiled standalone for use when loading ramdisk: */
1003 @@ -74,10 +72,8 @@
1004 #define large_malloc(a) vmalloc(a)
1005 #define large_free(a) vfree(a)
1007 -static void(*error)(char *m);
1008 #define set_error_fn(x) error = x;
1010 -#define INIT __init
1011 #define STATIC
1013 #include <linux/init.h>
1015 --- linux-2.6.30.6/include/linux/decompress/unlzma_mm.h
1016 +++ linux-2.6.30.6/include/linux/decompress/unlzma_mm.h
1017 @@ -0,0 +1,20 @@
1018 +#ifndef UNLZMA_MM_H
1019 +#define UNLZMA_MM_H
1021 +#ifdef STATIC
1023 +/* Code active when included from pre-boot environment: */
1024 +#define INIT
1026 +#elif defined(CONFIG_DECOMPRESS_LZMA_NEEDED)
1028 +/* Make it available to non initramfs/initrd code */
1029 +#define INIT
1030 +#include <linux/module.h>
1031 +#else
1033 +/* Compile for initramfs/initrd code only */
1034 +#define INIT __init
1035 +#endif
1037 +#endif
1039 --- linux-2.6.30.6/lib/Kconfig
1040 +++ linux-2.6.30.6/lib/Kconfig
1041 @@ -10,6 +10,9 @@
1042 config BITREVERSE
1043 tristate
1045 +config RATIONAL
1046 + boolean
1048 config GENERIC_FIND_FIRST_BIT
1049 bool
1051 @@ -114,6 +117,9 @@
1052 config DECOMPRESS_LZMA
1053 tristate
1055 +config DECOMPRESS_LZMA_NEEDED
1056 + boolean
1059 # Generic allocator support is selected if needed
1061 @@ -153,6 +159,9 @@
1062 config TEXTSEARCH_FSM
1063 tristate
1065 +config BTREE
1066 + boolean
1068 config HAS_IOMEM
1069 boolean
1070 depends on !NO_IOMEM
1071 @@ -190,5 +199,35 @@
1073 config NLATTR
1074 bool
1076 +#
1077 +# Generic 64-bit atomic support is selected if needed
1078 +#
1079 +config GENERIC_ATOMIC64
1080 + bool
1082 +config LRU_CACHE
1083 + tristate
1085 +config SHM_SIGNAL
1086 + tristate "SHM Signal - Generic shared-memory signaling mechanism"
1087 + default n
1088 + help
1089 + Provides a shared-memory based signaling mechanism to indicate
1090 + memory-dirty notifications between two end-points.
1092 + If unsure, say N
1094 +config IOQ
1095 + tristate "IO-Queue library - Generic shared-memory queue"
1096 + select SHM_SIGNAL
1097 + default n
1098 + help
1099 + IOQ is a generic shared-memory-queue mechanism that happens to be
1100 + friendly to virtualization boundaries. It can be used in a variety
1101 + of ways, though its intended purpose is to become a low-level
1102 + communication path for paravirtualized drivers.
1104 + If unsure, say N
1106 endmenu
1108 --- linux-2.6.30.6/lib/decompress_bunzip2.c
1109 +++ linux-2.6.30.6/lib/decompress_bunzip2.c
1110 @@ -45,12 +45,15 @@
1111 */
1114 -#ifndef STATIC
1115 +#ifdef STATIC
1116 +#define PREBOOT
1117 +#else
1118 #include <linux/decompress/bunzip2.h>
1119 -#endif /* !STATIC */
1120 +#include <linux/slab.h>
1121 +#endif /* STATIC */
1123 +#include <linux/decompress/bunzip2_mm.h>
1124 #include <linux/decompress/mm.h>
1125 -#include <linux/slab.h>
1127 #ifndef INT_MAX
1128 #define INT_MAX 0x7fffffff
1129 @@ -297,7 +300,7 @@
1130 again when using them (during symbol decoding).*/
1131 base = hufGroup->base-1;
1132 limit = hufGroup->limit-1;
1133 - /* Calculate permute[]. Concurently, initialize
1134 + /* Calculate permute[]. Concurrently, initialize
1135 * temp[] and limit[]. */
1136 pp = 0;
1137 for (i = minLen; i <= maxLen; i++) {
1138 @@ -635,6 +638,8 @@
1140 /* Allocate bunzip_data. Most fields initialize to zero. */
1141 bd = *bdp = malloc(i);
1142 + if (!bd)
1143 + return RETVAL_OUT_OF_MEMORY;
1144 memset(bd, 0, sizeof(struct bunzip_data));
1145 /* Setup input buffer */
1146 bd->inbuf = inbuf;
1147 @@ -662,6 +667,8 @@
1148 bd->dbufSize = 100000*(i-BZh0);
1150 bd->dbuf = large_malloc(bd->dbufSize * sizeof(int));
1151 + if (!bd->dbuf)
1152 + return RETVAL_OUT_OF_MEMORY;
1153 return RETVAL_OK;
1156 @@ -681,12 +688,10 @@
1157 set_error_fn(error_fn);
1158 if (flush)
1159 outbuf = malloc(BZIP2_IOBUF_SIZE);
1160 - else
1161 - len -= 4; /* Uncompressed size hack active in pre-boot
1162 - environment */
1164 if (!outbuf) {
1165 error("Could not allocate output bufer");
1166 - return -1;
1167 + return RETVAL_OUT_OF_MEMORY;
1169 if (buf)
1170 inbuf = buf;
1171 @@ -694,6 +699,7 @@
1172 inbuf = malloc(BZIP2_IOBUF_SIZE);
1173 if (!inbuf) {
1174 error("Could not allocate input bufer");
1175 + i = RETVAL_OUT_OF_MEMORY;
1176 goto exit_0;
1178 i = start_bunzip(&bd, inbuf, len, fill);
1179 @@ -720,11 +726,14 @@
1180 } else if (i == RETVAL_UNEXPECTED_OUTPUT_EOF) {
1181 error("Compressed file ends unexpectedly");
1183 + if (!bd)
1184 + goto exit_1;
1185 if (bd->dbuf)
1186 large_free(bd->dbuf);
1187 if (pos)
1188 *pos = bd->inbufPos;
1189 free(bd);
1190 +exit_1:
1191 if (!buf)
1192 free(inbuf);
1193 exit_0:
1194 @@ -733,4 +742,14 @@
1195 return i;
1198 -#define decompress bunzip2
1199 +#ifdef PREBOOT
1200 +STATIC int INIT decompress(unsigned char *buf, int len,
1201 + int(*fill)(void*, unsigned int),
1202 + int(*flush)(void*, unsigned int),
1203 + unsigned char *outbuf,
1204 + int *pos,
1205 + void(*error_fn)(char *x))
1206 +{
1207 + return bunzip2(buf, len - 4, fill, flush, outbuf, pos, error_fn);
1208 +}
1209 +#endif
1211 --- linux-2.6.30.6/lib/decompress_inflate.c
1212 +++ linux-2.6.30.6/lib/decompress_inflate.c
1213 @@ -19,14 +19,20 @@
1214 #include "zlib_inflate/inflate.h"
1216 #include "zlib_inflate/infutil.h"
1217 +#include <linux/slab.h>
1219 #endif /* STATIC */
1221 +#include <linux/decompress/inflate_mm.h>
1222 #include <linux/decompress/mm.h>
1223 -#include <linux/slab.h>
1225 -#define INBUF_LEN (16*1024)
1226 +#define GZIP_IOBUF_SIZE (16*1024)
1228 +static int nofill(void *buffer, unsigned int len)
1229 +{
1230 + return -1;
1231 +}
1233 /* Included from initramfs et al code */
1234 STATIC int INIT gunzip(unsigned char *buf, int len,
1235 int(*fill)(void*, unsigned int),
1236 @@ -55,7 +61,7 @@
1237 if (buf)
1238 zbuf = buf;
1239 else {
1240 - zbuf = malloc(INBUF_LEN);
1241 + zbuf = malloc(GZIP_IOBUF_SIZE);
1242 len = 0;
1244 if (!zbuf) {
1245 @@ -76,8 +82,11 @@
1246 goto gunzip_nomem4;
1249 + if (!fill)
1250 + fill = nofill;
1252 if (len == 0)
1253 - len = fill(zbuf, INBUF_LEN);
1254 + len = fill(zbuf, GZIP_IOBUF_SIZE);
1256 /* verify the gzip header */
1257 if (len < 10 ||
1258 @@ -113,7 +122,7 @@
1259 while (rc == Z_OK) {
1260 if (strm->avail_in == 0) {
1261 /* TODO: handle case where both pos and fill are set */
1262 - len = fill(zbuf, INBUF_LEN);
1263 + len = fill(zbuf, GZIP_IOBUF_SIZE);
1264 if (len < 0) {
1265 rc = -1;
1266 error("read error");
1268 --- linux-2.6.30.6/lib/decompress_unlzma.c
1269 +++ linux-2.6.30.6/lib/decompress_unlzma.c
1270 @@ -29,12 +29,15 @@
1271 *Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1272 */
1274 -#ifndef STATIC
1275 +#ifdef STATIC
1276 +#define PREBOOT
1277 +#else
1278 #include <linux/decompress/unlzma.h>
1279 +#include <linux/slab.h>
1280 #endif /* STATIC */
1282 +#include <linux/decompress/unlzma_mm.h>
1283 #include <linux/decompress/mm.h>
1284 -#include <linux/slab.h>
1286 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
1288 @@ -80,8 +83,13 @@
1289 #define RC_MODEL_TOTAL_BITS 11
1292 +static int nofill(void *buffer, unsigned int len)
1293 +{
1294 + return -1;
1295 +}
1297 /* Called twice: once at startup and once in rc_normalize() */
1298 -static void INIT rc_read(struct rc *rc)
1299 +static void INIT rc_read(struct rc *rc, void(*error)(char *x))
1301 rc->buffer_size = rc->fill((char *)rc->buffer, LZMA_IOBUF_SIZE);
1302 if (rc->buffer_size <= 0)
1303 @@ -95,7 +103,10 @@
1304 int (*fill)(void*, unsigned int),
1305 char *buffer, int buffer_size)
1307 - rc->fill = fill;
1308 + if (fill)
1309 + rc->fill = fill;
1310 + else
1311 + rc->fill = nofill;
1312 rc->buffer = (uint8_t *)buffer;
1313 rc->buffer_size = buffer_size;
1314 rc->buffer_end = rc->buffer + rc->buffer_size;
1315 @@ -105,13 +116,13 @@
1316 rc->range = 0xFFFFFFFF;
1319 -static inline void INIT rc_init_code(struct rc *rc)
1320 +static inline void INIT rc_init_code(struct rc *rc, void(*error)(char *x))
1322 int i;
1324 for (i = 0; i < 5; i++) {
1325 if (rc->ptr >= rc->buffer_end)
1326 - rc_read(rc);
1327 + rc_read(rc, error);
1328 rc->code = (rc->code << 8) | *rc->ptr++;
1331 @@ -124,32 +135,33 @@
1334 /* Called twice, but one callsite is in inline'd rc_is_bit_0_helper() */
1335 -static void INIT rc_do_normalize(struct rc *rc)
1336 +static void INIT rc_do_normalize(struct rc *rc, void(*error)(char *x))
1338 if (rc->ptr >= rc->buffer_end)
1339 - rc_read(rc);
1340 + rc_read(rc, error);
1341 rc->range <<= 8;
1342 rc->code = (rc->code << 8) | *rc->ptr++;
1344 -static inline void INIT rc_normalize(struct rc *rc)
1345 +static inline void INIT rc_normalize(struct rc *rc, void(*error)(char *x))
1347 if (rc->range < (1 << RC_TOP_BITS))
1348 - rc_do_normalize(rc);
1349 + rc_do_normalize(rc, error);
1352 /* Called 9 times */
1353 /* Why rc_is_bit_0_helper exists?
1354 *Because we want to always expose (rc->code < rc->bound) to optimizer
1355 */
1356 -static inline uint32_t INIT rc_is_bit_0_helper(struct rc *rc, uint16_t *p)
1357 +static inline uint32_t INIT rc_is_bit_0_helper(struct rc *rc, uint16_t *p,
1358 + void (*error)(char *x))
1360 - rc_normalize(rc);
1361 + rc_normalize(rc, error);
1362 rc->bound = *p * (rc->range >> RC_MODEL_TOTAL_BITS);
1363 return rc->bound;
1365 -static inline int INIT rc_is_bit_0(struct rc *rc, uint16_t *p)
1366 +static inline int INIT rc_is_bit_0(struct rc *rc, uint16_t *p, void(*error)(char *x))
1368 - uint32_t t = rc_is_bit_0_helper(rc, p);
1369 + uint32_t t = rc_is_bit_0_helper(rc, p, error);
1370 return rc->code < t;
1373 @@ -167,9 +179,9 @@
1376 /* Called 4 times in unlzma loop */
1377 -static int INIT rc_get_bit(struct rc *rc, uint16_t *p, int *symbol)
1378 +static int INIT rc_get_bit(struct rc *rc, uint16_t *p, int *symbol, void(*error)(char *x))
1380 - if (rc_is_bit_0(rc, p)) {
1381 + if (rc_is_bit_0(rc, p, error)) {
1382 rc_update_bit_0(rc, p);
1383 *symbol *= 2;
1384 return 0;
1385 @@ -181,9 +193,9 @@
1388 /* Called once */
1389 -static inline int INIT rc_direct_bit(struct rc *rc)
1390 +static inline int INIT rc_direct_bit(struct rc *rc , void(*error)(char *x))
1392 - rc_normalize(rc);
1393 + rc_normalize(rc, error);
1394 rc->range >>= 1;
1395 if (rc->code >= rc->range) {
1396 rc->code -= rc->range;
1397 @@ -194,13 +206,14 @@
1399 /* Called twice */
1400 static inline void INIT
1401 -rc_bit_tree_decode(struct rc *rc, uint16_t *p, int num_levels, int *symbol)
1402 +rc_bit_tree_decode(struct rc *rc, uint16_t *p, int num_levels, int *symbol,
1403 + void(*error)(char *x))
1405 int i = num_levels;
1407 *symbol = 1;
1408 while (i--)
1409 - rc_get_bit(rc, p + *symbol, symbol);
1410 + rc_get_bit(rc, p + *symbol, symbol, error);
1411 *symbol -= 1 << num_levels;
1414 @@ -278,10 +291,6 @@
1415 size_t global_pos;
1416 int(*flush)(void*, unsigned int);
1417 struct lzma_header *header;
1418 - int is_cpio_flush;
1419 - uint8_t **buffer_index;
1420 - int next_index;
1421 - int max_index;
1422 };
1424 struct cstate {
1425 @@ -298,14 +307,6 @@
1426 static inline uint8_t INIT peek_old_byte(struct writer *wr,
1427 uint32_t offs)
1429 - if (wr->is_cpio_flush) {
1430 - int32_t pos;
1431 - while (offs > wr->header->dict_size)
1432 - offs -= wr->header->dict_size;
1433 - pos = wr->buffer_pos - offs;
1434 - return wr->buffer_index[pos / LZMA_IOBUF_SIZE]
1435 - [pos % LZMA_IOBUF_SIZE];
1436 - }
1437 if (!wr->flush) {
1438 int32_t pos;
1439 while (offs > wr->header->dict_size)
1440 @@ -321,41 +322,8 @@
1444 -static inline void INIT write_byte_if_cpio(struct writer *wr, uint8_t byte)
1445 -{
1446 - if (wr->buffer_pos % LZMA_IOBUF_SIZE == 0) {
1447 - // if the following large_malloc fails, the initramfs
1448 - // whould not be load with is_cpio_flush forced 0 too.
1449 - // Remember we do not allocate historic buffer.
1450 - // Let's assume it will never fail !
1451 - if (wr->next_index >= wr->max_index) {
1452 - // realloc wr->buffer_index
1453 - uint8_t **p = wr->buffer_index;
1454 - wr->buffer_index = (uint8_t **)
1455 - large_malloc(LZMA_IOBUF_SIZE +
1456 - sizeof(*p) * wr->max_index);
1457 - if (wr->max_index) {
1458 - memcpy(wr->buffer_index, p,
1459 - sizeof(*p) * wr->max_index);
1460 - free(p);
1461 - }
1462 - wr->max_index += LZMA_IOBUF_SIZE / sizeof(*p);
1463 - }
1464 - wr->buffer_index[wr->next_index++] =
1465 - (uint8_t *) large_malloc(LZMA_IOBUF_SIZE);
1466 - }
1467 - wr->buffer_index[wr->buffer_pos / LZMA_IOBUF_SIZE]
1468 - [wr->buffer_pos % LZMA_IOBUF_SIZE] =
1469 - wr->previous_byte = byte;
1470 - wr->buffer_pos++;
1471 -}
1473 static inline void INIT write_byte(struct writer *wr, uint8_t byte)
1475 - if (wr->is_cpio_flush) {
1476 - write_byte_if_cpio(wr, byte);
1477 - return;
1478 - }
1479 wr->buffer[wr->buffer_pos++] = wr->previous_byte = byte;
1480 if (wr->flush && wr->buffer_pos == wr->header->dict_size) {
1481 wr->buffer_pos = 0;
1482 @@ -373,21 +341,7 @@
1483 static inline void INIT copy_bytes(struct writer *wr,
1484 uint32_t rep0, int len)
1486 - if (wr->is_cpio_flush) {
1487 - int32_t pos;
1488 - uint32_t offs = rep0;
1489 - while (offs > wr->header->dict_size)
1490 - offs -= wr->header->dict_size;
1491 - pos = wr->buffer_pos - offs;
1492 - do {
1493 - write_byte_if_cpio(wr,
1494 - wr->buffer_index[pos / LZMA_IOBUF_SIZE]
1495 - [pos % LZMA_IOBUF_SIZE]);
1496 - pos++;
1497 - len--;
1498 - } while (len != 0 && wr->buffer_pos < wr->header->dst_size);
1499 - }
1500 - else do {
1501 + do {
1502 copy_byte(wr, rep0);
1503 len--;
1504 } while (len != 0 && wr->buffer_pos < wr->header->dst_size);
1505 @@ -396,11 +350,9 @@
1506 static inline void INIT process_bit0(struct writer *wr, struct rc *rc,
1507 struct cstate *cst, uint16_t *p,
1508 int pos_state, uint16_t *prob,
1509 - int lc, uint32_t literal_pos_mask) {
1510 + int lc, uint32_t literal_pos_mask,
1511 + void(*error)(char *x)) {
1512 int mi = 1;
1513 - static const int state[LZMA_NUM_STATES] =
1514 - { 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5 };
1516 rc_update_bit_0(rc, prob);
1517 prob = (p + LZMA_LITERAL +
1518 (LZMA_LIT_SIZE
1519 @@ -417,7 +369,7 @@
1520 match_byte <<= 1;
1521 bit = match_byte & 0x100;
1522 prob_lit = prob + 0x100 + bit + mi;
1523 - if (rc_get_bit(rc, prob_lit, &mi)) {
1524 + if (rc_get_bit(rc, prob_lit, &mi, error)) {
1525 if (!bit)
1526 break;
1527 } else {
1528 @@ -428,23 +380,29 @@
1530 while (mi < 0x100) {
1531 uint16_t *prob_lit = prob + mi;
1532 - rc_get_bit(rc, prob_lit, &mi);
1533 + rc_get_bit(rc, prob_lit, &mi, error);
1535 write_byte(wr, mi);
1536 - cst->state = state[cst->state];
1537 + if (cst->state < 4)
1538 + cst->state = 0;
1539 + else if (cst->state < 10)
1540 + cst->state -= 3;
1541 + else
1542 + cst->state -= 6;
1545 static inline void INIT process_bit1(struct writer *wr, struct rc *rc,
1546 struct cstate *cst, uint16_t *p,
1547 - int pos_state, uint16_t *prob) {
1548 - int offset;
1549 + int pos_state, uint16_t *prob,
1550 + void(*error)(char *x)) {
1551 + int offset;
1552 uint16_t *prob_len;
1553 int num_bits;
1554 int len;
1556 rc_update_bit_1(rc, prob);
1557 prob = p + LZMA_IS_REP + cst->state;
1558 - if (rc_is_bit_0(rc, prob)) {
1559 + if (rc_is_bit_0(rc, prob, error)) {
1560 rc_update_bit_0(rc, prob);
1561 cst->rep3 = cst->rep2;
1562 cst->rep2 = cst->rep1;
1563 @@ -453,14 +411,14 @@
1564 prob = p + LZMA_LEN_CODER;
1565 } else {
1566 rc_update_bit_1(rc, prob);
1567 - prob += LZMA_IS_REP_G0 - LZMA_IS_REP;
1568 - if (rc_is_bit_0(rc, prob)) {
1569 + prob = p + LZMA_IS_REP_G0 + cst->state;
1570 + if (rc_is_bit_0(rc, prob, error)) {
1571 rc_update_bit_0(rc, prob);
1572 prob = (p + LZMA_IS_REP_0_LONG
1573 + (cst->state <<
1574 LZMA_NUM_POS_BITS_MAX) +
1575 pos_state);
1576 - if (rc_is_bit_0(rc, prob)) {
1577 + if (rc_is_bit_0(rc, prob, error)) {
1578 rc_update_bit_0(rc, prob);
1580 cst->state = cst->state < LZMA_NUM_LIT_STATES ?
1581 @@ -474,14 +432,14 @@
1582 uint32_t distance;
1584 rc_update_bit_1(rc, prob);
1585 - prob += LZMA_IS_REP_G1 - LZMA_IS_REP_G0;
1586 - if (rc_is_bit_0(rc, prob)) {
1587 + prob = p + LZMA_IS_REP_G1 + cst->state;
1588 + if (rc_is_bit_0(rc, prob, error)) {
1589 rc_update_bit_0(rc, prob);
1590 distance = cst->rep1;
1591 } else {
1592 rc_update_bit_1(rc, prob);
1593 - prob += LZMA_IS_REP_G2 - LZMA_IS_REP_G1;
1594 - if (rc_is_bit_0(rc, prob)) {
1595 + prob = p + LZMA_IS_REP_G2 + cst->state;
1596 + if (rc_is_bit_0(rc, prob, error)) {
1597 rc_update_bit_0(rc, prob);
1598 distance = cst->rep2;
1599 } else {
1600 @@ -499,33 +457,33 @@
1603 prob_len = prob + LZMA_LEN_CHOICE;
1604 - if (rc_is_bit_0(rc, prob_len)) {
1605 + if (rc_is_bit_0(rc, prob_len, error)) {
1606 rc_update_bit_0(rc, prob_len);
1607 - prob_len += LZMA_LEN_LOW - LZMA_LEN_CHOICE
1608 + prob_len = (prob + LZMA_LEN_LOW
1609 + (pos_state <<
1610 - LZMA_LEN_NUM_LOW_BITS);
1611 + LZMA_LEN_NUM_LOW_BITS));
1612 offset = 0;
1613 num_bits = LZMA_LEN_NUM_LOW_BITS;
1614 } else {
1615 rc_update_bit_1(rc, prob_len);
1616 - prob_len += LZMA_LEN_CHOICE_2 - LZMA_LEN_CHOICE;
1617 - if (rc_is_bit_0(rc, prob_len)) {
1618 + prob_len = prob + LZMA_LEN_CHOICE_2;
1619 + if (rc_is_bit_0(rc, prob_len, error)) {
1620 rc_update_bit_0(rc, prob_len);
1621 - prob_len += LZMA_LEN_MID - LZMA_LEN_CHOICE_2
1622 + prob_len = (prob + LZMA_LEN_MID
1623 + (pos_state <<
1624 - LZMA_LEN_NUM_MID_BITS);
1625 + LZMA_LEN_NUM_MID_BITS));
1626 offset = 1 << LZMA_LEN_NUM_LOW_BITS;
1627 num_bits = LZMA_LEN_NUM_MID_BITS;
1628 } else {
1629 rc_update_bit_1(rc, prob_len);
1630 - prob_len += LZMA_LEN_HIGH - LZMA_LEN_CHOICE_2;
1631 + prob_len = prob + LZMA_LEN_HIGH;
1632 offset = ((1 << LZMA_LEN_NUM_LOW_BITS)
1633 + (1 << LZMA_LEN_NUM_MID_BITS));
1634 num_bits = LZMA_LEN_NUM_HIGH_BITS;
1638 - rc_bit_tree_decode(rc, prob_len, num_bits, &len);
1639 + rc_bit_tree_decode(rc, prob_len, num_bits, &len, error);
1640 len += offset;
1642 if (cst->state < 4) {
1643 @@ -540,7 +498,7 @@
1644 << LZMA_NUM_POS_SLOT_BITS);
1645 rc_bit_tree_decode(rc, prob,
1646 LZMA_NUM_POS_SLOT_BITS,
1647 - &pos_slot);
1648 + &pos_slot, error);
1649 if (pos_slot >= LZMA_START_POS_MODEL_INDEX) {
1650 int i, mi;
1651 num_bits = (pos_slot >> 1) - 1;
1652 @@ -553,7 +511,7 @@
1653 num_bits -= LZMA_NUM_ALIGN_BITS;
1654 while (num_bits--)
1655 cst->rep0 = (cst->rep0 << 1) |
1656 - rc_direct_bit(rc);
1657 + rc_direct_bit(rc, error);
1658 prob = p + LZMA_ALIGN;
1659 cst->rep0 <<= LZMA_NUM_ALIGN_BITS;
1660 num_bits = LZMA_NUM_ALIGN_BITS;
1661 @@ -561,7 +519,7 @@
1662 i = 1;
1663 mi = 1;
1664 while (num_bits--) {
1665 - if (rc_get_bit(rc, prob + mi, &mi))
1666 + if (rc_get_bit(rc, prob + mi, &mi, error))
1667 cst->rep0 |= i;
1668 i <<= 1;
1670 @@ -578,15 +536,14 @@
1674 -STATIC inline int INIT unlzma(unsigned char *buf, int in_len,
1675 +STATIC int INIT unlzma(unsigned char *buf, int in_len,
1676 int(*fill)(void*, unsigned int),
1677 int(*flush)(void*, unsigned int),
1678 unsigned char *output,
1679 int *posp,
1680 - void(*error_fn)(char *x)
1681 + void(*error)(char *x)
1684 - extern int cpio_flush_buffer(void*, unsigned int);
1685 struct lzma_header header;
1686 int lc, pb, lp;
1687 uint32_t pos_state_mask;
1688 @@ -600,10 +557,6 @@
1689 unsigned char *inbuf;
1690 int ret = -1;
1692 - set_error_fn(error_fn);
1693 - if (!flush)
1694 - in_len -= 4; /* Uncompressed size hack active in pre-boot
1695 - environment */
1696 if (buf)
1697 inbuf = buf;
1698 else
1699 @@ -621,16 +574,12 @@
1700 wr.global_pos = 0;
1701 wr.previous_byte = 0;
1702 wr.buffer_pos = 0;
1703 - wr.is_cpio_flush = 0;
1704 - if (flush == cpio_flush_buffer)
1705 - wr.is_cpio_flush = 1;
1706 - wr.buffer_index = NULL;
1708 rc_init(&rc, fill, inbuf, in_len);
1710 for (i = 0; i < sizeof(header); i++) {
1711 if (rc.ptr >= rc.buffer_end)
1712 - rc_read(&rc);
1713 + rc_read(&rc, error);
1714 ((unsigned char *)&header)[i] = *rc.ptr++;
1717 @@ -658,34 +607,34 @@
1718 if (header.dict_size == 0)
1719 header.dict_size = 1;
1721 - if (output || wr.is_cpio_flush)
1722 + if (output)
1723 wr.buffer = output;
1724 else {
1725 wr.bufsize = MIN(header.dst_size, header.dict_size);
1726 wr.buffer = large_malloc(wr.bufsize);
1728 - if (wr.buffer == NULL && !wr.is_cpio_flush)
1729 + if (wr.buffer == NULL)
1730 goto exit_1;
1732 num_probs = LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp));
1733 p = (uint16_t *) large_malloc(num_probs * sizeof(*p));
1734 if (p == 0)
1735 goto exit_2;
1736 - num_probs += LZMA_LITERAL - LZMA_BASE_SIZE;
1737 + num_probs = LZMA_LITERAL + (LZMA_LIT_SIZE << (lc + lp));
1738 for (i = 0; i < num_probs; i++)
1739 p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1;
1740 - wr.max_index = wr.next_index = 0;
1741 - rc_init_code(&rc);
1743 + rc_init_code(&rc, error);
1745 while (get_pos(&wr) < header.dst_size) {
1746 int pos_state = get_pos(&wr) & pos_state_mask;
1747 uint16_t *prob = p + LZMA_IS_MATCH +
1748 (cst.state << LZMA_NUM_POS_BITS_MAX) + pos_state;
1749 - if (rc_is_bit_0(&rc, prob))
1750 + if (rc_is_bit_0(&rc, prob, error))
1751 process_bit0(&wr, &rc, &cst, p, pos_state, prob,
1752 - lc, literal_pos_mask);
1753 + lc, literal_pos_mask, error);
1754 else {
1755 - process_bit1(&wr, &rc, &cst, p, pos_state, prob);
1756 + process_bit1(&wr, &rc, &cst, p, pos_state, prob, error);
1757 if (cst.rep0 == 0)
1758 break;
1760 @@ -693,25 +642,12 @@
1762 if (posp)
1763 *posp = rc.ptr-rc.buffer;
1764 - if (wr.is_cpio_flush) {
1765 - int i;
1766 - for (i = 0; i < wr.next_index -1; i++) {
1767 - wr.flush(wr.buffer_index[i], LZMA_IOBUF_SIZE);
1768 - large_free(wr.buffer_index[i]);
1769 - }
1770 - if (i < wr.next_index) {
1771 - wr.flush(wr.buffer_index[i],
1772 - wr.buffer_pos % LZMA_IOBUF_SIZE);
1773 - large_free(wr.buffer_index[i]);
1774 - }
1775 - large_free(wr.buffer_index);
1776 - }
1777 - else if (wr.flush)
1778 + if (wr.flush)
1779 wr.flush(wr.buffer, wr.buffer_pos);
1780 ret = 0;
1781 large_free(p);
1782 exit_2:
1783 - if (!output && !wr.is_cpio_flush)
1784 + if (!output)
1785 large_free(wr.buffer);
1786 exit_1:
1787 if (!buf)
1788 @@ -719,5 +655,19 @@
1789 exit_0:
1790 return ret;
1792 +#if defined(CONFIG_DECOMPRESS_LZMA_NEEDED) && !defined(PREBOOT)
1793 +EXPORT_SYMBOL(unlzma);
1794 +#endif
1796 -#define decompress unlzma
1797 +#ifdef PREBOOT
1798 +STATIC int INIT decompress(unsigned char *buf, int in_len,
1799 + int(*fill)(void*, unsigned int),
1800 + int(*flush)(void*, unsigned int),
1801 + unsigned char *output,
1802 + int *posp,
1803 + void(*error_fn)(char *x)
1804 + )
1805 +{
1806 + return unlzma(buf, in_len - 4, fill, flush, output, posp, error_fn);
1807 +}
1808 +#endif