Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0
2 : /*
3 : * Copyright (C) 2008 Oracle. All rights reserved.
4 : *
5 : * Based on jffs2 zlib code:
6 : * Copyright © 2001-2007 Red Hat, Inc.
7 : * Created by David Woodhouse <dwmw2@infradead.org>
8 : */
9 :
10 : #include <linux/kernel.h>
11 : #include <linux/slab.h>
12 : #include <linux/zlib.h>
13 : #include <linux/zutil.h>
14 : #include <linux/mm.h>
15 : #include <linux/init.h>
16 : #include <linux/err.h>
17 : #include <linux/sched.h>
18 : #include <linux/pagemap.h>
19 : #include <linux/bio.h>
20 : #include <linux/refcount.h>
21 : #include "compression.h"
22 :
23 : /* workspace buffer size for s390 zlib hardware support */
24 : #define ZLIB_DFLTCC_BUF_SIZE (4 * PAGE_SIZE)
25 :
26 : struct workspace {
27 : z_stream strm;
28 : char *buf;
29 : unsigned int buf_size;
30 : struct list_head list;
31 : int level;
32 : };
33 :
34 : static struct workspace_manager wsm;
35 :
36 142620 : struct list_head *zlib_get_workspace(unsigned int level)
37 : {
38 142620 : struct list_head *ws = btrfs_get_workspace(BTRFS_COMPRESS_ZLIB, level);
39 142652 : struct workspace *workspace = list_entry(ws, struct workspace, list);
40 :
41 142652 : workspace->level = level;
42 :
43 142652 : return ws;
44 : }
45 :
46 0 : void zlib_free_workspace(struct list_head *ws)
47 : {
48 0 : struct workspace *workspace = list_entry(ws, struct workspace, list);
49 :
50 0 : kvfree(workspace->strm.workspace);
51 0 : kfree(workspace->buf);
52 0 : kfree(workspace);
53 0 : }
54 :
55 15 : struct list_head *zlib_alloc_workspace(unsigned int level)
56 : {
57 15 : struct workspace *workspace;
58 15 : int workspacesize;
59 :
60 15 : workspace = kzalloc(sizeof(*workspace), GFP_KERNEL);
61 15 : if (!workspace)
62 : return ERR_PTR(-ENOMEM);
63 :
64 15 : workspacesize = max(zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL),
65 : zlib_inflate_workspacesize());
66 15 : workspace->strm.workspace = kvzalloc(workspacesize, GFP_KERNEL | __GFP_NOWARN);
67 15 : workspace->level = level;
68 15 : workspace->buf = NULL;
69 : /*
70 : * In case of s390 zlib hardware support, allocate lager workspace
71 : * buffer. If allocator fails, fall back to a single page buffer.
72 : */
73 15 : if (zlib_deflate_dfltcc_enabled()) {
74 0 : workspace->buf = kmalloc(ZLIB_DFLTCC_BUF_SIZE,
75 : __GFP_NOMEMALLOC | __GFP_NORETRY |
76 : __GFP_NOWARN | GFP_NOIO);
77 0 : workspace->buf_size = ZLIB_DFLTCC_BUF_SIZE;
78 : }
79 15 : if (!workspace->buf) {
80 15 : workspace->buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
81 15 : workspace->buf_size = PAGE_SIZE;
82 : }
83 15 : if (!workspace->strm.workspace || !workspace->buf)
84 0 : goto fail;
85 :
86 15 : INIT_LIST_HEAD(&workspace->list);
87 :
88 15 : return &workspace->list;
89 : fail:
90 0 : zlib_free_workspace(&workspace->list);
91 0 : return ERR_PTR(-ENOMEM);
92 : }
93 :
94 141523 : int zlib_compress_pages(struct list_head *ws, struct address_space *mapping,
95 : u64 start, struct page **pages, unsigned long *out_pages,
96 : unsigned long *total_in, unsigned long *total_out)
97 : {
98 141523 : struct workspace *workspace = list_entry(ws, struct workspace, list);
99 141523 : int ret;
100 141523 : char *data_in = NULL;
101 141523 : char *cpage_out;
102 141523 : int nr_pages = 0;
103 141523 : struct page *in_page = NULL;
104 141523 : struct page *out_page = NULL;
105 141523 : unsigned long bytes_left;
106 141523 : unsigned int in_buf_pages;
107 141523 : unsigned long len = *total_out;
108 141523 : unsigned long nr_dest_pages = *out_pages;
109 141523 : const unsigned long max_out = nr_dest_pages * PAGE_SIZE;
110 :
111 141523 : *out_pages = 0;
112 141523 : *total_out = 0;
113 141523 : *total_in = 0;
114 :
115 141523 : if (Z_OK != zlib_deflateInit(&workspace->strm, workspace->level)) {
116 0 : pr_warn("BTRFS: deflateInit failed\n");
117 0 : ret = -EIO;
118 0 : goto out;
119 : }
120 :
121 141512 : workspace->strm.total_in = 0;
122 141512 : workspace->strm.total_out = 0;
123 :
124 141512 : out_page = alloc_page(GFP_NOFS);
125 141498 : if (out_page == NULL) {
126 0 : ret = -ENOMEM;
127 0 : goto out;
128 : }
129 141498 : cpage_out = page_address(out_page);
130 141498 : pages[0] = out_page;
131 141498 : nr_pages = 1;
132 :
133 141498 : workspace->strm.next_in = workspace->buf;
134 141498 : workspace->strm.avail_in = 0;
135 141498 : workspace->strm.next_out = cpage_out;
136 141498 : workspace->strm.avail_out = PAGE_SIZE;
137 :
138 4487652 : while (workspace->strm.total_in < len) {
139 : /*
140 : * Get next input pages and copy the contents to
141 : * the workspace buffer if required.
142 : */
143 4487652 : if (workspace->strm.avail_in == 0) {
144 4477351 : bytes_left = len - workspace->strm.total_in;
145 4477351 : in_buf_pages = min(DIV_ROUND_UP(bytes_left, PAGE_SIZE),
146 : workspace->buf_size / PAGE_SIZE);
147 4477351 : if (in_buf_pages > 1) {
148 : int i;
149 :
150 0 : for (i = 0; i < in_buf_pages; i++) {
151 0 : if (data_in) {
152 0 : kunmap_local(data_in);
153 0 : put_page(in_page);
154 : }
155 0 : in_page = find_get_page(mapping,
156 0 : start >> PAGE_SHIFT);
157 0 : data_in = kmap_local_page(in_page);
158 0 : copy_page(workspace->buf + i * PAGE_SIZE,
159 : data_in);
160 0 : start += PAGE_SIZE;
161 : }
162 0 : workspace->strm.next_in = workspace->buf;
163 : } else {
164 4477351 : if (data_in) {
165 4335863 : kunmap_local(data_in);
166 4335863 : put_page(in_page);
167 : }
168 4491990 : in_page = find_get_page(mapping,
169 4491990 : start >> PAGE_SHIFT);
170 4515870 : data_in = kmap_local_page(in_page);
171 4515870 : start += PAGE_SIZE;
172 4515870 : workspace->strm.next_in = data_in;
173 : }
174 4515870 : workspace->strm.avail_in = min(bytes_left,
175 : (unsigned long) workspace->buf_size);
176 : }
177 :
178 4526171 : ret = zlib_deflate(&workspace->strm, Z_SYNC_FLUSH);
179 4486924 : if (ret != Z_OK) {
180 0 : pr_debug("BTRFS: deflate in loop returned %d\n",
181 : ret);
182 0 : zlib_deflateEnd(&workspace->strm);
183 0 : ret = -EIO;
184 0 : goto out;
185 : }
186 :
187 : /* we're making it bigger, give up */
188 4486924 : if (workspace->strm.total_in > 8192 &&
189 : workspace->strm.total_in <
190 4218759 : workspace->strm.total_out) {
191 0 : ret = -E2BIG;
192 0 : goto out;
193 : }
194 : /* we need another page for writing out. Test this
195 : * before the total_in so we will pull in a new page for
196 : * the stream end if required
197 : */
198 4486924 : if (workspace->strm.avail_out == 0) {
199 106486 : if (nr_pages == nr_dest_pages) {
200 1 : ret = -E2BIG;
201 1 : goto out;
202 : }
203 106485 : out_page = alloc_page(GFP_NOFS);
204 106489 : if (out_page == NULL) {
205 0 : ret = -ENOMEM;
206 0 : goto out;
207 : }
208 106489 : cpage_out = page_address(out_page);
209 106489 : pages[nr_pages] = out_page;
210 106489 : nr_pages++;
211 106489 : workspace->strm.avail_out = PAGE_SIZE;
212 106489 : workspace->strm.next_out = cpage_out;
213 : }
214 : /* we're all done */
215 4486927 : if (workspace->strm.total_in >= len)
216 : break;
217 4346154 : if (workspace->strm.total_out > max_out)
218 : break;
219 : }
220 140773 : workspace->strm.avail_in = 0;
221 : /*
222 : * Call deflate with Z_FINISH flush parameter providing more output
223 : * space but no more input data, until it returns with Z_STREAM_END.
224 : */
225 140773 : while (ret != Z_STREAM_END) {
226 140773 : ret = zlib_deflate(&workspace->strm, Z_FINISH);
227 140944 : if (ret == Z_STREAM_END)
228 : break;
229 0 : if (ret != Z_OK && ret != Z_BUF_ERROR) {
230 0 : zlib_deflateEnd(&workspace->strm);
231 0 : ret = -EIO;
232 0 : goto out;
233 0 : } else if (workspace->strm.avail_out == 0) {
234 : /* get another page for the stream end */
235 0 : if (nr_pages == nr_dest_pages) {
236 0 : ret = -E2BIG;
237 0 : goto out;
238 : }
239 0 : out_page = alloc_page(GFP_NOFS);
240 0 : if (out_page == NULL) {
241 0 : ret = -ENOMEM;
242 0 : goto out;
243 : }
244 0 : cpage_out = page_address(out_page);
245 0 : pages[nr_pages] = out_page;
246 0 : nr_pages++;
247 0 : workspace->strm.avail_out = PAGE_SIZE;
248 0 : workspace->strm.next_out = cpage_out;
249 : }
250 : }
251 140944 : zlib_deflateEnd(&workspace->strm);
252 :
253 140738 : if (workspace->strm.total_out >= workspace->strm.total_in) {
254 0 : ret = -E2BIG;
255 0 : goto out;
256 : }
257 :
258 140738 : ret = 0;
259 140738 : *total_out = workspace->strm.total_out;
260 140738 : *total_in = workspace->strm.total_in;
261 140739 : out:
262 140739 : *out_pages = nr_pages;
263 140739 : if (data_in) {
264 140634 : kunmap_local(data_in);
265 140634 : put_page(in_page);
266 : }
267 :
268 141099 : return ret;
269 : }
270 :
271 1094 : int zlib_decompress_bio(struct list_head *ws, struct compressed_bio *cb)
272 : {
273 1094 : struct workspace *workspace = list_entry(ws, struct workspace, list);
274 1094 : int ret = 0, ret2;
275 1094 : int wbits = MAX_WBITS;
276 1094 : char *data_in;
277 1094 : size_t total_out = 0;
278 1094 : unsigned long page_in_index = 0;
279 1094 : size_t srclen = cb->compressed_len;
280 1094 : unsigned long total_pages_in = DIV_ROUND_UP(srclen, PAGE_SIZE);
281 1094 : unsigned long buf_start;
282 1094 : struct page **pages_in = cb->compressed_pages;
283 :
284 1094 : data_in = kmap_local_page(pages_in[page_in_index]);
285 1094 : workspace->strm.next_in = data_in;
286 1094 : workspace->strm.avail_in = min_t(size_t, srclen, PAGE_SIZE);
287 1094 : workspace->strm.total_in = 0;
288 :
289 1094 : workspace->strm.total_out = 0;
290 1094 : workspace->strm.next_out = workspace->buf;
291 1094 : workspace->strm.avail_out = workspace->buf_size;
292 :
293 : /* If it's deflate, and it's got no preset dictionary, then
294 : we can tell zlib to skip the adler32 check. */
295 1094 : if (srclen > 2 && !(data_in[1] & PRESET_DICT) &&
296 1094 : ((data_in[0] & 0x0f) == Z_DEFLATED) &&
297 1094 : !(((data_in[0]<<8) + data_in[1]) % 31)) {
298 :
299 1094 : wbits = -((data_in[0] >> 4) + 8);
300 1094 : workspace->strm.next_in += 2;
301 1094 : workspace->strm.avail_in -= 2;
302 : }
303 :
304 1094 : if (Z_OK != zlib_inflateInit2(&workspace->strm, wbits)) {
305 0 : pr_warn("BTRFS: inflateInit failed\n");
306 0 : kunmap_local(data_in);
307 0 : return -EIO;
308 : }
309 34343 : while (workspace->strm.total_in < srclen) {
310 34343 : ret = zlib_inflate(&workspace->strm, Z_NO_FLUSH);
311 34401 : if (ret != Z_OK && ret != Z_STREAM_END)
312 : break;
313 :
314 34401 : buf_start = total_out;
315 34401 : total_out = workspace->strm.total_out;
316 :
317 : /* we didn't make progress in this inflate call, we're done */
318 34401 : if (buf_start == total_out)
319 : break;
320 :
321 34401 : ret2 = btrfs_decompress_buf2page(workspace->buf,
322 : total_out - buf_start, cb, buf_start);
323 34343 : if (ret2 == 0) {
324 1094 : ret = 0;
325 1094 : goto done;
326 : }
327 :
328 33249 : workspace->strm.next_out = workspace->buf;
329 33249 : workspace->strm.avail_out = workspace->buf_size;
330 :
331 33249 : if (workspace->strm.avail_in == 0) {
332 52 : unsigned long tmp;
333 52 : kunmap_local(data_in);
334 52 : page_in_index++;
335 52 : if (page_in_index >= total_pages_in) {
336 : data_in = NULL;
337 : break;
338 : }
339 52 : data_in = kmap_local_page(pages_in[page_in_index]);
340 52 : workspace->strm.next_in = data_in;
341 52 : tmp = srclen - workspace->strm.total_in;
342 52 : workspace->strm.avail_in = min(tmp, PAGE_SIZE);
343 : }
344 : }
345 0 : if (ret != Z_STREAM_END)
346 : ret = -EIO;
347 : else
348 0 : ret = 0;
349 1094 : done:
350 1094 : zlib_inflateEnd(&workspace->strm);
351 1094 : if (data_in)
352 1094 : kunmap_local(data_in);
353 1094 : return ret;
354 : }
355 :
356 25 : int zlib_decompress(struct list_head *ws, const u8 *data_in,
357 : struct page *dest_page, unsigned long start_byte, size_t srclen,
358 : size_t destlen)
359 : {
360 25 : struct workspace *workspace = list_entry(ws, struct workspace, list);
361 25 : int ret = 0;
362 25 : int wbits = MAX_WBITS;
363 25 : unsigned long bytes_left;
364 25 : unsigned long total_out = 0;
365 25 : unsigned long pg_offset = 0;
366 :
367 25 : destlen = min_t(unsigned long, destlen, PAGE_SIZE);
368 25 : bytes_left = destlen;
369 :
370 25 : workspace->strm.next_in = data_in;
371 25 : workspace->strm.avail_in = srclen;
372 25 : workspace->strm.total_in = 0;
373 :
374 25 : workspace->strm.next_out = workspace->buf;
375 25 : workspace->strm.avail_out = workspace->buf_size;
376 25 : workspace->strm.total_out = 0;
377 : /* If it's deflate, and it's got no preset dictionary, then
378 : we can tell zlib to skip the adler32 check. */
379 25 : if (srclen > 2 && !(data_in[1] & PRESET_DICT) &&
380 25 : ((data_in[0] & 0x0f) == Z_DEFLATED) &&
381 25 : !(((data_in[0]<<8) + data_in[1]) % 31)) {
382 :
383 25 : wbits = -((data_in[0] >> 4) + 8);
384 25 : workspace->strm.next_in += 2;
385 25 : workspace->strm.avail_in -= 2;
386 : }
387 :
388 25 : if (Z_OK != zlib_inflateInit2(&workspace->strm, wbits)) {
389 0 : pr_warn("BTRFS: inflateInit failed\n");
390 0 : return -EIO;
391 : }
392 :
393 50 : while (bytes_left > 0) {
394 25 : unsigned long buf_start;
395 25 : unsigned long buf_offset;
396 25 : unsigned long bytes;
397 :
398 25 : ret = zlib_inflate(&workspace->strm, Z_NO_FLUSH);
399 25 : if (ret != Z_OK && ret != Z_STREAM_END)
400 : break;
401 :
402 25 : buf_start = total_out;
403 25 : total_out = workspace->strm.total_out;
404 :
405 25 : if (total_out == buf_start) {
406 : ret = -EIO;
407 : break;
408 : }
409 :
410 25 : if (total_out <= start_byte)
411 0 : goto next;
412 :
413 25 : if (total_out > start_byte && buf_start < start_byte)
414 0 : buf_offset = start_byte - buf_start;
415 : else
416 : buf_offset = 0;
417 :
418 25 : bytes = min(PAGE_SIZE - pg_offset,
419 : PAGE_SIZE - (buf_offset % PAGE_SIZE));
420 25 : bytes = min(bytes, bytes_left);
421 :
422 25 : memcpy_to_page(dest_page, pg_offset,
423 25 : workspace->buf + buf_offset, bytes);
424 :
425 25 : pg_offset += bytes;
426 25 : bytes_left -= bytes;
427 25 : next:
428 25 : workspace->strm.next_out = workspace->buf;
429 25 : workspace->strm.avail_out = workspace->buf_size;
430 : }
431 :
432 25 : if (ret != Z_STREAM_END && bytes_left != 0)
433 : ret = -EIO;
434 : else
435 25 : ret = 0;
436 :
437 25 : zlib_inflateEnd(&workspace->strm);
438 :
439 : /*
440 : * this should only happen if zlib returned fewer bytes than we
441 : * expected. btrfs_get_block is responsible for zeroing from the
442 : * end of the inline extent (destlen) to the end of the page
443 : */
444 25 : if (pg_offset < destlen) {
445 0 : memzero_page(dest_page, pg_offset, destlen - pg_offset);
446 : }
447 : return ret;
448 : }
449 :
450 : const struct btrfs_compress_op btrfs_zlib_compress = {
451 : .workspace_manager = &wsm,
452 : .max_level = 9,
453 : .default_level = BTRFS_ZLIB_DEFAULT_LEVEL,
454 : };
|