mirror of
https://github.com/linux-apfs/apfstests.git
synced 2026-05-01 15:01:44 -07:00
a0bcdb6cbf
Filipe noticed that btrfs/220 started failing with some mount option changes I made recently, but upon closer inspection this test actually fails in a lot of different ways normally, specifically if you specify MOUNT_OPTIONS, or if you make an fs with the free space tree. Address all these issues by reworking how we test that the mount options are what we expect. First get what the default mount options are for a plain mount of SCRATCH_DEV. This is used as the baseline, so no matter how the mount options change in the future it will always work properly. Secondly instead of specifying a rigid order of the mount options we're testing, which breaks if we adjust the order in /proc/self/mounts, simply specify the options we're actually interested in checking. Then in the test function combine the common options with the new options we're testing, and then combine that with our actual options and use some sort magic to see if there's any difference. If there's no difference then we know we have everything set as expected, if not we fail. This patch addresses the initial issue that Filipe noticed, but also fixes the failures when you specified MOUNT_OPTIONS, or if you made the fs with the free space tree. Signed-off-by: Josef Bacik <josef@toxicpanda.com> Reviewed-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: Eryu Guan <guaneryu@gmail.com>
332 lines
10 KiB
Bash
Executable File
332 lines
10 KiB
Bash
Executable File
#! /bin/bash
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
# Copyright (C) 2020 SUSE Linux Products GmbH. All Rights Reserved.
|
|
#
|
|
# FS QA Test 220
|
|
#
|
|
# Test all existent mount options of btrfs
|
|
# * device= argument is already being test by btrfs/125
|
|
# * space cache test already covered by test btrfs/131
|
|
seq=`basename $0`
|
|
seqres=$RESULT_DIR/$seq
|
|
echo "QA output created by $seq"
|
|
|
|
here=`pwd`
|
|
tmp=/tmp/$$
|
|
status=1 # failure is the default!
|
|
trap "cleanup; exit \$status" 0 1 2 3 15
|
|
|
|
# get standard environment, filters and checks
|
|
. ./common/rc
|
|
. ./common/filter
|
|
|
|
# remove previous $seqres.full before test
|
|
rm -f $seqres.full
|
|
|
|
_supported_fs btrfs
|
|
_require_scratch
|
|
|
|
cleanup()
|
|
{
|
|
cd /
|
|
rm -f $tmp.*
|
|
}
|
|
|
|
# Compare the mounted flags with $opt_check. When the comparison fails, $opt is
|
|
# echoed to help to track which option was used to trigger the unexpected
|
|
# results.
|
|
test_mount_flags()
|
|
{
|
|
local opt
|
|
local opt_check
|
|
local stripped
|
|
opt="$1"
|
|
opt_check="$2"
|
|
|
|
active_opt=$(cat /proc/self/mounts | grep $SCRATCH_MNT | \
|
|
$AWK_PROG '{ print $4 }')
|
|
|
|
if [ "$opt_check" != "$DEFAULT_OPTS" ]; then
|
|
# We only care about the common things between defaults and the
|
|
# active set, so strip out the uniq lines between the two, and
|
|
# then we'll add this to our $opt_check which should equal
|
|
# $active_opt. We also strip 'rw' as we may be checking 'ro',
|
|
# so we need to adjust that accordingly
|
|
stripped=$(echo "$DEFAULT_OPTS,$active_opt" | tr ',' '\n' | \
|
|
sort | grep -v 'rw' | uniq -d | tr '\n' ',' | \
|
|
sed 's/.$//')
|
|
opt_check="$opt_check,$stripped"
|
|
fi
|
|
|
|
# We diff by putting our wanted opts together with the current opts,
|
|
# turning it into one option per line, sort'ing, and then printing out
|
|
# any uniq lines left. This will catch anything that is set that we're
|
|
# not expecting, or anything that wasn't set that we wanted.
|
|
#
|
|
# We strip 'rw' because some tests flip ro, so just ignore rw.
|
|
diff=$(echo "$opt_check,$active_opt" | tr ',' '\n' | \
|
|
sort | grep -v 'rw' | uniq -u)
|
|
if [ -n "$diff" ]; then
|
|
echo "Unexepcted mount options, checking for '$opt_check' in '$active_opt' using '$opt'"
|
|
fi
|
|
}
|
|
|
|
# Mounts using opt ($1), remounts using remount_opt ($2), and remounts again
|
|
# using opt again (1), checking if the mount opts are being enabled/disabled by
|
|
# using _check arguments ($3 and $4)
|
|
test_enable_disable_mount_opt()
|
|
{
|
|
local opt
|
|
local opt_check
|
|
local remount_opt
|
|
local remount_opt_check
|
|
opt="$1"
|
|
opt_check="$2"
|
|
remount_opt="$3"
|
|
remount_opt_check="$4"
|
|
|
|
_scratch_mount "-o $opt"
|
|
|
|
test_mount_flags $opt $opt_check
|
|
|
|
_scratch_remount $remount_opt
|
|
|
|
test_mount_flags $remount_opt $remount_opt_check
|
|
|
|
_scratch_remount $opt
|
|
|
|
test_mount_flags $opt $opt_check
|
|
|
|
_scratch_unmount
|
|
}
|
|
|
|
# Checks if mount options are applied and reverted correctly.
|
|
# By using options to mount ($1) and remount ($2), this function will mount,
|
|
# remount, and the mount with the original args, checking if the mount options
|
|
# match the _check args ($3 and $4).
|
|
|
|
# Later, opt and remount_opt are swapped, testing the counterpart option if used
|
|
# to first mount the fs.
|
|
test_roundtrip_mount()
|
|
{
|
|
local opt
|
|
local opt_check
|
|
local remount_opt
|
|
local remount_opt_check
|
|
opt="$1"
|
|
opt_check="$2"
|
|
remount_opt="$3"
|
|
remount_opt_check="$4"
|
|
|
|
# invert the args to make sure that both options work at mount and
|
|
# remount time
|
|
test_enable_disable_mount_opt $opt $opt_check $remount_opt $remount_opt_check
|
|
test_enable_disable_mount_opt $remount_opt $remount_opt_check $opt $opt_check
|
|
}
|
|
|
|
# Just mount and check if the options were mounted correctly by comparing the
|
|
# results with $opt_check
|
|
test_mount_opt()
|
|
{
|
|
local opt
|
|
local opt_check
|
|
local active_opt
|
|
opt="$1"
|
|
opt_check="$2"
|
|
|
|
_scratch_mount "-o $opt"
|
|
|
|
test_mount_flags $opt $opt_check
|
|
|
|
_scratch_unmount
|
|
}
|
|
|
|
# Test mount options that should fail, usually by wrong arguments to options
|
|
test_should_fail()
|
|
{
|
|
local opt
|
|
opt="$1"
|
|
|
|
# wrong $opt on purpose, should fail
|
|
_try_scratch_mount "-o $opt" >/dev/null 2>&1
|
|
if [ $? -ne 0 ]; then
|
|
return
|
|
fi
|
|
echo "Option $opt should fail to mount"
|
|
_scratch_unmount
|
|
}
|
|
|
|
# Try to mount using $opt, and bail our if the mount fails without errors. If
|
|
# the mount succeeds, then compare the mount options with $opt_check
|
|
test_optional_mount_opts()
|
|
{
|
|
local opt
|
|
local opt_check
|
|
opt="$1"
|
|
opt_check="$2"
|
|
|
|
# $opt not enabled, return without running any tests
|
|
_try_scratch_mount "-o $opt" >/dev/null 2>&1 || return
|
|
_scratch_unmount
|
|
|
|
# option enabled, run the test
|
|
test_mount_opt $opt $opt_check
|
|
}
|
|
|
|
# Testes related to subvolumes, from subvol and subvolid options.
|
|
test_subvol()
|
|
{
|
|
test_should_fail "subvol=vol2"
|
|
|
|
_scratch_mount "-o subvol=vol1"
|
|
if [ ! -f "$SCRATCH_MNT/file.txt" ]; then
|
|
echo "file.txt not found inside vol1 using subvol=vol1 mount option"
|
|
fi
|
|
_scratch_unmount
|
|
|
|
test_should_fail "subvolid=222"
|
|
|
|
_scratch_mount "-o subvolid=256"
|
|
if [ ! -f "$SCRATCH_MNT/file.txt" ]; then
|
|
echo "file.txt not found inside vol1 using subvolid=256 mount option"
|
|
fi
|
|
_scratch_unmount
|
|
|
|
# subvol and subvolid should point to the same subvolume
|
|
test_should_fail "-o subvol=vol1,subvolid=1234132"
|
|
|
|
test_mount_opt "subvol=vol1,subvolid=256" "subvolid=256,subvol=/vol1"
|
|
test_roundtrip_mount "subvol=vol1" "subvolid=256,subvol=/vol1" "subvolid=256" "subvolid=256,subvol=/vol1"
|
|
}
|
|
|
|
# These options are enable at kernel compile time, so no bother if they fail
|
|
test_optional_kernel_features()
|
|
{
|
|
# Test options that are enabled by kernel config, and so can fail safely
|
|
test_optional_mount_opts "check_int" "check_int"
|
|
test_optional_mount_opts "check_int_data" "check_int_data"
|
|
test_optional_mount_opts "check_int_print_mask=123" "check_int_print_mask=123"
|
|
|
|
test_should_fail "fragment=invalid"
|
|
test_optional_mount_opts "fragment=all" "fragment=data,fragment=metadata"
|
|
test_optional_mount_opts "fragment=data" "fragment=data"
|
|
test_optional_mount_opts "fragment=metadata" "fragment=metadata"
|
|
}
|
|
|
|
test_non_revertible_options()
|
|
{
|
|
test_mount_opt "clear_cache" "clear_cache"
|
|
test_mount_opt "degraded" "degraded"
|
|
|
|
test_mount_opt "inode_cache" "inode_cache"
|
|
|
|
# nologreplay should be used only with
|
|
test_should_fail "nologreplay"
|
|
test_mount_opt "nologreplay,ro" "ro,rescue=nologreplay"
|
|
|
|
# norecovery should be used only with. This options is an alias to nologreplay
|
|
test_should_fail "norecovery"
|
|
test_mount_opt "norecovery,ro" "ro,rescue=nologreplay"
|
|
test_mount_opt "rescan_uuid_tree" "rescan_uuid_tree"
|
|
test_mount_opt "skip_balance" "skip_balance"
|
|
test_mount_opt "user_subvol_rm_allowed" "user_subvol_rm_allowed"
|
|
|
|
test_should_fail "rescue=invalid"
|
|
|
|
# nologreplay requires readonly
|
|
test_should_fail "rescue=nologreplay"
|
|
test_mount_opt "rescue=nologreplay,ro" "ro,rescue=nologreplay"
|
|
}
|
|
|
|
# All these options can be reverted (with their "no" counterpart), or can have
|
|
# their values set to default on remount
|
|
test_revertible_options()
|
|
{
|
|
test_roundtrip_mount "acl" "$DEFAULT_OPTS" "noacl" "noacl"
|
|
test_roundtrip_mount "autodefrag" "autodefrag" "noautodefrag" "$DEFAULT_OPTS"
|
|
test_roundtrip_mount "barrier" "$DEFAULT_OPTS" "nobarrier" "nobarrier"
|
|
|
|
test_should_fail "commit=-10"
|
|
# commit=0 sets the default, so btrfs hides this mount opt
|
|
test_roundtrip_mount "commit=35" "commit=35" "commit=0" "$DEFAULT_OPTS"
|
|
|
|
test_should_fail "compress=invalid"
|
|
test_should_fail "compress-force=invalid"
|
|
test_roundtrip_mount "compress" "compress=zlib:3" "compress=lzo" "compress=lzo"
|
|
test_roundtrip_mount "compress=zstd" "compress=zstd:3" "compress=no" "$DEFAULT_OPTS"
|
|
test_roundtrip_mount "compress-force=no" "$DEFAULT_OPTS" "compress-force=zstd" "compress-force=zstd:3"
|
|
# zlib's max level is 9 and zstd's max level is 15
|
|
test_roundtrip_mount "compress=zlib:20" "compress=zlib:9" "compress=zstd:16" "compress=zstd:15"
|
|
test_roundtrip_mount "compress-force=lzo" "compress-force=lzo" "compress-force=zlib:4" "compress-force=zlib:4"
|
|
|
|
# on remount, if we only pass datacow after nodatacow was used it will remain with nodatasum
|
|
test_roundtrip_mount "nodatacow" "nodatasum,nodatacow" "datacow,datasum" "$DEFAULT_OPTS"
|
|
# nodatacow disabled compression
|
|
test_roundtrip_mount "compress-force" "compress-force=zlib:3" "nodatacow" "nodatasum,nodatacow"
|
|
|
|
# nodatacow disabled both datacow and datasum, and datasum enabled datacow and datasum
|
|
test_roundtrip_mount "nodatacow" "nodatasum,nodatacow" "datasum" "$DEFAULT_OPTS"
|
|
test_roundtrip_mount "nodatasum" "nodatasum" "datasum" "$DEFAULT_OPTS"
|
|
|
|
test_should_fail "discard=invalid"
|
|
test_roundtrip_mount "discard" "discard" "discard=sync" "discard"
|
|
test_roundtrip_mount "discard=async" "discard=async" "discard=sync" "discard"
|
|
test_roundtrip_mount "discard=sync" "discard" "nodiscard" "$DEFAULT_OPTS"
|
|
|
|
test_roundtrip_mount "enospc_debug" "enospc_debug" "noenospc_debug" "$DEFAULT_OPTS"
|
|
|
|
test_should_fail "fatal_errors=pani"
|
|
# fatal_errors=bug is the default
|
|
test_roundtrip_mount "fatal_errors=panic" "fatal_errors=panic" "fatal_errors=bug" "$DEFAULT_OPTS"
|
|
|
|
test_roundtrip_mount "flushoncommit" "flushoncommit" "noflushoncommit" "$DEFAULT_OPTS"
|
|
|
|
# 2048 is the max_inline default value
|
|
test_roundtrip_mount "max_inline=1024" "max_inline=1024" "max_inline=2048" "$DEFAULT_OPTS"
|
|
|
|
test_roundtrip_mount "metadata_ratio=0" "$DEFAULT_OPTS" "metadata_ratio=10" "metadata_ratio=10"
|
|
|
|
# ssd_spread implies ssd, while nossd_spread only disables ssd_spread
|
|
test_roundtrip_mount "ssd_spread" "ssd_spread" "nossd" "nossd"
|
|
test_roundtrip_mount "ssd" "ssd" "nossd" "nossd"
|
|
test_mount_opt "ssd" "ssd"
|
|
|
|
test_should_fail "thread_pool=-10"
|
|
test_should_fail "thread_pool=0"
|
|
test_roundtrip_mount "thread_pool=10" "thread_pool=10" "thread_pool=50" "thread_pool=50"
|
|
|
|
test_roundtrip_mount "notreelog" "notreelog" "treelog" "$DEFAULT_OPTS"
|
|
}
|
|
|
|
# real QA test starts here
|
|
_scratch_mkfs >/dev/null
|
|
|
|
# This test checks mount options, so having random MOUNT_OPTIONS set could
|
|
# affect the results of a few of these tests.
|
|
MOUNT_OPTIONS=
|
|
|
|
# create a subvolume that will be used later
|
|
_scratch_mount
|
|
|
|
# We need to save the current default options so we can validate our changes
|
|
# from one mount option to the next one.
|
|
DEFAULT_OPTS=$(cat /proc/self/mounts | grep $SCRATCH_MNT | \
|
|
$AWK_PROG '{ print $4 }')
|
|
|
|
$BTRFS_UTIL_PROG subvolume create "$SCRATCH_MNT/vol1" > /dev/null
|
|
touch "$SCRATCH_MNT/vol1/file.txt"
|
|
_scratch_unmount
|
|
|
|
test_optional_kernel_features
|
|
|
|
test_non_revertible_options
|
|
|
|
test_revertible_options
|
|
|
|
test_subvol
|
|
|
|
echo "Silence is golden"
|
|
|
|
status=0
|
|
exit
|