]> git-server-git.apps.pok.os.sepia.ceph.com Git - xfstests-dev.git/commitdiff
common/btrfs: add helper to get the bytenr for a file extent item
authorFilipe Manana <fdmanana@suse.com>
Tue, 9 May 2023 11:52:04 +0000 (12:52 +0100)
committerZorro Lang <zlang@kernel.org>
Fri, 12 May 2023 12:20:07 +0000 (20:20 +0800)
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>
Reviewed-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: Zorro Lang <zlang@kernel.org>
common/btrfs
tests/btrfs/299

index 344509ce300c145be4f3f5f3ab57178a64581abd..42777df236888db5d0fecb90ff76a7cb1cab4b7b 100644 (file)
@@ -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 }'
+}
index 8ed23ac58992d0bc5e6db008985ed78e9cf3b8df..2ac059570e7dca0647b324651b1476270b3c6a50 100755 (executable)
@@ -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