Description
Description
Even though this exception sounds very similar to #108322 (comment) , it is actually a very different issue. It occurs in the Unix implementation of the RandomAccess.WriteGatherAtOffset
method
This is the stack trace
System.IO.IOException: Invalid argument
at System.IO.RandomAccess.WriteGatherAtOffset(SafeFileHandle handle, IReadOnlyList`1 buffers, Int64 fileOffset)
Looking at the implementation I have noticed that we call Interop.Sys.PWriteV
passing the buffersCount
as a parameter
which in turn calls the native implementation
runtime/src/native/libs/System.Native/pal_io.c
Line 2000 in c049b85
According to the documentation of pwritev
here http://man.he.net/man2/pwritev we cannot pass buffersCount
greater than 1024
NOTES
POSIX.1 allows an implementation to place a limit on the number of
items that can be passed in iov. An implementation can advertise its
limit by defining IOV_MAX in <limits.h> or at run time via the return
value from sysconf(_SC_IOV_MAX). On modern Linux systems, the limit is
1024. Back in Linux 2.0 days, this limit was 16.
Reproduction Steps
Call RandomAccess.Write(handle, buffers, fileOffset)
by passing list of buffers where buffers are more than 1024
Expected behavior
It should save the buffers to file
Actual behavior
It throws System.IO.IOException: Invalid argument
Regression?
Not tested on .NET6
Known Workarounds
You can split the buffers into smaller lists (<=1024 elements) and call RandomAccess.Write
multiple times with the proper offset
Configuration
Which version of .NET is the code running on?
.NET7
What OS and version, and what distro if applicable?
Ubuntu 22.04.3 LTS under WSL2
What is the architecture (x64, x86, ARM, ARM64)?
x64
Do you know whether it is specific to that configuration?
It is specific to the Unix implementation of the RandomAccess.WriteGatherAtOffset
method
Other information
Haven't tested it, but this should also affect Read(SafeFileHandle handle, IReadOnlyList<Memory<byte>> buffers, long fileOffset)
which calls ReadScatterAtOffset(SafeFileHandle handle, IReadOnlyList<Memory<byte>> buffers, long fileOffset)