1. 20 6月, 2017 8 次提交
  2. 10 6月, 2017 1 次提交
    • O
      Btrfs: fix delalloc accounting leak caused by u32 overflow · 70e7af24
      Omar Sandoval 提交于
      btrfs_calc_trans_metadata_size() does an unsigned 32-bit multiplication,
      which can overflow if num_items >= 4 GB / (nodesize * BTRFS_MAX_LEVEL * 2).
      For a nodesize of 16kB, this overflow happens at 16k items. Usually,
      num_items is a small constant passed to btrfs_start_transaction(), but
      we also use btrfs_calc_trans_metadata_size() for metadata reservations
      for extent items in btrfs_delalloc_{reserve,release}_metadata().
      
      In drop_outstanding_extents(), num_items is calculated as
      inode->reserved_extents - inode->outstanding_extents. The difference
      between these two counters is usually small, but if many delalloc
      extents are reserved and then the outstanding extents are merged in
      btrfs_merge_extent_hook(), the difference can become large enough to
      overflow in btrfs_calc_trans_metadata_size().
      
      The overflow manifests itself as a leak of a multiple of 4 GB in
      delalloc_block_rsv and the metadata bytes_may_use counter. This in turn
      can cause early ENOSPC errors. Additionally, these WARN_ONs in
      extent-tree.c will be hit when unmounting:
      
          WARN_ON(fs_info->delalloc_block_rsv.size > 0);
          WARN_ON(fs_info->delalloc_block_rsv.reserved > 0);
          WARN_ON(space_info->bytes_pinned > 0 ||
                  space_info->bytes_reserved > 0 ||
                  space_info->bytes_may_use > 0);
      
      Fix it by casting nodesize to a u64 so that
      btrfs_calc_trans_metadata_size() does a full 64-bit multiplication.
      While we're here, do the same in btrfs_calc_trunc_metadata_size(); this
      can't overflow with any existing uses, but it's better to be safe here
      than have another hard-to-debug problem later on.
      
      Cc: stable@vger.kernel.org
      Signed-off-by: NOmar Sandoval <osandov@fb.com>
      Reviewed-by: NDavid Sterba <dsterba@suse.com>
      Signed-off-by: NChris Mason <clm@fb.com>
      70e7af24
  3. 21 4月, 2017 1 次提交
  4. 18 4月, 2017 6 次提交
  5. 29 3月, 2017 1 次提交
    • G
      btrfs: Change qgroup_meta_rsv to 64bit · ce0dcee6
      Goldwyn Rodrigues 提交于
      Using an int value is causing qg->reserved to become negative and
      exclusive -EDQUOT to be reached prematurely.
      
      This affects exclusive qgroups only.
      
      TEST CASE:
      
      DEVICE=/dev/vdb
      MOUNTPOINT=/mnt
      SUBVOL=$MOUNTPOINT/tmp
      
      umount $SUBVOL
      umount $MOUNTPOINT
      
      mkfs.btrfs -f $DEVICE
      mount /dev/vdb $MOUNTPOINT
      btrfs quota enable $MOUNTPOINT
      btrfs subvol create $SUBVOL
      umount $MOUNTPOINT
      mount /dev/vdb $MOUNTPOINT
      mount -o subvol=tmp $DEVICE $SUBVOL
      btrfs qgroup limit -e 3G $SUBVOL
      
      btrfs quota rescan /mnt -w
      
      for i in `seq 1 44000`; do
        dd if=/dev/zero of=/mnt/tmp/test_$i bs=10k count=1
        if [[ $? > 0 ]]; then
           btrfs qgroup show -pcref $SUBVOL
           exit 1
        fi
      done
      Signed-off-by: NGoldwyn Rodrigues <rgoldwyn@suse.com>
      [ add reproducer to changelog ]
      Signed-off-by: NDavid Sterba <dsterba@suse.com>
      ce0dcee6
  6. 02 3月, 2017 1 次提交
  7. 28 2月, 2017 14 次提交
  8. 25 2月, 2017 1 次提交
  9. 17 2月, 2017 4 次提交
  10. 14 2月, 2017 3 次提交