diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2017-03-09 08:41:05 -0900 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2017-04-02 22:25:42 -0800 |
commit | 3d8f1a9b4c8c6544b24410523fd4ece6d35fcb34 (patch) | |
tree | 01a09a1535f425b6663db9a70646566da966ff1a | |
parent | dcabfc55070c8e89d66d83da857be86333327442 (diff) |
bcache: zstd compression supportbcachefs-zstd
-rw-r--r-- | fs/bcachefs/Kconfig | 1 | ||||
-rw-r--r-- | fs/bcachefs/bcachefs_format.h | 3 | ||||
-rw-r--r-- | fs/bcachefs/compress.c | 55 |
3 files changed, 58 insertions, 1 deletions
diff --git a/fs/bcachefs/Kconfig b/fs/bcachefs/Kconfig index cdd848f1e4a6..bad70a54fdbd 100644 --- a/fs/bcachefs/Kconfig +++ b/fs/bcachefs/Kconfig @@ -9,6 +9,7 @@ config BCACHE_FS select FS_POSIX_ACL select LZ4_COMPRESS select LZ4_DECOMPRESS + select ZSTD select ZLIB_DEFLATE select ZLIB_INFLATE select CRYPTO_SHA256 diff --git a/fs/bcachefs/bcachefs_format.h b/fs/bcachefs/bcachefs_format.h index 0a0dc8708b94..e964a0831ecd 100644 --- a/fs/bcachefs/bcachefs_format.h +++ b/fs/bcachefs/bcachefs_format.h @@ -1025,7 +1025,8 @@ enum bch_compression_opts { BCH_COMPRESSION_NONE = 0, BCH_COMPRESSION_LZ4 = 1, BCH_COMPRESSION_GZIP = 2, - BCH_COMPRESSION_NR = 3, + BCH_COMPRESSION_ZSTD = 3, + BCH_COMPRESSION_NR = 4, }; /* backing device specific stuff: */ diff --git a/fs/bcachefs/compress.c b/fs/bcachefs/compress.c index 547ea73213e2..45da21cb8681 100644 --- a/fs/bcachefs/compress.c +++ b/fs/bcachefs/compress.c @@ -6,6 +6,7 @@ #include <linux/lz4.h> #include <linux/zlib.h> +#include <linux/zstd.h> enum bounced { BOUNCED_CONTIG, @@ -186,6 +187,22 @@ static int __bio_uncompress(struct bch_fs *c, struct bio *src, } break; } + case BCH_COMPRESSION_ZSTD: { + ZSTD_DCtx *dctx = ZSTD_createDCtx(); + + src_len = le32_to_cpup(src_data); + + ret = ZSTD_decompressDCtx(dctx, + dst_data, dst_len, + src_data + 4, src_len); + ZSTD_freeDCtx(dctx); + + if (ret != dst_len) { + pr_info("ret %i", ret); + ret = -EIO; + } + break; + } default: BUG(); } @@ -362,6 +379,41 @@ zlib_err: *src_len = strm.total_in; break; } + case BCH_COMPRESSION_ZSTD: { + ZSTD_CCtx *workspace = ZSTD_createCCtx(); + + *dst_len = dst->bi_iter.bi_size; + *src_len = src->bi_iter.bi_size; + + while (*src_len > block_bytes(c) && + (ret = ZSTD_compressCCtx(workspace, + dst_data + 4, *dst_len - 4, + src_data, *src_len, + 10)) <= 0) { + /* + * 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)); + } + + if (ret > 0) { + *((__le32 *) dst_data) = cpu_to_le32(ret); + *dst_len = ret + 4; + ret = 0; + } + + ZSTD_freeCCtx(workspace); + + if (ret) + goto err; + break; + } default: BUG(); } @@ -399,6 +451,9 @@ void bch2_bio_compress(struct bch_fs *c, unsigned orig_dst = dst->bi_iter.bi_size; unsigned orig_src = src->bi_iter.bi_size; + if (*compression_type == BCH_COMPRESSION_LZ4) + *compression_type = BCH_COMPRESSION_ZSTD; + /* Don't consume more than BCH_ENCODED_EXTENT_MAX from @src: */ src->bi_iter.bi_size = min(src->bi_iter.bi_size, BCH_ENCODED_EXTENT_MAX << 9); |