decompressor_lzma.c (1758047057dbe329be712a31b79db7151b5871f8) decompressor_lzma.c (10e5f6e482e18dcdee9a9b7ff1a66f4977dd1ec2)
1// SPDX-License-Identifier: GPL-2.0-or-later
2#include <linux/xz.h>
3#include <linux/module.h>
4#include "compress.h"
5
6struct z_erofs_lzma {
7 struct z_erofs_lzma *next;
8 struct xz_dec_microlzma *state;

--- 142 unchanged lines hidden (view full) ---

151
152int z_erofs_lzma_decompress(struct z_erofs_decompress_req *rq,
153 struct page **pagepool)
154{
155 const unsigned int nrpages_out =
156 PAGE_ALIGN(rq->pageofs_out + rq->outputsize) >> PAGE_SHIFT;
157 const unsigned int nrpages_in =
158 PAGE_ALIGN(rq->inputsize) >> PAGE_SHIFT;
1// SPDX-License-Identifier: GPL-2.0-or-later
2#include <linux/xz.h>
3#include <linux/module.h>
4#include "compress.h"
5
6struct z_erofs_lzma {
7 struct z_erofs_lzma *next;
8 struct xz_dec_microlzma *state;

--- 142 unchanged lines hidden (view full) ---

151
152int z_erofs_lzma_decompress(struct z_erofs_decompress_req *rq,
153 struct page **pagepool)
154{
155 const unsigned int nrpages_out =
156 PAGE_ALIGN(rq->pageofs_out + rq->outputsize) >> PAGE_SHIFT;
157 const unsigned int nrpages_in =
158 PAGE_ALIGN(rq->inputsize) >> PAGE_SHIFT;
159 unsigned int inputmargin, inlen, outlen, pageofs;
159 unsigned int inlen, outlen, pageofs;
160 struct z_erofs_lzma *strm;
161 u8 *kin;
162 bool bounced = false;
163 int no, ni, j, err = 0;
164
165 /* 1. get the exact LZMA compressed size */
166 kin = kmap(*rq->in);
160 struct z_erofs_lzma *strm;
161 u8 *kin;
162 bool bounced = false;
163 int no, ni, j, err = 0;
164
165 /* 1. get the exact LZMA compressed size */
166 kin = kmap(*rq->in);
167 inputmargin = 0;
168 while (!kin[inputmargin & ~PAGE_MASK])
169 if (!(++inputmargin & ~PAGE_MASK))
170 break;
171
172 if (inputmargin >= PAGE_SIZE) {
167 err = z_erofs_fixup_insize(rq, kin + rq->pageofs_in,
168 min_t(unsigned int, rq->inputsize,
169 EROFS_BLKSIZ - rq->pageofs_in));
170 if (err) {
173 kunmap(*rq->in);
171 kunmap(*rq->in);
174 return -EFSCORRUPTED;
172 return err;
175 }
173 }
176 rq->inputsize -= inputmargin;
177
178 /* 2. get an available lzma context */
179again:
180 spin_lock(&z_erofs_lzma_lock);
181 strm = z_erofs_lzma_head;
182 if (!strm) {
183 spin_unlock(&z_erofs_lzma_lock);
184 wait_event(z_erofs_lzma_wq, READ_ONCE(z_erofs_lzma_head));
185 goto again;
186 }
187 z_erofs_lzma_head = strm->next;
188 spin_unlock(&z_erofs_lzma_lock);
189
190 /* 3. multi-call decompress */
191 inlen = rq->inputsize;
192 outlen = rq->outputsize;
193 xz_dec_microlzma_reset(strm->state, inlen, outlen,
194 !rq->partial_decoding);
195 pageofs = rq->pageofs_out;
174
175 /* 2. get an available lzma context */
176again:
177 spin_lock(&z_erofs_lzma_lock);
178 strm = z_erofs_lzma_head;
179 if (!strm) {
180 spin_unlock(&z_erofs_lzma_lock);
181 wait_event(z_erofs_lzma_wq, READ_ONCE(z_erofs_lzma_head));
182 goto again;
183 }
184 z_erofs_lzma_head = strm->next;
185 spin_unlock(&z_erofs_lzma_lock);
186
187 /* 3. multi-call decompress */
188 inlen = rq->inputsize;
189 outlen = rq->outputsize;
190 xz_dec_microlzma_reset(strm->state, inlen, outlen,
191 !rq->partial_decoding);
192 pageofs = rq->pageofs_out;
196 strm->buf.in = kin + inputmargin;
193 strm->buf.in = kin + rq->pageofs_in;
197 strm->buf.in_pos = 0;
194 strm->buf.in_pos = 0;
198 strm->buf.in_size = min_t(u32, inlen, PAGE_SIZE - inputmargin);
195 strm->buf.in_size = min_t(u32, inlen, PAGE_SIZE - rq->pageofs_in);
199 inlen -= strm->buf.in_size;
200 strm->buf.out = NULL;
201 strm->buf.out_pos = 0;
202 strm->buf.out_size = 0;
203
204 for (ni = 0, no = -1;;) {
205 enum xz_ret xz_err;
206

--- 84 unchanged lines hidden ---
196 inlen -= strm->buf.in_size;
197 strm->buf.out = NULL;
198 strm->buf.out_pos = 0;
199 strm->buf.out_size = 0;
200
201 for (ni = 0, no = -1;;) {
202 enum xz_ret xz_err;
203

--- 84 unchanged lines hidden ---