• Filipe Manana's avatar
    Btrfs: fix fitrim discarding device area reserved for boot loader's use · 8cdc7c5b
    Filipe Manana authored
    As of the 4.3 kernel release, the fitrim ioctl can now discard any region
    of a disk that is not allocated to any chunk/block group, including the
    first megabyte which is used for our primary superblock and by the boot
    loader (grub for example).
    
    Fix this by not allowing to trim/discard any region in the device starting
    with an offset not greater than min(alloc_start_mount_option, 1Mb), just
    as it was not possible before 4.3.
    
    A reproducer test case for xfstests follows.
    
      seq=`basename $0`
      seqres=$RESULT_DIR/$seq
      echo "QA output created by $seq"
      tmp=/tmp/$$
      status=1	# failure is the default!
      trap "_cleanup; exit \$status" 0 1 2 3 15
    
      _cleanup()
      {
          cd /
          rm -f $tmp.*
      }
    
      # get standard environment, filters and checks
      . ./common/rc
      . ./common/filter
    
      # real QA test starts here
      _need_to_be_root
      _supported_fs btrfs
      _supported_os Linux
      _require_scratch
    
      rm -f $seqres.full
    
      _scratch_mkfs >>$seqres.full 2>&1
    
      # Write to the [0, 64Kb[ and [68Kb, 1Mb[ ranges of the device. These ranges are
      # reserved for a boot loader to use (GRUB for example) and btrfs should never
      # use them - neither for allocating metadata/data nor should trim/discard them.
      # The range [64Kb, 68Kb[ is used for the primary superblock of the filesystem.
      $XFS_IO_PROG -c "pwrite -S 0xfd 0 64K" $SCRATCH_DEV | _filter_xfs_io
      $XFS_IO_PROG -c "pwrite -S 0xfd 68K 956K" $SCRATCH_DEV | _filter_xfs_io
    
      # Now mount the filesystem and perform a fitrim against it.
      _scratch_mount
      _require_batched_discard $SCRATCH_MNT
      $FSTRIM_PROG $SCRATCH_MNT
    
      # Now unmount the filesystem and verify the content of the ranges was not
      # modified (no trim/discard happened on them).
      _scratch_unmount
      echo "Content of the ranges [0, 64Kb] and [68Kb, 1Mb[ after fitrim:"
      od -t x1 -N $((64 * 1024)) $SCRATCH_DEV
      od -t x1 -j $((68 * 1024)) -N $((956 * 1024)) $SCRATCH_DEV
    
      status=0
      exit
    Reported-by: default avatarVincent Petry  <PVince81@yahoo.fr>
    Reported-by: default avatarAndrei Borzenkov <arvidjaar@gmail.com>
    Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=109341
    Fixes: 499f377f (btrfs: iterate over unused chunk space in FITRIM)
    Cc: stable@vger.kernel.org # 4.3+
    Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
    8cdc7c5b
volumes.c 181 KB