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
|
#! /bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2017 SUSE Linux Products GmbH. All Rights Reserved.
#
# FS QA Test 156
#
# Check if btrfs can correctly trim free space in block groups
#
# An ancient regression prevent btrfs from trimming free space inside
# existing block groups, if bytenr of block group starts beyond
# btrfs_super_block->total_bytes.
# However all bytenr in btrfs is in btrfs logical address space,
# where any bytenr in range [0, U64_MAX] is valid.
#
# Fixed by patch named "btrfs: Ensure btrfs_trim_fs can trim the whole fs".
#
. ./common/preamble
_begin_fstest auto quick trim balance
. ./common/filter
_supported_fs btrfs
_require_scratch
_require_fstrim
# We need the allocated space to actually use that amount so the trim amount
# comes out correctly. Because we mark free extents as TRIMMED we won't trim
# the free extents on the second fstrim and thus we'll get a trimmed bytes at <
# half of the device if we have compression enabled, even though fs trim did the
# correct thing.
_require_no_compress
# 1024fs size
fs_size=$((1024 * 1024 * 1024))
# Use small files to fill half of the fs
file_size=$(( 1024 * 1024 ))
nr_files=$(( $fs_size / $file_size / 2))
# Force to use single data and meta profile.
# Since the test relies on fstrim output, which will differ for different
# profiles
_check_minimal_fs_size $fs_size
_scratch_mkfs -b $fs_size -m single -d single > /dev/null
_scratch_mount
_require_batched_discard "$SCRATCH_MNT"
for n in $(seq -w 0 $(( $nr_files - 1))); do
$XFS_IO_PROG -f -c "pwrite 0 $file_size" "$SCRATCH_MNT/file_$n" \
> /dev/null
done
# Flush all buffer data into disk, to trigger chunk allocation
sync
# Now we have take at least 50% of the filesystem, relocate all chunks twice
# so all chunks will start after 1G in logical space.
# (Btrfs chunk allocation will not rewind to reuse lower space)
_run_btrfs_balance_start $SCRATCH_MNT >> $seqres.full
# To avoid possible false ENOSPC alert on v4.15-rc1, seems to be a
# reserved space related bug (maybe related to outstanding space rework?),
# but that's another story.
sync
_run_btrfs_balance_start $SCRATCH_MNT >> $seqres.full
# Now remove half of the files to make some holes for later trim.
# While still keep the chunk space fragmented, so no chunk will be freed
rm $SCRATCH_MNT/file_*[13579] -f
# Make sure space is freed
sync
trimmed=$($FSTRIM_PROG -v "$SCRATCH_MNT" | _filter_fstrim)
echo "Trimmed=$trimmed total_size=$fs_size ratio=$(($trimmed * 100 / $fs_size))%" \
>> $seqres.full
# For correct full fs trim, both unallocated space (less than 50%)
# and free space in existing block groups (about 25%) should be trimmed.
# If less than 50% is trimmed, then only unallocated space is trimmed.
# BTW, without fix only 31% can be trimmed, while after fix it's 64%.
if [ $trimmed -lt $(( $fs_size / 2)) ]; then
echo "Free space in block groups not trimmed"
echo "Trimmed=$trimmed total_size=$fs_size ratio=$(($trimmed * 100 / $fs_size))%"
fi
echo "Silence is golden"
# success, all done
status=0
exit
|