Blame view

fs/squashfs/zlib_wrapper.c 3.06 KB
e6a6d3795   Phillip Lougher   Squashfs: move zl...
1
2
3
4
  /*
   * Squashfs - a compressed read only filesystem for Linux
   *
   * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
d7f2ff671   Phillip Lougher   Squashfs: update ...
5
   * Phillip Lougher <phillip@squashfs.org.uk>
e6a6d3795   Phillip Lougher   Squashfs: move zl...
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License
   * as published by the Free Software Foundation; either version 2,
   * or (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
   *
   * zlib_wrapper.c
   */
  
  
  #include <linux/mutex.h>
  #include <linux/buffer_head.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
27
  #include <linux/slab.h>
e6a6d3795   Phillip Lougher   Squashfs: move zl...
28
  #include <linux/zlib.h>
117a91e0f   Phillip Lougher   Squashfs: Use vma...
29
  #include <linux/vmalloc.h>
e6a6d3795   Phillip Lougher   Squashfs: move zl...
30
31
32
  
  #include "squashfs_fs.h"
  #include "squashfs_fs_sb.h"
e6a6d3795   Phillip Lougher   Squashfs: move zl...
33
  #include "squashfs.h"
4c0f0bb23   Phillip Lougher   Squashfs: add a d...
34
  #include "decompressor.h"
846b730e9   Phillip Lougher   Squashfs: General...
35
  #include "page_actor.h"
e6a6d3795   Phillip Lougher   Squashfs: move zl...
36

9508c6b90   Phillip Lougher   Squashfs: Refacto...
37
  static void *zlib_init(struct squashfs_sb_info *dummy, void *buff)
f1a40359f   Phillip Lougher   Squashfs: factor ...
38
39
40
41
  {
  	z_stream *stream = kmalloc(sizeof(z_stream), GFP_KERNEL);
  	if (stream == NULL)
  		goto failed;
117a91e0f   Phillip Lougher   Squashfs: Use vma...
42
  	stream->workspace = vmalloc(zlib_inflate_workspacesize());
f1a40359f   Phillip Lougher   Squashfs: factor ...
43
44
45
46
47
48
49
50
51
  	if (stream->workspace == NULL)
  		goto failed;
  
  	return stream;
  
  failed:
  	ERROR("Failed to allocate zlib workspace
  ");
  	kfree(stream);
b7fc0ff09   Phillip Lougher   Squashfs: extend ...
52
  	return ERR_PTR(-ENOMEM);
f1a40359f   Phillip Lougher   Squashfs: factor ...
53
  }
4c0f0bb23   Phillip Lougher   Squashfs: add a d...
54
  static void zlib_free(void *strm)
f1a40359f   Phillip Lougher   Squashfs: factor ...
55
56
57
58
  {
  	z_stream *stream = strm;
  
  	if (stream)
117a91e0f   Phillip Lougher   Squashfs: Use vma...
59
  		vfree(stream->workspace);
f1a40359f   Phillip Lougher   Squashfs: factor ...
60
61
  	kfree(stream);
  }
9508c6b90   Phillip Lougher   Squashfs: Refacto...
62
  static int zlib_uncompress(struct squashfs_sb_info *msblk, void *strm,
846b730e9   Phillip Lougher   Squashfs: General...
63
64
  	struct buffer_head **bh, int b, int offset, int length,
  	struct squashfs_page_actor *output)
e6a6d3795   Phillip Lougher   Squashfs: move zl...
65
  {
846b730e9   Phillip Lougher   Squashfs: General...
66
  	int zlib_err, zlib_init = 0, k = 0;
9508c6b90   Phillip Lougher   Squashfs: Refacto...
67
  	z_stream *stream = strm;
e6a6d3795   Phillip Lougher   Squashfs: move zl...
68

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

e6a6d3795   Phillip Lougher   Squashfs: move zl...
73
  	do {
f1a40359f   Phillip Lougher   Squashfs: factor ...
74
  		if (stream->avail_in == 0 && k < b) {
170cf0216   Phillip Lougher   Squashfs: remove ...
75
76
  			int avail = min(length, msblk->devblksize - offset);
  			length -= avail;
f1a40359f   Phillip Lougher   Squashfs: factor ...
77
78
  			stream->next_in = bh[k]->b_data + offset;
  			stream->avail_in = avail;
e6a6d3795   Phillip Lougher   Squashfs: move zl...
79
80
  			offset = 0;
  		}
846b730e9   Phillip Lougher   Squashfs: General...
81
82
83
  		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...
84
  				stream->avail_out = PAGE_SIZE;
e6a6d3795   Phillip Lougher   Squashfs: move zl...
85
86
87
  		}
  
  		if (!zlib_init) {
f1a40359f   Phillip Lougher   Squashfs: factor ...
88
  			zlib_err = zlib_inflateInit(stream);
846b730e9   Phillip Lougher   Squashfs: General...
89
90
  			if (zlib_err != Z_OK) {
  				squashfs_finish_page(output);
9508c6b90   Phillip Lougher   Squashfs: Refacto...
91
  				goto out;
846b730e9   Phillip Lougher   Squashfs: General...
92
  			}
e6a6d3795   Phillip Lougher   Squashfs: move zl...
93
94
  			zlib_init = 1;
  		}
f1a40359f   Phillip Lougher   Squashfs: factor ...
95
  		zlib_err = zlib_inflate(stream, Z_SYNC_FLUSH);
e6a6d3795   Phillip Lougher   Squashfs: move zl...
96

f1a40359f   Phillip Lougher   Squashfs: factor ...
97
  		if (stream->avail_in == 0 && k < b)
e6a6d3795   Phillip Lougher   Squashfs: move zl...
98
99
  			put_bh(bh[k++]);
  	} while (zlib_err == Z_OK);
846b730e9   Phillip Lougher   Squashfs: General...
100
  	squashfs_finish_page(output);
9508c6b90   Phillip Lougher   Squashfs: Refacto...
101
102
  	if (zlib_err != Z_STREAM_END)
  		goto out;
e6a6d3795   Phillip Lougher   Squashfs: move zl...
103

f1a40359f   Phillip Lougher   Squashfs: factor ...
104
  	zlib_err = zlib_inflateEnd(stream);
9508c6b90   Phillip Lougher   Squashfs: Refacto...
105
106
  	if (zlib_err != Z_OK)
  		goto out;
e7ee11f0e   Phillip Lougher   Squashfs: add mis...
107

9508c6b90   Phillip Lougher   Squashfs: Refacto...
108
109
  	if (k < b)
  		goto out;
e6a6d3795   Phillip Lougher   Squashfs: move zl...
110

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

9508c6b90   Phillip Lougher   Squashfs: Refacto...
113
  out:
e6a6d3795   Phillip Lougher   Squashfs: move zl...
114
115
116
117
118
  	for (; k < b; k++)
  		put_bh(bh[k]);
  
  	return -EIO;
  }
4c0f0bb23   Phillip Lougher   Squashfs: add a d...
119
120
121
122
123
124
125
126
127
  
  const struct squashfs_decompressor squashfs_zlib_comp_ops = {
  	.init = zlib_init,
  	.free = zlib_free,
  	.decompress = zlib_uncompress,
  	.id = ZLIB_COMPRESSION,
  	.name = "zlib",
  	.supported = 1
  };