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 _begin_fstest auto quick aio
24 # Import common functions.
27 # real QA test starts here
30 _require_aiodio aio-dio-write-verify
32 localfile=$TEST_DIR/${seq}-aio-dio-write-verify-testfile
33 diosize=`_min_dio_alignment $TEST_DEV`
34 blocksize=`_get_block_size $TEST_DIR`
35 bufsize=$((blocksize * 2))
36 truncsize=$((bufsize+diosize))
38 # Need smaller logical block size to do non-block-aligned test
39 if [ $diosize -ge $blocksize ];then
40 _notrun "Need device logical block size($diosize) < fs block size($blocksize)"
43 rm -rf $localfile 2>/dev/null
44 # block-aligned aiodio write verification at first
45 $AIO_TEST -a size=$bufsize,off=0 -a size=$bufsize,off=$bufsize $localfile
47 # non-block-aligned aiodio write verification
48 # **************** **************** ****************
49 # * block 1&2 * * block 3&4 * * block 5&6 *
50 # **************** **************** ****************
51 # existing 0000000000000000 0000000000000000 0000000000000000
52 # truncate ---------------->|
53 # write 1 ZZZZZZZZZZZZZZZ Z
54 # write 2 |<---- ZZZZZZZZZZZZZZZ Z ---->|
56 # "Write 1" writes 2 blocks data at off=$diosize.
57 # "Write 2" seeks from 0 to "Write 1" end + block size, shift $diosize bytes each
58 # time, writes 2 blocksize data too.
59 # Verify there's not corruption each time.
61 while [ $((diosize * i)) -lt $((diosize + bufsize + blocksize)) ];do
62 position=$((diosize * i++))
63 # non-block-aligned AIO write on different i_size file
64 $AIO_TEST -t $truncsize -a size=$bufsize,off=$diosize \
65 -a size=$bufsize,off=$position \
68 echo "FAIL: [$truncsize, $bufsize, $diosize, $position]"
69 echo "-------------------------------------------------"
74 echo "Silence is golden"