t/zbd: Align block size to zone capacity
authorShin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Wed, 13 Oct 2021 06:09:02 +0000 (15:09 +0900)
committerJens Axboe <axboe@kernel.dk>
Sun, 17 Oct 2021 13:00:36 +0000 (07:00 -0600)
The test cases #5, #6, #15 and #37 writes data and read it back (or
write with verify option for read back). When test target zones have
zone capacity unaligned to the block size, read request can not be made
to all of the written data, and the test cases fail.

To avoid the failures, check zone capacity of zones and get block size
which can align to the zone capacities. Then use the block size for the
test cases.

Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Reviewed-by: Niklas Cassel <niklas.cassel@wdc.com>
Link: https://lore.kernel.org/r/20211013060903.166543-5-shinichiro.kawasaki@wdc.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
t/zbd/functions
t/zbd/test-zbd-support

index 08a2c629e842cc26e3666f992396ae23ecfdff37..e4e248b9ff26a0c99fe564598455ab4a86d5ac5f 100644 (file)
@@ -64,6 +64,32 @@ check_blkzone() {
        fi
 }
 
+# Check zone capacity of each zone and report block size aligned to the zone
+# capacities. If zone capacity is same as zone size for zones, report zone size.
+zone_cap_bs() {
+       local dev="${1}"
+       local zone_size="${2}"
+       local sed_str='s/.*len \([0-9A-Za-z]*\), cap \([0-9A-Za-z]*\).*/\1 \2/p'
+       local cap bs="$zone_size"
+
+       # When blkzone is not available or blkzone does not report capacity,
+       # assume that zone capacity is same as zone size for all zones.
+       if [ -z "${blkzone}" ] || ! blkzone_reports_capacity "${dev}"; then
+               echo "$zone_size"
+               return
+       fi
+
+       while read -r -a line; do
+               ((line[0] == line[1])) && continue
+               cap=$((line[1] * 512))
+               while ((bs > 512 && cap % bs)); do
+                       bs=$((bs / 2))
+               done
+       done < <(blkzone report "${dev}" | sed -n "${sed_str}")
+
+       echo "$bs"
+}
+
 # Reports the starting sector and length of the first sequential zone of device
 # $1.
 first_sequential_zone() {
index f9dc90010eba95ac014ca65c1ee5daf3437ad6af..4ee46de35f4f33adf128d6ee233a20bcba48cac0 100755 (executable)
@@ -321,15 +321,15 @@ test4() {
 
 # Sequential write to sequential zones.
 test5() {
-    local size off capacity
+    local size off capacity bs
 
     prep_write
     off=$((first_sequential_zone_sector * 512))
     capacity=$(total_zone_capacity 4 $off $dev)
     size=$((4 * zone_size))
+    bs=$(min "$(max $((zone_size / 64)) "$logical_block_size")" "$zone_cap_bs")
     run_fio_on_seq "$(ioengine "psync")" --iodepth=1 --rw=write        \
-                  --bs="$(max $((zone_size / 64)) "$logical_block_size")"\
-                  --do_verify=1 --verify=md5                           \
+                  --bs="$bs" --do_verify=1 --verify=md5 \
                   >>"${logfile}.${test_number}" 2>&1 || return $?
     check_written $capacity || return $?
     check_read $capacity || return $?
@@ -337,18 +337,18 @@ test5() {
 
 # Sequential read from sequential zones.
 test6() {
-    local size off capacity
+    local size off capacity bs
 
     prep_write
     off=$((first_sequential_zone_sector * 512))
     capacity=$(total_zone_capacity 4 $off $dev)
     size=$((4 * zone_size))
+    bs=$(min "$(max $((zone_size / 64)) "$logical_block_size")" "$zone_cap_bs")
     write_and_run_one_fio_job \
            $((first_sequential_zone_sector * 512)) "${size}" \
            --offset="${off}" \
            --size="${size}" --zonemode=zbd --zonesize="${zone_size}" \
-           "$(ioengine "psync")" --iodepth=1 --rw=read \
-           --bs="$(max $((zone_size / 64)) "$logical_block_size")" \
+           "$(ioengine "psync")" --iodepth=1 --rw=read --bs="$bs" \
            >>"${logfile}.${test_number}" 2>&1 || return $?
     check_read $capacity || return $?
 }
@@ -486,7 +486,7 @@ test14() {
 
 # Sequential read on a mix of empty and full zones.
 test15() {
-    local i off size
+    local i off size bs
     local w_off w_size w_capacity
 
     for ((i=0;i<4;i++)); do
@@ -500,8 +500,9 @@ test15() {
     w_capacity=$(total_zone_capacity 2 $w_off $dev)
     off=$((first_sequential_zone_sector * 512))
     size=$((4 * zone_size))
+    bs=$(min $((zone_size / 16)) "$zone_cap_bs")
     write_and_run_one_fio_job "${w_off}" "${w_size}" \
-                   "$(ioengine "psync")" --rw=read --bs=$((zone_size / 16)) \
+                   "$(ioengine "psync")" --rw=read --bs="$bs" \
                    --zonemode=zbd --zonesize="${zone_size}" --offset=$off \
                    --size=$((size)) >>"${logfile}.${test_number}" 2>&1 ||
        return $?
@@ -853,7 +854,7 @@ test37() {
        off=$(((first_sequential_zone_sector - 1) * 512))
     fi
     size=$((zone_size + 2 * 512))
-    bs=$((zone_size / 4))
+    bs=$(min $((zone_size / 4)) "$zone_cap_bs")
     run_one_fio_job --offset=$off --size=$size "$(ioengine "psync")"   \
                    --iodepth=1 --rw=write --do_verify=1 --verify=md5   \
                    --bs=$bs --zonemode=zbd --zonesize="${zone_size}"   \
@@ -1378,6 +1379,8 @@ fi
 echo -n "First sequential zone starts at sector $first_sequential_zone_sector;"
 echo " zone size: $((zone_size >> 20)) MB"
 
+zone_cap_bs=$(zone_cap_bs "$dev" "$zone_size")
+
 if [ "${#tests[@]}" = 0 ]; then
     readarray -t tests < <(declare -F | grep "test[0-9]*" | \
                                   tr -c -d "[:digit:]\n" | sort -n)