diff mbox series

[1/3] common/btrfs: add helper to get the bytenr for a file extent item

Message ID cf702a744eea3d163061afa789aecc5b2d2677b1.1683632565.git.fdmanana@suse.com (mailing list archive)
State New, archived
Headers show
Series btrfs: add test case for logical-resolve | expand

Commit Message

Filipe Manana May 9, 2023, 11:52 a.m. UTC
From: Filipe Manana <fdmanana@suse.com>

In upcoming changes there will be the need to find out the logical disk
address (bytenr) that a particular file extent item points to. This is
already implemented as local functions in the test btrfs/299, which is
a bit limited but works fine for that test. Some important or subtle
details why it works for this test:

1) It dumps all trees of the filesystem;

2) It relies on fsync'ing a file and then finding the desired file
   extent item in the log tree from the dump;

3) There's a single subvolume, so it always finds the correct file extent
   item. In case there were multiple subvolumes, it could pick the wrong
   file extent item in case we have inodes with the same number on
   multiple subvolumes (inode numbers are unique only within a subvolume,
   they are not unique across an entire filesystem).

So add a helper to get the bytenr associated to a file extent item to
common/btrfs and use it at btrfs/299 and the upcoming changes.

This helper will dump only the tree of the default subvolume, will sync
the filesystem to commit any open transaction and works only in case the
filesystem is using the scratch device. This is explicitly documented.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 common/btrfs    | 23 +++++++++++++++++++++++
 tests/btrfs/299 | 18 +-----------------
 2 files changed, 24 insertions(+), 17 deletions(-)

Comments

Anand Jain May 10, 2023, 5:50 a.m. UTC | #1
Looks good.

Reviewed-by: Anand Jain <anand.jain@oracle.com>
diff mbox series

Patch

diff --git a/common/btrfs b/common/btrfs
index 344509ce..42777df2 100644
--- a/common/btrfs
+++ b/common/btrfs
@@ -624,3 +624,26 @@  _require_btrfs_send_v2()
 	[ $(cat /sys/fs/btrfs/features/send_stream_version) -gt 1 ] || \
 		_notrun "kernel does not support send stream v2"
 }
+
+# Get the bytenr associated to a file extent item at a given file offset.
+#
+# NOTE: At the moment this only works if the file is on a filesystem on top of
+#       the scratch device and the file is in the default subvolume (tree id 5).
+_btrfs_get_file_extent_item_bytenr()
+{
+	local file="$1"
+	local offset="$2"
+	local ino=$(stat -c "%i" "$file")
+	local file_extent_key="($ino EXTENT_DATA $offset)"
+
+	_require_btrfs_command inspect-internal dump-tree
+
+	# The tree dump command below works on committed roots, by reading from
+	# a device directly, so we have to sync the filesystem to commit any
+	# open transaction.
+	$BTRFS_UTIL_PROG filesystem sync $SCRATCH_MNT
+
+	$BTRFS_UTIL_PROG inspect-internal dump-tree -t 5 $SCRATCH_DEV | \
+		grep -A4 "$file_extent_key" | grep "disk byte" | \
+		$AWK_PROG '{ print $5 }'
+}
diff --git a/tests/btrfs/299 b/tests/btrfs/299
index 8ed23ac5..2ac05957 100755
--- a/tests/btrfs/299
+++ b/tests/btrfs/299
@@ -22,25 +22,10 @@  _begin_fstest auto quick preallocrw
 _supported_fs btrfs
 _require_scratch
 _require_xfs_io_command "falloc" "-k"
-_require_btrfs_command inspect-internal dump-tree
 _require_btrfs_command inspect-internal logical-resolve
 _fixed_by_kernel_commit 560840afc3e6 \
 	"btrfs: fix resolving backrefs for inline extent followed by prealloc"
 
-dump_tree() {
-	$BTRFS_UTIL_PROG inspect-internal dump-tree $SCRATCH_DEV
-}
-
-get_extent_data() {
-	local ino=$1
-	dump_tree $SCRATCH_DEV | grep -A4 "($ino EXTENT_DATA "
-}
-
-get_prealloc_offset() {
-	local ino=$1
-	get_extent_data $ino | grep "disk byte" | $AWK_PROG '{print $5}'
-}
-
 # This test needs to create conditions s.t. the special inode's inline extent
 # is the first item in a leaf. Therefore, fix a leaf size and add
 # items that are otherwise not necessary to reproduce the inline-prealloc
@@ -81,8 +66,7 @@  done
 
 # grab the prealloc offset from dump tree while it's still the only
 # extent data item for the inode
-ino=$(stat -c '%i' $f.evil)
-logical=$(get_prealloc_offset $ino)
+logical=$(_btrfs_get_file_extent_item_bytenr $f.evil 0)
 
 # do the "small write; fsync; small write" pattern which reproduces the desired
 # item pattern of an inline extent followed by a preallocated extent. The 23