1. 16 8月, 2017 1 次提交
    • 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
  2. 15 7月, 2017 1 次提交
  3. 21 6月, 2017 1 次提交
  4. 20 6月, 2017 6 次提交
  5. 09 6月, 2017 1 次提交
  6. 18 4月, 2017 1 次提交
  7. 28 2月, 2017 6 次提交
  8. 17 2月, 2017 1 次提交
  9. 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
  10. 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
  11. 06 12月, 2016 3 次提交
  12. 30 11月, 2016 4 次提交
  13. 18 10月, 2016 1 次提交
  14. 27 9月, 2016 2 次提交
  15. 26 7月, 2016 1 次提交
  16. 08 6月, 2016 2 次提交
  17. 10 5月, 2016 4 次提交
  18. 27 4月, 2016 3 次提交
    • D
      btrfs: make find_workspace warn if there are no workspaces · ae55b9ec
      David Sterba 提交于
      Be verbose if there are no workspaces at all, ie. the module init time
      preallocation failed.
      Signed-off-by: NDavid Sterba <dsterba@suse.com>
      ae55b9ec
    • D
      btrfs: make find_workspace always succeed · 3b501d18
      David Sterba 提交于
      With just one preallocated workspace we can guarantee forward progress
      even if there's no memory available for new workspaces. The cost is more
      waiting but we also get rid of several error paths.
      
      On average, there will be several idle workspaces, so the waiting
      penalty won't be so bad.
      
      In the worst case, all cpus will compete for one workspace until there's
      some memory. Attempts to allocate a new one are done each time the
      waiters are woken up.
      Signed-off-by: NDavid Sterba <dsterba@suse.com>
      3b501d18
    • D
      btrfs: preallocate compression workspaces · 3853368b
      David Sterba 提交于
      Preallocate one workspace for each compression type so we can guarantee
      forward progress in the worst case. A failure cannot be a hard error as
      we might not use compression at all on the filesystem. If we can't
      allocate the workspaces later when need them, it might actually
      deadlock, but in such situation the system has effectively not enough
      memory to operate properly.
      Signed-off-by: NDavid Sterba <dsterba@suse.com>
      3853368b