fallocate-v3.patch
application/octet-stream
Filename: fallocate-v3.patch
Type: application/octet-stream
Part: 0
Patch
Format: unified
Series: patch v3
| File | + | − |
|---|---|---|
| configure | 1 | 1 |
| configure.in | 1 | 1 |
| src/backend/storage/ipc/dsm_impl.c | 42 | 1 |
| src/include/pg_config.h.in | 3 | 0 |
diff --git a/configure b/configure
index 8315dec23a8..aa13495cbbf 100755
--- a/configure
+++ b/configure
@@ -12892,7 +12892,7 @@ fi
LIBS_including_readline="$LIBS"
LIBS=`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'`
-for ac_func in cbrt clock_gettime dlopen fdatasync getifaddrs getpeerucred getrlimit mbstowcs_l memmove poll pstat pthread_is_threaded_np readlink setproctitle setsid shm_open symlink sync_file_range towlower utime utimes wcstombs wcstombs_l
+for ac_func in cbrt clock_gettime dlopen fallocate fdatasync getifaddrs getpeerucred getrlimit mbstowcs_l memmove poll pstat pthread_is_threaded_np readlink setproctitle setsid shm_open symlink sync_file_range towlower utime utimes wcstombs wcstombs_l
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
diff --git a/configure.in b/configure.in
index 11eb9c8acfc..47452bbac43 100644
--- a/configure.in
+++ b/configure.in
@@ -1429,7 +1429,7 @@ PGAC_FUNC_WCSTOMBS_L
LIBS_including_readline="$LIBS"
LIBS=`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'`
-AC_CHECK_FUNCS([cbrt clock_gettime dlopen fdatasync getifaddrs getpeerucred getrlimit mbstowcs_l memmove poll pstat pthread_is_threaded_np readlink setproctitle setsid shm_open symlink sync_file_range towlower utime utimes wcstombs wcstombs_l])
+AC_CHECK_FUNCS([cbrt clock_gettime dlopen fallocate fdatasync getifaddrs getpeerucred getrlimit mbstowcs_l memmove poll pstat pthread_is_threaded_np readlink setproctitle setsid shm_open symlink sync_file_range towlower utime utimes wcstombs wcstombs_l])
AC_REPLACE_FUNCS(fseeko)
case $host_os in
diff --git a/src/backend/storage/ipc/dsm_impl.c b/src/backend/storage/ipc/dsm_impl.c
index 1500465d31c..494a6218ed6 100644
--- a/src/backend/storage/ipc/dsm_impl.c
+++ b/src/backend/storage/ipc/dsm_impl.c
@@ -225,6 +225,46 @@ dsm_impl_can_resize(void)
#ifdef USE_DSM_POSIX
/*
+ * Set the size of a virtual memory region associate with a file descriptor.
+ * On Linux, also ensure that virtual memory is actually allocated by the
+ * operating system to avoid nasty surprises later.
+ *
+ * Returns non-zero if either truncation or allocation fails, and sets errno.
+ */
+static int
+dsm_impl_posix_resize(int fd, off_t size)
+{
+ int rc;
+
+ /* Truncate (or extend) the file to the requested size. */
+ rc = ftruncate(fd, size);
+
+#ifdef HAVE_FALLOCATE
+#ifdef __linux__
+ /*
+ * On Linux, a shm_open fd is backed by a tmpfs file. After resizing
+ * with ftruncate it may contain a hole. Accessing memory backed by a
+ * hole causes tmpfs to allocate pages, which fails with SIGBUS if
+ * there is no virtual memory available. So we ask tmpfs to allocate
+ * pages here, so we can fail gracefully with ENOSPC now rather than
+ * risking SIGBUS later.
+ */
+ if (rc == 0)
+ {
+ rc = fallocate(fd, 0, 0, size);
+ if (rc != 0 && errno == ENOSYS)
+ {
+ /* Kernel too old (< 2.6.23). */
+ rc = 0;
+ }
+ }
+#endif
+#endif
+
+ return rc;
+}
+
+/*
* Operating system primitives to support POSIX shared memory.
*
* POSIX shared memory segments are created and attached using shm_open()
@@ -319,7 +359,8 @@ dsm_impl_posix(dsm_op op, dsm_handle handle, Size request_size,
}
request_size = st.st_size;
}
- else if (*mapped_size != request_size && ftruncate(fd, request_size))
+ else if (*mapped_size != request_size &&
+ dsm_impl_posix_resize(fd, request_size) != 0)
{
int save_errno;
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 7a05c7e5b85..dcb9a846c7b 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -167,6 +167,9 @@
/* Define to 1 if you have the <editline/readline.h> header file. */
#undef HAVE_EDITLINE_READLINE_H
+/* Define to 1 if you have the `fallocate' function. */
+#undef HAVE_FALLOCATE
+
/* Define to 1 if you have the `fdatasync' function. */
#undef HAVE_FDATASYNC