| #! /bin/bash |
| # SPDX-License-Identifier: GPL-2.0 |
| # Copyright (C) 2020 SUSE Linux Products GmbH. All Rights Reserved. |
| # |
| # FS QA Test No. btrfs/222 |
| # |
| # Test an incremental send operation after doing a series of changes in a tree |
| # such that one inode gets two hardlinks with names and locations swapped with |
| # two other inodes that correspond to different directories, and one of these |
| # directories is the parent of the other directory. |
| # |
| . ./common/preamble |
| _begin_fstest auto quick send |
| |
| # Override the default cleanup function. |
| _cleanup() |
| { |
| cd / |
| rm -fr $send_files_dir |
| rm -f $tmp.* |
| } |
| |
| . ./common/filter |
| |
| _require_test |
| _require_scratch |
| _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 |
| |
| touch $SCRATCH_MNT/f1 |
| touch $SCRATCH_MNT/f2 |
| mkdir $SCRATCH_MNT/d1 |
| mkdir $SCRATCH_MNT/d1/d2 |
| |
| # Filesystem looks like: |
| # |
| # . (ino 256) |
| # |----- f1 (ino 257) |
| # |----- f2 (ino 258) |
| # |----- d1/ (ino 259) |
| # |----- d2/ (ino 260) |
| # |
| $BTRFS_UTIL_PROG subvolume snapshot -r $SCRATCH_MNT \ |
| $SCRATCH_MNT/mysnap1 > /dev/null |
| |
| $BTRFS_UTIL_PROG send -f $send_files_dir/1.snap \ |
| $SCRATCH_MNT/mysnap1 2>&1 1>/dev/null | _filter_scratch |
| |
| # Now do a series of changes such that: |
| # |
| # *) inode 258 has one new hardlink and the previous name changed |
| # |
| # *) both names conflict with the old names of two other inodes: |
| # |
| # 1) the new name "d1" conflicts with the old name of inode 259, under |
| # directory inode 256 (root) |
| # |
| # 2) the new name "d2" conflicts with the old name of inode 260 under |
| # directory inode 259 |
| # |
| # *) inodes 259 and 260 now have the old names of inode 258 |
| # |
| # *) inode 257 is now located under inode 260 - an inode with a number |
| # smaller than the inode (258) for which we created a second hard link |
| # and swapped its names with inodes 259 and 260 |
| # |
| ln $SCRATCH_MNT/f2 $SCRATCH_MNT/d1/f2_link |
| mv $SCRATCH_MNT/f1 $SCRATCH_MNT/d1/d2/f1 |
| |
| # Swap d1 and f2. |
| mv $SCRATCH_MNT/d1 $SCRATCH_MNT/tmp |
| mv $SCRATCH_MNT/f2 $SCRATCH_MNT/d1 |
| mv $SCRATCH_MNT/tmp $SCRATCH_MNT/f2 |
| |
| # Swap d2 and f2_link |
| mv $SCRATCH_MNT/f2/d2 $SCRATCH_MNT/tmp |
| mv $SCRATCH_MNT/f2/f2_link $SCRATCH_MNT/f2/d2 |
| mv $SCRATCH_MNT/tmp $SCRATCH_MNT/f2/f2_link |
| |
| # Filesystem now looks like: |
| # |
| # . (ino 256) |
| # |----- d1 (ino 258) |
| # |----- f2/ (ino 259) |
| # |----- f2_link/ (ino 260) |
| # | |----- f1 (ino 257) |
| # | |
| # |----- d2 (ino 258) |
| # |
| |
| $BTRFS_UTIL_PROG subvolume snapshot -r $SCRATCH_MNT \ |
| $SCRATCH_MNT/mysnap2 > /dev/null |
| $BTRFS_UTIL_PROG send -p $SCRATCH_MNT/mysnap1 -f $send_files_dir/2.snap \ |
| $SCRATCH_MNT/mysnap2 2>&1 1>/dev/null | _filter_scratch |
| |
| $FSSUM_PROG -A -f -w $send_files_dir/1.fssum $SCRATCH_MNT/mysnap1 |
| $FSSUM_PROG -A -f -w $send_files_dir/2.fssum \ |
| -x $SCRATCH_MNT/mysnap2/mysnap1 $SCRATCH_MNT/mysnap2 |
| |
| # Now recreate the filesystem by receiving both send streams and verify we get |
| # the same content that the original filesystem had. |
| _scratch_unmount |
| _scratch_mkfs >>$seqres.full 2>&1 |
| _scratch_mount |
| |
| $BTRFS_UTIL_PROG receive -f $send_files_dir/1.snap $SCRATCH_MNT > /dev/null |
| |
| # The receive operation below used to fail with the following error: |
| # |
| # ERROR: rename d1/d2 -> o260-6-0 failed: No such file or directory |
| # |
| # Because when processing inode 258, the kernel orphanized first inode 259, |
| # renaming it from "d1" to "o259-6-0", since it the new reference named "d1" |
| # for inode 258 conflicts with the old one of inode 259, which was not yet |
| # processed. After that, because the new reference named "d2" for inode 258 |
| # conflicts with the old reference of the not yet processed inode 260, it |
| # tried to orphanize inode 260 - however the corresponding rename operation |
| # used a source path of "d1/d2", instead of "o259-6-0/d2". |
| # |
| $BTRFS_UTIL_PROG receive -f $send_files_dir/2.snap $SCRATCH_MNT > /dev/null |
| |
| $FSSUM_PROG -r $send_files_dir/1.fssum $SCRATCH_MNT/mysnap1 |
| $FSSUM_PROG -r $send_files_dir/2.fssum $SCRATCH_MNT/mysnap2 |
| |
| status=0 |
| exit |