root/fs/squashfs/zlib_wrapper.c

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

DEFINITIONS

This source file includes following definitions.
  1. zlib_init
  2. zlib_free
  3. zlib_uncompress

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Squashfs - a compressed read only filesystem for Linux
   4  *
   5  * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
   6  * Phillip Lougher <phillip@squashfs.org.uk>
   7  *
   8  * zlib_wrapper.c
   9  */
  10 
  11 
  12 #include <linux/mutex.h>
  13 #include <linux/buffer_head.h>
  14 #include <linux/slab.h>
  15 #include <linux/zlib.h>
  16 #include <linux/vmalloc.h>
  17 
  18 #include "squashfs_fs.h"
  19 #include "squashfs_fs_sb.h"
  20 #include "squashfs.h"
  21 #include "decompressor.h"
  22 #include "page_actor.h"
  23 
  24 static void *zlib_init(struct squashfs_sb_info *dummy, void *buff)
  25 {
  26         z_stream *stream = kmalloc(sizeof(z_stream), GFP_KERNEL);
  27         if (stream == NULL)
  28                 goto failed;
  29         stream->workspace = vmalloc(zlib_inflate_workspacesize());
  30         if (stream->workspace == NULL)
  31                 goto failed;
  32 
  33         return stream;
  34 
  35 failed:
  36         ERROR("Failed to allocate zlib workspace\n");
  37         kfree(stream);
  38         return ERR_PTR(-ENOMEM);
  39 }
  40 
  41 
  42 static void zlib_free(void *strm)
  43 {
  44         z_stream *stream = strm;
  45 
  46         if (stream)
  47                 vfree(stream->workspace);
  48         kfree(stream);
  49 }
  50 
  51 
  52 static int zlib_uncompress(struct squashfs_sb_info *msblk, void *strm,
  53         struct buffer_head **bh, int b, int offset, int length,
  54         struct squashfs_page_actor *output)
  55 {
  56         int zlib_err, zlib_init = 0, k = 0;
  57         z_stream *stream = strm;
  58 
  59         stream->avail_out = PAGE_SIZE;
  60         stream->next_out = squashfs_first_page(output);
  61         stream->avail_in = 0;
  62 
  63         do {
  64                 if (stream->avail_in == 0 && k < b) {
  65                         int avail = min(length, msblk->devblksize - offset);
  66                         length -= avail;
  67                         stream->next_in = bh[k]->b_data + offset;
  68                         stream->avail_in = avail;
  69                         offset = 0;
  70                 }
  71 
  72                 if (stream->avail_out == 0) {
  73                         stream->next_out = squashfs_next_page(output);
  74                         if (stream->next_out != NULL)
  75                                 stream->avail_out = PAGE_SIZE;
  76                 }
  77 
  78                 if (!zlib_init) {
  79                         zlib_err = zlib_inflateInit(stream);
  80                         if (zlib_err != Z_OK) {
  81                                 squashfs_finish_page(output);
  82                                 goto out;
  83                         }
  84                         zlib_init = 1;
  85                 }
  86 
  87                 zlib_err = zlib_inflate(stream, Z_SYNC_FLUSH);
  88 
  89                 if (stream->avail_in == 0 && k < b)
  90                         put_bh(bh[k++]);
  91         } while (zlib_err == Z_OK);
  92 
  93         squashfs_finish_page(output);
  94 
  95         if (zlib_err != Z_STREAM_END)
  96                 goto out;
  97 
  98         zlib_err = zlib_inflateEnd(stream);
  99         if (zlib_err != Z_OK)
 100                 goto out;
 101 
 102         if (k < b)
 103                 goto out;
 104 
 105         return stream->total_out;
 106 
 107 out:
 108         for (; k < b; k++)
 109                 put_bh(bh[k]);
 110 
 111         return -EIO;
 112 }
 113 
 114 const struct squashfs_decompressor squashfs_zlib_comp_ops = {
 115         .init = zlib_init,
 116         .free = zlib_free,
 117         .decompress = zlib_uncompress,
 118         .id = ZLIB_COMPRESSION,
 119         .name = "zlib",
 120         .supported = 1
 121 };
 122 

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