diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2017-11-22 00:42:55 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2017-11-22 00:50:47 -0500 |
commit | 22291ae84a029d65334d1a90b67b5031f45cd540 (patch) | |
tree | ab9fefe205577324915545b21535fcccbff89f48 /libbcachefs/compress.c | |
parent | 74cb92203293a8d5b16b078389f6b3dba5300e89 (diff) |
Update bcachefs sources to 9e7ae5219c bcachefs: Make write points more dynamic
Diffstat (limited to 'libbcachefs/compress.c')
-rw-r--r-- | libbcachefs/compress.c | 47 |
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); |