Blame view

fs/squashfs/zlib_wrapper.c 2.42 KB
68252eb5f   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
e6a6d3795   Phillip Lougher   Squashfs: move zl...
2
3
4
5
  /*
   * Squashfs - a compressed read only filesystem for Linux
   *
   * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
d7f2ff671   Phillip Lougher   Squashfs: update ...
6
   * Phillip Lougher <phillip@squashfs.org.uk>
e6a6d3795   Phillip Lougher   Squashfs: move zl...
7
   *
e6a6d3795   Phillip Lougher   Squashfs: move zl...
8
9
10
11
12
13
   * zlib_wrapper.c
   */
  
  
  #include <linux/mutex.h>
  #include <linux/buffer_head.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
14
  #include <linux/slab.h>
e6a6d3795   Phillip Lougher   Squashfs: move zl...
15
  #include <linux/zlib.h>
117a91e0f   Phillip Lougher   Squashfs: Use vma...
16
  #include <linux/vmalloc.h>
e6a6d3795   Phillip Lougher   Squashfs: move zl...
17
18
19
  
  #include "squashfs_fs.h"
  #include "squashfs_fs_sb.h"
e6a6d3795   Phillip Lougher   Squashfs: move zl...
20
  #include "squashfs.h"
4c0f0bb23   Phillip Lougher   Squashfs: add a d...
21
  #include "decompressor.h"
846b730e9   Phillip Lougher   Squashfs: General...
22
  #include "page_actor.h"
e6a6d3795   Phillip Lougher   Squashfs: move zl...
23

9508c6b90   Phillip Lougher   Squashfs: Refacto...
24
  static void *zlib_init(struct squashfs_sb_info *dummy, void *buff)
f1a40359f   Phillip Lougher   Squashfs: factor ...
25
26
27
28
  {
  	z_stream *stream = kmalloc(sizeof(z_stream), GFP_KERNEL);
  	if (stream == NULL)
  		goto failed;
117a91e0f   Phillip Lougher   Squashfs: Use vma...
29
  	stream->workspace = vmalloc(zlib_inflate_workspacesize());
f1a40359f   Phillip Lougher   Squashfs: factor ...
30
31
32
33
34
35
36
37
38
  	if (stream->workspace == NULL)
  		goto failed;
  
  	return stream;
  
  failed:
  	ERROR("Failed to allocate zlib workspace
  ");
  	kfree(stream);
b7fc0ff09   Phillip Lougher   Squashfs: extend ...
39
  	return ERR_PTR(-ENOMEM);
f1a40359f   Phillip Lougher   Squashfs: factor ...
40
  }
4c0f0bb23   Phillip Lougher   Squashfs: add a d...
41
  static void zlib_free(void *strm)
f1a40359f   Phillip Lougher   Squashfs: factor ...
42
43
44
45
  {
  	z_stream *stream = strm;
  
  	if (stream)
117a91e0f   Phillip Lougher   Squashfs: Use vma...
46
  		vfree(stream->workspace);
f1a40359f   Phillip Lougher   Squashfs: factor ...
47
48
  	kfree(stream);
  }
9508c6b90   Phillip Lougher   Squashfs: Refacto...
49
  static int zlib_uncompress(struct squashfs_sb_info *msblk, void *strm,
846b730e9   Phillip Lougher   Squashfs: General...
50
51
  	struct buffer_head **bh, int b, int offset, int length,
  	struct squashfs_page_actor *output)
e6a6d3795   Phillip Lougher   Squashfs: move zl...
52
  {
846b730e9   Phillip Lougher   Squashfs: General...
53
  	int zlib_err, zlib_init = 0, k = 0;
9508c6b90   Phillip Lougher   Squashfs: Refacto...
54
  	z_stream *stream = strm;
e6a6d3795   Phillip Lougher   Squashfs: move zl...
55

09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
56
  	stream->avail_out = PAGE_SIZE;
846b730e9   Phillip Lougher   Squashfs: General...
57
  	stream->next_out = squashfs_first_page(output);
f1a40359f   Phillip Lougher   Squashfs: factor ...
58
  	stream->avail_in = 0;
e6a6d3795   Phillip Lougher   Squashfs: move zl...
59

e6a6d3795   Phillip Lougher   Squashfs: move zl...
60
  	do {
f1a40359f   Phillip Lougher   Squashfs: factor ...
61
  		if (stream->avail_in == 0 && k < b) {
170cf0216   Phillip Lougher   Squashfs: remove ...
62
63
  			int avail = min(length, msblk->devblksize - offset);
  			length -= avail;
f1a40359f   Phillip Lougher   Squashfs: factor ...
64
65
  			stream->next_in = bh[k]->b_data + offset;
  			stream->avail_in = avail;
e6a6d3795   Phillip Lougher   Squashfs: move zl...
66
67
  			offset = 0;
  		}
846b730e9   Phillip Lougher   Squashfs: General...
68
69
70
  		if (stream->avail_out == 0) {
  			stream->next_out = squashfs_next_page(output);
  			if (stream->next_out != NULL)
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
71
  				stream->avail_out = PAGE_SIZE;
e6a6d3795   Phillip Lougher   Squashfs: move zl...
72
73
74
  		}
  
  		if (!zlib_init) {
f1a40359f   Phillip Lougher   Squashfs: factor ...
75
  			zlib_err = zlib_inflateInit(stream);
846b730e9   Phillip Lougher   Squashfs: General...
76
77
  			if (zlib_err != Z_OK) {
  				squashfs_finish_page(output);
9508c6b90   Phillip Lougher   Squashfs: Refacto...
78
  				goto out;
846b730e9   Phillip Lougher   Squashfs: General...
79
  			}
e6a6d3795   Phillip Lougher   Squashfs: move zl...
80
81
  			zlib_init = 1;
  		}
f1a40359f   Phillip Lougher   Squashfs: factor ...
82
  		zlib_err = zlib_inflate(stream, Z_SYNC_FLUSH);
e6a6d3795   Phillip Lougher   Squashfs: move zl...
83

f1a40359f   Phillip Lougher   Squashfs: factor ...
84
  		if (stream->avail_in == 0 && k < b)
e6a6d3795   Phillip Lougher   Squashfs: move zl...
85
86
  			put_bh(bh[k++]);
  	} while (zlib_err == Z_OK);
846b730e9   Phillip Lougher   Squashfs: General...
87
  	squashfs_finish_page(output);
9508c6b90   Phillip Lougher   Squashfs: Refacto...
88
89
  	if (zlib_err != Z_STREAM_END)
  		goto out;
e6a6d3795   Phillip Lougher   Squashfs: move zl...
90

f1a40359f   Phillip Lougher   Squashfs: factor ...
91
  	zlib_err = zlib_inflateEnd(stream);
9508c6b90   Phillip Lougher   Squashfs: Refacto...
92
93
  	if (zlib_err != Z_OK)
  		goto out;
e7ee11f0e   Phillip Lougher   Squashfs: add mis...
94

9508c6b90   Phillip Lougher   Squashfs: Refacto...
95
96
  	if (k < b)
  		goto out;
e6a6d3795   Phillip Lougher   Squashfs: move zl...
97

9508c6b90   Phillip Lougher   Squashfs: Refacto...
98
  	return stream->total_out;
e6a6d3795   Phillip Lougher   Squashfs: move zl...
99

9508c6b90   Phillip Lougher   Squashfs: Refacto...
100
  out:
e6a6d3795   Phillip Lougher   Squashfs: move zl...
101
102
103
104
105
  	for (; k < b; k++)
  		put_bh(bh[k]);
  
  	return -EIO;
  }
4c0f0bb23   Phillip Lougher   Squashfs: add a d...
106
107
108
109
110
111
112
113
114
  
  const struct squashfs_decompressor squashfs_zlib_comp_ops = {
  	.init = zlib_init,
  	.free = zlib_free,
  	.decompress = zlib_uncompress,
  	.id = ZLIB_COMPRESSION,
  	.name = "zlib",
  	.supported = 1
  };