summaryrefslogtreecommitdiff
path: root/tests/btrfs/280
blob: 0f7f8a37420fd621339e96bfa69ff7490f29c53f (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
#! /bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2022 SUSE Linux Products GmbH. All Rights Reserved.
#
# FS QA Test 280
#
# Test that if we have a large file, with file extent items spanning several
# leaves in the fs tree, and that is shared due to a snapshot, if we COW one of
# the extents, doing a fiemap will report the respective file range as not
# shared.
#
# This exercises the processing of delayed references for metadata extents in
# the backref walking code, used by fiemap to determine if an extent is shared.
#
. ./common/preamble
_begin_fstest auto quick compress snapshot fiemap defrag

. ./common/filter
. ./common/punch # for _filter_fiemap_flags

_supported_fs btrfs
_require_scratch
_require_xfs_io_command "fiemap"

_fixed_by_kernel_commit 943553ef9b51 \
	"btrfs: fix processing of delayed tree block refs during backref walking"

_scratch_mkfs >> $seqres.full 2>&1
# We use compression because it's a very quick way to create a file with a very
# large number of extents (compression limits the maximum extent size to 128K)
# and while using very little disk space.
_scratch_mount -o compress

# A 128M file full of compressed extents results in a fs tree with a heigth
# of 2 (root at level 1), so we'll end up with tree block references in the
# extent tree (if the root was a leaf, we would have only data references).
$XFS_IO_PROG -f -c "pwrite -b 1M 0 128M" $SCRATCH_MNT/foo | _filter_xfs_io

# While writing the file it's possible, but rare, that writeback kicked in due
# to memory pressure or a concurrent sync call for example, so we may end up
# with extents smaller than 128K (the maximum size for compressed extents) and
# therefore make the test expectations fail because we get more extents than
# what the golden output expects. So run defrag to make sure we get exactly
# the expected number of 128K extents (1024 extents).
$BTRFS_UTIL_PROG filesystem defrag "$SCRATCH_MNT/foo" >> $seqres.full

# Create a RW snapshot of the default subvolume.
_btrfs subvolume snapshot $SCRATCH_MNT $SCRATCH_MNT/snap

echo
echo "File foo fiemap before COWing extent:"
echo
$XFS_IO_PROG -c "fiemap -v" $SCRATCH_MNT/foo | _filter_fiemap_flags 1

echo
echo "Overwriting file range [120M, 120M + 128K) in the snapshot"
echo
$XFS_IO_PROG -c "pwrite -b 128K 120M 128K" $SCRATCH_MNT/snap/foo | _filter_xfs_io
# Now fsync the file to force COWing the extent and the path from the root of
# the snapshot tree down to the leaf where the extent is at.
$XFS_IO_PROG -c "fsync" $SCRATCH_MNT/snap/foo

echo
echo "File foo fiemap after COWing extent in the snapshot:"
echo
# Now we should have all extents marked as shared except the 128K extent in the
# file range [120M, 120M + 128K).
$XFS_IO_PROG -c "fiemap -v" $SCRATCH_MNT/foo | _filter_fiemap_flags 1

# success, all done
status=0
exit