linux/fs/cramfs/uncompress.c
<<
>>
Prefs
   1/*
   2 * uncompress.c
   3 *
   4 * (C) Copyright 1999 Linus Torvalds
   5 *
   6 * cramfs interfaces to the uncompression library. There's really just
   7 * three entrypoints:
   8 *
   9 *  - cramfs_uncompress_init() - called to initialize the thing.
  10 *  - cramfs_uncompress_exit() - tell me when you're done
  11 *  - cramfs_uncompress_block() - uncompress a block.
  12 *
  13 * NOTE NOTE NOTE! The uncompression is entirely single-threaded. We
  14 * only have one stream, and we'll initialize it only once even if it
  15 * then is used by multiple filesystems.
  16 */
  17
  18#include <linux/kernel.h>
  19#include <linux/errno.h>
  20#include <linux/vmalloc.h>
  21#include <linux/zlib.h>
  22#include <linux/cramfs_fs.h>
  23
  24static z_stream stream;
  25static int initialized;
  26
  27/* Returns length of decompressed data. */
  28int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen)
  29{
  30        int err;
  31
  32        stream.next_in = src;
  33        stream.avail_in = srclen;
  34
  35        stream.next_out = dst;
  36        stream.avail_out = dstlen;
  37
  38        err = zlib_inflateReset(&stream);
  39        if (err != Z_OK) {
  40                printk("zlib_inflateReset error %d\n", err);
  41                zlib_inflateEnd(&stream);
  42                zlib_inflateInit(&stream);
  43        }
  44
  45        err = zlib_inflate(&stream, Z_FINISH);
  46        if (err != Z_STREAM_END)
  47                goto err;
  48        return stream.total_out;
  49
  50err:
  51        printk("Error %d while decompressing!\n", err);
  52        printk("%p(%d)->%p(%d)\n", src, srclen, dst, dstlen);
  53        return -EIO;
  54}
  55
  56int cramfs_uncompress_init(void)
  57{
  58        if (!initialized++) {
  59                stream.workspace = vmalloc(zlib_inflate_workspacesize());
  60                if ( !stream.workspace ) {
  61                        initialized = 0;
  62                        return -ENOMEM;
  63                }
  64                stream.next_in = NULL;
  65                stream.avail_in = 0;
  66                zlib_inflateInit(&stream);
  67        }
  68        return 0;
  69}
  70
  71void cramfs_uncompress_exit(void)
  72{
  73        if (!--initialized) {
  74                zlib_inflateEnd(&stream);
  75                vfree(stream.workspace);
  76        }
  77}
  78