]> git.ipfire.org Git - thirdparty/git.git/commit
wrapper: properly handle MAX_IO_SIZE in writev(3p)
authorPatrick Steinhardt <ps@pks.im>
Thu, 16 Jul 2026 07:52:21 +0000 (09:52 +0200)
committerJunio C Hamano <gitster@pobox.com>
Thu, 16 Jul 2026 20:59:13 +0000 (13:59 -0700)
commit2dee4c460bc4c95b51979ef36bb8d1c98244b4e9
tree6880ca6d6bb91dc7ec54687d88465657e011a8cb
parentba35aa3e0cea2dd396d254079913514d91bce584
wrapper: properly handle MAX_IO_SIZE in writev(3p)

Some systems like NonStop set a comparatively small `MAX_IO_SIZE`, which
limits the maximum number of bytes we're allowed to write in a single
call. We already handle this limit properly in `xwrite()`, but we have
recently introduced wrappers for writev(3p) where we don't. This will
cause the syscall to return EINVAL in case somebody passes an iovec
entry to writev(3p) that is larger than `MAX_IO_SIZE`.

Introduce a new function `xwritev()` that is similar to `xwrite()` in
that it handles such platform-specific nuances:

  - We only pass the leading iovec entries to writev(3p) that fit into
    `MAX_IO_SIZE`, pretending that the underlying syscall performed a
    short write. This mirrors how `xwrite()` chomps overly large
    requests before handing them to write(3p). As a consequence, callers
    will never see writev(3p)'s EINVAL error for requests whose summed
    length would overflow an ssize_t, but observe a short write instead.

  - If already the first iovec entry exceeds the limit we instead punt
    to `xwrite()`, which knows to handle this case for us.

  - We restart the underlying syscall on EINTR and EAGAIN, just like
    `xwrite()` does for write(3p).

Adapt `writev_in_full()` to use this new wrapper. With the retry logic
now living in `xwritev()`, the calling loop becomes the exact mirror
image of `write_in_full()`, which also retains the responsibility of
translating a zero-length write into ENOSPC.

Reported-by: Randall Becker <randall.becker@nexbridge.ca>
Helped-by: Jeff King <peff@peff.net>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
wrapper.c
wrapper.h