wok annotate linux/stuff/linux-squashfs-lzma-2.6.33.4.u @ rev 5578

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