diff options
author | Gao Xiang <hsiangkao@linux.alibaba.com> | 2021-12-28 08:46:01 +0300 |
---|---|---|
committer | Gao Xiang <hsiangkao@linux.alibaba.com> | 2021-12-29 01:42:07 +0300 |
commit | 10e5f6e482e18dcdee9a9b7ff1a66f4977dd1ec2 (patch) | |
tree | f78a209a88e2660e3e2ac6f49b94ba5ca512eaf6 /fs/erofs/decompressor.c | |
parent | d67aee76d41861cda99b1ea13f8bf33fd06c5f20 (diff) | |
download | linux-10e5f6e482e18dcdee9a9b7ff1a66f4977dd1ec2.tar.xz |
erofs: introduce z_erofs_fixup_insize
To prepare for the upcoming ztailpacking feature, introduce
z_erofs_fixup_insize() and pageofs_in to wrap up the process
to get the exact compressed size via zero padding.
Link: https://lore.kernel.org/r/20211228054604.114518-3-hsiangkao@linux.alibaba.com
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
Diffstat (limited to 'fs/erofs/decompressor.c')
-rw-r--r-- | fs/erofs/decompressor.c | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c index ebb478ade10b..92814913fe00 100644 --- a/fs/erofs/decompressor.c +++ b/fs/erofs/decompressor.c @@ -184,6 +184,24 @@ docopy: return src; } +/* + * Get the exact inputsize with zero_padding feature. + * - For LZ4, it should work if zero_padding feature is on (5.3+); + * - For MicroLZMA, it'd be enabled all the time. + */ +int z_erofs_fixup_insize(struct z_erofs_decompress_req *rq, const char *padbuf, + unsigned int padbufsize) +{ + const char *padend; + + padend = memchr_inv(padbuf, 0, padbufsize); + if (!padend) + return -EFSCORRUPTED; + rq->inputsize -= padend - padbuf; + rq->pageofs_in += padend - padbuf; + return 0; +} + static int z_erofs_lz4_decompress_mem(struct z_erofs_lz4_decompress_ctx *ctx, u8 *out) { @@ -198,21 +216,19 @@ static int z_erofs_lz4_decompress_mem(struct z_erofs_lz4_decompress_ctx *ctx, inputmargin = 0; support_0padding = false; - /* decompression inplace is only safe when zero_padding is enabled */ + /* LZ4 decompression inplace is only safe if zero_padding is enabled */ if (erofs_sb_has_zero_padding(EROFS_SB(rq->sb))) { support_0padding = true; - - while (!headpage[inputmargin & ~PAGE_MASK]) - if (!(++inputmargin & ~PAGE_MASK)) - break; - - if (inputmargin >= rq->inputsize) { + ret = z_erofs_fixup_insize(rq, headpage + rq->pageofs_in, + min_t(unsigned int, rq->inputsize, + EROFS_BLKSIZ - rq->pageofs_in)); + if (ret) { kunmap_atomic(headpage); - return -EIO; + return ret; } } - rq->inputsize -= inputmargin; + inputmargin = rq->pageofs_in; src = z_erofs_lz4_handle_overlap(ctx, headpage, &inputmargin, &maptype, support_0padding); if (IS_ERR(src)) |