From c5834d941693e0bedfbe87532823abbe41f33310 Mon Sep 17 00:00:00 2001
From: "Dmitry E. Oboukhov" <unera@debian.org>
Date: Thu, 6 Feb 2014 17:35:45 +0400
Subject: [PATCH] Drop recursive calls. Rewrite by review.

---
 src/fiob.c       | 78 +++++++++++++++++++-----------------------------
 src/log_io.cc    |  2 +-
 test/unit/fiob.c |  6 ++--
 3 files changed, 35 insertions(+), 51 deletions(-)

diff --git a/src/fiob.c b/src/fiob.c
index c4dbc44e2c..9b03a28e2f 100644
--- a/src/fiob.c
+++ b/src/fiob.c
@@ -109,26 +109,22 @@ fiob_flushb(struct fiob *f)
 	if (!f->buf || !f->bfill)
 		return 0;
 
-	off_t cur = lseek(f->fd, 0L, SEEK_CUR);
-	if (cur == (off_t)-1)
-		return -1;
-
-	off_t size = lseek(f->fd, 0L, SEEK_END);
-	if (size == (off_t)-1)
-		return -1;
-
-	if (lseek(f->fd, cur, SEEK_SET) == (off_t)-1)
-		return -1;
 
-	assert(cur + f->bfill >= size);
+	size_t tlen = f->bfill / 4096;
+	if (f->bfill % 4096)
+		tlen++;
+	tlen *= 4096;
 
-	if (fiob_writef(f, f->buf, f->bsize) < 0)
+	if (fiob_writef(f, f->buf, tlen) < 0) {
 		return -1;
+	}
 
-	if (lseek(f->fd, cur + f->bfill, SEEK_SET) == (off_t)-1)
+	off_t size = lseek(f->fd, (off_t)(f->bfill) - tlen, SEEK_CUR);
+	if (size == (off_t)-1) {
 		return -1;
+	}
+	int res = ftruncate(f->fd, size);
 
-	int res = ftruncate(f->fd, cur + f->bfill);
 	f->bfill = 0;
 	return res;
 }
@@ -143,54 +139,42 @@ fiob_write(void *cookie, const char *buf, size_t len)
 #endif
 {
 	struct fiob *f = (struct fiob *)cookie;
-	ssize_t wrdone;
 
-	if (f->buf) {
-		/* append buffer */
-		if (f->bsize - f->bfill >= len) {
-			memcpy(f->buf + f->bfill, buf, len);
-			f->bfill += len;
-			return len;
-		}
+	if (len == 0)
+		return 0;
 
+	if (!f->buf)
+		return fiob_writef(f, buf, len);
 
-		/* buffer is full */
-		if (f->bfill >= f->bsize) {
-			wrdone = fiob_writef(f, f->buf, f->bsize);
-			if (wrdone < 0)
-				return wrdone;
 
-			f->bfill = 0;
-			return fiob_write(cookie, buf, len);
+	for (ssize_t wrdone = 0, wrote;;) {
+		/* append buffer */
+		if (f->bsize - f->bfill > len) {
+			memcpy(f->buf + f->bfill, buf, len);
+			f->bfill += len;
+			return wrdone + len;
 		}
-
 		/* data is longer than buffer */
-		memcpy(f->buf + f->bfill, buf, f->bsize - f->bfill);
-
-		wrdone = fiob_writef(f, f->buf, f->bsize);
-
 
+		if (f->bsize > f->bfill)
+			memcpy(f->buf + f->bfill, buf, f->bsize - f->bfill);
 
-		if (wrdone < 0)
-			return wrdone;
-
-		wrdone -= f->bfill;
+		wrote = fiob_writef(f, f->buf, f->bsize);
+		if (wrote < 0)
+			return wrote;
 
+		wrote  -= f->bfill;
+		wrdone += wrote;
 		f->bfill = 0;
-		buf += wrdone;
-		len -= wrdone;
+		buf += wrote;
+		len -= wrote;
 
 
-		if (len > 0) {
-			ssize_t wrtail = fiob_write(cookie, buf, len);
-			if (wrtail < 0)
-				return wrtail;
-			wrdone += wrtail;
-		}
+		if (len > 0)
+			continue;
 		return wrdone;
 	}
 
-	return fiob_writef(f, buf, len);
 }
 
 #ifdef HAVE_FUNOPEN
diff --git a/src/log_io.cc b/src/log_io.cc
index 585c457360..33e3e96367 100644
--- a/src/log_io.cc
+++ b/src/log_io.cc
@@ -614,7 +614,7 @@ log_io_open_for_read(struct log_dir *dir, int64_t lsn, enum log_suffix suffix)
 	assert(lsn != 0);
 
 	const char *filename = format_filename(dir, lsn, suffix);
-	FILE *f = fiob_open(filename, "r");
+	FILE *f = fopen(filename, "r");
 	return log_io_open(dir, LOG_READ, filename, suffix, f);
 }
 
diff --git a/test/unit/fiob.c b/test/unit/fiob.c
index 63f9f45c00..090e6b0be5 100644
--- a/test/unit/fiob.c
+++ b/test/unit/fiob.c
@@ -194,9 +194,9 @@ main(void)
 			fgets(buf, 4096, f);
 			if (strcmp(buf, "Hello, world\n") == 0)
 				done++;
-			else
-				fprintf(stderr, "#   wrong line %zu: %s",
-					i, buf);
+/*                         else */
+/*                                 fprintf(stderr, "#   wrong line %zu: %s", */
+/*                                         i, buf); */
 		}
 		is(done, 1000000 + 1, "all records were written properly");
 
-- 
GitLab