Use truncate(2) where appropriate.
authorThomas Munro <tmunro@postgresql.org>
Tue, 1 Dec 2020 02:34:57 +0000 (15:34 +1300)
committerThomas Munro <tmunro@postgresql.org>
Tue, 1 Dec 2020 02:42:22 +0000 (15:42 +1300)
When truncating files by name, use truncate(2).  Windows hasn't got it,
so keep our previous coding based on ftruncate(2) as a fallback.

Discussion: https://postgr.es/m/16663-fe97ccf9932fc800%40postgresql.org

src/backend/storage/file/fd.c
src/backend/storage/smgr/md.c
src/include/storage/fd.h

index 05abcf72d685633af7a569960c3c803d17506844..88004c6fae8e22d8835c3b20b7fcf48bb6ee4729 100644 (file)
@@ -622,6 +622,33 @@ pg_flush_data(int fd, off_t offset, off_t nbytes)
 #endif
 }
 
+/*
+ * Truncate a file to a given length by name.
+ */
+int
+pg_truncate(const char *path, off_t length)
+{
+#ifdef WIN32
+   int         save_errno;
+   int         ret;
+   int         fd;
+
+   fd = OpenTransientFile(path, O_RDWR | PG_BINARY);
+   if (fd >= 0)
+   {
+       ret = ftruncate(fd, 0);
+       save_errno = errno;
+       CloseTransientFile(fd);
+       errno = save_errno;
+   }
+   else
+       ret = -1;
+
+   return ret;
+#else
+   return truncate(path, length);
+#endif
+}
 
 /*
  * fsync_fname -- fsync a file or directory, handling errors properly
index c697af00d98c58b53223d53bc7a6af45fdec8a92..9889ad6ad882fd5f2423fb72443f5ff1a7d3f4d3 100644 (file)
@@ -294,19 +294,8 @@ do_truncate(const char *path)
 {
    int         save_errno;
    int         ret;
-   int         fd;
 
-   /* truncate(2) would be easier here, but Windows hasn't got it */
-   fd = OpenTransientFile(path, O_RDWR | PG_BINARY);
-   if (fd >= 0)
-   {
-       ret = ftruncate(fd, 0);
-       save_errno = errno;
-       CloseTransientFile(fd);
-       errno = save_errno;
-   }
-   else
-       ret = -1;
+   ret = pg_truncate(path, 0);
 
    /* Log a warning here to avoid repetition in callers. */
    if (ret < 0 && errno != ENOENT)
index e209f047e8533d1ed087c22e951a6cd09ff96d3d..4e1cc12e239aa1f662e65f37f80a9610f02e4b63 100644 (file)
@@ -153,6 +153,7 @@ extern int  pg_fsync_no_writethrough(int fd);
 extern int pg_fsync_writethrough(int fd);
 extern int pg_fdatasync(int fd);
 extern void pg_flush_data(int fd, off_t offset, off_t amount);
+extern int pg_truncate(const char *path, off_t length);
 extern void fsync_fname(const char *fname, bool isdir);
 extern int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel);
 extern int durable_rename(const char *oldfile, const char *newfile, int loglevel);