2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (c) 2019 Red Hat, Inc. All Rights Reserved.
7 # Non-block-aligned direct AIO write test with an initial truncate i_size.
9 # Uncover "ext4: Fix data corruption caused by unaligned direct AIO":
10 # (Ext4 needs to serialize unaligned direct AIO because the zeroing of
11 # partial blocks of two competing unaligned AIOs can result in data
14 # However it decides not to serialize if the potentially unaligned aio is
15 # past i_size with the rationale that no pending writes are possible past
16 # i_size. Unfortunately if the i_size is not block aligned and the second
17 # unaligned write lands past i_size, but still into the same block, it has
18 # the potential of corrupting the previous unaligned write to the same
22 seqres=$RESULT_DIR/$seq
23 echo "QA output created by $seq"
27 status=1 # failure is the default!
28 trap "_cleanup; exit \$status" 0 1 2 3 15
36 # get standard environment, filters and checks
40 # remove previous $seqres.full before test
43 # real QA test starts here
46 _require_aiodio aio-dio-write-verify
48 localfile=$TEST_DIR/${seq}-aio-dio-write-verify-testfile
49 diosize=`_min_dio_alignment $TEST_DEV`
50 blocksize=`_get_block_size $TEST_DIR`
51 bufsize=$((blocksize * 2))
52 truncsize=$((bufsize+diosize))
54 # Need smaller logical block size to do non-block-aligned test
55 if [ $diosize -ge $blocksize ];then
56 _notrun "Need device logical block size($diosize) < fs block size($blocksize)"
59 rm -rf $localfile 2>/dev/null
60 # block-aligned aiodio write verification at first
61 $AIO_TEST -a size=$bufsize,off=0 -a size=$bufsize,off=$bufsize $localfile
63 # non-block-aligned aiodio write verification
64 # **************** **************** ****************
65 # * block 1&2 * * block 3&4 * * block 5&6 *
66 # **************** **************** ****************
67 # existing 0000000000000000 0000000000000000 0000000000000000
68 # truncate ---------------->|
69 # write 1 ZZZZZZZZZZZZZZZ Z
70 # write 2 |<---- ZZZZZZZZZZZZZZZ Z ---->|
72 # "Write 1" writes 2 blocks data at off=$diosize.
73 # "Write 2" seeks from 0 to "Write 1" end + block size, shift $diosize bytes each
74 # time, writes 2 blocksize data too.
75 # Verify there's not corruption each time.
77 while [ $((diosize * i)) -lt $((diosize + bufsize + blocksize)) ];do
78 position=$((diosize * i++))
79 # non-block-aligned AIO write on different i_size file
80 $AIO_TEST -t $truncsize -a size=$bufsize,off=$diosize \
81 -a size=$bufsize,off=$position \
84 echo "FAIL: [$truncsize, $bufsize, $diosize, $position]"
85 echo "-------------------------------------------------"
90 echo "Silence is golden"