mirror of
https://github.com/torvalds/linux.git
synced 2024-11-29 23:51:37 +00:00
erofs: support unaligned data decompression
Previously, compressed data was assumed as block-aligned. This should be changed due to in-block tail-packing inline data. Link: https://lore.kernel.org/r/20211228054604.114518-4-hsiangkao@linux.alibaba.com Reviewed-by: Chao Yu <chao@kernel.org> Signed-off-by: Yue Hu <huyue2@yulong.com> Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
This commit is contained in:
parent
10e5f6e482
commit
ab749badf9
@ -121,7 +121,7 @@ static int z_erofs_lz4_prepare_dstpages(struct z_erofs_lz4_decompress_ctx *ctx,
|
||||
|
||||
static void *z_erofs_lz4_handle_overlap(struct z_erofs_lz4_decompress_ctx *ctx,
|
||||
void *inpage, unsigned int *inputmargin, int *maptype,
|
||||
bool support_0padding)
|
||||
bool may_inplace)
|
||||
{
|
||||
struct z_erofs_decompress_req *rq = ctx->rq;
|
||||
unsigned int omargin, total, i, j;
|
||||
@ -130,7 +130,7 @@ static void *z_erofs_lz4_handle_overlap(struct z_erofs_lz4_decompress_ctx *ctx,
|
||||
|
||||
if (rq->inplace_io) {
|
||||
omargin = PAGE_ALIGN(ctx->oend) - ctx->oend;
|
||||
if (rq->partial_decoding || !support_0padding ||
|
||||
if (rq->partial_decoding || !may_inplace ||
|
||||
omargin < LZ4_DECOMPRESS_INPLACE_MARGIN(rq->inputsize))
|
||||
goto docopy;
|
||||
|
||||
@ -206,15 +206,13 @@ static int z_erofs_lz4_decompress_mem(struct z_erofs_lz4_decompress_ctx *ctx,
|
||||
u8 *out)
|
||||
{
|
||||
struct z_erofs_decompress_req *rq = ctx->rq;
|
||||
bool support_0padding = false, may_inplace = false;
|
||||
unsigned int inputmargin;
|
||||
u8 *headpage, *src;
|
||||
bool support_0padding;
|
||||
int ret, maptype;
|
||||
|
||||
DBG_BUGON(*rq->in == NULL);
|
||||
headpage = kmap_atomic(*rq->in);
|
||||
inputmargin = 0;
|
||||
support_0padding = false;
|
||||
|
||||
/* LZ4 decompression inplace is only safe if zero_padding is enabled */
|
||||
if (erofs_sb_has_zero_padding(EROFS_SB(rq->sb))) {
|
||||
@ -226,11 +224,13 @@ static int z_erofs_lz4_decompress_mem(struct z_erofs_lz4_decompress_ctx *ctx,
|
||||
kunmap_atomic(headpage);
|
||||
return ret;
|
||||
}
|
||||
may_inplace = !((rq->pageofs_in + rq->inputsize) &
|
||||
(EROFS_BLKSIZ - 1));
|
||||
}
|
||||
|
||||
inputmargin = rq->pageofs_in;
|
||||
src = z_erofs_lz4_handle_overlap(ctx, headpage, &inputmargin,
|
||||
&maptype, support_0padding);
|
||||
&maptype, may_inplace);
|
||||
if (IS_ERR(src))
|
||||
return PTR_ERR(src);
|
||||
|
||||
@ -320,7 +320,8 @@ static int z_erofs_shifted_transform(struct z_erofs_decompress_req *rq,
|
||||
{
|
||||
const unsigned int nrpages_out =
|
||||
PAGE_ALIGN(rq->pageofs_out + rq->outputsize) >> PAGE_SHIFT;
|
||||
const unsigned int righthalf = PAGE_SIZE - rq->pageofs_out;
|
||||
const unsigned int righthalf = min_t(unsigned int, rq->outputsize,
|
||||
PAGE_SIZE - rq->pageofs_out);
|
||||
unsigned char *src, *dst;
|
||||
|
||||
if (nrpages_out > 2) {
|
||||
@ -333,7 +334,7 @@ static int z_erofs_shifted_transform(struct z_erofs_decompress_req *rq,
|
||||
return 0;
|
||||
}
|
||||
|
||||
src = kmap_atomic(*rq->in);
|
||||
src = kmap_atomic(*rq->in) + rq->pageofs_in;
|
||||
if (rq->out[0]) {
|
||||
dst = kmap_atomic(rq->out[0]);
|
||||
memcpy(dst + rq->pageofs_out, src, righthalf);
|
||||
|
Loading…
Reference in New Issue
Block a user