# Random write to conventional zones.
test14() {
- local size
+ local off size
+ if ! result=($(first_online_zone "$dev")); then
+ echo "Failed to determine first online zone"
+ exit 1
+ fi
+ off=${result[0]}
prep_write
size=$((16 * 2**20)) # 20 MB
require_conv_zone_bytes "${size}" || return $SKIP_TESTCASE
run_one_fio_job "$(ioengine "libaio")" --iodepth=64 --rw=randwrite --bs=16K \
--zonemode=zbd --zonesize="${zone_size}" --do_verify=1 \
- --verify=md5 --size=$size \
+ --verify=md5 --offset=$off --size=$size\
>>"${logfile}.${test_number}" 2>&1 || return $?
check_written $((size)) || return $?
check_read $((size)) || return $?
# Random reads and writes in the last zone.
test17() {
- local io off read size written
+ local io off last read size written
off=$(((disk_size / zone_size - 1) * zone_size))
size=$((disk_size - off))
+ if ! last=($(last_online_zone "$dev")); then
+ echo "Failed to determine last online zone"
+ exit 1
+ fi
+ if [[ "$((last * 512))" -lt "$off" ]]; then
+ off=$((last * 512))
+ size=$zone_size
+ fi
if [ -n "$is_zbd" ]; then
reset_zone "$dev" $((off / 512)) || return $?
fi
prep_write
run_one_fio_job "$(ioengine "libaio")" --iodepth=8 --rw=randrw --bs=4K \
--zonemode=zbd --zonesize="${zone_size}" \
- --offset=$off --loops=2 --norandommap=1\
+ --offset=$off --loops=2 --norandommap=1 \
+ --size="$size"\
>>"${logfile}.${test_number}" 2>&1 || return $?
written=$(fio_written <"${logfile}.${test_number}")
read=$(fio_read <"${logfile}.${test_number}")
test31() {
local bs inc nz off opts size
- prep_write
- # Start with writing 128 KB to 128 sequential zones.
- bs=128K
- nz=128
- # shellcheck disable=SC2017
- inc=$(((disk_size - (first_sequential_zone_sector * 512)) / (nz * zone_size)
- * zone_size))
- opts=()
- for ((off = first_sequential_zone_sector * 512; off < disk_size;
- off += inc)); do
- opts+=("--name=$dev" "--filename=$dev" "--offset=$off" "--io_size=$bs")
- opts+=("--bs=$bs" "--size=$zone_size" "$(ioengine "libaio")")
- opts+=("--rw=write" "--direct=1" "--thread=1" "--stats=0")
- opts+=("--zonemode=zbd" "--zonesize=${zone_size}")
- opts+=(${job_var_opts[@]})
- done
- "$(dirname "$0")/../../fio" "${opts[@]}" >> "${logfile}.${test_number}" 2>&1
- # Next, run the test.
+ [ -n "$is_zbd" ] && reset_zone "$dev" -1
+
+ # As preparation, write 128 KB to sequential write required zones. Limit
+ # write target zones up to max_open_zones to keep test time reasonable.
+ # To distribute the write target zones evenly, skip certain zones for every
+ # write. Utilize zonemode strided for such write patterns.
+ bs=$((128 * 1024))
+ nz=$((max_open_zones))
+ if [[ $nz -eq 0 ]]; then
+ nz=128
+ fi
off=$((first_sequential_zone_sector * 512))
size=$((disk_size - off))
+ inc=$(((size / nz / zone_size) * zone_size))
+ opts=("--name=$dev" "--filename=$dev" "--rw=write" "--bs=${bs}")
+ opts+=("--offset=$off" "--size=$((inc * nz))" "--io_size=$((bs * nz))")
+ opts+=("--zonemode=strided" "--zonesize=${bs}" "--zonerange=${inc}")
+ opts+=("--direct=1")
+ echo "fio ${opts[@]}" >> "${logfile}.${test_number}"
+ "$(dirname "$0")/../../fio" "${opts[@]}" >> "${logfile}.${test_number}" 2>&1
+
+ # Next, run the test.
opts=("--name=$dev" "--filename=$dev" "--offset=$off" "--size=$size")
opts+=("--bs=$bs" "$(ioengine "psync")" "--rw=randread" "--direct=1")
opts+=("--thread=1" "--time_based" "--runtime=30" "--zonemode=zbd")
# Read one block from a block device.
read_one_block() {
+ local off
local bs
+ if ! result=($(first_online_zone "$dev")); then
+ echo "Failed to determine first online zone"
+ exit 1
+ fi
+ off=${result[0]}
bs=$((logical_block_size))
- run_one_fio_job --rw=read "$(ioengine "psync")" --bs=$bs --size=$bs "$@" 2>&1 |
+ run_one_fio_job --rw=read "$(ioengine "psync")" --offset=$off --bs=$bs \
+ --size=$bs "$@" 2>&1 |
tee -a "${logfile}.${test_number}"
}
test42() {
require_regular_block_dev || return $SKIP_TESTCASE
read_one_block --zonemode=zbd --zonesize=0 |
- grep -q 'Specifying the zone size is mandatory for regular block devices with --zonemode=zbd'
+ grep -q 'Specifying the zone size is mandatory for regular file/block device with --zonemode=zbd'
}
# Check whether fio handles --zonesize=1 correctly for regular block devices.
{ echo; echo "fio ${opts[*]}"; echo; } >>"${logfile}.${test_number}"
- timeout -v -s KILL 45s \
+ timeout -v -s KILL 180s \
"${dynamic_analyzer[@]}" "$fio" "${opts[@]}" \
>> "${logfile}.${test_number}" 2>&1 || return $?
}
return 1
}
+# Test read/write mix with verify.
+test54() {
+ require_zbd || return $SKIP_TESTCASE
+ require_seq_zones 8 || return $SKIP_TESTCASE
+
+ run_fio --name=job --filename=${dev} "$(ioengine "libaio")" \
+ --time_based=1 --runtime=30s --continue_on_error=0 \
+ --offset=$((first_sequential_zone_sector * 512)) \
+ --size=$((8*zone_size)) --direct=1 --iodepth=1 \
+ --rw=randrw:2 --rwmixwrite=25 --bsrange=4k-${zone_size} \
+ --zonemode=zbd --zonesize=${zone_size} \
+ --verify=crc32c --do_verify=1 --verify_backlog=2 \
+ --experimental_verify=1 \
+ --alloc-size=65536 --random_generator=tausworthe64 \
+ ${job_var_opts[@]} --debug=zbd \
+ >> "${logfile}.${test_number}" 2>&1 || return $?
+}
+
+# test 'z' suffix parsing only
+test55() {
+ local bs
+ bs=$((logical_block_size))
+
+ require_zbd || return $SKIP_TESTCASE
+ # offset=1z + offset_increment=10z + size=2z
+ require_seq_zones 13 || return $SKIP_TESTCASE
+
+ run_fio --name=j \
+ --filename=${dev} \
+ --direct=1 \
+ "$(ioengine "psync")" \
+ --zonemode=zbd \
+ --zonesize=${zone_size} \
+ --rw=write \
+ --bs=${bs} \
+ --numjobs=2 \
+ --offset_increment=10z \
+ --offset=1z \
+ --size=2z \
+ --io_size=3z \
+ ${job_var_opts[@]} --debug=zbd \
+ >> "${logfile}.${test_number}" 2>&1 || return $?
+}
+
+# test 'z' suffix parsing only
+test56() {
+ local bs
+ bs=$((logical_block_size))
+
+ require_regular_block_dev || return $SKIP_TESTCASE
+ require_seq_zones 10 || return $SKIP_TESTCASE
+
+ run_fio --name=j \
+ --filename=${dev} \
+ --direct=1 \
+ "$(ioengine "psync")" \
+ --zonemode=strided \
+ --zonesize=${zone_size} \
+ --rw=write \
+ --bs=${bs} \
+ --size=10z \
+ --zoneskip=2z \
+ ${job_var_opts[@]} --debug=zbd \
+ >> "${logfile}.${test_number}" 2>&1 || return $?
+}
+
+# Test that repeated async write job does not cause zone reset during writes
+# in-flight, when the block size is not a divisor of the zone size.
+test57() {
+ local bs off
+
+ require_zbd || return $SKIP_TESTCASE
+
+ bs=$((4096 * 7))
+ off=$((first_sequential_zone_sector * 512))
+
+ run_fio --name=job --filename="${dev}" --rw=randwrite --bs="${bs}" \
+ --offset="${off}" --size=$((4 * zone_size)) --iodepth=256 \
+ "$(ioengine "libaio")" --time_based=1 --runtime=30s \
+ --zonemode=zbd --direct=1 --zonesize="${zone_size}" \
+ ${job_var_opts[@]} \
+ >> "${logfile}.${test_number}" 2>&1 || return $?
+}
+
+SECONDS=0
tests=()
dynamic_analyzer=()
reset_all_zones=
-q) quit_on_err=1; shift;;
-z) zbd_debug=1; shift;;
--) shift; break;;
+ *) usage; exit 1;;
esac
done
if [[ -n ${max_open_zones_opt} ]]; then
# Override max_open_zones with the script option value
max_open_zones="${max_open_zones_opt}"
+ global_var_opts+=("--ignore_zone_limits=1")
job_var_opts+=("--max_open_zones=${max_open_zones_opt}")
fi
if [ $failed -gt 0 ]; then
echo " $failed tests failed"
fi
+echo "Run time: $(TZ=UTC0 printf "%(%H:%M:%S)T\n" $(( SECONDS )) )"
exit $rc