| #! /bin/bash |
| # SPDX-License-Identifier: GPL-2.0 |
| # |
| # FS QA Test 201 |
| # |
| # Regression test for fix "btrfs: fix invalid removal of root ref" |
| # |
| seq=`basename $0` |
| seqres=$RESULT_DIR/$seq |
| echo "QA output created by $seq" |
| |
| here=`pwd` |
| tmp=/tmp/$$ |
| status=1 # failure is the default! |
| trap "_cleanup; exit \$status" 0 1 2 3 15 |
| |
| _cleanup() |
| { |
| cd / |
| rm -f $tmp.* |
| } |
| |
| . ./common/rc |
| . ./common/filter |
| |
| rm -f $seqres.full |
| |
| _supported_fs btrfs |
| |
| _scratch_mkfs >> $seqres.full 2>&1 |
| _scratch_mount |
| |
| # Create a subvol b under a and then snapshot a into c. This create's a stub |
| # entry in c for b because c doesn't have a reference for b. |
| # |
| # But when we rename b c/foo it creates a ref for b in c. However if we go to |
| # remove c/b btrfs used to depend on not finding the root ref to handle the |
| # unlink properly, but we now have a ref for that root. We also had a bug that |
| # would allow us to remove mis-matched refs if the keys matched, so we'd end up |
| # removing too many entries which would cause a transaction abort. |
| |
| $BTRFS_UTIL_PROG subvolume create $SCRATCH_MNT/a | _filter_scratch |
| $BTRFS_UTIL_PROG subvolume create $SCRATCH_MNT/a/b | _filter_scratch |
| $BTRFS_UTIL_PROG subvolume snapshot $SCRATCH_MNT/a $SCRATCH_MNT/c \ |
| | _filter_scratch |
| |
| # Need the dummy entry created so that we get the invalid removal when we rmdir |
| ls $SCRATCH_MNT/c/b |
| |
| mkdir $SCRATCH_MNT/c/foo |
| mv $SCRATCH_MNT/a/b $SCRATCH_MNT/c/foo |
| rm -rf $SCRATCH_MNT/* |
| touch $SCRATCH_MNT/blah |
| |
| status=0 |
| exit |