blob: 9a0ec2c3809c51f61532d86370a2b6092007b3a2 [file] [log] [blame]
#! /bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2021 Oracle. All Rights Reserved.
#
# FS QA Test No. 643
#
# Regression test for commit:
#
# 36ca7943ac18 ("mm/swap: consider max pages in iomap_swapfile_add_extent")
#
# Xu Yu found that the iomap swapfile activation code failed to constrain
# itself to activating however many swap pages that the mm asked us for. This
# is an deviation in behavior from the classic swapfile code. It also leads to
# kernel memory corruption if the swapfile is cleverly constructed.
#
. ./common/preamble
_begin_fstest auto swap
# Override the default cleanup function.
_cleanup()
{
cd /
rm -f $tmp.*
test -n "$swapfile" && swapoff $swapfile &> /dev/null
}
. ./common/filter
# real QA test starts here
_supported_fs generic
_require_scratch_swapfile
_scratch_mkfs >> $seqres.full
_scratch_mount >> $seqres.full
# Assuming we're not borrowing a FAT16 partition from Windows 3.1, we need an
# unlikely enough name that we can grep /proc/swaps for this.
swapfile=$SCRATCH_MNT/386spart.par
before_blocks=$(_format_swapfile $swapfile 1m)
page_size=$(getconf PAGE_SIZE)
# Extend the length of the swapfile but do not rewrite the header.
# The subsequent swapon should set up 1MB worth of blocks, not 2MB.
$XFS_IO_PROG -f -c 'pwrite 1m 1m' $swapfile >> $seqres.full
_swapon_file $swapfile
after_blocks=$(swapon --show --bytes |grep $swapfile | awk '{print $3}')
swapoff $swapfile
# The swapon attempt should have found approximately the same number of blocks
# originally created by the mkswap.
# Unfortunately, mkswap and the kernel are a little odd -- the number of pages
# that mkswap writes into the swapfile header is one page less than the file
# size, and then the kernel itself doesn't always grab all the pages advertised
# in the header. Such cases include ext2 and ext3 with 1k block size and arm64
# with its 64k pages. Hence we let the number of swap pages increase by two pages.
page_variance=$(( page_size / 512 ))
_within_tolerance "swap blocks" $after_blocks $before_blocks 0 $page_variance -v
echo "pagesize: $page_size; before: $before_blocks; after: $after_blocks" >> $seqres.full
status=0
exit