mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-09-30 19:31:14 +02:00
Remove redundant ftruncate() for POSIX DSM memory.
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
This commit is contained in:
parent
4518c798b2
commit
712704d353
@ -364,43 +364,39 @@ dsm_impl_posix_resize(int fd, off_t size)
|
|||||||
*/
|
*/
|
||||||
PG_SETMASK(&BlockSig);
|
PG_SETMASK(&BlockSig);
|
||||||
|
|
||||||
/* Truncate (or extend) the file to the requested size. */
|
pgstat_report_wait_start(WAIT_EVENT_DSM_FILL_ZERO_WRITE);
|
||||||
do
|
#if defined(HAVE_POSIX_FALLOCATE) && defined(__linux__)
|
||||||
{
|
|
||||||
rc = ftruncate(fd, size);
|
|
||||||
} while (rc < 0 && errno == EINTR);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* On Linux, a shm_open fd is backed by a tmpfs file. After resizing with
|
* On Linux, a shm_open fd is backed by a tmpfs file. If we were to use
|
||||||
* ftruncate, the file may contain a hole. Accessing memory backed by a
|
* ftruncate, the file would contain a hole. Accessing memory backed by a
|
||||||
* hole causes tmpfs to allocate pages, which fails with SIGBUS if there
|
* 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
|
* 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
|
* here, so we can fail gracefully with ENOSPC now rather than risking
|
||||||
* SIGBUS later.
|
* 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__)
|
do
|
||||||
if (rc == 0)
|
|
||||||
{
|
{
|
||||||
/*
|
rc = posix_fallocate(fd, 0, size);
|
||||||
* We still use a traditional EINTR retry loop to handle SIGCONT.
|
} while (rc == EINTR);
|
||||||
* 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();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The caller expects errno to be set, but posix_fallocate() doesn't
|
* The caller expects errno to be set, but posix_fallocate() doesn't
|
||||||
* set it. Instead it returns error numbers directly. So set errno,
|
* set it. Instead it returns error numbers directly. So set errno,
|
||||||
* even though we'll also return rc to indicate success or failure.
|
* even though we'll also return rc to indicate success or failure.
|
||||||
*/
|
*/
|
||||||
errno = rc;
|
errno = rc;
|
||||||
}
|
#else
|
||||||
#endif /* HAVE_POSIX_FALLOCATE && __linux__ */
|
/* 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;
|
save_errno = errno;
|
||||||
PG_SETMASK(&UnBlockSig);
|
PG_SETMASK(&UnBlockSig);
|
||||||
|
Loading…
Reference in New Issue
Block a user