blob: 0d2628079cc65ee52e2e2da60512039e5df34fb8 [file] [log] [blame]
#!/bin/ksh -p
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
#
# Copyright 2018 Datto Inc.
#
. $STF_SUITE/include/libtest.shlib
#
# DESCRIPTION:
# Test async unlinked drain to ensure mounting is not held up when there are
# entries in the unlinked set. We also try to test that the list is able to be
# filled up and drained at the same time.
#
# STRATEGY:
# 1. Use zfs_unlink_suspend_progress tunable to disable freeing to build up
# the unlinked set
# 2. Make sure mount happens even when there are entries in the unlinked set
# 3. Drain and build up the unlinked list at the same time to test for races
#
function cleanup
{
log_must set_tunable32 zfs_unlink_suspend_progress $default_unlink_sp
for fs in $(seq 1 3); do
mounted $TESTDIR.$fs || zfs mount $TESTPOOL/$TESTFS.$fs
rm -f $TESTDIR.$fs/file-*
zfs set xattr=on $TESTPOOL/$TESTFS.$fs
done
}
function unlinked_size_is
{
MAX_ITERS=5 # iteration to do before we consider reported number stable
iters=0
last_usize=0
while [[ $iters -le $MAX_ITERS ]]; do
kstat_file=$(grep -nrwl /proc/spl/kstat/zfs/$2/objset-0x* -e $3)
nunlinks=`cat $kstat_file | grep nunlinks | awk '{print $3}'`
nunlinked=`cat $kstat_file | grep nunlinked | awk '{print $3}'`
usize=$(($nunlinks - $nunlinked))
if [[ $iters == $MAX_ITERS && $usize == $1 ]]; then
return 0
fi
if [[ $usize == $last_usize ]]; then
(( iters++ ))
else
iters=0
fi
last_usize=$usize
done
log_note "Unexpected unlinked set size: $last_usize, expected $1"
return 1
}
UNLINK_SP_PARAM=/sys/module/zfs/parameters/zfs_unlink_suspend_progress
default_unlink_sp=$(get_tunable zfs_unlink_suspend_progress)
log_onexit cleanup
log_assert "Unlinked list drain does not hold up mounting of fs"
for fs in 1 2 3; do
set -A xattrs on sa off
for xa in ${xattrs[@]}; do
# setup fs and ensure all deleted files got into unliked set
log_must mounted $TESTDIR.$fs
log_must zfs set xattr=$xa $TESTPOOL/$TESTFS.$fs
if [[ $xa == off ]]; then
for fn in $(seq 1 175); do
log_must mkfile 128k $TESTDIR.$fs/file-$fn
done
else
log_must xattrtest -f 175 -x 3 -r -k -p $TESTDIR.$fs
fi
log_must set_tunable32 zfs_unlink_suspend_progress 1
log_must unlinked_size_is 0 $TESTPOOL $TESTPOOL/$TESTFS.$fs
# build up unlinked set
for fn in $(seq 1 100); do
log_must eval "rm $TESTDIR.$fs/file-$fn &"
done
log_must unlinked_size_is 100 $TESTPOOL $TESTPOOL/$TESTFS.$fs
# test that we can mount fs without emptying the unlinked list
log_must zfs umount $TESTPOOL/$TESTFS.$fs
log_must unmounted $TESTDIR.$fs
log_must zfs mount $TESTPOOL/$TESTFS.$fs
log_must mounted $TESTDIR.$fs
log_must unlinked_size_is 100 $TESTPOOL $TESTPOOL/$TESTFS.$fs
# confirm we can drain and add to unlinked set at the same time
log_must set_tunable32 zfs_unlink_suspend_progress 0
log_must zfs umount $TESTPOOL/$TESTFS.$fs
log_must zfs mount $TESTPOOL/$TESTFS.$fs
for fn in $(seq 101 175); do
log_must eval "rm $TESTDIR.$fs/file-$fn &"
done
log_must unlinked_size_is 0 $TESTPOOL $TESTPOOL/$TESTFS.$fs
done
done
log_pass "Confirmed unlinked list drain does not hold up mounting of fs"