git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 0/5] Reintroduce writev(3p)

From
Patrick Steinhardt <ps@pks.im>
Date
Aug 7, 2026, 06:18 UTC
Message-ID
<20260807-pks-reintroduce-writev-v2-0-30fcff0e89c1@pks.im>
In-Reply-To
<20260716-pks-reintroduce-writev-v1-0-ea9038c884bc@pks.im>
Hi,

this patch series reintroduces the writev(3p) wrapper. This wrapper was originally introduced as part of Git 2.54 [1], but was ejected due to issues on NonStop [2].

This patch series here revives the effort with a couple of fixes on top:
  - It picks Dscho's fix for CMake [3].
  - It picks a fix for NonStop [4] and polishes it a bit.
  - It adapts one more site to demonstrate that its usefulness is not
    limited to a single callsite, only.

Furthermore, I have included benchmarks now that demonstrate the benefits to make this series a bit more appealing. Ultimately, I'd be fine if we say we rather don't want to go this way though. I merely wanted to tie some loose ends that I left dangling.

That, and it's nice to not work on pluggable object databases once in a while.

Changes in v2:
  - Adapt the writev compatibility shim to not do torn writes anymore
    across multiple iovecs. Instead, we now only write the first iovec,
    which should be fine as callers are expected to loop around writev
    anyway.
  - Link to v1: https://patch.msgid.link/20260716-pks-reintroduce-writev-v1-0-ea9038c884bc@pks.im
Thanks!
Patrick

[1]: <20260227-pks-upload-pack-write-contention-v1-0-7166fe255704@pks.im> [2]: <028901dcc859$d2419470$76c4bd50$@nexbridge.com> [3]: <pull.2078.git.1775206502134.gitgitgadget@gmail.com> [4]: <20260409-b4-pks-writev-max-io-size-v1-1-81730e8f35df@pks.im>

---
Patrick Steinhardt (5):
      compat/posix: introduce writev(3p) wrapper
      wrapper: introduce writev(3p) wrappers
      wrapper: properly handle MAX_IO_SIZE in writev(3p)
      sideband: use writev(3p) to send pktlines
      fast-import: use writev(3p) to send cat-blob responses
 Makefile                            |  4 ++
 builtin/fast-import.c               | 18 +++++++--
 compat/posix.h                      | 14 +++++++
 compat/writev.c                     | 41 +++++++++++++++++++
 config.mak.uname                    |  2 +
 contrib/buildsystems/CMakeLists.txt |  6 ++-
 meson.build                         |  1 +
 sideband.c                          | 14 +++++--
 wrapper.c                           | 78 +++++++++++++++++++++++++++++++++++++
 wrapper.h                           | 10 +++++
 write-or-die.c                      |  8 ++++
 write-or-die.h                      |  1 +
 12 files changed, 190 insertions(+), 7 deletions(-)
Range-diff versus v1:
1:  69b8be6ec5 ! 1:  f519260452 compat/posix: introduce writev(3p) wrapper
    @@ compat/writev.c (new)
     +
     +ssize_t git_writev(int fd, const struct iovec *iov, int iovcnt)
     +{
    -+	size_t total_written = 0;
     +	size_t sum = 0;
     +
    ++	if (iovcnt <= 0) {
    ++		errno = EINVAL;
    ++		return -1;
    ++	}
    ++
     +	/*
     +	 * According to writev(3p), the syscall shall error with EINVAL in case
     +	 * the sum of `iov_len` overflows `ssize_t`.
     +	 */
     +	for (int i = 0; i < iovcnt; i++) {
     +		if (iov[i].iov_len > maximum_signed_value_of_type(ssize_t) ||
    ++		    unsigned_add_overflows(iov[i].iov_len, sum) ||
     +		    iov[i].iov_len + sum > maximum_signed_value_of_type(ssize_t)) {
     +			errno = EINVAL;
     +			return -1;
    @@ compat/writev.c (new)
     +		sum += iov[i].iov_len;
     +	}
     +
    ++	/*
    ++	 * We only ever write the first non-empty vector so that we can
    ++	 * guarantee the call to be non-interleaving as guaranteed by POSIX.
    ++	 * This works just fine as callers have to loop around writev anyway.
    ++	 */
     +	for (int i = 0; i < iovcnt; i++) {
    -+		const char *bytes = iov[i].iov_base;
    -+		size_t iovec_written = 0;
    -+
    -+		while (iovec_written < iov[i].iov_len) {
    -+			ssize_t bytes_written = xwrite(fd, bytes + iovec_written,
    -+						       iov[i].iov_len - iovec_written);
    -+			if (bytes_written < 0) {
    -+				if (total_written)
    -+					goto out;
    -+				return bytes_written;
    -+			}
    -+			if (!bytes_written)
    -+				goto out;
    -+			iovec_written += bytes_written;
    -+			total_written += bytes_written;
    -+		}
    ++		if (!iov[i].iov_len)
    ++			continue;
    ++		return xwrite(fd, iov[i].iov_base, iov[i].iov_len);
     +	}
     +
    -+out:
    -+	return (ssize_t) total_written;
    ++	/* When all iovec members were zero we ought to return 0 according to POSIX. */
    ++	return 0;
     +}
     
      ## config.mak.uname ##
2:  f6013a18ba = 2:  41814b6668 wrapper: introduce writev(3p) wrappers
3:  3dc0eff00b = 3:  af2e351491 wrapper: properly handle MAX_IO_SIZE in writev(3p)
4:  95c872432f = 4:  d3ba9d73d2 sideband: use writev(3p) to send pktlines
5:  4c1efb5284 = 5:  148a2c8928 fast-import: use writev(3p) to send cat-blob responses

--- base-commit: 55526a18268bbc1ddaf8a6b7850c33d984eac9e9 change-id: 20260714-pks-reintroduce-writev-2d8f7e52eee9

Previous: Patrick SteinhardtNext: Patrick Steinhardt
Message 22 of 27 in “Reintroduce writev(3p)”
  1. 0/5 Reintroduce writev(3p)Patrick Steinhardt, Jul 16, 2026
  2. 1/5 compat/posix: introduce writev(3p) wrapperPatrick Steinhardt, Jul 16, 2026
  3. Simon RichterJul 16, 2026
  4. Junio C HamanoJul 16, 2026
  5. Junio C HamanoJul 16, 2026
  6. Patrick SteinhardtAug 5, 2026
  7. 2/5 wrapper: introduce writev(3p) wrappersPatrick Steinhardt, Jul 16, 2026
  8. 3/5 wrapper: properly handle MAX_IO_SIZE in writev(3p)Patrick Steinhardt, Jul 16, 2026
  9. 4/5 sideband: use writev(3p) to send pktlinesPatrick Steinhardt, Jul 16, 2026
  10. 5/5 fast-import: use writev(3p) to send cat-blob responsesPatrick Steinhardt, Jul 16, 2026
  11. Johannes SixtJul 16, 2026
  12. Junio C HamanoJul 27, 2026
  13. Patrick SteinhardtAug 5, 2026
  14. Junio C HamanoAug 5, 2026
  15. Johannes SixtAug 5, 2026
  16. Junio C HamanoAug 5, 2026
  17. Johannes SixtAug 5, 2026
  18. Junio C HamanoAug 5, 2026
  19. Patrick SteinhardtAug 6, 2026
  20. Junio C HamanoAug 6, 2026
  21. Patrick SteinhardtAug 7, 2026
  22. 0/5 Reintroduce writev(3p)Patrick Steinhardt, Aug 7, 2026
  23. 1/5 compat/posix: introduce writev(3p) wrapperPatrick Steinhardt, Aug 7, 2026
  24. 2/5 wrapper: introduce writev(3p) wrappersPatrick Steinhardt, Aug 7, 2026
  25. 3/5 wrapper: properly handle MAX_IO_SIZE in writev(3p)Patrick Steinhardt, Aug 7, 2026
  26. 4/5 sideband: use writev(3p) to send pktlinesPatrick Steinhardt, Aug 7, 2026
  27. 5/5 fast-import: use writev(3p) to send cat-blob responsesPatrick Steinhardt, Aug 7, 2026

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.