From: BingJing Chang Date: Fri, 21 Oct 2022 01:27:55 +0000 (+0800) Subject: btrfs: test incremental send for orphan inodes X-Git-Tag: v2022.10.30~8 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=12f6447865740839fe6d93e40f8b2a65955c58e7;p=xfstests-dev.git btrfs: test incremental send for orphan inodes Test that an incremental send operation can handle orphan files or directories in or not in the parent snapshot and the send snapshot. This issue is fixed by a kernel patch with the commit 9ed0a72e5b355d ("btrfs: send: fix failures when processing inodes with no links") Reviewed-by: Filipe Manana Signed-off-by: BingJing Chang Signed-off-by: Zorro Lang --- diff --git a/tests/btrfs/278 b/tests/btrfs/278 new file mode 100755 index 00000000..ff59ebd2 --- /dev/null +++ b/tests/btrfs/278 @@ -0,0 +1,218 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2022 BingJing Chang. +# +# FS QA Test No. btrfs/278 +# +# Regression test for btrfs incremental send issue when processing inodes +# with no links +# +# This issue is fixed by the following linux kernel btrfs patch: +# +# commit 9ed0a72e5b355d ("btrfs: send: fix failures when processing +# inodes with no links") +# +. ./common/preamble +_begin_fstest auto quick send + +# real QA test starts here +_supported_fs btrfs +_fixed_by_kernel_commit 9ed0a72e5b355d \ + "btrfs: send: fix failures when processing inodes with no links" +_require_test +_require_scratch +_require_btrfs_command "property" +_require_fssum + +send_files_dir=$TEST_DIR/btrfs-test-$seq + +rm -fr $send_files_dir +mkdir $send_files_dir + +_scratch_mkfs >>$seqres.full 2>&1 +_scratch_mount +_run_btrfs_util_prog subvolume create $SCRATCH_MNT/vol + +# Creating the first snapshot looks like: +# +# . (ino 256) +# |--- deleted.file (ino 257) +# |--- deleted.dir/ (ino 258) +# |--- changed_subcase1.file (ino 259) +# |--- changed_subcase2.file (ino 260) +# |--- changed_subcase1.dir/ (ino 261) +# | |---- foo (ino 262) +# |--- changed_subcase2.dir/ (ino 263) +# | |---- foo (ino 264) +# +touch $SCRATCH_MNT/vol/deleted.file +mkdir $SCRATCH_MNT/vol/deleted.dir +touch $SCRATCH_MNT/vol/changed_subcase1.file +touch $SCRATCH_MNT/vol/changed_subcase2.file +mkdir $SCRATCH_MNT/vol/changed_subcase1.dir +touch $SCRATCH_MNT/vol/changed_subcase1.dir/foo +mkdir $SCRATCH_MNT/vol/changed_subcase2.dir +touch $SCRATCH_MNT/vol/changed_subcase2.dir/foo +_run_btrfs_util_prog subvolume snapshot -r $SCRATCH_MNT/vol $SCRATCH_MNT/snap1 + +# Delete the deleted.*, create a new file and a new directory, and then +# take the second snapshot looks like: +# +# . (ino 256) +# |--- changed_subcase1.file (ino 259) +# |--- changed_subcase2.file (ino 260) +# |--- changed_subcase1.dir/ (ino 261) +# | |---- foo (ino 262) +# |--- changed_subcase2.dir/ (ino 263) +# | |---- foo (ino 264) +# |--- new.file (ino 265) +# |--- new.dir/ (ino 266) +# +unlink $SCRATCH_MNT/vol/deleted.file +rmdir $SCRATCH_MNT/vol/deleted.dir +touch $SCRATCH_MNT/vol/new.file +mkdir $SCRATCH_MNT/vol/new.dir +_run_btrfs_util_prog subvolume snapshot -r $SCRATCH_MNT/vol $SCRATCH_MNT/snap2 + +# Set the snapshot "snap1" to read-write mode and turn several inodes to +# orphans, so that the snapshot will look like this: +# +# . (ino 256) +# |--- (orphan) deleted.file (ino 257) +# |--- (orphan) deleted.dir/ (ino 258) +# |--- (orphan) changed_subcase1.file (ino 259) +# |--- changed_subcase2.file (ino 260) +# |--- (orphan) changed_subcase1.dir/ (ino 261) +# |--- changed_subcase2.dir/ (ino 263) +# | |---- foo (ino 264) +# +# Note: To make an easy illustration, I just put a tag "(orphan)" in front of +# their original names to indicate that they're deleted, but their inodes can +# not be removed because of open file descriptors on them. Mention that orphan +# inodes don't have names(paths). +# +$BTRFS_UTIL_PROG property set $SCRATCH_MNT/snap1 ro false +exec 71<$SCRATCH_MNT/snap1/deleted.file +exec 72<$SCRATCH_MNT/snap1/deleted.dir +exec 73<$SCRATCH_MNT/snap1/changed_subcase1.file +exec 74<$SCRATCH_MNT/snap1/changed_subcase1.dir +unlink $SCRATCH_MNT/snap1/deleted.file +rmdir $SCRATCH_MNT/snap1/deleted.dir +unlink $SCRATCH_MNT/snap1/changed_subcase1.file +unlink $SCRATCH_MNT/snap1/changed_subcase1.dir/foo +rmdir $SCRATCH_MNT/snap1/changed_subcase1.dir + +# Turn the snapshot "snap1" back to read-only mode. +$BTRFS_UTIL_PROG property set $SCRATCH_MNT/snap1 ro true + +# Set the snapshot "snap2" to read-write mode and turn several inodes to +# orphans, so that the snapshot will look like this: +# +# . (ino 256) +# |--- (orphan) changed_subcase1.file (ino 259) +# |--- (orphan) changed_subcase2.file (ino 260) +# |--- (orphan) changed_subcase1.dir/ (ino 261) +# |--- (orphan) changed_subcase2.dir/ (ino 263) +# |--- (orphan) new.file (ino 265) +# |--- (orphan) new.dir/ (ino 266) +# +# Note: Same notice as above. Mention that orphan inodes don't have +# names(paths). +# +$BTRFS_UTIL_PROG property set $SCRATCH_MNT/snap2 ro false +exec 81<$SCRATCH_MNT/snap2/changed_subcase1.file +exec 82<$SCRATCH_MNT/snap2/changed_subcase1.dir +exec 83<$SCRATCH_MNT/snap2/changed_subcase2.file +exec 84<$SCRATCH_MNT/snap2/changed_subcase2.dir +exec 85<$SCRATCH_MNT/snap2/new.file +exec 86<$SCRATCH_MNT/snap2/new.dir +unlink $SCRATCH_MNT/snap2/changed_subcase1.file +unlink $SCRATCH_MNT/snap2/changed_subcase1.dir/foo +rmdir $SCRATCH_MNT/snap2/changed_subcase1.dir +unlink $SCRATCH_MNT/snap2/changed_subcase2.file +unlink $SCRATCH_MNT/snap2/changed_subcase2.dir/foo +rmdir $SCRATCH_MNT/snap2/changed_subcase2.dir +unlink $SCRATCH_MNT/snap2/new.file +rmdir $SCRATCH_MNT/snap2/new.dir + +# Turn the snapshot "snap2" back to read-only mode. +$BTRFS_UTIL_PROG property set $SCRATCH_MNT/snap2 ro true + +# Test that a full send operation can handle orphans with no paths +_run_btrfs_util_prog send -f $send_files_dir/1.snap $SCRATCH_MNT/snap1 + +# Test that an incremental send operation can handle orphans. +# +# Here're descriptions for the details: +# +# Case 1: new.file and new.dir (BTRFS_COMPARE_TREE_NEW) +# | send snapshot | action +# -------------------------------- +# nlink | 0 | ignore +# +# They are new inodes in the send snapshot ("snap2"), but they don't have +# paths because they have no links. Test that the send operation can ignore +# them in order not to generate the creation commands for them. Or it will +# fail, with -ENOENT, when trying to generate paths for them. +# +# +# Case 2: deleted.file and deleted.dir (BTRFS_COMPARE_TREE_DELETED) +# | parent snapshot | action +# ---------------------------------- +# nlink | 0 | as usual +# +# They're deleted in the parent snapshot ("snap1") but become orphans which +# have no paths. Test that no deletion commands will be generated as usual. +# This case didn't fail before. +# +# +# Case 3: changed_*.file and changed_*.dir (BTRFS_COMPARE_TREE_CHANGED) +# | | parent snapshot | send snapshot | action +# ----------------------------------------------------------------------- +# subcase 1 | nlink | 0 | 0 | ignore +# subcase 2 | nlink | >0 | 0 | new_gen(deletion) +# +# In subcase 1, test that the send operation can ignore them without trying +# to generate any commands. +# +# In subcase 2, test that the send operation can generate an unlink command +# for that file and test that it can generate a rename command for the +# non-empty directory first and a rmdir command to remove it finally. Or +# the receive operation will fail with a wrong unlink on a non-empty +# directory. +# +_run_btrfs_util_prog send -p $SCRATCH_MNT/snap1 -f $send_files_dir/2.snap \ + $SCRATCH_MNT/snap2 + +$FSSUM_PROG -A -f -w $send_files_dir/1.fssum $SCRATCH_MNT/snap1 +$FSSUM_PROG -A -f -w $send_files_dir/2.fssum \ + -x $SCRATCH_MNT/snap2/snap1 $SCRATCH_MNT/snap2 + +# Recreate the filesystem by receiving both send streams and verify we get +# the same content that the original filesystem had. +exec 71>&- +exec 72>&- +exec 73>&- +exec 74>&- +exec 81>&- +exec 82>&- +exec 83>&- +exec 84>&- +exec 85>&- +exec 86>&- +_scratch_unmount +_scratch_mkfs >>$seqres.full 2>&1 +_scratch_mount + +# Add the first snapshot to the new filesystem by applying the first send +# stream. +_run_btrfs_util_prog receive -f $send_files_dir/1.snap $SCRATCH_MNT + +# Test the incremental send stream +_run_btrfs_util_prog receive -f $send_files_dir/2.snap $SCRATCH_MNT + +$FSSUM_PROG -r $send_files_dir/1.fssum $SCRATCH_MNT/snap1 +$FSSUM_PROG -r $send_files_dir/2.fssum $SCRATCH_MNT/snap2 + +status=0 +exit diff --git a/tests/btrfs/278.out b/tests/btrfs/278.out new file mode 100644 index 00000000..82b93b4e --- /dev/null +++ b/tests/btrfs/278.out @@ -0,0 +1,3 @@ +QA output created by 278 +OK +OK