File 2151-Handle-multi-giga-byte-writes-to-files.patch of Package erlang

From 5ae46e823a8a52ed4e5b960ff62975894b1a8302 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Tue, 29 Mar 2016 09:10:13 +0200
Subject: [PATCH] Handle multi-giga byte writes to files

Test cases that write 4Gb to a file at once would fail on
OS X and FreeBSD.

By running a simple test program on OS X (El Capitan 10.11.4/Darwin
15.4.0), I found that writev() can handle more than 4Gb of data, while
write() only can handle less than 2Gb. (Note that efile_drv.c will use
write() if there is only one element in the io vector, and writev() if
there is more than one.)

It is tempting to attempt to piggy-back on the existing mechanism
for segmenting write operations in efile_drv.c, but because of the
complex code I find it too dangerous, both from a correctness and
performance perspective.

Instead do the change in unix_efile.c, which is considerably
simpler.
---
 erts/emulator/drivers/unix/unix_efile.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/erts/emulator/drivers/unix/unix_efile.c b/erts/emulator/drivers/unix/unix_efile.c
index ac9b681..c097bc1 100644
--- a/erts/emulator/drivers/unix/unix_efile.c
+++ b/erts/emulator/drivers/unix/unix_efile.c
@@ -638,12 +638,21 @@ efile_writev(Efile_error* errInfo,   /* Where to return error codes */
 		do {
 		    w = writev(fd, &iov[cnt], b);
 		} while (w < 0 && errno == EINTR);
+		if (w < 0 && errno == EINVAL) {
+		    goto single_write;
+		}
 	    } else
+	    single_write:
 		/* Degenerated io vector - use regular write */
 #endif
 		{
 		    do {
-			w = write(fd, iov[cnt].iov_base, iov[cnt].iov_len);
+			size_t iov_len = iov[cnt].iov_len;
+			size_t limit = 1024*1024*1024; /* 1GB */
+			if (iov_len > limit) {
+			    iov_len = limit;
+			}
+			w = write(fd, iov[cnt].iov_base, iov_len);
 		    } while (w < 0 && errno == EINTR);
 		    ASSERT(w <= iov[cnt].iov_len ||
 			   (w == -1 && errno != EINTR));
-- 
2.1.4

openSUSE Build Service is sponsored by