summaryrefslogtreecommitdiff
path: root/cmds-restore.c
diff options
context:
space:
mode:
authorNick Terrell <terrelln@fb.com>2017-09-08 13:29:23 -0700
committerDavid Sterba <dsterba@suse.com>2017-09-25 15:17:13 +0200
commit717a8b1e5d1ba69154ef84b35be75c9cf7730e1d (patch)
tree0f8d0e15f92171dc4cd7ed23ec789f50b83d486c /cmds-restore.c
parent86529862e1ff1b1b27aafc207b75b0c851fbfd34 (diff)
btrfs-progs: Add zstd support
Adds zstd support to the btrfs program. An optional dependency on libzstd >= 1.0.0 is added. Autoconf accepts `--enable-zstd' or `--disable-zstd' and defaults to detecting if libzstd is present using `pkg-config'. The patch is also available in my fork of btrfs-progs [1], which passes Travis-CI with the new tests. The prebuilt binary is available there. I haven't updated Android.mk. [1] https://github.com/terrelln/btrfs-progs/tree/devel Signed-off-by: Nick Terrell <terrelln@fb.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'cmds-restore.c')
-rw-r--r--cmds-restore.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/cmds-restore.c b/cmds-restore.c
index ebc5e5ab..6196a1ed 100644
--- a/cmds-restore.c
+++ b/cmds-restore.c
@@ -29,6 +29,9 @@
#include <lzo/lzoconf.h>
#include <lzo/lzo1x.h>
#include <zlib.h>
+#if BTRFSRESTORE_ZSTD
+#include <zstd.h>
+#endif
#include <regex.h>
#include <getopt.h>
#include <sys/types.h>
@@ -156,6 +159,50 @@ static int decompress_lzo(struct btrfs_root *root, unsigned char *inbuf,
return 0;
}
+static int decompress_zstd(const char *inbuf, char *outbuf, u64 compress_len,
+ u64 decompress_len)
+{
+#if !BTRFSRESTORE_ZSTD
+ error("btrfs not compiled with zstd support");
+ return -1;
+#else
+ ZSTD_DStream *strm;
+ size_t zret;
+ int ret = 0;
+ ZSTD_inBuffer in = {inbuf, compress_len, 0};
+ ZSTD_outBuffer out = {outbuf, decompress_len, 0};
+
+ strm = ZSTD_createDStream();
+ if (!strm) {
+ error("zstd create failed");
+ return -1;
+ }
+
+ zret = ZSTD_initDStream(strm);
+ if (ZSTD_isError(zret)) {
+ error("zstd init failed: %s", ZSTD_getErrorName(zret));
+ ret = -1;
+ goto out;
+ }
+
+ zret = ZSTD_decompressStream(strm, &out, &in);
+ if (ZSTD_isError(zret)) {
+ error("zstd decompress failed %s\n", ZSTD_getErrorName(zret));
+ ret = -1;
+ goto out;
+ }
+ if (zret != 0) {
+ error("zstd frame incomplete");
+ ret = -1;
+ goto out;
+ }
+
+out:
+ ZSTD_freeDStream(strm);
+ return ret;
+#endif
+}
+
static int decompress(struct btrfs_root *root, char *inbuf, char *outbuf,
u64 compress_len, u64 *decompress_len, int compress)
{
@@ -166,6 +213,9 @@ static int decompress(struct btrfs_root *root, char *inbuf, char *outbuf,
case BTRFS_COMPRESS_LZO:
return decompress_lzo(root, (unsigned char *)inbuf, outbuf,
compress_len, decompress_len);
+ case BTRFS_COMPRESS_ZSTD:
+ return decompress_zstd(inbuf, outbuf, compress_len,
+ *decompress_len);
default:
break;
}