btrfs: test unaligned punch hole at ENOSPC

Try to punch hole with unaligned size and offset when the FS is full
and mounted with nodatacow option.

Mainly holes are punched at locations which are unaligned with the
file extent boundaries when the FS is full by data.  As the punching
holes at unaligned location will involve truncating blocks instead
of just dropping the extents, it shall involve reserving data and
metadata space for delalloc and so data alloc fails as the FS is
full.

btrfs_punch_hole()
 btrfs_truncate_block()
   btrfs_check_data_free_space() <-- ENOSPC

We don't fail punch hole if the holes are aligned with the file
extent boundaries as it shall involve just dropping the related
extents, without truncating data extent blocks.

This test was orignally merged as btrfs/172 (commit 4c2c678cd), then
Iremoved by commit 538d8a4bcc. But it's decided to bring back this
test case, now the problem is better understood and the fix is
available in the ML as below.

Link: https://patchwork.kernel.org/patch/11357415/

Reviewed-by: Filipe Manana <fdmanana@suse.com>
(cherry picked from commit 4c2c678cd5)
Signed-off-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: Eryu Guan <guaneryu@gmail.com>
This commit is contained in:
Anand Jain
2020-01-31 13:09:57 +08:00
committed by Eryu Guan
parent 2806589445
commit 108d8cde1c
3 changed files with 76 additions and 0 deletions
+73
View File
@@ -0,0 +1,73 @@
#! /bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2018 Oracle. All Rights Reserved.
#
# FS QA Test 204
#
# Test if the unaligned (by size and offset) punch hole is successful when FS
# is at ENOSPC.
#
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
_supported_os Linux
_require_scratch
_require_xfs_io_command "fpunch"
_scratch_mkfs_sized $((256 * 1024 *1024)) >> $seqres.full
# max_inline ensures data is not inlined within metadata extents
_scratch_mount "-o max_inline=0,nodatacow"
cat /proc/self/mounts | grep $SCRATCH_DEV >> $seqres.full
$BTRFS_UTIL_PROG filesystem df $SCRATCH_MNT >> $seqres.full
extent_size=$(_scratch_btrfs_sectorsize)
unalign_by=512
echo extent_size=$extent_size unalign_by=$unalign_by >> $seqres.full
$XFS_IO_PROG -f -c "pwrite -S 0xab 0 $((extent_size * 10))" \
$SCRATCH_MNT/testfile >> $seqres.full
echo "Fill all space available for data and all unallocated space." >> $seqres.full
dd status=none if=/dev/zero of=$SCRATCH_MNT/filler bs=512 >> $seqres.full 2>&1
hole_offset=0
hole_len=$unalign_by
$XFS_IO_PROG -c "fpunch $hole_offset $hole_len" $SCRATCH_MNT/testfile
hole_offset=$(($extent_size + $unalign_by))
hole_len=$(($extent_size - $unalign_by))
$XFS_IO_PROG -c "fpunch $hole_offset $hole_len" $SCRATCH_MNT/testfile
hole_offset=$(($extent_size * 2 + $unalign_by))
hole_len=$(($extent_size * 5))
$XFS_IO_PROG -c "fpunch $hole_offset $hole_len" $SCRATCH_MNT/testfile
# success, all done
echo "Silence is golden"
status=0
exit
+2
View File
@@ -0,0 +1,2 @@
QA output created by 204
Silence is golden
+1
View File
@@ -206,3 +206,4 @@
201 auto quick punch log
202 auto quick subvol snapshot
203 auto quick send clone
204 auto quick punch