Skip to content

Add read_blockwise_offset function for s390x and O_DIRECT reading

An EINVAL error can be thrown when attempting to read a file with O_DIRECT on some systems. While testing on a s390x system using TCRYPT_HDR_HIDDEN_OFFSET_OLD the file read was failing since the offset is not aligned properly.

read_blockwise_offset is just a simple wrapper to call read_blockwise first and then attempt to read again with a modified offset that is aligned.


I did this fix a long time ago (11/2014), so forgive me if I've forgotten some details.

One interesting detail was when opening without O_DIRECT the reads in the tests ran succeeded.

From one of my notes:
Had an idea that with O_DIRECT it was attempting to read an entire physical block size of 4096 bytes. There are only 1532 (sic) bytes left until the end of the file with version 2 and 3 hidden headers. Wrote a new test to seek to 4096 bytes before the end of the file and was able to read the file with the O_DIRECT flag. It seems to be that on s390x if there isn't enough space to read left on the file the read will fail instead of returning the rest of the file. I'm not sure why this succeeds on other architectures though.
I typo'd 1532, suppose to be 1536

I was told something in this message implies that reads on s390x should be aligned to 4096 bytes:
http://lists.gnu.org/archive/html/qemu-devel/2012-12/msg00921.html

This mentions one should use the BLKSSZGET ioctrl to get the proper block size rather than hardcoding 512 bytes.
https://www.quora.com/Why-does-O_DIRECT-require-I-O-to-be-512-byte-aligned

Merge request reports