| #! /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 |