pwritev64 can't write at offsets between [2 GiB, 4 GiB)
Updated by John Levon over 2 years ago
From Joyent OS-5904 :
I noticed that nginx was getting EINVAL returned to it when calling pwritev64(). The problem occurs when the offset is in the range of 2 GiB and less than 4 GiB. The problem is that pwritev64 tries to split up the off64_t into two different 32-bit values. If then says if the upper bits are greater than zero, that it is using the 64-bit off_t aware version.
However, this is complicated by the fact that the off_t is signed. That means the maximum 32-bit off_t value is 0x7ffffffff. This means that we have a region where we incorrectly assert that the caller is using the 32-bit i
interface and return EINVAL.
The maxoff value is incorrect since it does not properly take into account large-file aware applications. There are similar issues with preadv.
For testing a wrote a simple program that does a pwritev at offsets 1GB, 2GB, 3GB, 4GB and 5GB (minus 1MB to avoid the boundary). It then does a preadv the same way. I compiled and tested that as a standard 32-bit app, a large-file aware 32-bit app, and a 64-bit app. I get the expected result (data or error) for each write & read.
Work by Jerry Jelinek, except the unit test which is mine.
Updated by Electric Monk over 2 years ago
- Status changed from New to Closed
- % Done changed from 0 to 100
commit 81c3d08501e57b65e096ec6a2b1d62f87cf8ced7 Author: Jerry Jelinek <email@example.com> Date: 2020-03-17T10:13:50.000Z 12365 pwritev64 can't write at offsets between [2 GiB, 4 GiB) Portions contributed by: John Levon <firstname.lastname@example.org> Reviewed by: Patrick Mooney <email@example.com> Reviewed by: Robert Mustacchi <firstname.lastname@example.org> Approved by: Dan McDonald <email@example.com>