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 --- |