diff options
Diffstat (limited to 'libbcachefs/compress.c')
-rw-r--r-- | libbcachefs/compress.c | 38 |
1 files changed, 17 insertions, 21 deletions
diff --git a/libbcachefs/compress.c b/libbcachefs/compress.c index 547ea732..62b42042 100644 --- a/libbcachefs/compress.c +++ b/libbcachefs/compress.c @@ -148,9 +148,10 @@ static int __bio_uncompress(struct bch_fs *c, struct bio *src, switch (crc.compression_type) { case BCH_COMPRESSION_LZ4: - ret = lz4_decompress(src_data, &src_len, - dst_data, dst_len); - if (ret) { + ret = LZ4_decompress_safe(src_data, dst_data, + src_len, dst_len); + + if (ret != dst_len) { ret = -EIO; goto err; } @@ -286,32 +287,27 @@ static int __bio_compress(struct bch_fs *c, switch (compression_type) { case BCH_COMPRESSION_LZ4: { void *workspace; - - *dst_len = dst->bi_iter.bi_size; - *src_len = src->bi_iter.bi_size; + int srclen = src->bi_iter.bi_size; + ret = 0; workspace = mempool_alloc(&c->lz4_workspace_pool, GFP_NOIO); - while (*src_len > block_bytes(c) && - (ret = lz4_compress(src_data, *src_len, - dst_data, dst_len, - workspace))) { - /* - * On error, the compressed data was bigger than - * dst_len, and -ret is the amount of data we were able - * to compress - round down to nearest block and try - * again: - */ - BUG_ON(ret > 0); - BUG_ON(-ret >= *src_len); - - *src_len = round_down(-ret, block_bytes(c)); + while (srclen > block_bytes(c) && + (ret = LZ4_compress_destSize(src_data, dst_data, + &srclen, dst->bi_iter.bi_size, + workspace)) && + (srclen & (block_bytes(c) - 1))) { + /* Round down to nearest block and try again: */ + srclen = round_down(srclen, block_bytes(c)); } mempool_free(workspace, &c->lz4_workspace_pool); - if (ret) + if (!ret) goto err; + + *src_len = srclen; + *dst_len = ret; break; } case BCH_COMPRESSION_GZIP: { |