| #!/bin/bash |
| # SPDX-License-Identifier: GPL-2.0 |
| # Copyright 2011 (C) Red Hat, Inc., Lukas Czerner <lczerner@redhat.com> |
| # |
| # FS QA Test No. 260 |
| # |
| # Purpose of this test is to check FITRIM argument handling to make sure |
| # that the argument processing is right and that it does not overflow. |
| # |
| . ./common/preamble |
| _begin_fstest auto quick trim |
| |
| status=0 |
| chpid=0 |
| mypid=$$ |
| |
| # Import common functions. |
| . ./common/filter |
| |
| # real QA test starts here |
| _supported_fs generic |
| _require_math |
| |
| _require_scratch |
| _scratch_mkfs >/dev/null 2>&1 |
| _scratch_mount |
| |
| _require_batched_discard $SCRATCH_MNT |
| |
| fssize=$($DF_PROG -k | grep "$SCRATCH_MNT" | grep "$SCRATCH_DEV" | awk '{print $3}') |
| |
| beyond_eofs=$(_math "$fssize*2048") |
| max_64bit=$(_math "2^64 - 1") |
| [ $FSTYP == "btrfs" ] && beyond_eofs=$max_64bit |
| |
| # All these tests should return EINVAL |
| # since the start is beyond the end of |
| # the file system |
| |
| echo "[+] Start beyond the end of fs (should fail)" |
| out=$($FSTRIM_PROG -o $beyond_eofs $SCRATCH_MNT 2>&1) |
| [ $? -eq 0 ] && status=1 |
| echo $out | _filter_scratch |
| |
| echo "[+] Start beyond the end of fs with len set (should fail)" |
| out=$($FSTRIM_PROG -o $beyond_eofs -l1M $SCRATCH_MNT 2>&1) |
| [ $? -eq 0 ] && status=1 |
| echo $out | _filter_scratch |
| |
| echo "[+] Start = 2^64-1 (should fail)" |
| out=$($FSTRIM_PROG -o $max_64bit $SCRATCH_MNT 2>&1) |
| [ $? -eq 0 ] && status=1 |
| echo $out | _filter_scratch |
| |
| echo "[+] Start = 2^64-1 and len is set (should fail)" |
| out=$($FSTRIM_PROG -o $max_64bit -l1M $SCRATCH_MNT 2>&1) |
| [ $? -eq 0 ] && status=1 |
| echo $out | _filter_scratch |
| |
| _scratch_unmount |
| _scratch_mkfs >/dev/null 2>&1 |
| _scratch_mount |
| |
| # All these tests should succeed |
| # since the length should be truncated |
| |
| echo "[+] Default length (should succeed)" |
| $FSTRIM_PROG $SCRATCH_MNT |
| [ $? -ne 0 ] && status=1 |
| echo "[+] Default length with start set (should succeed)" |
| $FSTRIM_PROG -o10M $SCRATCH_MNT |
| [ $? -ne 0 ] && status=1 |
| echo "[+] Length beyond the end of fs (should succeed)" |
| $FSTRIM_PROG -l $beyond_eofs $SCRATCH_MNT |
| [ $? -ne 0 ] && status=1 |
| echo "[+] Length beyond the end of fs with start set (should succeed)" |
| $FSTRIM_PROG -o10M -l $beyond_eofs $SCRATCH_MNT |
| [ $? -ne 0 ] && status=1 |
| |
| _scratch_unmount |
| _scratch_mkfs >/dev/null 2>&1 |
| _scratch_mount |
| |
| # This is a bit fuzzy, but since the file system is fresh |
| # there should be at least (fssize/2) free space to trim. |
| # This is supposed to catch wrong FITRIM argument handling |
| bytes=$($FSTRIM_PROG -v -o10M $SCRATCH_MNT | _filter_fstrim) |
| |
| if [ $bytes -gt $(_math "$fssize*1024") ]; then |
| status=1 |
| echo "After the full fs discard $bytes bytes were discarded"\ |
| "however the file system is $(_math "$fssize*1024") bytes long." |
| fi |
| |
| # Btrfs is special and this test does not apply to it |
| # It is because btrfs does not have not-yet-used parts of the device |
| # mapped and since we got here right after the mkfs, there is not |
| # enough free extents in the root tree. |
| # F2fs is also special. F2fs can tag a special flag TRIMMED_FLAG to |
| # indicate the whole filesystem is trimmed, so after mkfs/fstrim(), |
| # following fstrim() won't trim any block. |
| if [ $bytes -le $(_math "$fssize*512") ] && [ $FSTYP != "btrfs" ] && [ $FSTYP != "f2fs" ]; then |
| status=1 |
| echo "After the full fs discard $bytes bytes were discarded"\ |
| "however the file system is $(_math "$fssize*1024") bytes long." |
| fi |
| |
| # Now to catch overflows due to fsblk->allocation group number conversion |
| # This is different for every file system and it also apply just to some of |
| # them. In order to add check specific for file system you're interested in |
| # compute the arguments as you need and make the file system with proper |
| # alignment |
| |
| # (2^32-1) + 2 (this is set to overflow 32bit variable by 2) |
| base=$(_math "2^32+1") |
| |
| case $FSTYP in |
| ext[34]) |
| agsize=32768 |
| bsize=4096 |
| start=$(_math "$base*$agsize*$bsize") |
| len=$start |
| export MKFS_OPTIONS="-F -b $bsize -g $agsize" |
| ;; |
| xfs) |
| agsize=65538 |
| bsize=4096 |
| start=$(_math "$base*$agsize*$bsize") |
| len=$start |
| export MKFS_OPTIONS="-f -d agsize=$(_math "$agsize*$bsize") -b size=$bsize" |
| ;; |
| btrfs) |
| # Btrfs doesn't care about any of this, just test max_64bit |
| # since it'll fail |
| start=$max_64bit |
| len=$(_math "$start / 2") |
| ;; |
| *) |
| # (2^32-1) * 4096 * 65536 == 32bit max size * block size * ag size |
| start=$(_math "(2^32 - 1) * 4096 * 65536") |
| len=$start |
| ;; |
| esac |
| |
| _scratch_unmount |
| _scratch_mkfs >/dev/null 2>&1 |
| _scratch_mount |
| # It should fail since $start is beyond the end of file system |
| $FSTRIM_PROG -o$start -l10M $SCRATCH_MNT &> /dev/null |
| if [ $? -eq 0 ]; then |
| status=1 |
| echo "It seems that fs logic handling start"\ |
| "argument overflows" |
| fi |
| |
| _scratch_unmount |
| _scratch_mkfs >/dev/null 2>&1 |
| _scratch_mount |
| |
| # len should be big enough to cover the whole file system, so if the |
| # number of discarded bytes is smaller than file system size/2 then it |
| # most likely overflowed |
| # Btrfs is special and this test does not apply to it |
| # It is because btrfs does not have not-yet-used parts of the device |
| # mapped and since we got here right after the mkfs, there is not |
| # enough free extents in the root tree. |
| # F2fs is also special. F2fs can tag a special flag TRIMMED_FLAG to |
| # indicate the whole filesystem is trimmed, so after mkfs/fstrim(), |
| # following fstrim() won't trim any block. |
| bytes=$($FSTRIM_PROG -v -l$len $SCRATCH_MNT | _filter_fstrim) |
| if [ $bytes -le $(_math "$fssize*512") ] && [ $FSTYP != "btrfs" ] && [ $FSTYP != "f2fs" ]; then |
| status=1 |
| echo "It seems that fs logic handling len argument overflows" |
| fi |
| |
| echo "Test done" |
| exit |