[PATCH blktests] block/045: respect dma_alignment
Shin'ichiro Kawasaki <[email protected]> Thu, 6 Aug 2026 18:42:18 +0900
| Newsgroups | org.kernel.vger.linux-block |
|---|---|
| Message-ID | <[email protected]> |
Since the kernel commit 14b007e17881 ("block: validate user space
vectors during extraction"), the test case block/045 fails with the
error message below:
block/045 (test direct I/O full-trim bvec alignment) [failed]
runtime 0.550s ... 0.630s
--- tests/block/045.out 2026-08-03 19:26:40.407053612 +0900
+++ /home/shin/Blktests/blktests/results/nodev/block/045.out.bad 2026-08-05 20:48:33.366932845 +0900
@@ -1,2 +1,4 @@
Running block/045
+bio-full-trim: pread returned -1 (errno 22)
+bio-full-trim helper failed
Test complete
The errno 22 means EINVAL. The commit introduced the dma_alignment check
and returns EINVAL when the check is not fulfilled. The test case calls
pread() with one byte offset. This offset is not aligned to the
dma_alignment, then EINVAL is returned.
To avoid the failure, respect the dma_alignment check. Get the
dma_alignment value and pass it to bio-full-trim command. Use the
alignment to decide the offset value.
Link: https://lore.kernel.org/linux-block/anMscoGkR5BYjSGy@shinmob/
Signed-off-by: Shin'ichiro Kawasaki <[email protected]>
---
I confirmed that block/045 can detect the KASAN stack-out-of-bounds
that was caused by the v1 kernel patch titled "block: fix aligning of
bounced dio read bios" [*], regardless of whether this blktests patch
is applied or not.
[*] https://lore.kernel.org/linux-block/[email protected]/
src/bio-full-trim.c | 27 +++++++++++++++++++++++++--
tests/block/045 | 3 ++-
2 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/src/bio-full-trim.c b/src/bio-full-trim.c
index e304b2c..a3dda4c 100644
--- a/src/bio-full-trim.c
+++ b/src/bio-full-trim.c
@@ -12,26 +12,49 @@
#include <sys/mman.h>
#include <unistd.h>
+static int msb(unsigned int v)
+{
+ unsigned int b = 0;
+
+ while (v >>= 1)
+ b++;
+
+ return b;
+}
+
int main(int argc, char **argv)
{
unsigned int block_size;
unsigned char *p;
long page_size;
+ unsigned int dma_alignment;
+ unsigned int dma_aligned_offset;
ssize_t ret;
int fd;
- if (argc != 2)
+ if (argc != 3)
return EXIT_FAILURE;
+
page_size = sysconf(_SC_PAGESIZE);
if (page_size <= 0)
errx(EXIT_FAILURE, "invalid page size");
+ dma_alignment = atoi(argv[2]);
+ if (dma_alignment == 0)
+ errx(EXIT_FAILURE, "unexpected dma_alignment");
+
fd = open(argv[1], O_RDONLY | O_DIRECT);
if (fd < 0)
err(EXIT_FAILURE, "open %s", argv[1]);
if (ioctl(fd, BLKSSZGET, &block_size))
err(EXIT_FAILURE, "BLKSSZGET");
+ dma_aligned_offset = 1 << (msb(dma_alignment) + 1);
+ if (dma_aligned_offset >= block_size)
+ errx(EXIT_FAILURE,
+ "unexpected dma_alignment %u for block size %u",
+ dma_alignment, block_size);
+
p = mmap(NULL, 2 * page_size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (p == MAP_FAILED)
@@ -40,7 +63,7 @@ int main(int argc, char **argv)
err(EXIT_FAILURE, "mprotect");
errno = 0;
- ret = pread(fd, p + page_size - 1, block_size, 0);
+ ret = pread(fd, p + page_size - dma_aligned_offset, block_size, 0);
if (ret == -1 && errno == EFAULT)
return EXIT_SUCCESS;
errx(EXIT_FAILURE, "pread returned %zd (errno %d)", ret, errno);
diff --git a/tests/block/045 b/tests/block/045
index 65bfcb9..6e112b6 100755
--- a/tests/block/045
+++ b/tests/block/045
@@ -25,7 +25,8 @@ test() {
return 1
fi
- if ! src/bio-full-trim /dev/nullb1; then
+ if ! src/bio-full-trim /dev/nullb1 \
+ $(< /sys/block/nullb1/queue/dma_alignment); then
echo "bio-full-trim helper failed"
fi
--
2.54.0