1. 11 Jun, 2018 1 commit
    • Qu Wenruo's avatar
      btrfs: scrub: Don't use inode pages for device replace · ac0b4145
      Qu Wenruo authored
      [BUG]
      Btrfs can create compressed extent without checksum (even though it
      shouldn't), and if we then try to replace device containing such extent,
      the result device will contain all the uncompressed data instead of the
      compressed one.
      
      Test case already submitted to fstests:
      https://patchwork.kernel.org/patch/10442353/
      
      [CAUSE]
      When handling compressed extent without checksum, device replace will
      goe into copy_nocow_pages() function.
      
      In that function, btrfs will get all inodes referring to this data
      extents and then use find_or_create_page() to get pages direct from that
      inode.
      
      The problem here is, pages directly from inode are always uncompressed.
      And for compressed data extent, they mismatch with on-disk data.
      Thus this leads to corrupted compressed data extent written to replace
      device.
      
      [FIX]
      In this attempt, we could just remove the "optimization" branch, and let
      unified scrub_pages() to handle it.
      
      Although scrub_pages() won't bother reusing page cache, it will be a
      little slower, but it does the correct csum checking and won't cause
      such data corruption caused by "optimization".
      
      Note about the fix: this is the minimal fix that can be backported to
      older stable trees without conflicts. The whole callchain from
      copy_nocow_pages() can be deleted, and will be in followup patches.
      
      Fixes: ff023aac ("Btrfs: add code to scrub to copy read data to another disk")
      CC: stable@vger.kernel.org # 4.4+
      Reported-by: default avatarJames Harvey <jamespharvey20@gmail.com>
      Reviewed-by: default avatarJames Harvey <jamespharvey20@gmail.com>
      Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
      [ remove code removal, add note why ]
      Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
      ac0b4145
  2. 07 Jun, 2018 2 commits
    • Souptick Joarder's avatar
      btrfs: change return type of btrfs_page_mkwrite to vm_fault_t · a528a241
      Souptick Joarder authored
      Use the new return type vm_fault_t for fault handler. For now, this is
      just documenting that the function returns a VM_FAULT value rather than
      an errno. Once all instances are converted, vm_fault_t will become a
      distinct type.
      
      Reference commit 1c8f4220 ("mm: change return type to vm_fault_t")
      
      vmf_error() is the newly introduced inline function in 4.17-rc6.
      Signed-off-by: default avatarSouptick Joarder <jrdr.linux@gmail.com>
      Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
      Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
      a528a241
    • Robbie Ko's avatar
      Btrfs: fiemap: pass correct bytenr when fm_extent_count is zero · 9d311e11
      Robbie Ko authored
      [BUG]
      fm_mapped_extents is not correct when fm_extent_count is 0
      Like:
         # mount /dev/vdb5 /mnt/btrfs
         # dd if=/dev/zero bs=16K count=4 oflag=dsync of=/mnt/btrfs/file
         # xfs_io -c "fiemap -v" /mnt/btrfs/file
         /mnt/btrfs/file:
         EXT: FILE-OFFSET      BLOCK-RANGE      TOTAL FLAGS
           0: [0..127]:        25088..25215       128   0x1
      
      When user space wants to get the number of file extents,
      set fm_extent_count to 0 to run fiemap and then read fm_mapped_extents.
      
      In the above example, fiemap will return with fm_mapped_extents set to 4,
      but it should be 1 since there's only one entry in the output.
      
      [REASON]
      The problem seems to be that disko is only set if
      fieinfo->fi_extents_max is set. And this member is initialized, in the
      generic ioctl_fiemap function, to the value of used-passed
      fm_extent_count. So when the user passes 0 then fi_extent_max is also
      set to zero and this causes btrfs to not initialize disko at all.
      Eventually this leads emit_fiemap_extent being called with a bogus
      'phys' argument preventing proper fiemap entries merging.
      
      [FIX]
      Move the disko initialization earlier in extent_fiemap making it
      independent of user-passed arguments, allowing emit_fiemap_extent to
      properly handle consecutive extent entries.
      Signed-off-by: default avatarRobbie Ko <robbieko@synology.com>
      Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
      9d311e11
  3. 05 Jun, 2018 1 commit
  4. 31 May, 2018 3 commits
  5. 30 May, 2018 24 commits
  6. 29 May, 2018 9 commits