From 557cfc51068921766e8cd6b242feb4c929cb45ea Mon Sep 17 00:00:00 2001 From: Shin'ichiro Kawasaki Date: Mon, 6 Mar 2023 14:58:40 +0900 Subject: [PATCH] t/zbd: fix minimum write size to sequential write required zones ZBC and ZAC require that writes to sequential write required zones shall be aligned to physical block size. However, the t/zbd/test-zbd-support script uses logical block size as the minimum write size. When SMR drives have the physical block size larger than the logical block size, writes with the logical block size causes unaligned write command error. To fix it, use correct value as the minimum write size. As for zoned block devices, introduce a helper function min_seq_write_size(), which checks sysfs attributes and returns the correct size. Refer the attribute zone_write_granularity when it is available, which provides the minimum write size regardless of the device type. If the attribute is not available, refer the attribute physical_block_size for SMR devices, and the logical_block_size attribute for other devices. As for SG node device, refer physical block size that zbc_info command reports. Signed-off-by: Shin'ichiro Kawasaki Signed-off-by: Vincent Fu --- t/zbd/functions | 28 +++++++++++++++++++++++++--- t/zbd/test-zbd-support | 6 +++--- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/t/zbd/functions b/t/zbd/functions index 812320f529..9a6d699910 100644 --- a/t/zbd/functions +++ b/t/zbd/functions @@ -238,18 +238,40 @@ max_open_zones() { fi } +# Get minimum block size to write to seq zones. Refer the sysfs attribute +# zone_write_granularity which shows the valid minimum size regardless of zoned +# block device type. If the sysfs attribute is not available, refer physical +# block size for rotational SMR drives. For non-rotational devices such as ZNS +# devices, refer logical block size. +min_seq_write_size() { + local sys_path="/sys/block/$1/queue" + local -i size=0 + + if [[ -r "$sys_path/zone_write_granularity" ]]; then + size=$(<"$sys_path/zone_write_granularity") + fi + + if ((size)); then + echo "$size" + elif (($(<"$sys_path/rotational"))); then + cat "$sys_path/physical_block_size" + else + cat "$sys_path/logical_block_size" + fi +} + is_zbc() { local dev=$1 [[ -z "$(${zbc_info} "$dev" | grep "is not a zoned block device")" ]] } -zbc_logical_block_size() { +zbc_physical_block_size() { local dev=$1 ${zbc_info} "$dev" | - grep "logical blocks" | - sed -n 's/^[[:blank:]]*[0-9]* logical blocks of[[:blank:]]*//p' | + grep "physical blocks" | + sed -n 's/^[[:blank:]]*[0-9]* physical blocks of[[:blank:]]*//p' | sed 's/ B//' } diff --git a/t/zbd/test-zbd-support b/t/zbd/test-zbd-support index 7b229002c5..996160e769 100755 --- a/t/zbd/test-zbd-support +++ b/t/zbd/test-zbd-support @@ -1427,7 +1427,7 @@ if [[ -b "$realdev" ]]; then realsysfs=$(readlink "/sys/dev/block/$major:$minor") basename=$(basename "${realsysfs%/*}") fi - min_seq_write_size=$(<"/sys/block/$basename/queue/logical_block_size") + min_seq_write_size=$(min_seq_write_size "$basename") case "$(<"/sys/class/block/$basename/queue/zoned")" in host-managed|host-aware) is_zbd=true @@ -1476,8 +1476,8 @@ elif [[ -c "$realdev" ]]; then echo "Failed to determine disk size" exit 1 fi - if ! min_seq_write_size=($(zbc_logical_block_size "$dev")); then - echo "Failed to determine logical block size" + if ! min_seq_write_size=($(zbc_physical_block_size "$dev")); then + echo "Failed to determine physical block size" exit 1 fi if ! result=($(first_sequential_zone "$dev")); then