On Wed, Nov 11, 2020 at 11:32 AM Qu Wenruo <wqu@xxxxxxxx> wrote: > > There is a bug that, when btrfs is beyond qgroup limit, touching a file > could crash btrfs. > > Such beyond limit situation needs to be intentionally created, e.g. > writing 1GiB file, then limit the subvolume to 512 MiB. > As current qgroup works pretty well at preventing us from reaching the > limit. > > This makes existing qgroup test cases unable to detect it. > > The regression is introduced by commit c53e9653605d ("btrfs: qgroup: try > to flush qgroup space when we get -EDQUOT"), and the fix is titled > "btrfs: qgroup: don't commit transaction when we have already > hold a transaction handler" > > Link: https://bugzilla.suse.com/show_bug.cgi?id=1178634 > Signed-off-by: Qu Wenruo <wqu@xxxxxxxx> Reviewed-by: Filipe Manana <fdmanana@xxxxxxxx> Looks good, just one comment below. > --- > tests/btrfs/154 | 62 +++++++++++++++++++++++++++++++++++++++++++++ > tests/btrfs/154.out | 2 ++ > tests/btrfs/group | 1 + > 3 files changed, 65 insertions(+) > create mode 100755 tests/btrfs/154 > create mode 100644 tests/btrfs/154.out > > diff --git a/tests/btrfs/154 b/tests/btrfs/154 > new file mode 100755 > index 00000000..2a65d182 > --- /dev/null > +++ b/tests/btrfs/154 > @@ -0,0 +1,62 @@ > +#! /bin/bash > +# SPDX-License-Identifier: GPL-2.0 > +# Copyright (c) 2020 SUSE Linux Products GmbH. All Rights Reserved. > +# > +# FS QA Test 154 > +# > +# Test if btrfs qgroup would crash if we're modifying the fs > +# after exceeding the limit > +# > +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.* > +} > + > +# get standard environment, filters and checks > +. ./common/rc > +. ./common/filter > + > +# remove previous $seqres.full before test > +rm -f $seqres.full > + > +# real QA test starts here > + > +# Modify as appropriate. > +_supported_fs btrfs > + > +# Need at least 2GiB > +_require_scratch_size $((2 * 1024 * 1024)) > +_scratch_mkfs > /dev/null 2>&1 > + > +_scratch_mount > + > +_pwrite_byte 0xcd 0 1G $SCRATCH_MNT/file >> $seqres.full > + > +# Make sure the data reach disk so later qgroup scan can see it > +sync > + > +$BTRFS_UTIL_PROG quota enable $SCRATCH_MNT > +$BTRFS_UTIL_PROG quota rescan -w $SCRATCH_MNT >> $seqres.full > + > +# Set the limit to just 512MiB, which is way below the existing usage > +$BTRFS_UTIL_PROG qgroup limit 512M $SCRATCH_MNT $SCRATCH_MNT $SCRATCH_MNT twice by mistake, though the command still works and the test still reproduces the issue. Eryu can probably remove one occurrence when picking this patch. Thanks. > + > +# Touch above file, if kernel not patched, it will trigger an ASSERT() > +# > +# Even for patched kernel, we will still get EDQUOT error, but that > +# is expected behavior. > +touch $SCRATCH_MNT/file 2>&1 | _filter_scratch > + > +# success, all done > +status=0 > +exit > diff --git a/tests/btrfs/154.out b/tests/btrfs/154.out > new file mode 100644 > index 00000000..b526c3f3 > --- /dev/null > +++ b/tests/btrfs/154.out > @@ -0,0 +1,2 @@ > +QA output created by 154 > +touch: setting times of 'SCRATCH_MNT/file': Disk quota exceeded > diff --git a/tests/btrfs/group b/tests/btrfs/group > index d18450c7..c491e339 100644 > --- a/tests/btrfs/group > +++ b/tests/btrfs/group > @@ -156,6 +156,7 @@ > 151 auto quick volume > 152 auto quick metadata qgroup send > 153 auto quick qgroup limit > +154 auto quick qgroup limit > 155 auto quick send > 156 auto quick trim balance > 157 auto quick raid > -- > 2.28.0 > -- Filipe David Manana, “Whether you think you can, or you think you can't — you're right.”