Skip to content

dd iflag=direct reads fail with "IO error: Invalid input" on devices with strict dma_alignment #12085

Description

@chrboe

dd … iflag=direct fails with IO error: Invalid input when reading from a block device whose /sys/block/X/queue/dma_alignment is >= 511, even for fully aligned offsets and aligned I/O sizes. The read-side I/O buffer is allocated with default heap alignment (~16 bytes) instead of being aligned to the device's dma_alignment requirement, so the kernel rejects the O_DIRECT read with EINVAL.

This is related to #9003 / #9016. PR #9016 fixed the write path (partial-block writes at end-of-output). The read path still under-aligns its buffer; both bs=4K count=1 from offset 0 and large multi-block reads fail.

Originally spotted with DRBD, but this reproduces with all block device drivers that set dma_alignment to 511. For example, loop, virtio_blk, brd, nbd, zram are all affected.

Reproducer

Tested on Ubuntu 26.04 (resolute) with dd (uutils coreutils) 0.8.0, rust-coreutils 0.8.0-0ubuntu3, kernel 7.0.0-14-generic.

$ truncate -s 1M /tmp/loop.img
$ losetup --find --show /tmp/loop.img
/dev/loop0
$ cat /sys/block/loop0/queue/dma_alignment
511
$ dd if=/dev/loop0 of=/dev/null bs=4K count=1 iflag=direct
dd: IO error: Invalid input

Sanity check, the same read works with GNU dd:

$ gnudd --version
dd (coreutils) 9.7
Packaged by Ubuntu (9.7-3ubuntu2)
$ gnudd if=/dev/loop0 of=/dev/null bs=4K count=1 iflag=direct
1+0 records in
1+0 records out
4096 bytes (4.1 kB, 4.0 KiB) copied, 6.258e-05 s, 65.5 MB/s

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions