Add support to uncompressed data layout with on-disk offset for compressed files.
Signed-off-by: Yue Hu <huy...@coolpad.com> --- include/erofs/decompress.h | 3 +++ lib/data.c | 8 +++++++- lib/decompress.c | 10 ++++++++-- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/include/erofs/decompress.h b/include/erofs/decompress.h index 82bf7b8..b622df5 100644 --- a/include/erofs/decompress.h +++ b/include/erofs/decompress.h @@ -23,6 +23,9 @@ struct z_erofs_decompress_req { unsigned int decodedskip; unsigned int inputsize, decodedlength; + /* head offset of uncompressed data */ + unsigned int shiftedhead; + /* indicate the algorithm will be used for decompression */ unsigned int alg; bool partial_decoding; diff --git a/lib/data.c b/lib/data.c index c2ecbc9..5e44db9 100644 --- a/lib/data.c +++ b/lib/data.c @@ -226,7 +226,7 @@ static int z_erofs_read_data(struct erofs_inode *inode, char *buffer, }; struct erofs_map_dev mdev; bool partial; - unsigned int bufsize = 0; + unsigned int bufsize = 0, head; char *raw = NULL; int ret = 0; @@ -313,10 +313,16 @@ static int z_erofs_read_data(struct erofs_inode *inode, char *buffer, if (ret < 0) break; + head = 0; + if (erofs_sb_has_fragments() && + map.m_algorithmformat == Z_EROFS_COMPRESSION_SHIFTED) + head = erofs_blkoff(end); + ret = z_erofs_decompress(&(struct z_erofs_decompress_req) { .in = raw, .out = buffer + end - offset, .decodedskip = skip, + .shiftedhead = head, .inputsize = map.m_plen, .decodedlength = length, .alg = map.m_algorithmformat, diff --git a/lib/decompress.c b/lib/decompress.c index 1661f91..08a0861 100644 --- a/lib/decompress.c +++ b/lib/decompress.c @@ -132,14 +132,20 @@ out: int z_erofs_decompress(struct z_erofs_decompress_req *rq) { if (rq->alg == Z_EROFS_COMPRESSION_SHIFTED) { + unsigned int count, rightpart; + if (rq->inputsize > EROFS_BLKSIZ) return -EFSCORRUPTED; DBG_BUGON(rq->decodedlength > EROFS_BLKSIZ); DBG_BUGON(rq->decodedlength < rq->decodedskip); - memcpy(rq->out, rq->in + rq->decodedskip, - rq->decodedlength - rq->decodedskip); + count = rq->decodedlength - rq->decodedskip; + rightpart = min(EROFS_BLKSIZ - rq->shiftedhead, count); + + memcpy(rq->out, rq->in + (erofs_sb_has_fragments() ? + rq->shiftedhead : rq->decodedskip), rightpart); + memcpy(rq->out + rightpart, rq->in, count - rightpart); return 0; } -- 2.17.1