summaryrefslogtreecommitdiff
path: root/libbcachefs/compress.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2017-11-22 00:42:55 -0500
committerKent Overstreet <kent.overstreet@gmail.com>2017-11-22 00:50:47 -0500
commit22291ae84a029d65334d1a90b67b5031f45cd540 (patch)
treeab9fefe205577324915545b21535fcccbff89f48 /libbcachefs/compress.c
parent74cb92203293a8d5b16b078389f6b3dba5300e89 (diff)
Update bcachefs sources to 9e7ae5219c bcachefs: Make write points more dynamic
Diffstat (limited to 'libbcachefs/compress.c')
-rw-r--r--libbcachefs/compress.c47
1 files changed, 28 insertions, 19 deletions
diff --git a/libbcachefs/compress.c b/libbcachefs/compress.c
index c8a03c7f..7b45bb78 100644
--- a/libbcachefs/compress.c
+++ b/libbcachefs/compress.c
@@ -25,7 +25,7 @@ static struct bbuf __bounce_alloc(struct bch_fs *c, unsigned size, int rw)
{
void *b;
- BUG_ON(size > c->sb.encoded_extent_max);
+ BUG_ON(size > c->sb.encoded_extent_max << 9);
b = kmalloc(size, GFP_NOIO|__GFP_NOWARN);
if (b)
@@ -164,8 +164,8 @@ static int __bio_uncompress(struct bch_fs *c, struct bio *src,
}
break;
case BCH_COMPRESSION_LZ4:
- ret = LZ4_decompress_safe(src_data.b, dst_data,
- src_len, dst_len);
+ ret = LZ4_decompress_safe_partial(src_data.b, dst_data,
+ src_len, dst_len, dst_len);
if (ret != dst_len) {
ret = -EIO;
goto err;
@@ -269,7 +269,8 @@ int bch2_bio_uncompress(struct bch_fs *c, struct bio *src,
size_t dst_len = crc_uncompressed_size(NULL, &crc) << 9;
int ret = -ENOMEM;
- if (crc_uncompressed_size(NULL, &crc) < c->sb.encoded_extent_max)
+ if (crc_uncompressed_size(NULL, &crc) > c->sb.encoded_extent_max ||
+ crc_compressed_size(NULL, &crc) > c->sb.encoded_extent_max)
return -EIO;
dst_data = dst_len == dst_iter.bi_size
@@ -294,7 +295,7 @@ static int __bio_compress(struct bch_fs *c,
{
struct bbuf src_data = { NULL }, dst_data = { NULL };
unsigned pad;
- int ret;
+ int ret = 0;
dst_data = bio_map_or_bounce(c, dst, WRITE);
src_data = bio_map_or_bounce(c, src, READ);
@@ -307,23 +308,28 @@ static int __bio_compress(struct bch_fs *c,
void *workspace;
int len = src->bi_iter.bi_size;
- ret = 0;
-
workspace = mempool_alloc(&c->lz4_workspace_pool, GFP_NOIO);
- while (len > block_bytes(c) &&
- (!(ret = LZ4_compress_destSize(
+ while (1) {
+ if (len <= block_bytes(c)) {
+ ret = 0;
+ break;
+ }
+
+ ret = LZ4_compress_destSize(
src_data.b, dst_data.b,
&len, dst->bi_iter.bi_size,
- workspace)) ||
- (len & (block_bytes(c) - 1)))) {
- /*
- * On error, the compressed data was bigger than
- * dst_len - round down to nearest block and try again:
- */
+ workspace);
+ if (ret >= len) {
+ /* uncompressible: */
+ ret = 0;
+ break;
+ }
+
+ if (!(len & (block_bytes(c) - 1)))
+ break;
len = round_down(len, block_bytes(c));
}
-
mempool_free(workspace, &c->lz4_workspace_pool);
if (!ret)
@@ -331,6 +337,7 @@ static int __bio_compress(struct bch_fs *c,
*src_len = len;
*dst_len = ret;
+ ret = 0;
break;
}
case BCH_COMPRESSION_GZIP: {
@@ -446,20 +453,22 @@ int bch2_check_set_has_compressed_data(struct bch_fs *c,
unsigned compression_type)
{
switch (compression_type) {
- case BCH_COMPRESSION_NONE:
+ case BCH_COMPRESSION_OPT_NONE:
return 0;
- case BCH_COMPRESSION_LZ4:
+ case BCH_COMPRESSION_OPT_LZ4:
if (bch2_sb_test_feature(c->disk_sb, BCH_FEATURE_LZ4))
return 0;
bch2_sb_set_feature(c->disk_sb, BCH_FEATURE_LZ4);
break;
- case BCH_COMPRESSION_GZIP:
+ case BCH_COMPRESSION_OPT_GZIP:
if (bch2_sb_test_feature(c->disk_sb, BCH_FEATURE_GZIP))
return 0;
bch2_sb_set_feature(c->disk_sb, BCH_FEATURE_GZIP);
break;
+ default:
+ BUG();
}
return bch2_fs_compress_init(c);