> On Sep 26, 2022, at 2:51 PM, Allison Henderson <allison.henderson@xxxxxxxxxx> wrote: > > On Fri, 2022-09-23 at 17:49 -0700, Darrick J. Wong wrote: >> On Tue, Jun 14, 2022 at 03:01:29PM -0700, Catherine Hoang wrote: >>> From: Allison Henderson <allison.henderson@xxxxxxxxxx> >>> >>> This patch adds a test for basic parent pointer operations, >>> including link, unlink, rename, overwrite, hardlinks and >>> error inject. >>> >>> Signed-off-by: Allison Henderson <allison.henderson@xxxxxxxxxx> >>> Signed-off-by: Catherine Hoang <catherine.hoang@xxxxxxxxxx> >>> --- >>> common/parent | 196 +++++++++ >>> common/rc | 3 + >>> doc/group-names.txt | 1 + >>> tests/xfs/547 | 126 ++++++ >>> tests/xfs/547.out | 59 +++ >>> tests/xfs/548 | 97 +++++ >>> tests/xfs/548.out | 1002 >>> +++++++++++++++++++++++++++++++++++++++++++ >>> tests/xfs/549 | 110 +++++ >>> tests/xfs/549.out | 14 + >>> 9 files changed, 1608 insertions(+) >>> create mode 100644 common/parent >>> create mode 100755 tests/xfs/547 >>> create mode 100644 tests/xfs/547.out >>> create mode 100755 tests/xfs/548 >>> create mode 100644 tests/xfs/548.out >>> create mode 100755 tests/xfs/549 >>> create mode 100644 tests/xfs/549.out >>> >>> diff --git a/common/parent b/common/parent >>> new file mode 100644 >>> index 00000000..0af12553 >>> --- /dev/null >>> +++ b/common/parent >>> @@ -0,0 +1,196 @@ >>> +# >>> +# Parent pointer common functions >>> +# >>> + >>> +# >>> +# parse_parent_pointer parents parent_inode parent_pointer_name >>> +# >>> +# Given a list of parent pointers, find the record that matches >>> +# the given inode and filename >>> +# >>> +# inputs: >>> +# parents : A list of parent pointers in the format of: >>> +# inode/generation/name_length/name >>> +# parent_inode : The parent inode to search for >>> +# parent_name : The parent name to search for >>> +# >>> +# outputs: >>> +# PPINO : Parent pointer inode >>> +# PPGEN : Parent pointer generation >>> +# PPNAME : Parent pointer name >>> +# PPNAME_LEN : Parent pointer name length >>> +# >>> +_parse_parent_pointer() >>> +{ >>> + local parents=$1 >>> + local pino=$2 >>> + local parent_pointer_name=$3 >>> + >>> + local found=0 >>> + >>> + # Find the entry that has the same inode as the parent >>> + # and parse out the entry info >>> + while IFS=\/ read PPINO PPGEN PPNAME_LEN PPNAME; do >>> + if [ "$PPINO" != "$pino" ]; then >>> + continue >>> + fi >>> + >>> + if [ "$PPNAME" != "$parent_pointer_name" ]; then >>> + continue >>> + fi >>> + >>> + found=1 >>> + break >>> + done <<< $(echo "$parents") >>> + >>> + # Check to see if we found anything >>> + # We do not fail the test because we also use this >>> + # routine to verify when parent pointers should >>> + # be removed or updated (ie a rename or a move >>> + # operation changes your parent pointer) >>> + if [ $found -eq "0" ]; then >>> + return 1 >>> + fi >>> + >>> + # Verify the parent pointer name length is correct >>> + if [ "$PPNAME_LEN" -ne "${#parent_pointer_name}" ] >>> + then >>> + _fail "Bad parent pointer reclen" >> >> Do you really want to _fail the whole test immediately? Or simply >> let >> the golden output comparison mark the test failed because there's >> unexpected output from "echo 'bad parent pointer reclen'" ? > I think it wouldnt be a bad idea to print out what the name and length > are vs what they were expected to be. Since that will only print > during a test fail anyway, I think that's clearer than having to go > pour through the diff output. That makes sense, I’ll add those print statements. > >> >>> + fi >>> + >>> + #return sucess >>> + return 0 >>> +} >>> + >>> +# >>> +# _verify_parent parent_path parent_pointer_name child_path >>> +# >>> +# Verify that the given child path lists the given parent as a >>> parent pointer >>> +# and that the parent pointer name matches the given name >>> +# >>> +# Examples: >>> +# >>> +# #simple example >>> +# mkdir testfolder1 >>> +# touch testfolder1/file1 >>> +# verify_parent testfolder1 file1 testfolder1/file1 >>> +# >>> +# # In this above example, we want to verify that "testfolder1" >>> +# # appears as a parent pointer of "testfolder1/file1". >>> Additionally >>> +# # we verify that the name record of the parent pointer is >>> "file1" >>> +# >>> +# >>> +# #hardlink example >>> +# mkdir testfolder1 >>> +# mkdir testfolder2 >>> +# touch testfolder1/file1 >>> +# ln testfolder1/file1 testfolder2/file1_ln >>> +# verify_parent testfolder2 file1_ln testfolder1/file1 >>> +# >>> +# # In this above example, we want to verify that "testfolder2" >>> +# # appears as a parent pointer of "testfolder1/file1". >>> Additionally >>> +# # we verify that the name record of the parent pointer is >>> "file1_ln" >>> +# >>> +_verify_parent() >>> +{ >>> + >>> + local parent_path=$1 >>> + local parent_pointer_name=$2 >>> + local child_path=$3 >>> + >>> + local parent_ppath="$parent_path/$parent_pointer_name" >>> + >>> + # Verify parent exists >>> + if [ ! -d $SCRATCH_MNT/$parent_path ]; then >>> + _fail "$SCRATCH_MNT/$parent_path not found" >>> + else >>> + echo "*** $parent_path OK" >>> + fi >>> + >>> + # Verify child exists >>> + if [ ! -f $SCRATCH_MNT/$child_path ]; then >>> + _fail "$SCRATCH_MNT/$child_path not found" >>> + else >>> + echo "*** $child_path OK" >>> + fi >>> + >>> + # Verify the parent pointer name exists as a child of the >>> parent >>> + if [ ! -f $SCRATCH_MNT/$parent_ppath ]; then >>> + _fail "$SCRATCH_MNT/$parent_ppath not found" >>> + else >>> + echo "*** $parent_ppath OK" >>> + fi >>> + >>> + # Get the inodes of both parent and child >>> + pino="$(stat -c '%i' $SCRATCH_MNT/$parent_path)" >>> + cino="$(stat -c '%i' $SCRATCH_MNT/$child_path)" >>> + >>> + # Get all the parent pointers of the child >>> + parents=($($XFS_IO_PROG -x -c "parent -f -i $pino -n >>> $parent_pointer_name" $SCRATCH_MNT/$child_path)) >>> + if [[ $? != 0 ]]; then >>> + _fail "No parent pointers found for $child_path" >>> + fi >>> + >>> + # Parse parent pointer output. >>> + # This sets PPINO PPGEN PPNAME PPNAME_LEN >>> + _parse_parent_pointer $parents $pino $parent_pointer_name >>> + >>> + # If we didnt find one, bail out >>> + if [ $? -ne 0 ]; then >>> + _fail "No parent pointer record found for >>> $parent_path in $child_path" >>> + fi >>> + >>> + # Verify the inode generated by the parent pointer name is >>> + # the same as the child inode >>> + pppino="$(stat -c '%i' $SCRATCH_MNT/$parent_ppath)" >>> + if [ $cino -ne $pppino ] >>> + then >>> + _fail "Bad parent pointer name value for >>> $child_path."\ >>> + "$SCRATCH_MNT/$parent_ppath belongs >>> to inode $PPPINO, but should be $cino" >>> + fi >>> + >>> + echo "*** Verified parent pointer:"\ >>> + "name:$PPNAME, namelen:$PPNAME_LEN" >>> + echo "*** Parent pointer OK for child $child_path" >>> +} >>> + >>> +# >>> +# _verify_parent parent_pointer_name pino child_path >>> +# >>> +# Verify that the given child path contains no parent pointer >>> entry >>> +# for the given inode and file name >>> +# >>> +_verify_no_parent() >>> +{ >>> + >>> + local parent_pname=$1 >>> + local pino=$2 >>> + local child_path=$3 >>> + >>> + # Verify child exists >>> + if [ ! -f $SCRATCH_MNT/$child_path ]; then >>> + _fail "$SCRATCH_MNT/$child_path not found" >>> + else >>> + echo "*** $child_path OK" >>> + fi >>> + >>> + # Get all the parent pointers of the child >>> + local parents=($($XFS_IO_PROG -x -c "parent -f -i $pino -n >>> $parent_pname" $SCRATCH_MNT/$child_path)) >>> + if [[ $? != 0 ]]; then >>> + return 0 >>> + fi >>> + >>> + # Parse parent pointer output. >>> + # This sets PPINO PPGEN PPNAME PPNAME_LEN >>> + _parse_parent_pointer $parents $pino $parent_pname >>> + >>> + # If we didnt find one, return sucess >>> + if [ $? -ne 0 ]; then >>> + return 0 >>> + fi >>> + >>> + _fail "Parent pointer entry found where none should:"\ >>> + "inode:$PPINO, gen:$PPGEN," >>> + "name:$PPNAME, namelen:$PPNAME_LEN" >>> +} >>> + >>> diff --git a/common/rc b/common/rc >>> index 4201a059..68752cdc 100644 >>> --- a/common/rc >>> +++ b/common/rc >>> @@ -2701,6 +2701,9 @@ _require_xfs_io_command() >>> echo $testio | grep -q "invalid option" && \ >>> _notrun "xfs_io $command support is >>> missing" >>> ;; >>> + "parent") >>> + testio=`$XFS_IO_PROG -x -c "parent" $TEST_DIR 2>&1` >>> + ;; >>> "pwrite") >>> # -N (RWF_NOWAIT) only works with direct vectored >>> I/O writes >>> local pwrite_opts=" " >>> diff --git a/doc/group-names.txt b/doc/group-names.txt >>> index e8e3477e..98bbe3b7 100644 >>> --- a/doc/group-names.txt >>> +++ b/doc/group-names.txt >>> @@ -77,6 +77,7 @@ nfs4_acl NFSv4 access control lists >>> nonsamefs overlayfs layers on different filesystems >>> online_repair online repair functionality tests >>> other dumping ground, do not add more tests to >>> this group >>> +parent Parent pointer tests >>> pattern specific IO pattern tests >>> perms access control and permission checking >>> pipe pipe functionality >>> diff --git a/tests/xfs/547 b/tests/xfs/547 >>> new file mode 100755 >>> index 00000000..5c7d1d45 >>> --- /dev/null >>> +++ b/tests/xfs/547 >>> @@ -0,0 +1,126 @@ >>> +#! /bin/bash >>> +# SPDX-License-Identifier: GPL-2.0 >>> +# Copyright (c) 2022, Oracle and/or its affiliates. All Rights >>> Reserved. >>> +# >>> +# FS QA Test 547 >>> +# >>> +# simple parent pointer test >>> +# >>> + >>> +. ./common/preamble >>> +_begin_fstest auto quick parent >>> + >>> +cleanup() >>> +{ >>> + cd / >>> + rm -f $tmp.* >>> + echo 0 > /sys/fs/xfs/debug/larp >>> +} >>> + >>> +full() >>> +{ >>> + echo "" >>$seqres.full >>> + echo "*** $* ***" >>$seqres.full >>> + echo "" >>$seqres.full >>> +} >>> + >>> +# get standard environment, filters and checks >>> +. ./common/filter >>> +. ./common/reflink >>> +. ./common/inject >>> +. ./common/parent >>> + >>> +# Modify as appropriate >>> +_supported_fs xfs >>> +_require_scratch >>> +_require_xfs_sysfs debug/larp >>> +_require_xfs_io_error_injection "larp" >>> + >>> +echo 1 > /sys/fs/xfs/debug/larp >> >> Doesn't the parent pointer code turn on LARP mode automatically? >> Why does the test need to do that explicitly? > I think it does now. We went through a couple different > implementations of larp knobs and at some point it really wasn't > reasonable to continue pushing out all the resulting changes that would > ripple through not only usr space but all the test cases as well. I > think thats setting down now, so I think it's ok for this line to come > out. Ok, will remove this. Thanks! > >> >>> + >>> +# real QA test starts here >>> + >>> +# Create a directory tree using a protofile and >>> +# make sure all inodes created have parent pointers >>> + >>> +protofile=$tmp.proto >>> + >>> +cat >$protofile <<EOF >>> +DUMMY1 >>> +0 0 >>> +: root directory >>> +d--777 3 1 >>> +: a directory >>> +testfolder1 d--755 3 1 >>> +file1 ---755 3 1 /dev/null >>> +$ >>> +: back in the root >>> +testfolder2 d--755 3 1 >>> +file2 ---755 3 1 /dev/null >>> +: done >>> +$ >>> +EOF >>> + >>> +if [ $? -ne 0 ] >>> +then >>> + _fail "failed to create test protofile" >>> +fi >>> + >>> +_scratch_mkfs -f -n parent=1 -p $protofile >>$seqres.full 2>&1 \ >>> + || _fail "mkfs failed" >>> +_check_scratch_fs >>> + >>> +_scratch_mount >>$seqres.full 2>&1 \ >>> + || _fail "mount failed" >>> + >>> +testfolder1="testfolder1" >>> +testfolder2="testfolder2" >>> +file1="file1" >>> +file2="file2" >>> +file3="file3" >>> +file4="file4" >>> +file5="file5" >>> +file1_ln="file1_link" >>> + >>> +echo "" >>> +# Create parent pointer test >>> +_verify_parent "$testfolder1" "$file1" "$testfolder1/$file1" >>> + >>> +echo "" >>> +# Move parent pointer test >>> +mv $SCRATCH_MNT/$testfolder1/$file1 >>> $SCRATCH_MNT/$testfolder2/$file1 >>> +_verify_parent "$testfolder2" "$file1" "$testfolder2/$file1" >>> + >>> +echo "" >>> +# Hard link parent pointer test >>> +ln $SCRATCH_MNT/$testfolder2/$file1 >>> $SCRATCH_MNT/$testfolder1/$file1_ln >>> +_verify_parent "$testfolder1" "$file1_ln" >>> "$testfolder1/$file1_ln" >>> +_verify_parent "$testfolder1" "$file1_ln" "$testfolder2/$file1" >>> +_verify_parent "$testfolder2" "$file1" >>> "$testfolder1/$file1_ln" >>> +_verify_parent "$testfolder2" "$file1" "$testfolder2/$file1" >>> + >>> +echo "" >>> +# Remove hard link parent pointer test >>> +ino="$(stat -c '%i' $SCRATCH_MNT/$testfolder2/$file1)" >>> +rm $SCRATCH_MNT/$testfolder2/$file1 >>> +_verify_parent "$testfolder1" "$file1_ln" >>> "$testfolder1/$file1_ln" >>> +_verify_no_parent "$file1" "$ino" "$testfolder1/$file1_ln" >>> + >>> +echo "" >>> +# Rename parent pointer test >>> +ino="$(stat -c '%i' $SCRATCH_MNT/$testfolder1/$file1_ln)" >>> +mv $SCRATCH_MNT/$testfolder1/$file1_ln >>> $SCRATCH_MNT/$testfolder1/$file2 >>> +_verify_parent "$testfolder1" "$file2" "$testfolder1/$file2" >>> +_verify_no_parent "$file1_ln" "$ino" "$testfolder1/$file2" >>> + >>> +echo "" >>> +# Over write parent pointer test >>> +touch $SCRATCH_MNT/$testfolder2/$file3 >>> +_verify_parent "$testfolder2" "$file3" "$testfolder2/$file3" >>> +ino="$(stat -c '%i' $SCRATCH_MNT/$testfolder2/$file3)" >>> +mv -f $SCRATCH_MNT/$testfolder2/$file3 >>> $SCRATCH_MNT/$testfolder1/$file2 >>> +_verify_parent "$testfolder1" "$file2" "$testfolder1/$file2" >>> + >>> +# success, all done >>> +status=0 >>> +exit >>> diff --git a/tests/xfs/547.out b/tests/xfs/547.out >>> new file mode 100644 >>> index 00000000..e0ce9e65 >>> --- /dev/null >>> +++ b/tests/xfs/547.out >>> @@ -0,0 +1,59 @@ >>> +QA output created by 547 >>> + >>> +*** testfolder1 OK >>> +*** testfolder1/file1 OK >>> +*** testfolder1/file1 OK >>> +*** Verified parent pointer: name:file1, namelen:5 >>> +*** Parent pointer OK for child testfolder1/file1 >>> + >>> +*** testfolder2 OK >>> +*** testfolder2/file1 OK >>> +*** testfolder2/file1 OK >>> +*** Verified parent pointer: name:file1, namelen:5 >>> +*** Parent pointer OK for child testfolder2/file1 >>> + >>> +*** testfolder1 OK >>> +*** testfolder1/file1_link OK >>> +*** testfolder1/file1_link OK >>> +*** Verified parent pointer: name:file1_link, namelen:10 >>> +*** Parent pointer OK for child testfolder1/file1_link >>> +*** testfolder1 OK >>> +*** testfolder2/file1 OK >>> +*** testfolder1/file1_link OK >>> +*** Verified parent pointer: name:file1_link, namelen:10 >>> +*** Parent pointer OK for child testfolder2/file1 >>> +*** testfolder2 OK >>> +*** testfolder1/file1_link OK >>> +*** testfolder2/file1 OK >>> +*** Verified parent pointer: name:file1, namelen:5 >>> +*** Parent pointer OK for child testfolder1/file1_link >>> +*** testfolder2 OK >>> +*** testfolder2/file1 OK >>> +*** testfolder2/file1 OK >>> +*** Verified parent pointer: name:file1, namelen:5 >>> +*** Parent pointer OK for child testfolder2/file1 >>> + >>> +*** testfolder1 OK >>> +*** testfolder1/file1_link OK >>> +*** testfolder1/file1_link OK >>> +*** Verified parent pointer: name:file1_link, namelen:10 >>> +*** Parent pointer OK for child testfolder1/file1_link >>> +*** testfolder1/file1_link OK >>> + >>> +*** testfolder1 OK >>> +*** testfolder1/file2 OK >>> +*** testfolder1/file2 OK >>> +*** Verified parent pointer: name:file2, namelen:5 >>> +*** Parent pointer OK for child testfolder1/file2 >>> +*** testfolder1/file2 OK >>> + >>> +*** testfolder2 OK >>> +*** testfolder2/file3 OK >>> +*** testfolder2/file3 OK >>> +*** Verified parent pointer: name:file3, namelen:5 >>> +*** Parent pointer OK for child testfolder2/file3 >>> +*** testfolder1 OK >>> +*** testfolder1/file2 OK >>> +*** testfolder1/file2 OK >>> +*** Verified parent pointer: name:file2, namelen:5 >>> +*** Parent pointer OK for child testfolder1/file2 >>> diff --git a/tests/xfs/548 b/tests/xfs/548 >>> new file mode 100755 >>> index 00000000..229d871a >>> --- /dev/null >>> +++ b/tests/xfs/548 >>> @@ -0,0 +1,97 @@ >>> +#! /bin/bash >>> +# SPDX-License-Identifier: GPL-2.0 >>> +# Copyright (c) 2022, Oracle and/or its affiliates. All Rights >>> Reserved. >>> +# >>> +# FS QA Test 548 >>> +# >>> +# multi link parent pointer test >>> +# >>> +. ./common/preamble >>> +_begin_fstest auto quick parent >>> + >>> +cleanup() >>> +{ >>> + cd / >>> + rm -f $tmp.* >>> + echo 0 > /sys/fs/xfs/debug/larp >>> +} >>> + >>> +full() >>> +{ >>> + echo "" >>$seqres.full >>> + echo "*** $* ***" >>$seqres.full >>> + echo "" >>$seqres.full >>> +} >>> + >>> +# get standard environment, filters and checks >>> +. ./common/filter >>> +. ./common/reflink >>> +. ./common/inject >>> +. ./common/parent >>> + >>> +# Modify as appropriate >>> +_supported_fs xfs >>> +_require_scratch >>> +_require_xfs_io_error_injection "larp" >>> +_require_xfs_sysfs debug/larp >>> + >>> +echo 1 > /sys/fs/xfs/debug/larp >>> + >>> +# real QA test starts here >>> + >>> +# Create a directory tree using a protofile and >>> +# make sure all inodes created have parent pointers >>> + >>> +protofile=$tmp.proto >>> + >>> +cat >$protofile <<EOF >>> +DUMMY1 >>> +0 0 >>> +: root directory >>> +d--777 3 1 >>> +: a directory >>> +testfolder1 d--755 3 1 >>> +file1 ---755 3 1 /dev/null >>> +: done >>> +$ >>> +EOF >>> + >>> +if [ $? -ne 0 ] >>> +then >>> + _fail "failed to create test protofile" >>> +fi >>> + >>> +_scratch_mkfs -f -n parent=1 -p $protofile >>$seqresres.full 2>&1 >>> \ >>> + || _fail "mkfs failed" >>> +_check_scratch_fs >>> + >>> +_scratch_mount >>$seqres.full 2>&1 \ >>> + || _fail "mount failed" >>> + >>> +testfolder1="testfolder1" >>> +testfolder2="testfolder2" >>> +file1="file1" >>> +file2="file2" >>> +file3="file3" >>> +file4="file4" >>> +file5="file5" >>> +file1_ln="file1_link" >>> + >>> +echo "" >>> +# Multi link parent pointer test >>> +NLINKS=100 >>> +for (( j=0; j<$NLINKS; j++ )); do >>> + ln $SCRATCH_MNT/$testfolder1/$file1 >>> $SCRATCH_MNT/$testfolder1/$file1_ln.$j >>> + _verify_parent "$testfolder1" "$file1_ln.$j" >>> "$testfolder1/$file1" >>> + _verify_parent "$testfolder1" "$file1" >>> "$testfolder1/$file1_ln.$j" >>> +done >>> +# Multi unlink parent pointer test >>> +for (( j=$NLINKS-1; j<=0; j-- )); do >>> + ino="$(stat -c '%i' >>> $SCRATCH_MNT/$testfolder1/$file1_ln.$j)" >>> + rm $SCRATCH_MNT/$testfolder1/$file1_ln.$j >>> + _verify_no_parent "$file1_ln.$j" "$ino" >>> "$testfolder1/$file1" >>> +done >>> + >>> +# success, all done >>> +status=0 >>> +exit >>> diff --git a/tests/xfs/548.out b/tests/xfs/548.out >>> new file mode 100644 >>> index 00000000..afdc083b >>> --- /dev/null >>> +++ b/tests/xfs/548.out >>> @@ -0,0 +1,1002 @@ >>> +QA output created by 548 >>> + >>> +*** testfolder1 OK >> >> <snip> >> >>> +*** testfolder1 OK >>> +*** testfolder1/file1_link.99 OK >>> +*** testfolder1/file1 OK >>> +*** Verified parent pointer: name:file1, namelen:5 >>> +*** Parent pointer OK for child testfolder1/file1_link.99 >>> diff --git a/tests/xfs/549 b/tests/xfs/549 >>> new file mode 100755 >>> index 00000000..e8e74b8a >>> --- /dev/null >>> +++ b/tests/xfs/549 >>> @@ -0,0 +1,110 @@ >>> +#! /bin/bash >>> +# SPDX-License-Identifier: GPL-2.0 >>> +# Copyright (c) 2022, Oracle and/or its affiliates. All Rights >>> Reserved. >>> +# >>> +# FS QA Test 549 >>> +# >>> +# parent pointer inject test >>> +# >>> +. ./common/preamble >>> +_begin_fstest auto quick parent >>> + >>> +cleanup() >>> +{ >>> + cd / >>> + rm -f $tmp.* >>> + echo 0 > /sys/fs/xfs/debug/larp >>> +} >>> + >>> +full() >>> +{ >>> + echo "" >>$seqres.full >>> + echo "*** $* ***" >>$seqres.full >>> + echo "" >>$seqres.full >>> +} >>> + >>> +# get standard environment, filters and checks >>> +. ./common/filter >>> +. ./common/reflink >>> +. ./common/inject >>> +. ./common/parent >>> + >>> +# Modify as appropriate >>> +_supported_fs xfs >>> +_require_scratch >>> +_require_xfs_sysfs debug/larp >>> +_require_xfs_io_error_injection "larp" >>> + >>> +echo 1 > /sys/fs/xfs/debug/larp >>> + >>> +# real QA test starts here >>> + >>> +# Create a directory tree using a protofile and >>> +# make sure all inodes created have parent pointers >> >> Looks like we're testing the error injection knobs too? > Yes, this is similar to the larp replay tests except we ensure the > replayed attr contains the expected pptr > >> >> --D >> >>> + >>> +protofile=$tmp.proto >>> + >>> +cat >$protofile <<EOF >>> +DUMMY1 >>> +0 0 >>> +: root directory >>> +d--777 3 1 >>> +: a directory >>> +testfolder1 d--755 3 1 >>> +file1 ---755 3 1 /dev/null >>> +$ >>> +: back in the root >>> +testfolder2 d--755 3 1 >>> +file2 ---755 3 1 /dev/null >>> +: done >>> +$ >>> +EOF >>> + >>> +if [ $? -ne 0 ] >>> +then >>> + _fail "failed to create test protofile" >>> +fi >>> + >>> +_scratch_mkfs -f -n parent=1 -p $protofile >>$seqres.full 2>&1 \ >>> + || _fail "mkfs failed" >>> +_check_scratch_fs >>> + >>> +_scratch_mount >>$seqres.full 2>&1 \ >>> + || _fail "mount failed" >>> + >>> +testfolder1="testfolder1" >>> +testfolder2="testfolder2" >>> +file1="file1" >>> +file2="file2" >>> +file3="file3" >>> +file4="file4" >>> +file5="file5" >>> +file1_ln="file1_link" >>> + >>> +echo "" >>> + >>> +# Create files >>> +touch $SCRATCH_MNT/$testfolder1/$file4 >>> +_verify_parent "$testfolder1" "$file4" "$testfolder1/$file4" >>> + >>> +# Inject error >>> +_scratch_inject_error "larp" >>> + >>> +# Move files >>> +mv $SCRATCH_MNT/$testfolder1/$file4 >>> $SCRATCH_MNT/$testfolder2/$file5 2>&1 | _filter_scratch >>> + >>> +# FS should be shut down, touch will fail >>> +touch $SCRATCH_MNT/$testfolder2/$file5 2>&1 | _filter_scratch >>> + >>> +# Remount to replay log >>> +_scratch_remount_dump_log >> $seqres.full >>> + >>> +# FS should be online, touch should succeed >>> +touch $SCRATCH_MNT/$testfolder2/$file5 >>> + >>> +# Check files again >>> +_verify_parent "$testfolder2" "$file5" "$testfolder2/$file5" >>> + >>> +# success, all done >>> +status=0 >>> +exit >>> diff --git a/tests/xfs/549.out b/tests/xfs/549.out >>> new file mode 100644 >>> index 00000000..1af49c73 >>> --- /dev/null >>> +++ b/tests/xfs/549.out >>> @@ -0,0 +1,14 @@ >>> +QA output created by 549 >>> + >>> +*** testfolder1 OK >>> +*** testfolder1/file4 OK >>> +*** testfolder1/file4 OK >>> +*** Verified parent pointer: name:file4, namelen:5 >>> +*** Parent pointer OK for child testfolder1/file4 >>> +mv: cannot stat 'SCRATCH_MNT/testfolder1/file4': Input/output >>> error >>> +touch: cannot touch 'SCRATCH_MNT/testfolder2/file5': Input/output >>> error >>> +*** testfolder2 OK >>> +*** testfolder2/file5 OK >>> +*** testfolder2/file5 OK >>> +*** Verified parent pointer: name:file5, namelen:5 >>> +*** Parent pointer OK for child testfolder2/file5 >>> -- >>> 2.25.1