root/fs/cramfs/uncompress.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cramfs_uncompress_block
  2. cramfs_uncompress_init
  3. cramfs_uncompress_exit

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

/* [<][>][^][v][top][bottom][index][help] */