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);