blob: a6efcd4cf4c1b828aa38752c2738e4aa3c014f19 [file] [log] [blame]
#! /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