Remove redundant ftruncate() for POSIX DSM memory.
authorThomas Munro <[email protected]>
Thu, 14 Jul 2022 07:23:35 +0000 (19:23 +1200)
committerThomas Munro <[email protected]>
Thu, 14 Jul 2022 11:56:22 +0000 (23:56 +1200)
In early releases of the DSM infrastructure, it was possible to resize
segments.  That was removed in release 12 by commit 3c60d0fa.  Now the
ftruncate() + posix_fallocate() sequence during DSM segment creation has
a redundant step: we're always extending from zero to the desired size,
so we might as well just call posix_fallocate().

Let's also include the remaining ftruncate() call (non-Linux POSIX
systems) in the wait event reporting, for good measure.

Discussion: https://postgr.es/m/CA%2BhUKGJSm-nq8s%2B_59zb7NbFQF-OS%3DxTnTAiGLrQpuSmU2y_1A%40mail.gmail.com

src/backend/storage/ipc/dsm_impl.c

index 33a27b3a452e1c19d29faa3cdaa45a83349ba88f..6f21a757758f327bf77646dbf8d9774b541fd4ac 100644 (file)
@@ -364,43 +364,39 @@ dsm_impl_posix_resize(int fd, off_t size)
     */
    PG_SETMASK(&BlockSig);
 
-   /* Truncate (or extend) the file to the requested size. */
-   do
-   {
-       rc = ftruncate(fd, size);
-   } while (rc < 0 && errno == EINTR);
-
+   pgstat_report_wait_start(WAIT_EVENT_DSM_FILL_ZERO_WRITE);
+#if defined(HAVE_POSIX_FALLOCATE) && defined(__linux__)
    /*
-    * On Linux, a shm_open fd is backed by a tmpfs file.  After resizing with
-    * ftruncate, the file may contain a hole.  Accessing memory backed by a
+    * On Linux, a shm_open fd is backed by a tmpfs file.  If we were to use
+    * ftruncate, the file would contain a hole.  Accessing memory backed by a
     * hole causes tmpfs to allocate pages, which fails with SIGBUS if there
     * is no more tmpfs space available.  So we ask tmpfs to allocate pages
     * here, so we can fail gracefully with ENOSPC now rather than risking
     * SIGBUS later.
+    *
+    * We still use a traditional EINTR retry loop to handle SIGCONT.
+    * posix_fallocate() doesn't restart automatically, and we don't want
+    * this to fail if you attach a debugger.
     */
-#if defined(HAVE_POSIX_FALLOCATE) && defined(__linux__)
-   if (rc == 0)
+   do
    {
-       /*
-        * We still use a traditional EINTR retry loop to handle SIGCONT.
-        * posix_fallocate() doesn't restart automatically, and we don't want
-        * this to fail if you attach a debugger.
-        */
-       pgstat_report_wait_start(WAIT_EVENT_DSM_FILL_ZERO_WRITE);
-       do
-       {
-           rc = posix_fallocate(fd, 0, size);
-       } while (rc == EINTR);
-       pgstat_report_wait_end();
+       rc = posix_fallocate(fd, 0, size);
+   } while (rc == EINTR);
 
-       /*
-        * The caller expects errno to be set, but posix_fallocate() doesn't
-        * set it.  Instead it returns error numbers directly.  So set errno,
-        * even though we'll also return rc to indicate success or failure.
-        */
-       errno = rc;
-   }
-#endif                         /* HAVE_POSIX_FALLOCATE && __linux__ */
+   /*
+    * The caller expects errno to be set, but posix_fallocate() doesn't
+    * set it.  Instead it returns error numbers directly.  So set errno,
+    * even though we'll also return rc to indicate success or failure.
+    */
+   errno = rc;
+#else
+   /* Extend the file to the requested size. */
+   do
+   {
+       rc = ftruncate(fd, size);
+   } while (rc < 0 && errno == EINTR);
+#endif
+   pgstat_report_wait_end();
 
    save_errno = errno;
    PG_SETMASK(&UnBlockSig);