From: Jeff King <peff@peff.net>
To: Junio C Hamano <gitster@pobox.com>
Cc: Patrick Steinhardt <ps@pks.im>,
git@vger.kernel.org, Matt Smiley <msmiley@gitlab.com>,
"brian m. carlson" <sandals@crustytoothpaste.net>
Subject: Re: [PATCH v2 05/10] compat/posix: introduce writev(3p) wrapper
Date: Wed, 4 Mar 2026 19:37:45 -0500 [thread overview]
Message-ID: <20260305003745.GA4943@coredump.intra.peff.net> (raw)
In-Reply-To: <xmqqseaf5k5t.fsf@gitster.g>
On Wed, Mar 04, 2026 at 02:01:18PM -0800, Junio C Hamano wrote:
> Because we do not check the accumulation of bytes_written in the two
> accumulator variables inside the inner loop, it is very possible for
> total_written to wraparound size_t and end up below the largest
> value possible to be stored in ssize_t type.
Coverity complained about it, too.
> IOW, the cast_size_t_to_ssize_t() introduced in the previous step is
> pointless, isn't it?
>
> According to [*1*], the real
>
> ssize_t writev(int fd, const struct iovec *iov, int iovcnt)
>
> is supposed to report error with errno set to EINVAL when the sum of
> iov_len member of the iov[] array elements exceed half of the
> maximum size_t.
>
> EINVAL The sum of the iov_len values overflows an ssize_t value.
>
> So instead of dying with cast_size_t_to_ssize_t(), we probably would
> want the check done in a more stupid and straight-forward way?
> Adding up iov[i].iov_len while the addition would not wraparound in
> each and every step, and return error with EINVAL before attempting
> even a single call to xwrite(), and then have the above double loop
> that does not care about integer wraparound at all, and return
> total_written with simple cast to (ssize_t)?
I like that writev() can work as a drop-in replacement for write() at
the lowest level. But given that our main use is likely to be pkt-lines,
I do kind of wonder if we should just try to be more clever in forming
our buffers. That makes all of the portability and compat questions go
away (and gives the benefit to platforms that don't even have writev).
E.g., the somewhat ugly patch below is enough to do single write()s for
the pack data in upload-pack. I think if the pkt-writing API were less
ad-hoc (and had an actual buffer in "struct packet_writer"), this could
be made a bit more universal.
diff --git a/upload-pack.c b/upload-pack.c
index 1b1c81ea63..d01b547b10 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -179,11 +179,32 @@ static void reset_timeout(unsigned int timeout)
alarm(timeout);
}
-static void send_client_data(int fd, const char *data, ssize_t sz,
- int use_sideband)
+#define send_client_data(fd, data, sz, use_sideband) \
+ send_client_data_1((fd), (data), (sz), (use_sideband), NULL)
+static void send_client_data_1(int fd, const char *data, ssize_t sz,
+ int use_sideband, char *hdr_buf)
{
if (use_sideband) {
- send_sideband(1, fd, data, sz, use_sideband);
+ /*
+ * If we don't have a contiguous header buf, or if the data is
+ * too big for a single packet (which I don't think happens
+ * with any of our current callers), bail to the old-style
+ * send_sideband.
+ */
+ if (!hdr_buf || sz > LARGE_PACKET_DATA_MAX - 1) {
+ send_sideband(1, fd, data, sz, use_sideband);
+ return;
+ }
+
+ if (hdr_buf + 5 != data)
+ BUG("hdr_buf should be contiguous with pkt data");
+
+ if (use_sideband < 0)
+ BUG("negative sideband!?");
+
+ set_packet_header(hdr_buf, sz + 5);
+ hdr_buf[4] = 1; /* sideband 1 */
+ write_or_die(fd, hdr_buf, sz + 5);
return;
}
if (fd == 3)
@@ -211,7 +232,14 @@ struct output_state {
* sideband-64k the band designator takes up 1 byte of space. Because
* relay_pack_data keeps the last byte to itself, we make the buffer 1
* byte bigger than the intended maximum write size.
+ *
+ * However, we also reserve 5 bytes before the buffer so we can format
+ * a packet header and send it with a single write(). We may be pushing
+ * our luck on assuming there will be no padding here (though we do
+ * check it with a BUG(), but there are other ways to write it
+ * (e.g., a single large buffer with "buffer" as a pointer into it).
*/
+ char hdr[5];
char buffer[(LARGE_PACKET_DATA_MAX - 1) + 1];
int used;
unsigned packfile_uris_started : 1;
@@ -284,7 +312,7 @@ static int relay_pack_data(int pack_objects_out, struct output_state *os,
return readsz;
if (os->used > 1) {
- send_client_data(1, os->buffer, os->used - 1, use_sideband);
+ send_client_data_1(1, os->buffer, os->used - 1, use_sideband, os->hdr);
os->buffer[0] = os->buffer[os->used - 1];
os->used = 1;
} else {
-Peff
next prev parent reply other threads:[~2026-03-05 0:37 UTC|newest]
Thread overview: 64+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-27 11:22 [PATCH 0/2] upload-pack: reduce lock contention when writing packfile data Patrick Steinhardt
2026-02-27 11:23 ` [PATCH 1/2] upload-pack: fix debug statement when flushing " Patrick Steinhardt
2026-02-27 11:23 ` [PATCH 2/2] upload-pack: reduce lock contention when writing " Patrick Steinhardt
2026-02-27 13:04 ` brian m. carlson
2026-02-27 18:14 ` Patrick Steinhardt
2026-02-27 17:29 ` Junio C Hamano
2026-02-27 19:37 ` Jeff King
2026-03-02 12:12 ` Patrick Steinhardt
2026-03-02 18:20 ` Jeff King
2026-03-03 9:31 ` Patrick Steinhardt
2026-03-03 13:35 ` Jeff King
2026-03-03 13:47 ` Patrick Steinhardt
2026-03-03 15:00 ` [PATCH v2 00/10] " Patrick Steinhardt
2026-03-03 15:00 ` [PATCH v2 01/10] upload-pack: fix debug statement when flushing " Patrick Steinhardt
2026-03-03 15:00 ` [PATCH v2 02/10] upload-pack: adapt keepalives based on buffering Patrick Steinhardt
2026-03-05 0:56 ` Jeff King
2026-03-10 12:08 ` Patrick Steinhardt
2026-03-03 15:00 ` [PATCH v2 03/10] upload-pack: reduce lock contention when writing packfile data Patrick Steinhardt
2026-03-05 1:16 ` Jeff King
2026-03-10 12:14 ` Patrick Steinhardt
2026-03-03 15:00 ` [PATCH v2 04/10] git-compat-util: introduce `cast_size_t_to_ssize_t()` Patrick Steinhardt
2026-03-03 15:00 ` [PATCH v2 05/10] compat/posix: introduce writev(3p) wrapper Patrick Steinhardt
2026-03-04 22:01 ` Junio C Hamano
2026-03-05 0:37 ` Jeff King [this message]
2026-03-05 2:16 ` brian m. carlson
2026-03-05 6:39 ` Johannes Sixt
2026-03-05 22:22 ` brian m. carlson
2026-03-10 12:09 ` Patrick Steinhardt
2026-03-03 15:00 ` [PATCH v2 06/10] wrapper: introduce writev(3p) wrappers Patrick Steinhardt
2026-03-03 15:00 ` [PATCH v2 07/10] sideband: use writev(3p) to send pktlines Patrick Steinhardt
2026-03-04 22:05 ` Junio C Hamano
2026-03-03 15:00 ` [PATCH v2 08/10] csum-file: introduce `hashfd_ext()` Patrick Steinhardt
2026-03-04 22:11 ` Junio C Hamano
2026-03-10 12:09 ` Patrick Steinhardt
2026-03-03 15:00 ` [PATCH v2 09/10] csum-file: drop `hashfd_throughput()` Patrick Steinhardt
2026-03-03 15:00 ` [PATCH v2 10/10] builtin/pack-objects: reduce lock contention when writing packfile data Patrick Steinhardt
2026-03-10 13:24 ` [PATCH v3 00/10] upload-pack: " Patrick Steinhardt
2026-03-10 13:24 ` [PATCH v3 01/10] upload-pack: fix debug statement when flushing " Patrick Steinhardt
2026-03-10 13:24 ` [PATCH v3 02/10] upload-pack: adapt keepalives based on buffering Patrick Steinhardt
2026-03-10 13:24 ` [PATCH v3 03/10] upload-pack: prefer flushing data over sending keepalive Patrick Steinhardt
2026-03-10 17:09 ` Junio C Hamano
2026-03-10 17:43 ` Patrick Steinhardt
2026-03-10 13:25 ` [PATCH v3 04/10] upload-pack: reduce lock contention when writing packfile data Patrick Steinhardt
2026-03-10 13:25 ` [PATCH v3 05/10] compat/posix: introduce writev(3p) wrapper Patrick Steinhardt
2026-03-10 16:59 ` Junio C Hamano
2026-03-10 13:25 ` [PATCH v3 06/10] wrapper: introduce writev(3p) wrappers Patrick Steinhardt
2026-03-10 13:25 ` [PATCH v3 07/10] sideband: use writev(3p) to send pktlines Patrick Steinhardt
2026-03-10 13:25 ` [PATCH v3 08/10] csum-file: introduce `hashfd_ext()` Patrick Steinhardt
2026-03-10 13:25 ` [PATCH v3 09/10] csum-file: drop `hashfd_throughput()` Patrick Steinhardt
2026-03-10 13:25 ` [PATCH v3 10/10] builtin/pack-objects: reduce lock contention when writing packfile data Patrick Steinhardt
2026-03-10 17:11 ` [PATCH v3 00/10] upload-pack: " Junio C Hamano
2026-03-10 20:56 ` Johannes Sixt
2026-03-11 6:27 ` Patrick Steinhardt
2026-03-13 6:45 ` [PATCH v4 " Patrick Steinhardt
2026-03-13 6:45 ` [PATCH v4 01/10] upload-pack: fix debug statement when flushing " Patrick Steinhardt
2026-03-13 6:45 ` [PATCH v4 02/10] upload-pack: adapt keepalives based on buffering Patrick Steinhardt
2026-03-13 6:45 ` [PATCH v4 03/10] upload-pack: prefer flushing data over sending keepalive Patrick Steinhardt
2026-03-13 6:45 ` [PATCH v4 04/10] upload-pack: reduce lock contention when writing packfile data Patrick Steinhardt
2026-03-13 6:45 ` [PATCH v4 05/10] compat/posix: introduce writev(3p) wrapper Patrick Steinhardt
2026-03-13 6:45 ` [PATCH v4 06/10] wrapper: introduce writev(3p) wrappers Patrick Steinhardt
2026-03-13 6:45 ` [PATCH v4 07/10] sideband: use writev(3p) to send pktlines Patrick Steinhardt
2026-03-13 6:45 ` [PATCH v4 08/10] csum-file: introduce `hashfd_ext()` Patrick Steinhardt
2026-03-13 6:45 ` [PATCH v4 09/10] csum-file: drop `hashfd_throughput()` Patrick Steinhardt
2026-03-13 6:45 ` [PATCH v4 10/10] builtin/pack-objects: reduce lock contention when writing packfile data Patrick Steinhardt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260305003745.GA4943@coredump.intra.peff.net \
--to=peff@peff.net \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=msmiley@gitlab.com \
--cc=ps@pks.im \
--cc=sandals@crustytoothpaste.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox