From a194574ddee4dd1876835516aed2f4fbd7a4a4c7 Mon Sep 17 00:00:00 2001
From: Bruce Momjian <bruce@momjian.us>
Date: Wed, 14 Jun 2000 03:19:24 +0000
Subject: [PATCH] > If read or write fails. Position will left the same. This >
 situation is already tracked in File routines, but a little bit >
 incorrectly.

> After small survey in Linux kernel code, I am not sure about
> it.  New patch set pos to unknown in the case of read/write
> fails. And do lseek again.

> Here is the full patch for this. This patch reduce amount of
> lseek call ten ti mes for update statement and twenty times for
> select statement. I tested joined up date and count(*) select
> for table with rows > 170000 and 10 indices.  I think this is
> worse of trying. Before lseek calls account for more than 5% o
> f time.  Now they are 0.89 and 0.15 respectevly.
>
> Due to only one file modification patch should be applied in
> src/backedn/stora ge/file/ dir.

-- Sincerely Yours,
Denis Perchine
---
 src/backend/storage/file/fd.c | 31 ++++++++++++++++++++++++++-----
 1 file changed, 26 insertions(+), 5 deletions(-)

diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index fdb2fc57a59..b8ad36d0162 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/storage/file/fd.c,v 1.59 2000/06/02 15:57:24 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/storage/file/fd.c,v 1.60 2000/06/14 03:19:24 momjian Exp $
  *
  * NOTES:
  *
@@ -95,6 +95,8 @@
 
 #define FileIsNotOpen(file) (VfdCache[file].fd == VFD_CLOSED)
 
+#define FileUnknownPos (-1)
+
 typedef struct vfd
 {
 	signed short fd;			/* current FD, or VFD_CLOSED if none */
@@ -790,6 +792,8 @@ FileRead(File file, char *buffer, int amount)
 	returnCode = read(VfdCache[file].fd, buffer, amount);
 	if (returnCode > 0)
 		VfdCache[file].seekPos += returnCode;
+	else
+		VfdCache[file].seekPos = FileUnknownPos;
 
 	return returnCode;
 }
@@ -806,11 +810,12 @@ FileWrite(File file, char *buffer, int amount)
 
 	FileAccess(file);
 	returnCode = write(VfdCache[file].fd, buffer, amount);
-	if (returnCode > 0)
+	if (returnCode > 0) {
 		VfdCache[file].seekPos += returnCode;
-
 	/* mark the file as needing fsync */
 	VfdCache[file].fdstate |= FD_DIRTY;
+	} else
+		VfdCache[file].seekPos = FileUnknownPos;
 
 	return returnCode;
 }
@@ -840,10 +845,26 @@ FileSeek(File file, long offset, int whence)
 			default:
 				elog(ERROR, "FileSeek: invalid whence: %d", whence);
 				break;
-		}
 	}
-	else
+	} else
+		switch (whence) {
+			case SEEK_SET:
+				if (offset < 0)
+					elog(ERROR, "FileSeek: invalid offset: %ld", offset);
+				if (VfdCache[file].seekPos != offset)
+					VfdCache[file].seekPos = lseek(VfdCache[file].fd, offset, whence);
+				break;
+			case SEEK_CUR:
+				if ((offset != 0) || (VfdCache[file].seekPos == FileUnknownPos));
 		VfdCache[file].seekPos = lseek(VfdCache[file].fd, offset, whence);
+				break;
+			case SEEK_END:
+				VfdCache[file].seekPos = lseek(VfdCache[file].fd, offset, whence);
+				break;
+			default:
+				elog(ERROR, "FileSeek: invalid whence: %d", whence);
+				break;
+		}
 	return VfdCache[file].seekPos;
 }
 
-- 
GitLab