]> git.proxmox.com Git - mirror_zfs.git/blob - tests/zfs-tests/tests/functional/mount/umount_unlinked_drain.ksh
port async unlinked drain from illumos-nexenta
[mirror_zfs.git] / tests / zfs-tests / tests / functional / mount / umount_unlinked_drain.ksh
1 #!/bin/ksh -p
2
3 #
4 # This file and its contents are supplied under the terms of the
5 # Common Development and Distribution License ("CDDL"), version 1.0.
6 # You may only use this file in accordance with the terms of version
7 # 1.0 of the CDDL.
8 #
9 # A full copy of the text of the CDDL should have accompanied this
10 # source. A copy of the CDDL is also available via the Internet at
11 # http://www.illumos.org/license/CDDL.
12 #
13
14 #
15 # Copyright 2018 Datto Inc.
16 #
17
18 . $STF_SUITE/include/libtest.shlib
19
20 #
21 # DESCRIPTION:
22 # Test async unlinked drain to ensure mounting is not held up when there are
23 # entries in the unlinked set. We also try to test that the list is able to be
24 # filled up and drained at the same time.
25 #
26 # STRATEGY:
27 # 1. Use zfs_unlink_suspend_progress tunable to disable freeing to build up
28 # the unlinked set
29 # 2. Make sure mount happens even when there are entries in the unlinked set
30 # 3. Drain and build up the unlinked list at the same time to test for races
31 #
32
33 function cleanup
34 {
35 log_must set_tunable32 zfs_unlink_suspend_progress $default_unlink_sp
36 for fs in $(seq 1 3); do
37 mounted $TESTDIR.$fs || zfs mount $TESTPOOL/$TESTFS.$fs
38 rm -f $TESTDIR.$fs/file-*
39 zfs set xattr=on $TESTPOOL/$TESTFS.$fs
40 done
41 }
42
43 function unlinked_size_is
44 {
45 MAX_ITERS=5 # iteration to do before we consider reported number stable
46 iters=0
47 last_usize=0
48 while [[ $iters -le $MAX_ITERS ]]; do
49 kstat_file=$(grep -nrwl /proc/spl/kstat/zfs/$2/objset-0x* -e $3)
50 nunlinks=`cat $kstat_file | grep nunlinks | awk '{print $3}'`
51 nunlinked=`cat $kstat_file | grep nunlinked | awk '{print $3}'`
52 usize=$(($nunlinks - $nunlinked))
53 if [[ $iters == $MAX_ITERS && $usize == $1 ]]; then
54 return 0
55 fi
56 if [[ $usize == $last_usize ]]; then
57 (( iters++ ))
58 else
59 iters=0
60 fi
61 last_usize=$usize
62 done
63
64 log_note "Unexpected unlinked set size: $last_usize, expected $1"
65 return 1
66 }
67
68
69 UNLINK_SP_PARAM=/sys/module/zfs/parameters/zfs_unlink_suspend_progress
70 default_unlink_sp=$(get_tunable zfs_unlink_suspend_progress)
71
72 log_onexit cleanup
73
74 log_assert "Unlinked list drain does not hold up mounting of fs"
75
76 for fs in 1 2 3; do
77 set -A xattrs on sa off
78 for xa in ${xattrs[@]}; do
79 # setup fs and ensure all deleted files got into unliked set
80 log_must mounted $TESTDIR.$fs
81
82 log_must zfs set xattr=$xa $TESTPOOL/$TESTFS.$fs
83
84 if [[ $xa == off ]]; then
85 for fn in $(seq 1 175); do
86 log_must mkfile 128k $TESTDIR.$fs/file-$fn
87 done
88 else
89 log_must xattrtest -f 175 -x 3 -r -k -p $TESTDIR.$fs
90 fi
91
92 log_must set_tunable32 zfs_unlink_suspend_progress 1
93 log_must unlinked_size_is 0 $TESTPOOL $TESTPOOL/$TESTFS.$fs
94
95 # build up unlinked set
96 for fn in $(seq 1 100); do
97 log_must eval "rm $TESTDIR.$fs/file-$fn &"
98 done
99 log_must unlinked_size_is 100 $TESTPOOL $TESTPOOL/$TESTFS.$fs
100
101 # test that we can mount fs without emptying the unlinked list
102 log_must zfs umount $TESTPOOL/$TESTFS.$fs
103 log_must unmounted $TESTDIR.$fs
104 log_must zfs mount $TESTPOOL/$TESTFS.$fs
105 log_must mounted $TESTDIR.$fs
106 log_must unlinked_size_is 100 $TESTPOOL $TESTPOOL/$TESTFS.$fs
107
108 # confirm we can drain and add to unlinked set at the same time
109 log_must set_tunable32 zfs_unlink_suspend_progress 0
110 log_must zfs umount $TESTPOOL/$TESTFS.$fs
111 log_must zfs mount $TESTPOOL/$TESTFS.$fs
112 for fn in $(seq 101 175); do
113 log_must eval "rm $TESTDIR.$fs/file-$fn &"
114 done
115 log_must unlinked_size_is 0 $TESTPOOL $TESTPOOL/$TESTFS.$fs
116 done
117 done
118
119 log_pass "Confirmed unlinked list drain does not hold up mounting of fs"