blob: 2be3b844cfc6e1b68d855ce6e1537d41d18f19b5 [file] [log] [blame]
Huang Jianan7dcfbb12022-02-26 15:05:49 +08001// SPDX-License-Identifier: GPL-2.0+
2#include "decompress.h"
3
4#if IS_ENABLED(CONFIG_LZ4)
5#include <u-boot/lz4.h>
6static int z_erofs_decompress_lz4(struct z_erofs_decompress_req *rq)
7{
8 int ret = 0;
9 char *dest = rq->out;
10 char *src = rq->in;
11 char *buff = NULL;
12 bool support_0padding = false;
13 unsigned int inputmargin = 0;
14
15 if (erofs_sb_has_lz4_0padding()) {
16 support_0padding = true;
17
18 while (!src[inputmargin & ~PAGE_MASK])
19 if (!(++inputmargin & ~PAGE_MASK))
20 break;
21
22 if (inputmargin >= rq->inputsize)
23 return -EIO;
24 }
25
26 if (rq->decodedskip) {
27 buff = malloc(rq->decodedlength);
28 if (!buff)
29 return -ENOMEM;
30 dest = buff;
31 }
32
33 if (rq->partial_decoding || !support_0padding)
34 ret = LZ4_decompress_safe_partial(src + inputmargin, dest,
35 rq->inputsize - inputmargin,
36 rq->decodedlength, rq->decodedlength);
37 else
38 ret = LZ4_decompress_safe(src + inputmargin, dest,
39 rq->inputsize - inputmargin,
40 rq->decodedlength);
41
42 if (ret != (int)rq->decodedlength) {
43 ret = -EIO;
44 goto out;
45 }
46
47 if (rq->decodedskip)
48 memcpy(rq->out, dest + rq->decodedskip,
49 rq->decodedlength - rq->decodedskip);
50
51out:
52 if (buff)
53 free(buff);
54
55 return ret;
56}
57#endif
58
59int z_erofs_decompress(struct z_erofs_decompress_req *rq)
60{
61 if (rq->alg == Z_EROFS_COMPRESSION_SHIFTED) {
62 if (rq->inputsize != EROFS_BLKSIZ)
63 return -EFSCORRUPTED;
64
65 DBG_BUGON(rq->decodedlength > EROFS_BLKSIZ);
66 DBG_BUGON(rq->decodedlength < rq->decodedskip);
67
68 memcpy(rq->out, rq->in + rq->decodedskip,
69 rq->decodedlength - rq->decodedskip);
70 return 0;
71 }
72
73#if IS_ENABLED(CONFIG_LZ4)
74 if (rq->alg == Z_EROFS_COMPRESSION_LZ4)
75 return z_erofs_decompress_lz4(rq);
76#endif
77 return -EOPNOTSUPP;
78}