Skip to content

Commit

Permalink
t/zbd: fix minimum write size to sequential write required zones
Browse files Browse the repository at this point in the history
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 <shinichiro.kawasaki@wdc.com>
Signed-off-by: Vincent Fu <vincent.fu@samsung.com>
  • Loading branch information
kawasaki authored and vincentkfu committed Mar 7, 2023
1 parent 7920177 commit 557cfc5
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 6 deletions.
28 changes: 25 additions & 3 deletions t/zbd/functions
Original file line number Diff line number Diff line change
Expand Up @@ -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//'
}

Expand Down
6 changes: 3 additions & 3 deletions t/zbd/test-zbd-support
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 557cfc5

Please sign in to comment.