summaryrefslogtreecommitdiff
path: root/tests/btrfs/237
blob: 3c660edbe27d3b281e75f3188cd6fbe75a50984d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#! /bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2021 Western Digital Corporation.  All Rights Reserved.
#
# FS QA Test 237
#
# Test that zone autoreclaim works as expected, that is: if the dirty
# threshold is exceeded the data gets relocated to new block group and the
# old block group gets deleted. On block group deletion, the underlying device
# zone also needs to be reset.
#
. ./common/preamble
_begin_fstest auto quick zone balance

# Import common functions.
. ./common/zoned

# real QA test starts here

_supported_fs btrfs
_require_scratch
_require_btrfs_command inspect-internal dump-tree
_require_btrfs_command filesystem sync
_require_command "$BLKZONE_PROG" blkzone
_require_zoned_device "$SCRATCH_DEV"

# This test requires specific data space usage, skip if we have compression
# enabled.
_require_no_compress

get_data_bg()
{
	$BTRFS_UTIL_PROG inspect-internal dump-tree -t CHUNK $SCRATCH_DEV |\
		grep -A 1 "CHUNK_ITEM" | grep -B 1 "type DATA" |\
		grep -Eo "CHUNK_ITEM [[:digit:]]+" | cut -d ' ' -f 2
}

get_data_bg_physical()
{
	# Assumes SINGLE data profile
	$BTRFS_UTIL_PROG inspect-internal dump-tree -t CHUNK $SCRATCH_DEV |\
		grep -A 4 CHUNK_ITEM | grep -A 3 'type DATA\|SINGLE' |\
	        grep -Eo 'offset [[:digit:]]+'| cut -d ' ' -f 2
}

_scratch_mkfs >/dev/null 2>&1
_scratch_mount -o commit=1 # 1s commit time to speed up test

uuid=$($BTRFS_UTIL_PROG filesystem show $SCRATCH_DEV |grep uuid: |\
        $AWK_PROG '{print $NF}')

if [[ "$uuid" == "" ]]; then
	echo "UUID for $SCRATCH_DEV is empty, this is not expected"
	exit 1
fi

start_data_bg_phy=$(get_data_bg_physical)
start_data_bg_phy=$((start_data_bg_phy >> 9))
size=$(_zone_capacity $start_data_bg_phy)

reclaim_threshold=75
echo $reclaim_threshold > /sys/fs/btrfs/"$uuid"/bg_reclaim_threshold
fill_percent=$((reclaim_threshold + 2))
rest_percent=$((90 - fill_percent)) # make sure we're not creating a new BG
fill_size=$((size * fill_percent / 100))
rest=$((size * rest_percent / 100))

# step 1, fill FS over $fillsize
$XFS_IO_PROG -fc "pwrite 0 $fill_size" $SCRATCH_MNT/$seq.test1 >> $seqres.full
$XFS_IO_PROG -fc "pwrite 0 $rest" $SCRATCH_MNT/$seq.test2 >> $seqres.full
$BTRFS_UTIL_PROG filesystem sync $SCRATCH_MNT

zones_before=$($BLKZONE_PROG report $SCRATCH_DEV | grep -v -e em -e nw | wc -l)
echo "Before reclaim: $zones_before zones open" >> $seqres.full
old_data_zone=$(get_data_bg)
old_data_zone=$((old_data_zone >> 9))
printf "Old data zone 0x%x\n" $old_data_zone >> $seqres.full

# step 2, delete the 1st $fill_size sized file to trigger reclaim
rm $SCRATCH_MNT/$seq.test1
$BTRFS_UTIL_PROG filesystem sync $SCRATCH_MNT
sleep 2 # 1 transaction commit for 'rm' and 1 for balance

# check that we don't have more zones open than before
zones_after=$($BLKZONE_PROG report $SCRATCH_DEV | grep -v -e em -e nw | wc -l)
echo "After reclaim: $zones_after zones open" >> $seqres.full

# Check that old data zone was reset
old_wptr=$($BLKZONE_PROG report -o $old_data_zone -c 1 $SCRATCH_DEV |\
	grep -Eo "wptr 0x[[:xdigit:]]+" | cut -d ' ' -f 2)
if [ "$old_wptr" != "0x000000" ]; then
	_fail "Old wptr still at $old_wptr"
fi

new_data_zone=$(get_data_bg)
new_data_zone=$((new_data_zone >> 9))
printf "New data zone 0x%x\n" $new_data_zone >> $seqres.full

# Check that data was really relocated to a different zone
if [ $old_data_zone -eq $new_data_zone ]; then
	echo "New zone same as old zone"
fi

# success, all done
echo "Silence is golden"
status=0
exit