Message ID | 169567819441.2270025.10851897053852323695.stgit@frogsfrogsfrogs (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | fstests: fix unshare data corruption bug | expand |
"Darrick J. Wong" <djwong@kernel.org> writes: > From: Darrick J. Wong <djwong@kernel.org> > > Add a regression test for funsharing uncached files to ensure that we > actually manage the pagecache state correctly. > > Signed-off-by: Darrick J. Wong <djwong@kernel.org> > --- > tests/xfs/1936 | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > tests/xfs/1936.out | 4 ++ > 2 files changed, 92 insertions(+) > create mode 100755 tests/xfs/1936 > create mode 100644 tests/xfs/1936.out > > > diff --git a/tests/xfs/1936 b/tests/xfs/1936 > new file mode 100755 > index 0000000000..e07b8f4796 > --- /dev/null > +++ b/tests/xfs/1936 > @@ -0,0 +1,88 @@ > +#! /bin/bash > +# SPDX-License-Identifier: GPL-2.0 > +# Copyright (c) 2023 Oracle. All Rights Reserved. > +# > +# FS QA Test 1936 > +# > +# This is a regression test for the kernel commit noted below. The stale > +# memory exposure can be exploited by creating a file with shared blocks, > +# evicting the page cache for that file, and then funshareing at least one > +# memory page's worth of data. iomap will mark the page uptodate and dirty > +# without ever reading the ondisk contents. > +# > +. ./common/preamble > +_begin_fstest auto quick unshare clone > + > +_cleanup() > +{ > + cd / > + rm -r -f $tmp.* $testdir > +} > + > +# real QA test starts here > + > +# Import common functions. > +. ./common/filter > +. ./common/attr We might as well remove above imports if we are not using those in this test. > +. ./common/reflink > + > +_fixed_by_git_commit kernel XXXXXXXXXXXXX \ > + "iomap: don't skip reading in !uptodate folios when unsharing a range" Once I guess it is merged, we will have the commit-id. Ohh wait, we have it already right? https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=35d30c9cf12730a1e37053dfde4007c7cc452d1a With that the testcode looks good to me. Thanks for finding an easy reproducer. Please feel free to add - Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com> -ritesh
On Tue, Sep 26, 2023 at 10:51:19AM +0530, Ritesh Harjani wrote: > "Darrick J. Wong" <djwong@kernel.org> writes: > > > From: Darrick J. Wong <djwong@kernel.org> > > > > Add a regression test for funsharing uncached files to ensure that we > > actually manage the pagecache state correctly. > > > > Signed-off-by: Darrick J. Wong <djwong@kernel.org> > > --- > > tests/xfs/1936 | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > > tests/xfs/1936.out | 4 ++ > > 2 files changed, 92 insertions(+) > > create mode 100755 tests/xfs/1936 > > create mode 100644 tests/xfs/1936.out > > > > > > diff --git a/tests/xfs/1936 b/tests/xfs/1936 > > new file mode 100755 > > index 0000000000..e07b8f4796 > > --- /dev/null > > +++ b/tests/xfs/1936 > > @@ -0,0 +1,88 @@ > > +#! /bin/bash > > +# SPDX-License-Identifier: GPL-2.0 > > +# Copyright (c) 2023 Oracle. All Rights Reserved. > > +# > > +# FS QA Test 1936 > > +# > > +# This is a regression test for the kernel commit noted below. The stale > > +# memory exposure can be exploited by creating a file with shared blocks, > > +# evicting the page cache for that file, and then funshareing at least one > > +# memory page's worth of data. iomap will mark the page uptodate and dirty > > +# without ever reading the ondisk contents. > > +# > > +. ./common/preamble > > +_begin_fstest auto quick unshare clone > > + > > +_cleanup() > > +{ > > + cd / > > + rm -r -f $tmp.* $testdir > > +} > > + > > +# real QA test starts here > > + > > +# Import common functions. > > +. ./common/filter > > +. ./common/attr > > We might as well remove above imports if we are not using those in this test. <nod> > > +. ./common/reflink > > + > > +_fixed_by_git_commit kernel XXXXXXXXXXXXX \ > > + "iomap: don't skip reading in !uptodate folios when unsharing a range" > > Once I guess it is merged, we will have the commit-id. Ohh wait, we have > it already right? > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=35d30c9cf12730a1e37053dfde4007c7cc452d1a Oops, yeah, I'll update the tag. > With that the testcode looks good to me. Thanks for finding an easy > reproducer. Please feel free to add - > > Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com> Thanks! > -ritesh
diff --git a/tests/xfs/1936 b/tests/xfs/1936 new file mode 100755 index 0000000000..e07b8f4796 --- /dev/null +++ b/tests/xfs/1936 @@ -0,0 +1,88 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2023 Oracle. All Rights Reserved. +# +# FS QA Test 1936 +# +# This is a regression test for the kernel commit noted below. The stale +# memory exposure can be exploited by creating a file with shared blocks, +# evicting the page cache for that file, and then funshareing at least one +# memory page's worth of data. iomap will mark the page uptodate and dirty +# without ever reading the ondisk contents. +# +. ./common/preamble +_begin_fstest auto quick unshare clone + +_cleanup() +{ + cd / + rm -r -f $tmp.* $testdir +} + +# real QA test starts here + +# Import common functions. +. ./common/filter +. ./common/attr +. ./common/reflink + +_fixed_by_git_commit kernel XXXXXXXXXXXXX \ + "iomap: don't skip reading in !uptodate folios when unsharing a range" + +# real QA test starts here +_require_test_reflink +_require_cp_reflink +_require_xfs_io_command "funshare" + +testdir=$TEST_DIR/test-$seq +rm -rf $testdir +mkdir $testdir + +# Create a file that is at least four pages in size and aligned to the +# file allocation unit size so that we don't trigger any unnecessary zeroing. +pagesz=$(_get_page_size) +alloc_unit=$(_get_file_block_size $TEST_DIR) +filesz=$(( ( (4 * pagesz) + alloc_unit - 1) / alloc_unit * alloc_unit)) + +echo "Create the original file and a clone" +_pwrite_byte 0x61 0 $filesz $testdir/file2.chk >> $seqres.full +_pwrite_byte 0x61 0 $filesz $testdir/file1 >> $seqres.full +_cp_reflink $testdir/file1 $testdir/file2 +_cp_reflink $testdir/file1 $testdir/file3 + +_test_cycle_mount + +cat $testdir/file3 > /dev/null + +echo "Funshare at least one pagecache page" +$XFS_IO_PROG -c "funshare 0 $filesz" $testdir/file2 +$XFS_IO_PROG -c "funshare 0 $filesz" $testdir/file3 +_pwrite_byte 0x61 0 $filesz $testdir/file2.chk >> $seqres.full + +echo "Check contents" + +# file2 wasn't cached when it was unshared, but it should match +if ! cmp -s $testdir/file2.chk $testdir/file2; then + echo "file2.chk does not match file2" + + echo "file2.chk contents" >> $seqres.full + od -tx1 -Ad -c $testdir/file2.chk >> $seqres.full + echo "file2 contents" >> $seqres.full + od -tx1 -Ad -c $testdir/file2 >> $seqres.full + echo "end bad contents" >> $seqres.full +fi + +# file3 was cached when it was unshared, and it should match +if ! cmp -s $testdir/file2.chk $testdir/file3; then + echo "file2.chk does not match file3" + + echo "file2.chk contents" >> $seqres.full + od -tx1 -Ad -c $testdir/file2.chk >> $seqres.full + echo "file3 contents" >> $seqres.full + od -tx1 -Ad -c $testdir/file3 >> $seqres.full + echo "end bad contents" >> $seqres.full +fi + +# success, all done +status=0 +exit diff --git a/tests/xfs/1936.out b/tests/xfs/1936.out new file mode 100644 index 0000000000..c7c820ced5 --- /dev/null +++ b/tests/xfs/1936.out @@ -0,0 +1,4 @@ +QA output created by 1936 +Create the original file and a clone +Funshare at least one pagecache page +Check contents