| #! /bin/bash |
| # SPDX-License-Identifier: GPL-2.0 |
| # Copyright (c) 2021 Red Hat Inc. All Rights Reserved. |
| # |
| # FS QA Test 641 |
| # |
| # Test small swapfile which doesn't contain even a single page-aligned contiguous |
| # range of blocks. This case covered commit 5808fecc5723 ("iomap: Fix negative |
| # assignment to unsigned sis->pages in iomap_swapfile_activate"). |
| # |
| . ./common/preamble |
| _begin_fstest auto quick swap collapse |
| |
| # Import common functions |
| . ./common/filter |
| |
| _require_scratch |
| _require_scratch_swapfile |
| _require_test_program mkswap |
| _require_test_program swapon |
| _require_xfs_io_command fcollapse |
| |
| make_unaligned_swapfile() |
| { |
| local fname=$1 |
| local n=$((psize / bsize - 1)) |
| |
| # Make sure the swapfile doesn't contain even a single page-aligned |
| # contiguous range of blocks. This's necessary to cover the bug |
| $XFS_IO_PROG -f -t -c "pwrite 0 $(((psize + bsize) * n))" $fname >> $seqres.full 2>&1 |
| for((i=1; i<=n; i++));do |
| $XFS_IO_PROG -c "fcollapse $(((psize - bsize) * i)) $bsize" $fname |
| done |
| chmod 0600 $fname |
| $CHATTR_PROG +C $fname > /dev/null 2>&1 |
| $here/src/mkswap $fname |
| } |
| |
| _scratch_mkfs >> $seqres.full 2>&1 |
| _scratch_mount |
| psize=`_get_page_size` |
| bsize=`_get_file_block_size $SCRATCH_MNT` |
| # Due to we need page-unaligned blocks, so blocksize < pagesize is necessary. |
| # If not, try to make a smaller enough block size |
| if [ $bsize -ge $psize ];then |
| _scratch_unmount |
| _scratch_mkfs_blocksized 1024 >> $seqres.full 2>&1 |
| if [ $? -ne 0 ];then |
| _notrun "Can't make filesystem block size < page size." |
| fi |
| _scratch_mount |
| bsize=`_get_file_block_size $SCRATCH_MNT` |
| if [ $bsize -ne 1024 ];then |
| _notrun "Can't force 1024-byte file block size." |
| fi |
| fi |
| swapfile=$SCRATCH_MNT/$seq.swapfile |
| make_unaligned_swapfile $swapfile |
| # Expect EINVAL from swapon. If not, might miss 5808fecc5723 ("iomap: Fix |
| # negative assignment to unsigned sis->pages in iomap_swapfile_activate") |
| $here/src/swapon $swapfile |
| # Further testing, check if swap size <= swapfile size, if swapon passed |
| if [ $? -eq 0 ];then |
| swapsize=$(awk -v fname="$swapfile" '{if ($1~fname) print $3}' /proc/swaps) |
| swapsize=$((swapsize * 1024)) |
| filesize=$(_get_filesize $swapfile) |
| if [ $swapsize -gt $filesize ]; then |
| echo "Allocated swap size($swapsize) shouldn't be greater than swapfile size($filesize)" |
| fi |
| fi |
| swapoff $swapfile 2>/dev/null |
| |
| # success, all done |
| status=0 |
| exit |