aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/props.c
diff options
context:
space:
mode:
authorNick Terrell <terrelln@fb.com>2017-08-09 22:39:02 -0400
committerChris Mason <clm@fb.com>2017-08-15 12:02:09 -0400
commit5c1aab1dd5445ed8bdcdbb575abc1b0d7ee5b2e7 (patch)
tree3dbf4bef55ed320a36623f9fde983ee3ebb9f621 /fs/btrfs/props.c
parent73f3d1b48f5069d46ba48aa28c2898dc93185560 (diff)
btrfs: Add zstd support
Add zstd compression and decompression support to BtrFS. zstd at its fastest level compresses almost as well as zlib, while offering much faster compression and decompression, approaching lzo speeds. I benchmarked btrfs with zstd compression against no compression, lzo compression, and zlib compression. I benchmarked two scenarios. Copying a set of files to btrfs, and then reading the files. Copying a tarball to btrfs, extracting it to btrfs, and then reading the extracted files. After every operation, I call `sync` and include the sync time. Between every pair of operations I unmount and remount the filesystem to avoid caching. The benchmark files can be found in the upstream zstd source repository under `contrib/linux-kernel/{btrfs-benchmark.sh,btrfs-extract-benchmark.sh}` [1] [2]. I ran the benchmarks on a Ubuntu 14.04 VM with 2 cores and 4 GiB of RAM. The VM is running on a MacBook Pro with a 3.1 GHz Intel Core i7 processor, 16 GB of RAM, and a SSD. The first compression benchmark is copying 10 copies of the unzipped Silesia corpus [3] into a BtrFS filesystem mounted with `-o compress-force=Method`. The decompression benchmark times how long it takes to `tar` all 10 copies into `/dev/null`. The compression ratio is measured by comparing the output of `df` and `du`. See the benchmark file [1] for details. I benchmarked multiple zstd compression levels, although the patch uses zstd level 1. | Method | Ratio | Compression MB/s | Decompression speed | |---------|-------|------------------|---------------------| | None | 0.99 | 504 | 686 | | lzo | 1.66 | 398 | 442 | | zlib | 2.58 | 65 | 241 | | zstd 1 | 2.57 | 260 | 383 | | zstd 3 | 2.71 | 174 | 408 | | zstd 6 | 2.87 | 70 | 398 | | zstd 9 | 2.92 | 43 | 406 | | zstd 12 | 2.93 | 21 | 408 | | zstd 15 | 3.01 | 11 | 354 | The next benchmark first copies `linux-4.11.6.tar` [4] to btrfs. Then it measures the compression ratio, extracts the tar, and deletes the tar. Then it measures the compression ratio again, and `tar`s the extracted files into `/dev/null`. See the benchmark file [2] for details. | Method | Tar Ratio | Extract Ratio | Copy (s) | Extract (s)| Read (s) | |--------|-----------|---------------|----------|------------|----------| | None | 0.97 | 0.78 | 0.981 | 5.501 | 8.807 | | lzo | 2.06 | 1.38 | 1.631 | 8.458 | 8.585 | | zlib | 3.40 | 1.86 | 7.750 | 21.544 | 11.744 | | zstd 1 | 3.57 | 1.85 | 2.579 | 11.479 | 9.389 | [1] https://github.com/facebook/zstd/blob/dev/contrib/linux-kernel/btrfs-benchmark.sh [2] https://github.com/facebook/zstd/blob/dev/contrib/linux-kernel/btrfs-extract-benchmark.sh [3] http://sun.aei.polsl.pl/~sdeor/index.php?page=silesia [4] https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.11.6.tar.xz zstd source repository: https://github.com/facebook/zstd Signed-off-by: Nick Terrell <terrelln@fb.com> Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs/btrfs/props.c')
-rw-r--r--fs/btrfs/props.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/fs/btrfs/props.c b/fs/btrfs/props.c
index 4b23ae5d0e5c..20631e9273a0 100644
--- a/fs/btrfs/props.c
+++ b/fs/btrfs/props.c
@@ -390,6 +390,8 @@ static int prop_compression_validate(const char *value, size_t len)
390 return 0; 390 return 0;
391 else if (!strncmp("zlib", value, len)) 391 else if (!strncmp("zlib", value, len))
392 return 0; 392 return 0;
393 else if (!strncmp("zstd", value, len))
394 return 0;
393 395
394 return -EINVAL; 396 return -EINVAL;
395} 397}
@@ -412,6 +414,8 @@ static int prop_compression_apply(struct inode *inode,
412 type = BTRFS_COMPRESS_LZO; 414 type = BTRFS_COMPRESS_LZO;
413 else if (!strncmp("zlib", value, len)) 415 else if (!strncmp("zlib", value, len))
414 type = BTRFS_COMPRESS_ZLIB; 416 type = BTRFS_COMPRESS_ZLIB;
417 else if (!strncmp("zstd", value, len))
418 type = BTRFS_COMPRESS_ZSTD;
415 else 419 else
416 return -EINVAL; 420 return -EINVAL;
417 421
@@ -429,6 +433,8 @@ static const char *prop_compression_extract(struct inode *inode)
429 return "zlib"; 433 return "zlib";
430 case BTRFS_COMPRESS_LZO: 434 case BTRFS_COMPRESS_LZO:
431 return "lzo"; 435 return "lzo";
436 case BTRFS_COMPRESS_ZSTD:
437 return "zstd";
432 } 438 }
433 439
434 return NULL; 440 return NULL;