From 303f0c6342c7728059a23eaf7c0e72eb1c40777e Mon Sep 17 00:00:00 2001
From: Konstantin Osipov <kostja@tarantool.org>
Date: Thu, 13 Aug 2015 00:32:59 +0300
Subject: [PATCH] gh-916: (limit of statements in transaction) review fixes

- update comments
- fix the logic of partial write recovery (still needs a test)
---
 src/box/wal.cc | 14 +++++++-------
 src/fio.c      | 13 ++++++++-----
 2 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/src/box/wal.cc b/src/box/wal.cc
index 79fb5985a3..444028ec67 100644
--- a/src/box/wal.cc
+++ b/src/box/wal.cc
@@ -327,22 +327,22 @@ wal_write_to_disk(struct recovery_state *r, struct wal_writer *writer,
 
 	/*
 	 * This code tries to write queued requests (=transactions) using as
-	 * less as possible I/O syscalls and memory copies. For this reason
+	 * few I/O syscalls and memory copies as possible. For this reason
 	 * writev(2) and `struct iovec[]` are used (see `struct fio_batch`).
 	 *
 	 * For each request (=transaction) each request row (=statement) is
 	 * added to iov `batch`. A row can contain up to XLOG_IOVMAX iovecs.
 	 * A request can have an **unlimited** number of rows. Since OS has
-	 * hardcoded limit up to `sysconf(_SC_IOV_MAX)` iovecs (usually 1024),
-	 * a single batch can't fit huge transactions. Therefore, it is not
-	 * possible to "atomically" write an entire transaction using the
-	 * single writev(2) call.
+	 * a hard coded limit up to `sysconf(_SC_IOV_MAX)` iovecs (usually
+	 * 1024), a huge transaction may not fit into a single batch.
+	 * Therefore, it is not possible to "atomically" write an entire
+	 * transaction using a single writev(2) call.
 	 *
 	 * Request boundaries and batch boundaries are not connected at all
 	 * in this code. Batches flushed to disk as soon as they are full.
 	 * In order to guarantee that a transaction is either fully written
 	 * to file or isn't written at all, ftruncate(2) is used to shrink
-	 * file to the last fuly written request. The absolute position
+	 * the file to the last fully written request. The absolute position
 	 * of request in xlog file is stored inside `struct wal_request`.
 	 */
 
@@ -400,7 +400,7 @@ wal_write_to_disk(struct recovery_state *r, struct wal_writer *writer,
 	/* Flush remaining data in batch (if any) */
 	if (fio_batch_size(batch) > 0) {
 		ssize_t nwr = wal_fio_batch_write(batch, fileno(wal->f));
-		if (nwr >= 0) {
+		if (nwr > 0) {
 			/* Update cached file offset */
 			written_bytes += nwr;
 		}
diff --git a/src/fio.c b/src/fio.c
index 8561d625a4..594ca49f69 100644
--- a/src/fio.c
+++ b/src/fio.c
@@ -221,13 +221,16 @@ fio_batch_rotate(struct fio_batch *batch, size_t bytes_written)
 
 	struct iovec *iov = batch->iov;
 	struct iovec *iovend = iov + batch->iovcnt;
-	for (; bytes_written >= iov->iov_len; ++iov)
+	for (; iov < iovend; ++iov) {
+		if (iov->iov_len > bytes_written) {
+			iov->iov_base = (char *) iov->iov_base + bytes_written;
+			iov->iov_len -= bytes_written;
+			break;
+		}
 		bytes_written -= iov->iov_len;
-
+	}
 	assert(iov < iovend); /* Partial write  */
-	iov->iov_base = (char *) iov->iov_base + bytes_written;
-	iov->iov_len -= bytes_written;
-	memmove(batch->iov, iov, iovend - iov);
+	memmove(batch->iov, iov, (iovend - iov) * sizeof(struct iovec));
 	batch->iovcnt = iovend - iov;
 }
 
-- 
GitLab