wok annotate linux/stuff/linux-squashfs-lzma-2.6.34.u @ rev 5640

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