Skip to content

Commit 3775cf2

Browse files
committed
ZTS: test for STATX_DIOALIGN
Uses the statx helper to test the results of the STATX_DIOALIGN request as we manipulate DIO enable, dataset recordsize and file size and structure. Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris <[email protected]>
1 parent 981b1e0 commit 3775cf2

File tree

4 files changed

+154
-2
lines changed

4 files changed

+154
-2
lines changed

tests/runfiles/common.run

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -975,7 +975,7 @@ tests = ['sparse_001_pos']
975975
tags = ['functional', 'sparse']
976976

977977
[tests/functional/stat]
978-
tests = ['stat_001_pos']
978+
tests = ['stat_001_pos', 'statx_dioalign']
979979
tags = ['functional', 'stat']
980980

981981
[tests/functional/suid]

tests/test-runner/bin/zts-report.py.in

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,11 @@ idmap_reason = 'Idmapped mount needs kernel 5.12+'
128128
#
129129
cfr_reason = 'Kernel copy_file_range support required'
130130

131+
#
132+
# Some statx fields are not supported by all kernels
133+
#
134+
statx_reason = 'Needed statx(2) field not supported on this kernel'
135+
131136
if sys.platform.startswith('freebsd'):
132137
cfr_cross_reason = 'copy_file_range(2) cross-filesystem needs FreeBSD 14+'
133138
else:
@@ -293,7 +298,8 @@ if sys.platform.startswith('freebsd'):
293298
'block_cloning/block_cloning_cross_enc_dataset':
294299
['SKIP', cfr_cross_reason],
295300
'block_cloning/block_cloning_copyfilerange_cross_dataset':
296-
['SKIP', cfr_cross_reason]
301+
['SKIP', cfr_cross_reason],
302+
'stat/statx_dioalign': ['SKIP', 'na_reason'],
297303
})
298304
elif sys.platform.startswith('linux'):
299305
maybe.update({
@@ -361,6 +367,7 @@ elif sys.platform.startswith('linux'):
361367
'mmp/mmp_active_import': ['FAIL', known_reason],
362368
'mmp/mmp_exported_import': ['FAIL', known_reason],
363369
'mmp/mmp_inactive_import': ['FAIL', known_reason],
370+
'stat/statx_dioalign': ['SKIP', 'statx_reason'],
364371
})
365372

366373

tests/zfs-tests/tests/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2050,6 +2050,7 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
20502050
functional/stat/cleanup.ksh \
20512051
functional/stat/setup.ksh \
20522052
functional/stat/stat_001_pos.ksh \
2053+
functional/stat/statx_dioalign.ksh \
20532054
functional/suid/cleanup.ksh \
20542055
functional/suid/setup.ksh \
20552056
functional/suid/suid_write_to_none.ksh \
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
#!/bin/ksh -p
2+
#
3+
# CDDL HEADER START
4+
#
5+
# The contents of this file are subject to the terms of the
6+
# Common Development and Distribution License (the "License").
7+
# You may not use this file except in compliance with the License.
8+
#
9+
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10+
# or https://opensource.org/licenses/CDDL-1.0.
11+
# See the License for the specific language governing permissions
12+
# and limitations under the License.
13+
#
14+
# When distributing Covered Code, include this CDDL HEADER in each
15+
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16+
# If applicable, add the following below this CDDL HEADER, with the
17+
# fields enclosed by brackets "[]" replaced with your own identifying
18+
# information: Portions Copyright [yyyy] [name of copyright owner]
19+
#
20+
# CDDL HEADER END
21+
#
22+
23+
#
24+
# Copyright (c) 2025, Rob Norris <[email protected]>
25+
#
26+
27+
#
28+
# Uses the statx helper to test the results of the STATX_DIOALIGN request as we
29+
# manipulate DIO enable, dataset recordsize and file size and structure.
30+
#
31+
32+
. $STF_SUITE/include/libtest.shlib
33+
34+
verify_runnable "both"
35+
36+
if ! is_linux ; then
37+
log_unsupported "statx(2) only available on Linux"
38+
fi
39+
40+
if [[ $(linux_version) -lt $(linux_version "6.1") ]] ; then
41+
log_unsupported "STATX_DIOALIGN not available before Linux 6.1"
42+
fi
43+
44+
CLAIM="STATX_DIOALIGN returns useful values when Direct IO is available."
45+
46+
TESTDS=${TESTPOOL}/${TESTFS}
47+
TESTFILE=${TESTDIR}/${TESTFILE0}
48+
49+
log_must save_tunable DIO_ENABLED
50+
typeset recordsize_saved=$(get_prop recordsize $TESTDS)
51+
typeset direct_saved=$(get_prop direct $TESTDS)
52+
53+
function cleanup
54+
{
55+
rm -f ${TESTFILE}
56+
zfs set recordsize=$recordsize_saved $TESTDS
57+
zfs set direct=$direct_saved $TESTDS
58+
restore_tunable DIO_ENABLED
59+
}
60+
log_onexit cleanup
61+
62+
# assert_dioalign <file> <memalign> <ioalign>
63+
function assert_dioalign
64+
{
65+
typeset file=$1
66+
typeset -i memalign=$2
67+
typeset -i ioalign=$3
68+
69+
typeset -a v=($(statx dioalign $file | cut -f2- -d' '))
70+
log_note "statx dioalign returned: $file: mem=${v[0]} io=${v[1]}"
71+
log_must [ ${v[0]} -eq $memalign -a ${v[1]} -eq $ioalign ]
72+
}
73+
74+
log_assert $CLAIM
75+
76+
# Compute the expected IO size. Testing this properly means changing the
77+
# ashift, which means recreating the pool, which is slightly fiddly here, so
78+
# I have not bothered.
79+
typeset -i PAGE_SIZE=$(getconf PAGE_SIZE)
80+
typeset -i IO_SIZE=$(( 1 << $(zpool get -H -o value ashift $TESTPOOL) ))
81+
if [[ $IO_SIZE -lt $PAGE_SIZE ]] ; then
82+
IO_SIZE=$PAGE_SIZE
83+
fi
84+
85+
# Set recordsize and make a recordsized file for the general tests.
86+
log_must zfs set recordsize=128K $TESTDS
87+
log_must dd if=/dev/urandom of=$TESTFILE bs=128k count=1
88+
log_must zpool sync
89+
90+
# when DIO is disabled via tunable, result should always be zero, no matter
91+
# what the value of the direct= property.
92+
log_must set_tunable32 DIO_ENABLED 0
93+
94+
for d in disabled standard always ; do
95+
log_must zfs set direct=$d $TESTDS
96+
assert_dioalign $TESTFILE 0 0
97+
done
98+
99+
# when DIO is enabled via tunable, behaviour is dependent on the direct=
100+
# property.
101+
log_must set_tunable32 DIO_ENABLED 1
102+
103+
# when DIO is disabled via property, result should be zero.
104+
log_must zfs set direct=disabled $TESTDS
105+
assert_dioalign $TESTFILE 0 0
106+
107+
# when DIO is enabled, the result should be mem=recordsize, io=pagesize
108+
for d in standard always ; do
109+
log_must zfs set direct=$d $TESTDS
110+
assert_dioalign $TESTFILE 131072 $IO_SIZE
111+
done
112+
113+
# setting the recordsize smaller than the blocksize on an existing file
114+
# will use the file's blocksize
115+
log_must zfs set recordsize=32K $TESTDS
116+
for d in standard always ; do
117+
log_must zfs set direct=$d $TESTDS
118+
assert_dioalign $TESTFILE 131072 $IO_SIZE
119+
done
120+
121+
# setting the recordsize larger than the blocksize on an existing file with
122+
# only one block will use the dataset's recordsize, ie the size that the block
123+
# could grow to
124+
log_must zfs set recordsize=256K $TESTDS
125+
for d in standard always ; do
126+
log_must zfs set direct=$d $TESTDS
127+
assert_dioalign $TESTFILE 262144 $IO_SIZE
128+
done
129+
130+
# extending a file into the second block fixes its blocksize, so result should
131+
# be its blocksize, regardless of how the recordsize changes
132+
log_must zfs set recordsize=128K $TESTDS
133+
log_must dd if=/dev/urandom of=$TESTFILE bs=128k count=1 seek=1
134+
log_must zpool sync
135+
136+
for rs in 64K 128K 256K 512K ; do
137+
log_must zfs set recordsize=$rs $TESTDS
138+
for d in standard always ; do
139+
log_must zfs set direct=$d $TESTDS
140+
assert_dioalign $TESTFILE 131072 $IO_SIZE
141+
done
142+
done
143+
144+
log_pass $CLAIM

0 commit comments

Comments
 (0)