From 786fafb408ba0b9080941170eedcb6a58c2df8d1 Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Fri, 18 May 2018 12:42:32 -0700 Subject: [PATCH v1 4/7] WIP: Allow to create a transient file for a previously openend FD. It might be better to extend the normal vfd files instead, adding a flag that prohibits closing the underlying file (and removing them from the LRU). Author: Andres Freund Reviewed-By: Discussion: https://postgr.es/m/ Backpatch: --- src/backend/storage/file/fd.c | 32 ++++++++++++++++++++++++++++++++ src/include/storage/fd.h | 2 ++ 2 files changed, 34 insertions(+) diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c index 8ae13a51ec1..e2492ce94d5 100644 --- a/src/backend/storage/file/fd.c +++ b/src/backend/storage/file/fd.c @@ -2430,6 +2430,38 @@ OpenTransientFilePerm(const char *fileName, int fileFlags, mode_t fileMode) return -1; /* failure */ } +void +ReserveTransientFile(void) +{ + if (!reserveAllocatedDesc()) + ereport(PANIC, + (errcode(ERRCODE_INSUFFICIENT_RESOURCES), + errmsg("exceeded maxAllocatedDescs (%d) while trying to open file", + maxAllocatedDescs))); + + /* Close excess kernel FDs. */ + ReleaseLruFiles(); + + Assert(nfile + numAllocatedDescs <= max_safe_fds); +} + +void +RegisterTransientFile(int fd) +{ + AllocateDesc *desc; + + /* make sure ReserveTransientFile was called sufficiently recently */ + Assert(fd >= 0); + Assert(nfile + numAllocatedDescs <= max_safe_fds); + Assert(numAllocatedDescs < maxAllocatedDescs); + + desc = &allocatedDescs[numAllocatedDescs]; + desc->kind = AllocateDescRawFD; + desc->desc.fd = fd; + desc->create_subid = GetCurrentSubTransactionId(); + numAllocatedDescs++; +} + /* * Routines that want to initiate a pipe stream should use OpenPipeStream * rather than plain popen(). This lets fd.c deal with freeing FDs if diff --git a/src/include/storage/fd.h b/src/include/storage/fd.h index 5e016d69a5a..9bb32771602 100644 --- a/src/include/storage/fd.h +++ b/src/include/storage/fd.h @@ -105,6 +105,8 @@ extern int FreeDir(DIR *dir); /* Operations to allow use of a plain kernel FD, with automatic cleanup */ extern int OpenTransientFile(const char *fileName, int fileFlags); extern int OpenTransientFilePerm(const char *fileName, int fileFlags, mode_t fileMode); +extern void ReserveTransientFile(void); +extern void RegisterTransientFile(int fd); extern int CloseTransientFile(int fd); /* If you've really really gotta have a plain kernel FD, use this */ -- 2.17.0.rc1.dirty