1. 22 1月, 2018 3 次提交
  2. 28 11月, 2017 1 次提交
    • Q
      btrfs: Fix wild memory access in compression level parser · eae8d825
      Qu Wenruo 提交于
      [BUG]
      Kernel panic when mounting with "-o compress" mount option.
      KASAN will report like:
      ------
      ==================================================================
      BUG: KASAN: wild-memory-access in strncmp+0x31/0xc0
      Read of size 1 at addr d86735fce994f800 by task mount/662
      ...
      Call Trace:
       dump_stack+0xe3/0x175
       kasan_report+0x163/0x370
       __asan_load1+0x47/0x50
       strncmp+0x31/0xc0
       btrfs_compress_str2level+0x20/0x70 [btrfs]
       btrfs_parse_options+0xff4/0x1870 [btrfs]
       open_ctree+0x2679/0x49f0 [btrfs]
       btrfs_mount+0x1b7f/0x1d30 [btrfs]
       mount_fs+0x49/0x190
       vfs_kern_mount.part.29+0xba/0x280
       vfs_kern_mount+0x13/0x20
       btrfs_mount+0x31e/0x1d30 [btrfs]
       mount_fs+0x49/0x190
       vfs_kern_mount.part.29+0xba/0x280
       do_mount+0xaad/0x1a00
       SyS_mount+0x98/0xe0
       entry_SYSCALL_64_fastpath+0x1f/0xbe
      ------
      
      [Cause]
      For 'compress' and 'compress_force' options, its token doesn't expect
      any parameter so its args[0] contains uninitialized data.
      Accessing args[0] will cause above wild memory access.
      
      [Fix]
      For Opt_compress and Opt_compress_force, set compression level to
      the default.
      Signed-off-by: NQu Wenruo <wqu@suse.com>
      Reviewed-by: NDavid Sterba <dsterba@suse.com>
      [ set the default in advance ]
      Signed-off-by: NDavid Sterba <dsterba@suse.com>
      eae8d825
  3. 15 11月, 2017 1 次提交
    • L
      Btrfs: add write_flags for compression bio · f82b7359
      Liu Bo 提交于
      Compression code path has only flaged bios with REQ_OP_WRITE no matter
      where the bios come from, but it could be a sync write if fsync starts
      this writeback or a normal writeback write if wb kthread starts a
      periodic writeback.
      
      It breaks the rule that sync writes and writeback writes need to be
      differentiated from each other, because from the POV of block layer,
      all bios need to be recognized by these flags in order to do some
      management, e.g. throttlling.
      
      This passes writeback_control to compression write path so that it can
      send bios with proper flags to block layer.
      Signed-off-by: NLiu Bo <bo.li.liu@oracle.com>
      Reviewed-by: NDavid Sterba <dsterba@suse.com>
      Signed-off-by: NDavid Sterba <dsterba@suse.com>
      f82b7359
  4. 02 11月, 2017 9 次提交
  5. 30 10月, 2017 1 次提交
  6. 26 9月, 2017 2 次提交
  7. 16 8月, 2017 3 次提交
    • T
      Btrfs: add skeleton code for compression heuristic · c2fcdcdf
      Timofey Titovets 提交于
      Add skeleton code for compresison heuristics. Now it iterates over all
      the pages, but in the end always says "yes, compress please", ie it does
      not change the current behaviour.
      
      In the future we're going to add various heuristics to analyze the data.
      This patch can be used as a baseline for measuring if the effectivness
      and performance.
      Signed-off-by: NTimofey Titovets <nefelim4ag@gmail.com>
      Reviewed-by: NDavid Sterba <dsterba@suse.com>
      [ enhanced changelog, modified comments ]
      Signed-off-by: NDavid Sterba <dsterba@suse.com>
      c2fcdcdf
    • N
      btrfs: Keep one more workspace around · 26b28dce
      Nick Terrell 提交于
      find_workspace() allocates up to num_online_cpus() + 1 workspaces.
      free_workspace() will only keep num_online_cpus() workspaces. When
      (de)compressing we will allocate num_online_cpus() + 1 workspaces, then
      free one, and repeat. Instead, we can just keep num_online_cpus() + 1
      workspaces around, and never have to allocate/free another workspace in the
      common case.
      
      I tested on a Ubuntu 14.04 VM with 2 cores and 4 GiB of RAM. I mounted a
      BtrFS partition with -o compress-force={lzo,zlib,zstd} and logged whenever
      a workspace was allocated of freed. Then I copied vmlinux (527 MB) to the
      partition. Before the patch, during the copy it would allocate and free 5-6
      workspaces. After, it only allocated the initial 3. This held true for lzo,
      zlib, and zstd. The time it took to execute cp vmlinux /mnt/btrfs && sync
      dropped from 1.70s to 1.44s with lzo compression, and from 2.04s to 1.80s
      for zstd compression.
      Signed-off-by: NNick Terrell <terrelln@fb.com>
      Reviewed-by: NOmar Sandoval <osandov@fb.com>
      Signed-off-by: NDavid Sterba <dsterba@suse.com>
      26b28dce
    • N
      btrfs: Add zstd support · 5c1aab1d
      Nick Terrell 提交于
      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/zstdSigned-off-by: NNick Terrell <terrelln@fb.com>
      Signed-off-by: NChris Mason <clm@fb.com>
      5c1aab1d
  8. 15 7月, 2017 1 次提交
  9. 21 6月, 2017 1 次提交
  10. 20 6月, 2017 6 次提交
  11. 09 6月, 2017 1 次提交
  12. 18 4月, 2017 1 次提交
  13. 28 2月, 2017 6 次提交
  14. 17 2月, 2017 1 次提交
  15. 14 2月, 2017 1 次提交
    • N
      btrfs: Make btrfs_ino take a struct btrfs_inode · 4a0cc7ca
      Nikolay Borisov 提交于
      Currently btrfs_ino takes a struct inode and this causes a lot of
      internal btrfs functions which consume this ino to take a VFS inode,
      rather than btrfs' own struct btrfs_inode. In order to fix this "leak"
      of VFS structs into the internals of btrfs first it's necessary to
      eliminate all uses of struct inode for the purpose of inode. This patch
      does that by using BTRFS_I to convert an inode to btrfs_inode. With
      this problem eliminated subsequent patches will start eliminating the
      passing of struct inode altogether, eventually resulting in a lot cleaner
      code.
      Signed-off-by: NNikolay Borisov <n.borisov.lkml@gmail.com>
      [ fix btrfs_get_extent tracepoint prototype ]
      Signed-off-by: NDavid Sterba <dsterba@suse.com>
      4a0cc7ca
  16. 11 2月, 2017 1 次提交
    • O
      Btrfs: fix btrfs_decompress_buf2page() · 6e78b3f7
      Omar Sandoval 提交于
      If btrfs_decompress_buf2page() is handed a bio with its page in the
      middle of the working buffer, then we adjust the offset into the working
      buffer. After we copy into the bio, we advance the iterator by the
      number of bytes we copied. Then, we have some logic to handle the case
      of discontiguous pages and adjust the offset into the working buffer
      again. However, if we didn't advance the bio to a new page, we may enter
      this case in error, essentially repeating the adjustment that we already
      made when we entered the function. The end result is bogus data in the
      bio.
      
      Previously, we only checked for this case when we advanced to a new
      page, but the conversion to bio iterators changed that. This restores
      the old, correct behavior.
      
      A case I saw when testing with zlib was:
      
          buf_start = 42769
          total_out = 46865
          working_bytes = total_out - buf_start = 4096
          start_byte = 45056
      
      The condition (total_out > start_byte && buf_start < start_byte) is
      true, so we adjust the offset:
      
          buf_offset = start_byte - buf_start = 2287
          working_bytes -= buf_offset = 1809
          current_buf_start = buf_start = 42769
      
      Then, we copy
      
          bytes = min(bvec.bv_len, PAGE_SIZE - buf_offset, working_bytes) = 1809
          buf_offset += bytes = 4096
          working_bytes -= bytes = 0
          current_buf_start += bytes = 44578
      
      After bio_advance(), we are still in the same page, so start_byte is the
      same. Then, we check (total_out > start_byte && current_buf_start < start_byte),
      which is true! So, we adjust the values again:
      
          buf_offset = start_byte - buf_start = 2287
          working_bytes = total_out - start_byte = 1809
          current_buf_start = buf_start + buf_offset = 45056
      
      But note that working_bytes was already zero before this, so we should
      have stopped copying.
      
      Fixes: 974b1adc ("btrfs: use bio iterators for the decompression handlers")
      Reported-by: NPat Erley <pat-lkml@erley.org>
      Reviewed-by: NChris Mason <clm@fb.com>
      Signed-off-by: NOmar Sandoval <osandov@fb.com>
      Signed-off-by: NChris Mason <clm@fb.com>
      Reviewed-by: NLiu Bo <bo.li.liu@oracle.com>
      Tested-by: NLiu Bo <bo.li.liu@oracle.com>
      6e78b3f7
  17. 06 12月, 2016 1 次提交