PostgreSQL Source Code git master
fd.c File Reference
#include "postgres.h"
#include <dirent.h>
#include <sys/file.h>
#include <sys/param.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <limits.h>
#include <unistd.h>
#include <fcntl.h>
#include "access/xact.h"
#include "access/xlog.h"
#include "catalog/pg_tablespace.h"
#include "common/file_perm.h"
#include "common/file_utils.h"
#include "common/pg_prng.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "postmaster/startup.h"
#include "storage/fd.h"
#include "storage/ipc.h"
#include "utils/guc.h"
#include "utils/guc_hooks.h"
#include "utils/resowner.h"
#include "utils/varlena.h"
Include dependency graph for fd.c:

Go to the source code of this file.

Data Structures

struct  vfd
 
struct  AllocateDesc
 

Macros

#define NUM_RESERVED_FDS   10
 
#define FD_MINFREE   48
 
#define DO_DB(A)    ((void) 0)
 
#define VFD_CLOSED   (-1)
 
#define FileIsValid(file)    ((file) > 0 && (file) < (int) SizeVfdCache && VfdCache[file].fileName != NULL)
 
#define FileIsNotOpen(file)   (VfdCache[file].fd == VFD_CLOSED)
 
#define FD_DELETE_AT_CLOSE   (1 << 0) /* T = delete when closed */
 
#define FD_CLOSE_AT_EOXACT   (1 << 1) /* T = close at eoXact */
 
#define FD_TEMP_FILE_LIMIT   (1 << 2) /* T = respect temp_file_limit */
 

Typedefs

typedef struct vfd Vfd
 

Enumerations

enum  AllocateDescKind { AllocateDescFile , AllocateDescPipe , AllocateDescDir , AllocateDescRawFD }
 

Functions

static void Delete (File file)
 
static void LruDelete (File file)
 
static void Insert (File file)
 
static int LruInsert (File file)
 
static bool ReleaseLruFile (void)
 
static void ReleaseLruFiles (void)
 
static File AllocateVfd (void)
 
static void FreeVfd (File file)
 
static int FileAccess (File file)
 
static File OpenTemporaryFileInTablespace (Oid tblspcOid, bool rejectError)
 
static bool reserveAllocatedDesc (void)
 
static int FreeDesc (AllocateDesc *desc)
 
static void BeforeShmemExit_Files (int code, Datum arg)
 
static void CleanupTempFiles (bool isCommit, bool isProcExit)
 
static void RemovePgTempRelationFiles (const char *tsdirname)
 
static void RemovePgTempRelationFilesInDbspace (const char *dbspacedirname)
 
static void walkdir (const char *path, void(*action)(const char *fname, bool isdir, int elevel), bool process_symlinks, int elevel)
 
static void datadir_fsync_fname (const char *fname, bool isdir, int elevel)
 
static void unlink_if_exists_fname (const char *fname, bool isdir, int elevel)
 
static int fsync_parent_path (const char *fname, int elevel)
 
static void ResOwnerReleaseFile (Datum res)
 
static char * ResOwnerPrintFile (Datum res)
 
static void ResourceOwnerRememberFile (ResourceOwner owner, File file)
 
static void ResourceOwnerForgetFile (ResourceOwner owner, File file)
 
int pg_fsync (int fd)
 
int pg_fsync_no_writethrough (int fd)
 
int pg_fsync_writethrough (int fd)
 
int pg_fdatasync (int fd)
 
bool pg_file_exists (const char *name)
 
void pg_flush_data (int fd, off_t offset, off_t nbytes)
 
static int pg_ftruncate (int fd, off_t length)
 
int pg_truncate (const char *path, off_t length)
 
void fsync_fname (const char *fname, bool isdir)
 
int durable_rename (const char *oldfile, const char *newfile, int elevel)
 
int durable_unlink (const char *fname, int elevel)
 
void InitFileAccess (void)
 
void InitTemporaryFileAccess (void)
 
static void count_usable_fds (int max_to_probe, int *usable_fds, int *already_open)
 
void set_max_safe_fds (void)
 
int BasicOpenFile (const char *fileName, int fileFlags)
 
int BasicOpenFilePerm (const char *fileName, int fileFlags, mode_t fileMode)
 
bool AcquireExternalFD (void)
 
void ReserveExternalFD (void)
 
void ReleaseExternalFD (void)
 
static void ReportTemporaryFileUsage (const char *path, off_t size)
 
static void RegisterTemporaryFile (File file)
 
File PathNameOpenFile (const char *fileName, int fileFlags)
 
File PathNameOpenFilePerm (const char *fileName, int fileFlags, mode_t fileMode)
 
void PathNameCreateTemporaryDir (const char *basedir, const char *directory)
 
void PathNameDeleteTemporaryDir (const char *dirname)
 
File OpenTemporaryFile (bool interXact)
 
void TempTablespacePath (char *path, Oid tablespace)
 
File PathNameCreateTemporaryFile (const char *path, bool error_on_failure)
 
File PathNameOpenTemporaryFile (const char *path, int mode)
 
bool PathNameDeleteTemporaryFile (const char *path, bool error_on_failure)
 
void FileClose (File file)
 
int FilePrefetch (File file, off_t offset, off_t amount, uint32 wait_event_info)
 
void FileWriteback (File file, off_t offset, off_t nbytes, uint32 wait_event_info)
 
ssize_t FileReadV (File file, const struct iovec *iov, int iovcnt, off_t offset, uint32 wait_event_info)
 
ssize_t FileWriteV (File file, const struct iovec *iov, int iovcnt, off_t offset, uint32 wait_event_info)
 
int FileSync (File file, uint32 wait_event_info)
 
int FileZero (File file, off_t offset, off_t amount, uint32 wait_event_info)
 
int FileFallocate (File file, off_t offset, off_t amount, uint32 wait_event_info)
 
off_t FileSize (File file)
 
int FileTruncate (File file, off_t offset, uint32 wait_event_info)
 
char * FilePathName (File file)
 
int FileGetRawDesc (File file)
 
int FileGetRawFlags (File file)
 
mode_t FileGetRawMode (File file)
 
FILE * AllocateFile (const char *name, const char *mode)
 
int OpenTransientFile (const char *fileName, int fileFlags)
 
int OpenTransientFilePerm (const char *fileName, int fileFlags, mode_t fileMode)
 
FILE * OpenPipeStream (const char *command, const char *mode)
 
int FreeFile (FILE *file)
 
int CloseTransientFile (int fd)
 
DIRAllocateDir (const char *dirname)
 
struct direntReadDir (DIR *dir, const char *dirname)
 
struct direntReadDirExtended (DIR *dir, const char *dirname, int elevel)
 
int FreeDir (DIR *dir)
 
int ClosePipeStream (FILE *file)
 
void closeAllVfds (void)
 
void SetTempTablespaces (Oid *tableSpaces, int numSpaces)
 
bool TempTablespacesAreSet (void)
 
int GetTempTablespaces (Oid *tableSpaces, int numSpaces)
 
Oid GetNextTempTableSpace (void)
 
void AtEOSubXact_Files (bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
 
void AtEOXact_Files (bool isCommit)
 
void RemovePgTempFiles (void)
 
void RemovePgTempFilesInDir (const char *tmpdirname, bool missing_ok, bool unlink_all)
 
bool looks_like_temp_rel_name (const char *name)
 
void SyncDataDirectory (void)
 
int fsync_fname_ext (const char *fname, bool isdir, bool ignore_perm, int elevel)
 
int MakePGDirectory (const char *directoryName)
 
int data_sync_elevel (int elevel)
 
bool check_debug_io_direct (char **newval, void **extra, GucSource source)
 
void assign_debug_io_direct (const char *newval, void *extra)
 

Variables

int max_files_per_process = 1000
 
int max_safe_fds = FD_MINFREE
 
bool data_sync_retry = false
 
int recovery_init_sync_method = DATA_DIR_SYNC_METHOD_FSYNC
 
int io_direct_flags
 
static VfdVfdCache
 
static Size SizeVfdCache = 0
 
static int nfile = 0
 
static bool have_xact_temporary_files = false
 
static uint64 temporary_files_size = 0
 
static int numAllocatedDescs = 0
 
static int maxAllocatedDescs = 0
 
static AllocateDescallocatedDescs = NULL
 
static int numExternalFDs = 0
 
static long tempFileCounter = 0
 
static OidtempTableSpaces = NULL
 
static int numTempTableSpaces = -1
 
static int nextTempTableSpace = 0
 
static const ResourceOwnerDesc file_resowner_desc
 

Macro Definition Documentation

◆ DO_DB

#define DO_DB (   A)     ((void) 0)

Definition at line 179 of file fd.c.

◆ FD_CLOSE_AT_EOXACT

#define FD_CLOSE_AT_EOXACT   (1 << 1) /* T = close at eoXact */

Definition at line 192 of file fd.c.

◆ FD_DELETE_AT_CLOSE

#define FD_DELETE_AT_CLOSE   (1 << 0) /* T = delete when closed */

Definition at line 191 of file fd.c.

◆ FD_MINFREE

#define FD_MINFREE   48

Definition at line 137 of file fd.c.

◆ FD_TEMP_FILE_LIMIT

#define FD_TEMP_FILE_LIMIT   (1 << 2) /* T = respect temp_file_limit */

Definition at line 193 of file fd.c.

◆ FileIsNotOpen

#define FileIsNotOpen (   file)    (VfdCache[file].fd == VFD_CLOSED)

Definition at line 188 of file fd.c.

◆ FileIsValid

#define FileIsValid (   file)     ((file) > 0 && (file) < (int) SizeVfdCache && VfdCache[file].fileName != NULL)

Definition at line 185 of file fd.c.

◆ NUM_RESERVED_FDS

#define NUM_RESERVED_FDS   10

Definition at line 128 of file fd.c.

◆ VFD_CLOSED

#define VFD_CLOSED   (-1)

Definition at line 183 of file fd.c.

Typedef Documentation

◆ Vfd

typedef struct vfd Vfd

Enumeration Type Documentation

◆ AllocateDescKind

Enumerator
AllocateDescFile 
AllocateDescPipe 
AllocateDescDir 
AllocateDescRawFD 

Definition at line 246 of file fd.c.

247{
AllocateDescKind
Definition: fd.c:247
@ AllocateDescDir
Definition: fd.c:250
@ AllocateDescPipe
Definition: fd.c:249
@ AllocateDescFile
Definition: fd.c:248
@ AllocateDescRawFD
Definition: fd.c:251

Function Documentation

◆ AcquireExternalFD()

bool AcquireExternalFD ( void  )

Definition at line 1185 of file fd.c.

1186{
1187 /*
1188 * We don't want more than max_safe_fds / 3 FDs to be consumed for
1189 * "external" FDs.
1190 */
1191 if (numExternalFDs < max_safe_fds / 3)
1192 {
1194 return true;
1195 }
1196 errno = EMFILE;
1197 return false;
1198}
int max_safe_fds
Definition: fd.c:158
void ReserveExternalFD(void)
Definition: fd.c:1220
static int numExternalFDs
Definition: fd.c:273

References max_safe_fds, numExternalFDs, and ReserveExternalFD().

Referenced by CreateWaitEventSet(), and libpqsrv_connect_prepare().

◆ AllocateDir()

DIR * AllocateDir ( const char *  dirname)

Definition at line 2865 of file fd.c.

2866{
2867 DIR *dir;
2868
2869 DO_DB(elog(LOG, "AllocateDir: Allocated %d (%s)",
2870 numAllocatedDescs, dirname));
2871
2872 /* Can we allocate another non-virtual FD? */
2873 if (!reserveAllocatedDesc())
2874 ereport(ERROR,
2875 (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2876 errmsg("exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"",
2877 maxAllocatedDescs, dirname)));
2878
2879 /* Close excess kernel FDs. */
2881
2882TryAgain:
2883 if ((dir = opendir(dirname)) != NULL)
2884 {
2886
2887 desc->kind = AllocateDescDir;
2888 desc->desc.dir = dir;
2891 return desc->desc.dir;
2892 }
2893
2894 if (errno == EMFILE || errno == ENFILE)
2895 {
2896 int save_errno = errno;
2897
2898 ereport(LOG,
2899 (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2900 errmsg("out of file descriptors: %m; release and retry")));
2901 errno = 0;
2902 if (ReleaseLruFile())
2903 goto TryAgain;
2904 errno = save_errno;
2905 }
2906
2907 return NULL;
2908}
DIR * opendir(const char *)
Definition: dirent.c:33
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define LOG
Definition: elog.h:31
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
#define ereport(elevel,...)
Definition: elog.h:149
static bool ReleaseLruFile(void)
Definition: fd.c:1381
static int maxAllocatedDescs
Definition: fd.c:267
static int numAllocatedDescs
Definition: fd.c:266
#define DO_DB(A)
Definition: fd.c:179
static AllocateDesc * allocatedDescs
Definition: fd.c:268
static bool reserveAllocatedDesc(void)
Definition: fd.c:2530
static void ReleaseLruFiles(void)
Definition: fd.c:1403
SubTransactionId create_subid
Definition: fd.c:257
DIR * dir
Definition: fd.c:261
union AllocateDesc::@20 desc
AllocateDescKind kind
Definition: fd.c:256
Definition: dirent.c:26
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:790

References allocatedDescs, AllocateDescDir, AllocateDesc::create_subid, AllocateDesc::desc, AllocateDesc::dir, DO_DB, elog, ereport, errcode(), errmsg(), ERROR, GetCurrentSubTransactionId(), AllocateDesc::kind, LOG, maxAllocatedDescs, numAllocatedDescs, opendir(), ReleaseLruFile(), ReleaseLruFiles(), and reserveAllocatedDesc().

Referenced by calculate_database_size(), calculate_tablespace_size(), CheckPointLogicalRewriteHeap(), CheckPointSnapBuild(), CheckTablespaceDirectory(), CleanupBackupHistory(), copydir(), db_dir_size(), DeleteAllExportedSnapshotFiles(), destroy_tablespace_directories(), directory_is_empty(), do_pg_backup_start(), dsm_cleanup_for_mmap(), extension_file_exists(), get_ext_ver_list(), GetConfFilesInDir(), getInstallationPaths(), GetWalSummaries(), movedb(), ParseTzFile(), perform_base_backup(), pg_available_extension_versions(), pg_available_extensions(), pg_ls_dir(), pg_ls_dir_files(), pg_tablespace_databases(), pg_tzenumerate_next(), pg_tzenumerate_start(), pgarch_readyXlog(), RelationCacheInitFileRemove(), RelationCacheInitFileRemoveInDir(), RemoveNonParentXlogFiles(), RemoveOldXlogFiles(), RemovePgTempFiles(), RemovePgTempFilesInDir(), RemovePgTempRelationFiles(), RemovePgTempRelationFilesInDbspace(), RemoveTempXlogFiles(), ReorderBufferCleanupSerializedTXNs(), ResetUnloggedRelations(), ResetUnloggedRelationsInDbspaceDir(), ResetUnloggedRelationsInTablespaceDir(), restoreTwoPhaseData(), scan_directory_ci(), sendDir(), SlruScanDirectory(), StartupReorderBuffer(), StartupReplicationSlots(), SyncDataDirectory(), UpdateLogicalMappings(), walkdir(), and XLogGetOldestSegno().

◆ AllocateFile()

FILE * AllocateFile ( const char *  name,
const char *  mode 
)

Definition at line 2605 of file fd.c.

2606{
2607 FILE *file;
2608
2609 DO_DB(elog(LOG, "AllocateFile: Allocated %d (%s)",
2611
2612 /* Can we allocate another non-virtual FD? */
2613 if (!reserveAllocatedDesc())
2614 ereport(ERROR,
2615 (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2616 errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2618
2619 /* Close excess kernel FDs. */
2621
2622TryAgain:
2623 if ((file = fopen(name, mode)) != NULL)
2624 {
2626
2627 desc->kind = AllocateDescFile;
2628 desc->desc.file = file;
2631 return desc->desc.file;
2632 }
2633
2634 if (errno == EMFILE || errno == ENFILE)
2635 {
2636 int save_errno = errno;
2637
2638 ereport(LOG,
2639 (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2640 errmsg("out of file descriptors: %m; release and retry")));
2641 errno = 0;
2642 if (ReleaseLruFile())
2643 goto TryAgain;
2644 errno = save_errno;
2645 }
2646
2647 return NULL;
2648}
static PgChecksumMode mode
Definition: pg_checksums.c:55
FILE * file
Definition: fd.c:260
const char * name

References allocatedDescs, AllocateDescFile, AllocateDesc::create_subid, AllocateDesc::desc, DO_DB, elog, ereport, errcode(), errmsg(), ERROR, AllocateDesc::file, GetCurrentSubTransactionId(), AllocateDesc::kind, LOG, maxAllocatedDescs, mode, name, numAllocatedDescs, ReleaseLruFile(), ReleaseLruFiles(), and reserveAllocatedDesc().

Referenced by AlterSystemSetConfigFile(), apw_dump_now(), apw_load_buffers(), BeginCopyFrom(), BeginCopyTo(), checkControlFile(), do_pg_backup_stop(), entry_reset(), existsTimeLineHistory(), ExportSnapshot(), gc_qtexts(), GetHugePageSize(), ImportSnapshot(), load_dh_file(), load_relcache_init_file(), open_auth_file(), parse_extension_control_file(), ParseConfigFile(), ParseTzFile(), pg_current_logfile(), pg_promote(), pgss_shmem_shutdown(), pgss_shmem_startup(), pgstat_read_statsfile(), pgstat_write_statsfile(), read_backup_label(), read_binary_file(), read_tablespace_map(), read_whole_file(), readTimeLineHistory(), tsearch_readline_begin(), ValidatePgVersion(), write_relcache_init_file(), XLogArchiveForceDone(), and XLogArchiveNotify().

◆ AllocateVfd()

static File AllocateVfd ( void  )
static

Definition at line 1413 of file fd.c.

1414{
1415 Index i;
1416 File file;
1417
1418 DO_DB(elog(LOG, "AllocateVfd. Size %zu", SizeVfdCache));
1419
1420 Assert(SizeVfdCache > 0); /* InitFileAccess not called? */
1421
1422 if (VfdCache[0].nextFree == 0)
1423 {
1424 /*
1425 * The free list is empty so it is time to increase the size of the
1426 * array. We choose to double it each time this happens. However,
1427 * there's not much point in starting *real* small.
1428 */
1429 Size newCacheSize = SizeVfdCache * 2;
1430 Vfd *newVfdCache;
1431
1432 if (newCacheSize < 32)
1433 newCacheSize = 32;
1434
1435 /*
1436 * Be careful not to clobber VfdCache ptr if realloc fails.
1437 */
1438 newVfdCache = (Vfd *) realloc(VfdCache, sizeof(Vfd) * newCacheSize);
1439 if (newVfdCache == NULL)
1440 ereport(ERROR,
1441 (errcode(ERRCODE_OUT_OF_MEMORY),
1442 errmsg("out of memory")));
1443 VfdCache = newVfdCache;
1444
1445 /*
1446 * Initialize the new entries and link them into the free list.
1447 */
1448 for (i = SizeVfdCache; i < newCacheSize; i++)
1449 {
1450 MemSet(&(VfdCache[i]), 0, sizeof(Vfd));
1451 VfdCache[i].nextFree = i + 1;
1453 }
1454 VfdCache[newCacheSize - 1].nextFree = 0;
1456
1457 /*
1458 * Record the new size
1459 */
1460 SizeVfdCache = newCacheSize;
1461 }
1462
1463 file = VfdCache[0].nextFree;
1464
1466
1467 return file;
1468}
#define Assert(condition)
Definition: c.h:815
unsigned int Index
Definition: c.h:571
#define MemSet(start, val, len)
Definition: c.h:977
size_t Size
Definition: c.h:562
static Size SizeVfdCache
Definition: fd.c:216
#define VFD_CLOSED
Definition: fd.c:183
static Vfd * VfdCache
Definition: fd.c:215
int File
Definition: fd.h:51
#define realloc(a, b)
Definition: header.h:60
int i
Definition: isn.c:72
Definition: fd.c:196
int fd
Definition: fd.c:197
File nextFree
Definition: fd.c:200

References Assert, DO_DB, elog, ereport, errcode(), errmsg(), ERROR, vfd::fd, i, LOG, MemSet, vfd::nextFree, realloc, SizeVfdCache, VFD_CLOSED, and VfdCache.

Referenced by PathNameOpenFilePerm().

◆ assign_debug_io_direct()

void assign_debug_io_direct ( const char *  newval,
void *  extra 
)

Definition at line 4050 of file fd.c.

4051{
4052 int *flags = (int *) extra;
4053
4054 io_direct_flags = *flags;
4055}
int io_direct_flags
Definition: fd.c:167

References io_direct_flags.

◆ AtEOSubXact_Files()

void AtEOSubXact_Files ( bool  isCommit,
SubTransactionId  mySubid,
SubTransactionId  parentSubid 
)

Definition at line 3154 of file fd.c.

3156{
3157 Index i;
3158
3159 for (i = 0; i < numAllocatedDescs; i++)
3160 {
3161 if (allocatedDescs[i].create_subid == mySubid)
3162 {
3163 if (isCommit)
3164 allocatedDescs[i].create_subid = parentSubid;
3165 else
3166 {
3167 /* have to recheck the item after FreeDesc (ugly) */
3169 }
3170 }
3171 }
3172}
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2764

References allocatedDescs, AllocateDesc::create_subid, FreeDesc(), i, and numAllocatedDescs.

Referenced by AbortSubTransaction(), and CommitSubTransaction().

◆ AtEOXact_Files()

void AtEOXact_Files ( bool  isCommit)

Definition at line 3187 of file fd.c.

3188{
3189 CleanupTempFiles(isCommit, false);
3190 tempTableSpaces = NULL;
3191 numTempTableSpaces = -1;
3192}
static int numTempTableSpaces
Definition: fd.c:288
static Oid * tempTableSpaces
Definition: fd.c:287
static void CleanupTempFiles(bool isCommit, bool isProcExit)
Definition: fd.c:3224

References CleanupTempFiles(), numTempTableSpaces, and tempTableSpaces.

Referenced by AbortTransaction(), BackgroundWriterMain(), CheckpointerMain(), CommitTransaction(), pgarch_archiveXlog(), PrepareTransaction(), WalSummarizerMain(), and WalWriterMain().

◆ BasicOpenFile()

int BasicOpenFile ( const char *  fileName,
int  fileFlags 
)

Definition at line 1086 of file fd.c.

1087{
1088 return BasicOpenFilePerm(fileName, fileFlags, pg_file_create_mode);
1089}
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1108
int pg_file_create_mode
Definition: file_perm.c:19

References BasicOpenFilePerm(), and pg_file_create_mode.

Referenced by AlterSystemSetConfigFile(), ReadControlFile(), update_controlfile(), wal_segment_open(), WalSndSegmentOpen(), WriteControlFile(), XLogFileInit(), XLogFileInitInternal(), XLogFileOpen(), and XLogFileRead().

◆ BasicOpenFilePerm()

int BasicOpenFilePerm ( const char *  fileName,
int  fileFlags,
mode_t  fileMode 
)

Definition at line 1108 of file fd.c.

1109{
1110 int fd;
1111
1112tryAgain:
1113#ifdef PG_O_DIRECT_USE_F_NOCACHE
1114
1115 /*
1116 * The value we defined to stand in for O_DIRECT when simulating it with
1117 * F_NOCACHE had better not collide with any of the standard flags.
1118 */
1120 (O_APPEND |
1121 O_CLOEXEC |
1122 O_CREAT |
1123 O_DSYNC |
1124 O_EXCL |
1125 O_RDWR |
1126 O_RDONLY |
1127 O_SYNC |
1128 O_TRUNC |
1129 O_WRONLY)) == 0,
1130 "PG_O_DIRECT value collides with standard flag");
1131 fd = open(fileName, fileFlags & ~PG_O_DIRECT, fileMode);
1132#else
1133 fd = open(fileName, fileFlags, fileMode);
1134#endif
1135
1136 if (fd >= 0)
1137 {
1138#ifdef PG_O_DIRECT_USE_F_NOCACHE
1139 if (fileFlags & PG_O_DIRECT)
1140 {
1141 if (fcntl(fd, F_NOCACHE, 1) < 0)
1142 {
1143 int save_errno = errno;
1144
1145 close(fd);
1146 errno = save_errno;
1147 return -1;
1148 }
1149 }
1150#endif
1151
1152 return fd; /* success! */
1153 }
1154
1155 if (errno == EMFILE || errno == ENFILE)
1156 {
1157 int save_errno = errno;
1158
1159 ereport(LOG,
1160 (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
1161 errmsg("out of file descriptors: %m; release and retry")));
1162 errno = 0;
1163 if (ReleaseLruFile())
1164 goto tryAgain;
1165 errno = save_errno;
1166 }
1167
1168 return -1; /* failure */
1169}
#define StaticAssertStmt(condition, errmessage)
Definition: c.h:895
#define PG_O_DIRECT
Definition: fd.h:97
#define close(a)
Definition: win32.h:12
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define O_CLOEXEC
Definition: win32_port.h:349
#define O_DSYNC
Definition: win32_port.h:342

References close, ereport, errcode(), errmsg(), fd(), LOG, O_CLOEXEC, O_DSYNC, PG_O_DIRECT, ReleaseLruFile(), and StaticAssertStmt.

Referenced by BasicOpenFile(), LruInsert(), OpenTransientFilePerm(), PathNameOpenFilePerm(), and readRecoverySignalFile().

◆ BeforeShmemExit_Files()

static void BeforeShmemExit_Files ( int  code,
Datum  arg 
)
static

Definition at line 3201 of file fd.c.

3202{
3203 CleanupTempFiles(false, true);
3204
3205 /* prevent further temp files from being created */
3206#ifdef USE_ASSERT_CHECKING
3207 temporary_files_allowed = false;
3208#endif
3209}

References CleanupTempFiles().

Referenced by InitTemporaryFileAccess().

◆ check_debug_io_direct()

bool check_debug_io_direct ( char **  newval,
void **  extra,
GucSource  source 
)

Definition at line 3965 of file fd.c.

3966{
3967 bool result = true;
3968 int flags;
3969
3970#if PG_O_DIRECT == 0
3971 if (strcmp(*newval, "") != 0)
3972 {
3973 GUC_check_errdetail("\"%s\" is not supported on this platform.",
3974 "debug_io_direct");
3975 result = false;
3976 }
3977 flags = 0;
3978#else
3979 List *elemlist;
3980 ListCell *l;
3981 char *rawstring;
3982
3983 /* Need a modifiable copy of string */
3984 rawstring = pstrdup(*newval);
3985
3986 if (!SplitGUCList(rawstring, ',', &elemlist))
3987 {
3988 GUC_check_errdetail("Invalid list syntax in parameter \"%s\".",
3989 "debug_io_direct");
3990 pfree(rawstring);
3991 list_free(elemlist);
3992 return false;
3993 }
3994
3995 flags = 0;
3996 foreach(l, elemlist)
3997 {
3998 char *item = (char *) lfirst(l);
3999
4000 if (pg_strcasecmp(item, "data") == 0)
4001 flags |= IO_DIRECT_DATA;
4002 else if (pg_strcasecmp(item, "wal") == 0)
4003 flags |= IO_DIRECT_WAL;
4004 else if (pg_strcasecmp(item, "wal_init") == 0)
4005 flags |= IO_DIRECT_WAL_INIT;
4006 else
4007 {
4008 GUC_check_errdetail("Invalid option \"%s\".", item);
4009 result = false;
4010 break;
4011 }
4012 }
4013
4014 /*
4015 * It's possible to configure block sizes smaller than our assumed I/O
4016 * alignment size, which could result in invalid I/O requests.
4017 */
4018#if XLOG_BLCKSZ < PG_IO_ALIGN_SIZE
4019 if (result && (flags & (IO_DIRECT_WAL | IO_DIRECT_WAL_INIT)))
4020 {
4021 GUC_check_errdetail("\"%s\" is not supported for WAL because %s is too small.",
4022 "debug_io_direct", "XLOG_BLCKSZ");
4023 result = false;
4024 }
4025#endif
4026#if BLCKSZ < PG_IO_ALIGN_SIZE
4027 if (result && (flags & IO_DIRECT_DATA))
4028 {
4029 GUC_check_errdetail("\"%s\" is not supported for WAL because %s is too small.",
4030 "debug_io_direct", "BLCKSZ");
4031 result = false;
4032 }
4033#endif
4034
4035 pfree(rawstring);
4036 list_free(elemlist);
4037#endif
4038
4039 if (!result)
4040 return result;
4041
4042 /* Save the flags in *extra, for use by assign_debug_io_direct */
4043 *extra = guc_malloc(ERROR, sizeof(int));
4044 *((int *) *extra) = flags;
4045
4046 return result;
4047}
#define IO_DIRECT_WAL
Definition: fd.h:55
#define IO_DIRECT_DATA
Definition: fd.h:54
#define IO_DIRECT_WAL_INIT
Definition: fd.h:56
void * guc_malloc(int elevel, size_t size)
Definition: guc.c:638
#define newval
#define GUC_check_errdetail
Definition: guc.h:480
void list_free(List *list)
Definition: list.c:1546
char * pstrdup(const char *in)
Definition: mcxt.c:1696
void pfree(void *pointer)
Definition: mcxt.c:1521
#define lfirst(lc)
Definition: pg_list.h:172
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
Definition: pg_list.h:54
bool SplitGUCList(char *rawstring, char separator, List **namelist)
Definition: varlena.c:3680

References ERROR, GUC_check_errdetail, guc_malloc(), IO_DIRECT_DATA, IO_DIRECT_WAL, IO_DIRECT_WAL_INIT, lfirst, list_free(), newval, pfree(), pg_strcasecmp(), pstrdup(), and SplitGUCList().

◆ CleanupTempFiles()

static void CleanupTempFiles ( bool  isCommit,
bool  isProcExit 
)
static

Definition at line 3224 of file fd.c.

3225{
3226 Index i;
3227
3228 /*
3229 * Careful here: at proc_exit we need extra cleanup, not just
3230 * xact_temporary files.
3231 */
3232 if (isProcExit || have_xact_temporary_files)
3233 {
3234 Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
3235 for (i = 1; i < SizeVfdCache; i++)
3236 {
3237 unsigned short fdstate = VfdCache[i].fdstate;
3238
3239 if (((fdstate & FD_DELETE_AT_CLOSE) || (fdstate & FD_CLOSE_AT_EOXACT)) &&
3240 VfdCache[i].fileName != NULL)
3241 {
3242 /*
3243 * If we're in the process of exiting a backend process, close
3244 * all temporary files. Otherwise, only close temporary files
3245 * local to the current transaction. They should be closed by
3246 * the ResourceOwner mechanism already, so this is just a
3247 * debugging cross-check.
3248 */
3249 if (isProcExit)
3250 FileClose(i);
3251 else if (fdstate & FD_CLOSE_AT_EOXACT)
3252 {
3253 elog(WARNING,
3254 "temporary file %s not closed at end-of-transaction",
3255 VfdCache[i].fileName);
3256 FileClose(i);
3257 }
3258 }
3259 }
3260
3262 }
3263
3264 /* Complain if any allocated files remain open at commit. */
3265 if (isCommit && numAllocatedDescs > 0)
3266 elog(WARNING, "%d temporary files and directories not closed at end-of-transaction",
3268
3269 /* Clean up "allocated" stdio files, dirs and fds. */
3270 while (numAllocatedDescs > 0)
3272}
#define WARNING
Definition: elog.h:36
#define FD_DELETE_AT_CLOSE
Definition: fd.c:191
#define FD_CLOSE_AT_EOXACT
Definition: fd.c:192
void FileClose(File file)
Definition: fd.c:1977
#define FileIsNotOpen(file)
Definition: fd.c:188
static bool have_xact_temporary_files
Definition: fd.c:227
unsigned short fdstate
Definition: fd.c:198

References allocatedDescs, Assert, elog, FD_CLOSE_AT_EOXACT, FD_DELETE_AT_CLOSE, vfd::fdstate, FileClose(), FileIsNotOpen, FreeDesc(), have_xact_temporary_files, i, numAllocatedDescs, SizeVfdCache, VfdCache, and WARNING.

Referenced by AtEOXact_Files(), and BeforeShmemExit_Files().

◆ closeAllVfds()

void closeAllVfds ( void  )

Definition at line 3042 of file fd.c.

3043{
3044 Index i;
3045
3046 if (SizeVfdCache > 0)
3047 {
3048 Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
3049 for (i = 1; i < SizeVfdCache; i++)
3050 {
3051 if (!FileIsNotOpen(i))
3052 LruDelete(i);
3053 }
3054 }
3055}
static void LruDelete(File file)
Definition: fd.c:1286

References Assert, FileIsNotOpen, i, LruDelete(), and SizeVfdCache.

Referenced by standard_ProcessUtility().

◆ ClosePipeStream()

int ClosePipeStream ( FILE *  file)

Definition at line 3013 of file fd.c.

3014{
3015 int i;
3016
3017 DO_DB(elog(LOG, "ClosePipeStream: Allocated %d", numAllocatedDescs));
3018
3019 /* Remove file from list of allocated files, if it's present */
3020 for (i = numAllocatedDescs; --i >= 0;)
3021 {
3022 AllocateDesc *desc = &allocatedDescs[i];
3023
3024 if (desc->kind == AllocateDescPipe && desc->desc.file == file)
3025 return FreeDesc(desc);
3026 }
3027
3028 /* Only get here if someone passes us a file not in allocatedDescs */
3029 elog(WARNING, "file passed to ClosePipeStream was not obtained from OpenPipeStream");
3030
3031 return pclose(file);
3032}

References allocatedDescs, AllocateDescPipe, AllocateDesc::desc, DO_DB, elog, AllocateDesc::file, FreeDesc(), i, AllocateDesc::kind, LOG, numAllocatedDescs, and WARNING.

Referenced by ClosePipeFromProgram(), ClosePipeToProgram(), pg_import_system_collations(), run_ssl_passphrase_command(), and shell_finish_command().

◆ CloseTransientFile()

int CloseTransientFile ( int  fd)

Definition at line 2831 of file fd.c.

2832{
2833 int i;
2834
2835 DO_DB(elog(LOG, "CloseTransientFile: Allocated %d", numAllocatedDescs));
2836
2837 /* Remove fd from list of allocated files, if it's present */
2838 for (i = numAllocatedDescs; --i >= 0;)
2839 {
2840 AllocateDesc *desc = &allocatedDescs[i];
2841
2842 if (desc->kind == AllocateDescRawFD && desc->desc.fd == fd)
2843 return FreeDesc(desc);
2844 }
2845
2846 /* Only get here if someone passes us a file not in allocatedDescs */
2847 elog(WARNING, "fd passed to CloseTransientFile was not obtained from OpenTransientFile");
2848
2849 return close(fd);
2850}
int fd
Definition: fd.c:262

References allocatedDescs, AllocateDescRawFD, close, AllocateDesc::desc, DO_DB, elog, AllocateDesc::fd, fd(), FreeDesc(), i, AllocateDesc::kind, LOG, numAllocatedDescs, and WARNING.

Referenced by ApplyLogicalMappingFile(), be_lo_export(), CheckPointLogicalRewriteHeap(), CheckPointReplicationOrigin(), compare_files(), copy_file(), CreateDirAndVersionFile(), dsm_impl_mmap(), durable_rename(), fsync_fname_ext(), get_controlfile_by_exact_path(), heap_xlog_logical_rewrite(), lo_import_internal(), perform_base_backup(), pg_truncate(), qtext_load_file(), qtext_store(), read_relmap_file(), ReadTwoPhaseFile(), RecreateTwoPhaseFile(), ReorderBufferSerializeChange(), ReorderBufferSerializeTXN(), RestoreSlotFromDisk(), SaveSlotToPath(), sendFile(), SendTimeLineHistory(), SimpleLruDoesPhysicalPageExist(), SimpleLruWriteAll(), SlruInternalWritePage(), SlruPhysicalReadPage(), SlruPhysicalWritePage(), SlruSyncFileTag(), SnapBuildRestoreContents(), SnapBuildRestoreSnapshot(), SnapBuildSerialize(), StartupReplicationOrigin(), write_relmap_file(), writeTimeLineHistory(), writeTimeLineHistoryFile(), and XLogFileCopy().

◆ count_usable_fds()

static void count_usable_fds ( int  max_to_probe,
int *  usable_fds,
int *  already_open 
)
static

Definition at line 963 of file fd.c.

964{
965 int *fd;
966 int size;
967 int used = 0;
968 int highestfd = 0;
969 int j;
970
971#ifdef HAVE_GETRLIMIT
972 struct rlimit rlim;
973 int getrlimit_status;
974#endif
975
976 size = 1024;
977 fd = (int *) palloc(size * sizeof(int));
978
979#ifdef HAVE_GETRLIMIT
980 getrlimit_status = getrlimit(RLIMIT_NOFILE, &rlim);
981 if (getrlimit_status != 0)
982 ereport(WARNING, (errmsg("getrlimit failed: %m")));
983#endif /* HAVE_GETRLIMIT */
984
985 /* dup until failure or probe limit reached */
986 for (;;)
987 {
988 int thisfd;
989
990#ifdef HAVE_GETRLIMIT
991
992 /*
993 * don't go beyond RLIMIT_NOFILE; causes irritating kernel logs on
994 * some platforms
995 */
996 if (getrlimit_status == 0 && highestfd >= rlim.rlim_cur - 1)
997 break;
998#endif
999
1000 thisfd = dup(2);
1001 if (thisfd < 0)
1002 {
1003 /* Expect EMFILE or ENFILE, else it's fishy */
1004 if (errno != EMFILE && errno != ENFILE)
1005 elog(WARNING, "duplicating stderr file descriptor failed after %d successes: %m", used);
1006 break;
1007 }
1008
1009 if (used >= size)
1010 {
1011 size *= 2;
1012 fd = (int *) repalloc(fd, size * sizeof(int));
1013 }
1014 fd[used++] = thisfd;
1015
1016 if (highestfd < thisfd)
1017 highestfd = thisfd;
1018
1019 if (used >= max_to_probe)
1020 break;
1021 }
1022
1023 /* release the files we opened */
1024 for (j = 0; j < used; j++)
1025 close(fd[j]);
1026
1027 pfree(fd);
1028
1029 /*
1030 * Return results. usable_fds is just the number of successful dups. We
1031 * assume that the system limit is highestfd+1 (remember 0 is a legal FD
1032 * number) and so already_open is highestfd+1 - usable_fds.
1033 */
1034 *usable_fds = used;
1035 *already_open = highestfd + 1 - used;
1036}
int j
Definition: isn.c:73
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1541
void * palloc(Size size)
Definition: mcxt.c:1317
static pg_noinline void Size size
Definition: slab.c:607

References close, elog, ereport, errmsg(), fd(), j, palloc(), pfree(), repalloc(), size, and WARNING.

Referenced by set_max_safe_fds().

◆ data_sync_elevel()

◆ datadir_fsync_fname()

static void datadir_fsync_fname ( const char *  fname,
bool  isdir,
int  elevel 
)
static

Definition at line 3782 of file fd.c.

3783{
3784 ereport_startup_progress("syncing data directory (fsync), elapsed time: %ld.%02d s, current path: %s",
3785 fname);
3786
3787 /*
3788 * We want to silently ignoring errors about unreadable files. Pass that
3789 * desire on to fsync_fname_ext().
3790 */
3791 fsync_fname_ext(fname, isdir, true, elevel);
3792}
int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3820
#define ereport_startup_progress(msg,...)
Definition: startup.h:18

References ereport_startup_progress, and fsync_fname_ext().

Referenced by SyncDataDirectory().

◆ Delete()

static void Delete ( File  file)
static

Definition at line 1267 of file fd.c.

1268{
1269 Vfd *vfdP;
1270
1271 Assert(file != 0);
1272
1273 DO_DB(elog(LOG, "Delete %d (%s)",
1274 file, VfdCache[file].fileName));
1275 DO_DB(_dump_lru());
1276
1277 vfdP = &VfdCache[file];
1278
1281
1282 DO_DB(_dump_lru());
1283}
File lruLessRecently
Definition: fd.c:202
File lruMoreRecently
Definition: fd.c:201

References Assert, DO_DB, elog, LOG, vfd::lruLessRecently, vfd::lruMoreRecently, and VfdCache.

Referenced by FileAccess(), FileClose(), and LruDelete().

◆ durable_rename()

int durable_rename ( const char *  oldfile,
const char *  newfile,
int  elevel 
)

Definition at line 781 of file fd.c.

782{
783 int fd;
784
785 /*
786 * First fsync the old and target path (if it exists), to ensure that they
787 * are properly persistent on disk. Syncing the target file is not
788 * strictly necessary, but it makes it easier to reason about crashes;
789 * because it's then guaranteed that either source or target file exists
790 * after a crash.
791 */
792 if (fsync_fname_ext(oldfile, false, false, elevel) != 0)
793 return -1;
794
795 fd = OpenTransientFile(newfile, PG_BINARY | O_RDWR);
796 if (fd < 0)
797 {
798 if (errno != ENOENT)
799 {
800 ereport(elevel,
802 errmsg("could not open file \"%s\": %m", newfile)));
803 return -1;
804 }
805 }
806 else
807 {
808 if (pg_fsync(fd) != 0)
809 {
810 int save_errno;
811
812 /* close file upon error, might not be in transaction context */
813 save_errno = errno;
815 errno = save_errno;
816
817 ereport(elevel,
819 errmsg("could not fsync file \"%s\": %m", newfile)));
820 return -1;
821 }
822
823 if (CloseTransientFile(fd) != 0)
824 {
825 ereport(elevel,
827 errmsg("could not close file \"%s\": %m", newfile)));
828 return -1;
829 }
830 }
831
832 /* Time to do the real deal... */
833 if (rename(oldfile, newfile) < 0)
834 {
835 ereport(elevel,
837 errmsg("could not rename file \"%s\" to \"%s\": %m",
838 oldfile, newfile)));
839 return -1;
840 }
841
842 /*
843 * To guarantee renaming the file is persistent, fsync the file with its
844 * new name, and its containing directory.
845 */
846 if (fsync_fname_ext(newfile, false, false, elevel) != 0)
847 return -1;
848
849 if (fsync_parent_path(newfile, elevel) != 0)
850 return -1;
851
852 return 0;
853}
#define PG_BINARY
Definition: c.h:1230
int errcode_for_file_access(void)
Definition: elog.c:876
int CloseTransientFile(int fd)
Definition: fd.c:2831
int pg_fsync(int fd)
Definition: fd.c:385
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3896
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2655

References CloseTransientFile(), ereport, errcode_for_file_access(), errmsg(), fd(), fsync_fname_ext(), fsync_parent_path(), OpenTransientFile(), PG_BINARY, and pg_fsync().

Referenced by AlterSystemSetConfigFile(), apw_dump_now(), BaseBackup(), basic_archive_file(), bbsink_server_end_manifest(), CheckPointReplicationOrigin(), CleanupAfterArchiveRecovery(), dir_close(), InitWalRecovery(), InstallXLogFileSegment(), KeepFileRestoredFromArchive(), pgss_shmem_shutdown(), pgstat_write_statsfile(), StartupXLOG(), SummarizeWAL(), write_relmap_file(), writeTimeLineHistory(), writeTimeLineHistoryFile(), and XLogArchiveForceDone().

◆ durable_unlink()

int durable_unlink ( const char *  fname,
int  elevel 
)

Definition at line 871 of file fd.c.

872{
873 if (unlink(fname) < 0)
874 {
875 ereport(elevel,
877 errmsg("could not remove file \"%s\": %m",
878 fname)));
879 return -1;
880 }
881
882 /*
883 * To guarantee that the removal of the file is persistent, fsync its
884 * parent directory.
885 */
886 if (fsync_parent_path(fname, elevel) != 0)
887 return -1;
888
889 return 0;
890}

References ereport, errcode_for_file_access(), errmsg(), and fsync_parent_path().

Referenced by InstallXLogFileSegment(), RemoveXlogFile(), and StartupXLOG().

◆ FileAccess()

static int FileAccess ( File  file)
static

Definition at line 1491 of file fd.c.

1492{
1493 int returnValue;
1494
1495 DO_DB(elog(LOG, "FileAccess %d (%s)",
1496 file, VfdCache[file].fileName));
1497
1498 /*
1499 * Is the file open? If not, open it and put it at the head of the LRU
1500 * ring (possibly closing the least recently used file to get an FD).
1501 */
1502
1503 if (FileIsNotOpen(file))
1504 {
1505 returnValue = LruInsert(file);
1506 if (returnValue != 0)
1507 return returnValue;
1508 }
1509 else if (VfdCache[0].lruLessRecently != file)
1510 {
1511 /*
1512 * We now know that the file is open and that it is not the last one
1513 * accessed, so we need to move it to the head of the Lru ring.
1514 */
1515
1516 Delete(file);
1517 Insert(file);
1518 }
1519
1520 return 0;
1521}
static void Delete(File file)
Definition: fd.c:1267
static void Insert(File file)
Definition: fd.c:1312
static int LruInsert(File file)
Definition: fd.c:1334

References Delete(), DO_DB, elog, FileIsNotOpen, Insert(), LOG, LruInsert(), and VfdCache.

Referenced by FileFallocate(), FilePrefetch(), FileReadV(), FileSize(), FileSync(), FileTruncate(), FileWriteback(), FileWriteV(), and FileZero().

◆ FileClose()

void FileClose ( File  file)

Definition at line 1977 of file fd.c.

1978{
1979 Vfd *vfdP;
1980
1981 Assert(FileIsValid(file));
1982
1983 DO_DB(elog(LOG, "FileClose: %d (%s)",
1984 file, VfdCache[file].fileName));
1985
1986 vfdP = &VfdCache[file];
1987
1988 if (!FileIsNotOpen(file))
1989 {
1990 /* close the file */
1991 if (close(vfdP->fd) != 0)
1992 {
1993 /*
1994 * We may need to panic on failure to close non-temporary files;
1995 * see LruDelete.
1996 */
1998 "could not close file \"%s\": %m", vfdP->fileName);
1999 }
2000
2001 --nfile;
2002 vfdP->fd = VFD_CLOSED;
2003
2004 /* remove the file from the lru ring */
2005 Delete(file);
2006 }
2007
2008 if (vfdP->fdstate & FD_TEMP_FILE_LIMIT)
2009 {
2010 /* Subtract its size from current usage (do first in case of error) */
2012 vfdP->fileSize = 0;
2013 }
2014
2015 /*
2016 * Delete the file if it was temporary, and make a log entry if wanted
2017 */
2018 if (vfdP->fdstate & FD_DELETE_AT_CLOSE)
2019 {
2020 struct stat filestats;
2021 int stat_errno;
2022
2023 /*
2024 * If we get an error, as could happen within the ereport/elog calls,
2025 * we'll come right back here during transaction abort. Reset the
2026 * flag to ensure that we can't get into an infinite loop. This code
2027 * is arranged to ensure that the worst-case consequence is failing to
2028 * emit log message(s), not failing to attempt the unlink.
2029 */
2030 vfdP->fdstate &= ~FD_DELETE_AT_CLOSE;
2031
2032
2033 /* first try the stat() */
2034 if (stat(vfdP->fileName, &filestats))
2035 stat_errno = errno;
2036 else
2037 stat_errno = 0;
2038
2039 /* in any case do the unlink */
2040 if (unlink(vfdP->fileName))
2041 ereport(LOG,
2043 errmsg("could not delete file \"%s\": %m", vfdP->fileName)));
2044
2045 /* and last report the stat results */
2046 if (stat_errno == 0)
2047 ReportTemporaryFileUsage(vfdP->fileName, filestats.st_size);
2048 else
2049 {
2050 errno = stat_errno;
2051 ereport(LOG,
2053 errmsg("could not stat file \"%s\": %m", vfdP->fileName)));
2054 }
2055 }
2056
2057 /* Unregister it from the resource owner */
2058 if (vfdP->resowner)
2059 ResourceOwnerForgetFile(vfdP->resowner, file);
2060
2061 /*
2062 * Return the Vfd slot to the free list
2063 */
2064 FreeVfd(file);
2065}
static void ResourceOwnerForgetFile(ResourceOwner owner, File file)
Definition: fd.c:376
#define FileIsValid(file)
Definition: fd.c:185
static int nfile
Definition: fd.c:221
static void FreeVfd(File file)
Definition: fd.c:1471
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:193
int data_sync_elevel(int elevel)
Definition: fd.c:3959
static void ReportTemporaryFileUsage(const char *path, off_t size)
Definition: fd.c:1527
static uint64 temporary_files_size
Definition: fd.c:235
char * fileName
Definition: fd.c:204
ResourceOwner resowner
Definition: fd.c:199
off_t fileSize
Definition: fd.c:203
#define stat
Definition: win32_port.h:274

References Assert, close, data_sync_elevel(), Delete(), DO_DB, elog, ereport, errcode_for_file_access(), errmsg(), vfd::fd, FD_DELETE_AT_CLOSE, FD_TEMP_FILE_LIMIT, vfd::fdstate, FileIsNotOpen, FileIsValid, vfd::fileName, vfd::fileSize, FreeVfd(), LOG, nfile, ReportTemporaryFileUsage(), ResourceOwnerForgetFile(), vfd::resowner, stat::st_size, stat, temporary_files_size, VFD_CLOSED, and VfdCache.

Referenced by bbsink_server_end_archive(), bbsink_server_end_manifest(), BufFileClose(), BufFileTruncateFileSet(), CleanupTempFiles(), logical_end_heap_rewrite(), mdclose(), mdimmedsync(), mdregistersync(), mdsyncfiletag(), mdtruncate(), pg_wal_summary_contents(), PrepareForIncrementalBackup(), ReorderBufferIterTXNFinish(), ReorderBufferRestoreChanges(), ResOwnerReleaseFile(), and SummarizeWAL().

◆ FileFallocate()

int FileFallocate ( File  file,
off_t  offset,
off_t  amount,
uint32  wait_event_info 
)

Definition at line 2391 of file fd.c.

2392{
2393#ifdef HAVE_POSIX_FALLOCATE
2394 int returnCode;
2395
2396 Assert(FileIsValid(file));
2397
2398 DO_DB(elog(LOG, "FileFallocate: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
2399 file, VfdCache[file].fileName,
2400 (int64) offset, (int64) amount));
2401
2402 returnCode = FileAccess(file);
2403 if (returnCode < 0)
2404 return -1;
2405
2406retry:
2407 pgstat_report_wait_start(wait_event_info);
2408 returnCode = posix_fallocate(VfdCache[file].fd, offset, amount);
2410
2411 if (returnCode == 0)
2412 return 0;
2413 else if (returnCode == EINTR)
2414 goto retry;
2415
2416 /* for compatibility with %m printing etc */
2417 errno = returnCode;
2418
2419 /*
2420 * Return in cases of a "real" failure, if fallocate is not supported,
2421 * fall through to the FileZero() backed implementation.
2422 */
2423 if (returnCode != EINVAL && returnCode != EOPNOTSUPP)
2424 return -1;
2425#endif
2426
2427 return FileZero(file, offset, amount, wait_event_info);
2428}
#define INT64_FORMAT
Definition: c.h:506
int64_t int64
Definition: c.h:485
static int FileAccess(File file)
Definition: fd.c:1491
int FileZero(File file, off_t offset, off_t amount, uint32 wait_event_info)
Definition: fd.c:2346
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:85
static void pgstat_report_wait_end(void)
Definition: wait_event.h:101
#define EINTR
Definition: win32_port.h:364
#define EOPNOTSUPP
Definition: win32_port.h:388

References Assert, DO_DB, EINTR, elog, EOPNOTSUPP, fd(), FileAccess(), FileIsValid, FileZero(), INT64_FORMAT, LOG, pgstat_report_wait_end(), pgstat_report_wait_start(), and VfdCache.

Referenced by mdzeroextend().

◆ FileGetRawDesc()

int FileGetRawDesc ( File  file)

Definition at line 2499 of file fd.c.

2500{
2501 Assert(FileIsValid(file));
2502 return VfdCache[file].fd;
2503}

References Assert, vfd::fd, FileIsValid, and VfdCache.

◆ FileGetRawFlags()

int FileGetRawFlags ( File  file)

Definition at line 2509 of file fd.c.

2510{
2511 Assert(FileIsValid(file));
2512 return VfdCache[file].fileFlags;
2513}
int fileFlags
Definition: fd.c:206

References Assert, vfd::fileFlags, FileIsValid, and VfdCache.

◆ FileGetRawMode()

mode_t FileGetRawMode ( File  file)

Definition at line 2519 of file fd.c.

2520{
2521 Assert(FileIsValid(file));
2522 return VfdCache[file].fileMode;
2523}
mode_t fileMode
Definition: fd.c:207

References Assert, FileIsValid, vfd::fileMode, and VfdCache.

◆ FilePathName()

◆ FilePrefetch()

int FilePrefetch ( File  file,
off_t  offset,
off_t  amount,
uint32  wait_event_info 
)

Definition at line 2076 of file fd.c.

2077{
2078 Assert(FileIsValid(file));
2079
2080 DO_DB(elog(LOG, "FilePrefetch: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
2081 file, VfdCache[file].fileName,
2082 (int64) offset, (int64) amount));
2083
2084#if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
2085 {
2086 int returnCode;
2087
2088 returnCode = FileAccess(file);
2089 if (returnCode < 0)
2090 return returnCode;
2091
2092retry:
2093 pgstat_report_wait_start(wait_event_info);
2094 returnCode = posix_fadvise(VfdCache[file].fd, offset, amount,
2095 POSIX_FADV_WILLNEED);
2097
2098 if (returnCode == EINTR)
2099 goto retry;
2100
2101 return returnCode;
2102 }
2103#elif defined(__darwin__)
2104 {
2105 struct radvisory
2106 {
2107 off_t ra_offset; /* offset into the file */
2108 int ra_count; /* size of the read */
2109 } ra;
2110 int returnCode;
2111
2112 returnCode = FileAccess(file);
2113 if (returnCode < 0)
2114 return returnCode;
2115
2116 ra.ra_offset = offset;
2117 ra.ra_count = amount;
2118 pgstat_report_wait_start(wait_event_info);
2119 returnCode = fcntl(VfdCache[file].fd, F_RDADVISE, &ra);
2121 if (returnCode != -1)
2122 return 0;
2123 else
2124 return errno;
2125 }
2126#else
2127 return 0;
2128#endif
2129}

References Assert, DO_DB, EINTR, elog, fd(), FileAccess(), FileIsValid, INT64_FORMAT, LOG, pgstat_report_wait_end(), pgstat_report_wait_start(), and VfdCache.

Referenced by mdprefetch().

◆ FileReadV()

ssize_t FileReadV ( File  file,
const struct iovec *  iov,
int  iovcnt,
off_t  offset,
uint32  wait_event_info 
)

Definition at line 2158 of file fd.c.

2160{
2161 ssize_t returnCode;
2162 Vfd *vfdP;
2163
2164 Assert(FileIsValid(file));
2165
2166 DO_DB(elog(LOG, "FileReadV: %d (%s) " INT64_FORMAT " %d",
2167 file, VfdCache[file].fileName,
2168 (int64) offset,
2169 iovcnt));
2170
2171 returnCode = FileAccess(file);
2172 if (returnCode < 0)
2173 return returnCode;
2174
2175 vfdP = &VfdCache[file];
2176
2177retry:
2178 pgstat_report_wait_start(wait_event_info);
2179 returnCode = pg_preadv(vfdP->fd, iov, iovcnt, offset);
2181
2182 if (returnCode < 0)
2183 {
2184 /*
2185 * Windows may run out of kernel buffers and return "Insufficient
2186 * system resources" error. Wait a bit and retry to solve it.
2187 *
2188 * It is rumored that EINTR is also possible on some Unix filesystems,
2189 * in which case immediate retry is indicated.
2190 */
2191#ifdef WIN32
2192 DWORD error = GetLastError();
2193
2194 switch (error)
2195 {
2196 case ERROR_NO_SYSTEM_RESOURCES:
2197 pg_usleep(1000L);
2198 errno = EINTR;
2199 break;
2200 default:
2202 break;
2203 }
2204#endif
2205 /* OK to retry if interrupted */
2206 if (errno == EINTR)
2207 goto retry;
2208 }
2209
2210 return returnCode;
2211}
static ssize_t pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
Definition: pg_iovec.h:44
void pg_usleep(long microsec)
Definition: signal.c:53
static void error(void)
Definition: sql-dyntest.c:147
void _dosmaperr(unsigned long)
Definition: win32error.c:177

References _dosmaperr(), Assert, DO_DB, EINTR, elog, error(), vfd::fd, FileAccess(), FileIsValid, INT64_FORMAT, LOG, pg_preadv(), pg_usleep(), pgstat_report_wait_end(), pgstat_report_wait_start(), and VfdCache.

Referenced by FileRead(), and mdreadv().

◆ FileSize()

off_t FileSize ( File  file)

Definition at line 2431 of file fd.c.

2432{
2433 Assert(FileIsValid(file));
2434
2435 DO_DB(elog(LOG, "FileSize %d (%s)",
2436 file, VfdCache[file].fileName));
2437
2438 if (FileIsNotOpen(file))
2439 {
2440 if (FileAccess(file) < 0)
2441 return (off_t) -1;
2442 }
2443
2444 return lseek(VfdCache[file].fd, 0, SEEK_END);
2445}

References Assert, DO_DB, elog, fd(), FileAccess(), FileIsNotOpen, FileIsValid, LOG, and VfdCache.

Referenced by _mdnblocks(), BufFileSeek(), and BufFileSize().

◆ FileSync()

int FileSync ( File  file,
uint32  wait_event_info 
)

Definition at line 2319 of file fd.c.

2320{
2321 int returnCode;
2322
2323 Assert(FileIsValid(file));
2324
2325 DO_DB(elog(LOG, "FileSync: %d (%s)",
2326 file, VfdCache[file].fileName));
2327
2328 returnCode = FileAccess(file);
2329 if (returnCode < 0)
2330 return returnCode;
2331
2332 pgstat_report_wait_start(wait_event_info);
2333 returnCode = pg_fsync(VfdCache[file].fd);
2335
2336 return returnCode;
2337}

References Assert, DO_DB, elog, fd(), FileAccess(), FileIsValid, LOG, pg_fsync(), pgstat_report_wait_end(), pgstat_report_wait_start(), and VfdCache.

Referenced by bbsink_server_end_archive(), logical_end_heap_rewrite(), mdimmedsync(), mdsyncfiletag(), and register_dirty_segment().

◆ FileTruncate()

int FileTruncate ( File  file,
off_t  offset,
uint32  wait_event_info 
)

Definition at line 2448 of file fd.c.

2449{
2450 int returnCode;
2451
2452 Assert(FileIsValid(file));
2453
2454 DO_DB(elog(LOG, "FileTruncate %d (%s)",
2455 file, VfdCache[file].fileName));
2456
2457 returnCode = FileAccess(file);
2458 if (returnCode < 0)
2459 return returnCode;
2460
2461 pgstat_report_wait_start(wait_event_info);
2462 returnCode = pg_ftruncate(VfdCache[file].fd, offset);
2464
2465 if (returnCode == 0 && VfdCache[file].fileSize > offset)
2466 {
2467 /* adjust our state for truncation of a temp file */
2468 Assert(VfdCache[file].fdstate & FD_TEMP_FILE_LIMIT);
2469 temporary_files_size -= VfdCache[file].fileSize - offset;
2470 VfdCache[file].fileSize = offset;
2471 }
2472
2473 return returnCode;
2474}
static int pg_ftruncate(int fd, off_t length)
Definition: fd.c:702

References Assert, DO_DB, elog, fd(), FD_TEMP_FILE_LIMIT, FileAccess(), FileIsValid, vfd::fileSize, LOG, pg_ftruncate(), pgstat_report_wait_end(), pgstat_report_wait_start(), temporary_files_size, and VfdCache.

Referenced by BufFileTruncateFileSet(), and mdtruncate().

◆ FileWriteback()

void FileWriteback ( File  file,
off_t  offset,
off_t  nbytes,
uint32  wait_event_info 
)

Definition at line 2132 of file fd.c.

2133{
2134 int returnCode;
2135
2136 Assert(FileIsValid(file));
2137
2138 DO_DB(elog(LOG, "FileWriteback: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
2139 file, VfdCache[file].fileName,
2140 (int64) offset, (int64) nbytes));
2141
2142 if (nbytes <= 0)
2143 return;
2144
2145 if (VfdCache[file].fileFlags & PG_O_DIRECT)
2146 return;
2147
2148 returnCode = FileAccess(file);
2149 if (returnCode < 0)
2150 return;
2151
2152 pgstat_report_wait_start(wait_event_info);
2153 pg_flush_data(VfdCache[file].fd, offset, nbytes);
2155}
void pg_flush_data(int fd, off_t offset, off_t nbytes)
Definition: fd.c:524

References Assert, DO_DB, elog, fd(), FileAccess(), FileIsValid, INT64_FORMAT, LOG, pg_flush_data(), PG_O_DIRECT, pgstat_report_wait_end(), pgstat_report_wait_start(), and VfdCache.

Referenced by mdwriteback().

◆ FileWriteV()

ssize_t FileWriteV ( File  file,
const struct iovec *  iov,
int  iovcnt,
off_t  offset,
uint32  wait_event_info 
)

Definition at line 2214 of file fd.c.

2216{
2217 ssize_t returnCode;
2218 Vfd *vfdP;
2219
2220 Assert(FileIsValid(file));
2221
2222 DO_DB(elog(LOG, "FileWriteV: %d (%s) " INT64_FORMAT " %d",
2223 file, VfdCache[file].fileName,
2224 (int64) offset,
2225 iovcnt));
2226
2227 returnCode = FileAccess(file);
2228 if (returnCode < 0)
2229 return returnCode;
2230
2231 vfdP = &VfdCache[file];
2232
2233 /*
2234 * If enforcing temp_file_limit and it's a temp file, check to see if the
2235 * write would overrun temp_file_limit, and throw error if so. Note: it's
2236 * really a modularity violation to throw error here; we should set errno
2237 * and return -1. However, there's no way to report a suitable error
2238 * message if we do that. All current callers would just throw error
2239 * immediately anyway, so this is safe at present.
2240 */
2241 if (temp_file_limit >= 0 && (vfdP->fdstate & FD_TEMP_FILE_LIMIT))
2242 {
2243 off_t past_write = offset;
2244
2245 for (int i = 0; i < iovcnt; ++i)
2246 past_write += iov[i].iov_len;
2247
2248 if (past_write > vfdP->fileSize)
2249 {
2250 uint64 newTotal = temporary_files_size;
2251
2252 newTotal += past_write - vfdP->fileSize;
2253 if (newTotal > (uint64) temp_file_limit * (uint64) 1024)
2254 ereport(ERROR,
2255 (errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED),
2256 errmsg("temporary file size exceeds \"temp_file_limit\" (%dkB)",
2257 temp_file_limit)));
2258 }
2259 }
2260
2261retry:
2262 pgstat_report_wait_start(wait_event_info);
2263 returnCode = pg_pwritev(vfdP->fd, iov, iovcnt, offset);
2265
2266 if (returnCode >= 0)
2267 {
2268 /*
2269 * Some callers expect short writes to set errno, and traditionally we
2270 * have assumed that they imply disk space shortage. We don't want to
2271 * waste CPU cycles adding up the total size here, so we'll just set
2272 * it for all successful writes in case such a caller determines that
2273 * the write was short and ereports "%m".
2274 */
2275 errno = ENOSPC;
2276
2277 /*
2278 * Maintain fileSize and temporary_files_size if it's a temp file.
2279 */
2280 if (vfdP->fdstate & FD_TEMP_FILE_LIMIT)
2281 {
2282 off_t past_write = offset + returnCode;
2283
2284 if (past_write > vfdP->fileSize)
2285 {
2286 temporary_files_size += past_write - vfdP->fileSize;
2287 vfdP->fileSize = past_write;
2288 }
2289 }
2290 }
2291 else
2292 {
2293 /*
2294 * See comments in FileReadV()
2295 */
2296#ifdef WIN32
2297 DWORD error = GetLastError();
2298
2299 switch (error)
2300 {
2301 case ERROR_NO_SYSTEM_RESOURCES:
2302 pg_usleep(1000L);
2303 errno = EINTR;
2304 break;
2305 default:
2307 break;
2308 }
2309#endif
2310 /* OK to retry if interrupted */
2311 if (errno == EINTR)
2312 goto retry;
2313 }
2314
2315 return returnCode;
2316}
uint64_t uint64
Definition: c.h:489
int temp_file_limit
Definition: guc_tables.c:533
static ssize_t pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
Definition: pg_iovec.h:83

References _dosmaperr(), Assert, DO_DB, EINTR, elog, ereport, errcode(), errmsg(), ERROR, error(), vfd::fd, FD_TEMP_FILE_LIMIT, vfd::fdstate, FileAccess(), FileIsValid, vfd::fileSize, i, INT64_FORMAT, LOG, pg_pwritev(), pg_usleep(), pgstat_report_wait_end(), pgstat_report_wait_start(), temp_file_limit, temporary_files_size, and VfdCache.

Referenced by FileWrite(), and mdwritev().

◆ FileZero()

int FileZero ( File  file,
off_t  offset,
off_t  amount,
uint32  wait_event_info 
)

Definition at line 2346 of file fd.c.

2347{
2348 int returnCode;
2349 ssize_t written;
2350
2351 Assert(FileIsValid(file));
2352
2353 DO_DB(elog(LOG, "FileZero: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
2354 file, VfdCache[file].fileName,
2355 (int64) offset, (int64) amount));
2356
2357 returnCode = FileAccess(file);
2358 if (returnCode < 0)
2359 return returnCode;
2360
2361 pgstat_report_wait_start(wait_event_info);
2362 written = pg_pwrite_zeros(VfdCache[file].fd, amount, offset);
2364
2365 if (written < 0)
2366 return -1;
2367 else if (written != amount)
2368 {
2369 /* if errno is unset, assume problem is no disk space */
2370 if (errno == 0)
2371 errno = ENOSPC;
2372 return -1;
2373 }
2374
2375 return 0;
2376}
ssize_t pg_pwrite_zeros(int fd, size_t size, off_t offset)
Definition: file_utils.c:688

References Assert, DO_DB, elog, fd(), FileAccess(), FileIsValid, INT64_FORMAT, LOG, pg_pwrite_zeros(), pgstat_report_wait_end(), pgstat_report_wait_start(), and VfdCache.

Referenced by FileFallocate(), and mdzeroextend().

◆ FreeDesc()

static int FreeDesc ( AllocateDesc desc)
static

Definition at line 2764 of file fd.c.

2765{
2766 int result;
2767
2768 /* Close the underlying object */
2769 switch (desc->kind)
2770 {
2771 case AllocateDescFile:
2772 result = fclose(desc->desc.file);
2773 break;
2774 case AllocateDescPipe:
2775 result = pclose(desc->desc.file);
2776 break;
2777 case AllocateDescDir:
2778 result = closedir(desc->desc.dir);
2779 break;
2780 case AllocateDescRawFD:
2781 result = close(desc->desc.fd);
2782 break;
2783 default:
2784 elog(ERROR, "AllocateDesc kind not recognized");
2785 result = 0; /* keep compiler quiet */
2786 break;
2787 }
2788
2789 /* Compact storage in the allocatedDescs array */
2792
2793 return result;
2794}
int closedir(DIR *)
Definition: dirent.c:127

References allocatedDescs, AllocateDescDir, AllocateDescFile, AllocateDescPipe, AllocateDescRawFD, close, closedir(), AllocateDesc::desc, AllocateDesc::dir, elog, ERROR, AllocateDesc::fd, AllocateDesc::file, AllocateDesc::kind, and numAllocatedDescs.

Referenced by AtEOSubXact_Files(), CleanupTempFiles(), ClosePipeStream(), CloseTransientFile(), FreeDir(), and FreeFile().

◆ FreeDir()

int FreeDir ( DIR dir)

Definition at line 2983 of file fd.c.

2984{
2985 int i;
2986
2987 /* Nothing to do if AllocateDir failed */
2988 if (dir == NULL)
2989 return 0;
2990
2991 DO_DB(elog(LOG, "FreeDir: Allocated %d", numAllocatedDescs));
2992
2993 /* Remove dir from list of allocated dirs, if it's present */
2994 for (i = numAllocatedDescs; --i >= 0;)
2995 {
2996 AllocateDesc *desc = &allocatedDescs[i];
2997
2998 if (desc->kind == AllocateDescDir && desc->desc.dir == dir)
2999 return FreeDesc(desc);
3000 }
3001
3002 /* Only get here if someone passes us a dir not in allocatedDescs */
3003 elog(WARNING, "dir passed to FreeDir was not obtained from AllocateDir");
3004
3005 return closedir(dir);
3006}

References allocatedDescs, AllocateDescDir, closedir(), AllocateDesc::desc, AllocateDesc::dir, DO_DB, elog, FreeDesc(), i, AllocateDesc::kind, LOG, numAllocatedDescs, and WARNING.

Referenced by calculate_database_size(), calculate_tablespace_size(), CheckPointLogicalRewriteHeap(), CheckPointSnapBuild(), CleanupBackupHistory(), copydir(), db_dir_size(), DeleteAllExportedSnapshotFiles(), destroy_tablespace_directories(), directory_is_empty(), do_pg_backup_start(), dsm_cleanup_for_mmap(), extension_file_exists(), get_ext_ver_list(), GetConfFilesInDir(), getInstallationPaths(), GetWalSummaries(), movedb(), ParseTzFile(), perform_base_backup(), pg_available_extension_versions(), pg_available_extensions(), pg_ls_dir(), pg_ls_dir_files(), pg_tablespace_databases(), pg_tzenumerate_end(), pg_tzenumerate_next(), pgarch_readyXlog(), RelationCacheInitFileRemove(), RelationCacheInitFileRemoveInDir(), RemoveNonParentXlogFiles(), RemoveOldXlogFiles(), RemovePgTempFiles(), RemovePgTempFilesInDir(), RemovePgTempRelationFiles(), RemovePgTempRelationFilesInDbspace(), RemoveTempXlogFiles(), ReorderBufferCleanupSerializedTXNs(), ResetUnloggedRelations(), ResetUnloggedRelationsInDbspaceDir(), ResetUnloggedRelationsInTablespaceDir(), restoreTwoPhaseData(), scan_directory_ci(), sendDir(), SlruScanDirectory(), StartupReorderBuffer(), StartupReplicationSlots(), SyncDataDirectory(), UpdateLogicalMappings(), walkdir(), and XLogGetOldestSegno().

◆ FreeFile()

int FreeFile ( FILE *  file)

Definition at line 2803 of file fd.c.

2804{
2805 int i;
2806
2807 DO_DB(elog(LOG, "FreeFile: Allocated %d", numAllocatedDescs));
2808
2809 /* Remove file from list of allocated files, if it's present */
2810 for (i = numAllocatedDescs; --i >= 0;)
2811 {
2812 AllocateDesc *desc = &allocatedDescs[i];
2813
2814 if (desc->kind == AllocateDescFile && desc->desc.file == file)
2815 return FreeDesc(desc);
2816 }
2817
2818 /* Only get here if someone passes us a file not in allocatedDescs */
2819 elog(WARNING, "file passed to FreeFile was not obtained from AllocateFile");
2820
2821 return fclose(file);
2822}

References allocatedDescs, AllocateDescFile, AllocateDesc::desc, DO_DB, elog, AllocateDesc::file, FreeDesc(), i, AllocateDesc::kind, LOG, numAllocatedDescs, and WARNING.

Referenced by AlterSystemSetConfigFile(), apw_dump_now(), apw_load_buffers(), checkControlFile(), do_pg_backup_stop(), EndCopy(), EndCopyFrom(), entry_reset(), existsTimeLineHistory(), ExportSnapshot(), free_auth_file(), gc_qtexts(), GetHugePageSize(), ImportSnapshot(), load_dh_file(), load_relcache_init_file(), parse_extension_control_file(), ParseConfigFile(), ParseTzFile(), pg_current_logfile(), pg_promote(), pgss_shmem_shutdown(), pgss_shmem_startup(), pgstat_read_statsfile(), pgstat_write_statsfile(), read_backup_label(), read_binary_file(), read_tablespace_map(), read_whole_file(), readTimeLineHistory(), tsearch_readline_end(), ValidatePgVersion(), write_relcache_init_file(), XLogArchiveForceDone(), and XLogArchiveNotify().

◆ FreeVfd()

static void FreeVfd ( File  file)
static

Definition at line 1471 of file fd.c.

1472{
1473 Vfd *vfdP = &VfdCache[file];
1474
1475 DO_DB(elog(LOG, "FreeVfd: %d (%s)",
1476 file, vfdP->fileName ? vfdP->fileName : ""));
1477
1478 if (vfdP->fileName != NULL)
1479 {
1480 free(vfdP->fileName);
1481 vfdP->fileName = NULL;
1482 }
1483 vfdP->fdstate = 0x0;
1484
1485 vfdP->nextFree = VfdCache[0].nextFree;
1486 VfdCache[0].nextFree = file;
1487}
#define free(a)
Definition: header.h:65

References DO_DB, elog, vfd::fdstate, vfd::fileName, free, LOG, vfd::nextFree, and VfdCache.

Referenced by FileClose(), and PathNameOpenFilePerm().

◆ fsync_fname()

◆ fsync_fname_ext()

int fsync_fname_ext ( const char *  fname,
bool  isdir,
bool  ignore_perm,
int  elevel 
)

Definition at line 3820 of file fd.c.

3821{
3822 int fd;
3823 int flags;
3824 int returncode;
3825
3826 /*
3827 * Some OSs require directories to be opened read-only whereas other
3828 * systems don't allow us to fsync files opened read-only; so we need both
3829 * cases here. Using O_RDWR will cause us to fail to fsync files that are
3830 * not writable by our userid, but we assume that's OK.
3831 */
3832 flags = PG_BINARY;
3833 if (!isdir)
3834 flags |= O_RDWR;
3835 else
3836 flags |= O_RDONLY;
3837
3838 fd = OpenTransientFile(fname, flags);
3839
3840 /*
3841 * Some OSs don't allow us to open directories at all (Windows returns
3842 * EACCES), just ignore the error in that case. If desired also silently
3843 * ignoring errors about unreadable files. Log others.
3844 */
3845 if (fd < 0 && isdir && (errno == EISDIR || errno == EACCES))
3846 return 0;
3847 else if (fd < 0 && ignore_perm && errno == EACCES)
3848 return 0;
3849 else if (fd < 0)
3850 {
3851 ereport(elevel,
3853 errmsg("could not open file \"%s\": %m", fname)));
3854 return -1;
3855 }
3856
3857 returncode = pg_fsync(fd);
3858
3859 /*
3860 * Some OSes don't allow us to fsync directories at all, so we can ignore
3861 * those errors. Anything else needs to be logged.
3862 */
3863 if (returncode != 0 && !(isdir && (errno == EBADF || errno == EINVAL)))
3864 {
3865 int save_errno;
3866
3867 /* close file upon error, might not be in transaction context */
3868 save_errno = errno;
3869 (void) CloseTransientFile(fd);
3870 errno = save_errno;
3871
3872 ereport(elevel,
3874 errmsg("could not fsync file \"%s\": %m", fname)));
3875 return -1;
3876 }
3877
3878 if (CloseTransientFile(fd) != 0)
3879 {
3880 ereport(elevel,
3882 errmsg("could not close file \"%s\": %m", fname)));
3883 return -1;
3884 }
3885
3886 return 0;
3887}

References CloseTransientFile(), ereport, errcode_for_file_access(), errmsg(), fd(), OpenTransientFile(), PG_BINARY, and pg_fsync().

Referenced by datadir_fsync_fname(), durable_rename(), fsync_fname(), and fsync_parent_path().

◆ fsync_parent_path()

static int fsync_parent_path ( const char *  fname,
int  elevel 
)
static

Definition at line 3896 of file fd.c.

3897{
3898 char parentpath[MAXPGPATH];
3899
3900 strlcpy(parentpath, fname, MAXPGPATH);
3901 get_parent_directory(parentpath);
3902
3903 /*
3904 * get_parent_directory() returns an empty string if the input argument is
3905 * just a file name (see comments in path.c), so handle that as being the
3906 * current directory.
3907 */
3908 if (strlen(parentpath) == 0)
3909 strlcpy(parentpath, ".", MAXPGPATH);
3910
3911 if (fsync_fname_ext(parentpath, true, false, elevel) != 0)
3912 return -1;
3913
3914 return 0;
3915}
#define MAXPGPATH
void get_parent_directory(char *path)
Definition: path.c:1068
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45

References fsync_fname_ext(), get_parent_directory(), MAXPGPATH, and strlcpy().

Referenced by dir_close(), dir_open_for_write(), durable_rename(), durable_unlink(), and tar_finish().

◆ GetNextTempTableSpace()

Oid GetNextTempTableSpace ( void  )

Definition at line 3133 of file fd.c.

3134{
3135 if (numTempTableSpaces > 0)
3136 {
3137 /* Advance nextTempTableSpace counter with wraparound */
3141 }
3142 return InvalidOid;
3143}
static int nextTempTableSpace
Definition: fd.c:289
#define InvalidOid
Definition: postgres_ext.h:37

References InvalidOid, nextTempTableSpace, numTempTableSpaces, and tempTableSpaces.

Referenced by GetDefaultTablespace(), and OpenTemporaryFile().

◆ GetTempTablespaces()

int GetTempTablespaces ( Oid tableSpaces,
int  numSpaces 
)

Definition at line 3115 of file fd.c.

3116{
3117 int i;
3118
3120 for (i = 0; i < numTempTableSpaces && i < numSpaces; ++i)
3121 tableSpaces[i] = tempTableSpaces[i];
3122
3123 return i;
3124}
bool TempTablespacesAreSet(void)
Definition: fd.c:3100

References Assert, i, numTempTableSpaces, tempTableSpaces, and TempTablespacesAreSet().

Referenced by FileSetInit().

◆ InitFileAccess()

void InitFileAccess ( void  )

Definition at line 902 of file fd.c.

903{
904 Assert(SizeVfdCache == 0); /* call me only once */
905
906 /* initialize cache header entry */
907 VfdCache = (Vfd *) malloc(sizeof(Vfd));
908 if (VfdCache == NULL)
910 (errcode(ERRCODE_OUT_OF_MEMORY),
911 errmsg("out of memory")));
912
913 MemSet(&(VfdCache[0]), 0, sizeof(Vfd));
915
916 SizeVfdCache = 1;
917}
#define FATAL
Definition: elog.h:41
#define malloc(a)
Definition: header.h:50

References Assert, ereport, errcode(), errmsg(), FATAL, vfd::fd, malloc, MemSet, SizeVfdCache, VFD_CLOSED, and VfdCache.

Referenced by BaseInit().

◆ InitTemporaryFileAccess()

void InitTemporaryFileAccess ( void  )

Definition at line 932 of file fd.c.

933{
934 Assert(SizeVfdCache != 0); /* InitFileAccess() needs to have run */
935 Assert(!temporary_files_allowed); /* call me only once */
936
937 /*
938 * Register before-shmem-exit hook to ensure temp files are dropped while
939 * we can still report stats.
940 */
942
943#ifdef USE_ASSERT_CHECKING
944 temporary_files_allowed = true;
945#endif
946}
static void BeforeShmemExit_Files(int code, Datum arg)
Definition: fd.c:3201
void before_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:337

References Assert, before_shmem_exit(), BeforeShmemExit_Files(), and SizeVfdCache.

Referenced by BaseInit().

◆ Insert()

static void Insert ( File  file)
static

Definition at line 1312 of file fd.c.

1313{
1314 Vfd *vfdP;
1315
1316 Assert(file != 0);
1317
1318 DO_DB(elog(LOG, "Insert %d (%s)",
1319 file, VfdCache[file].fileName));
1320 DO_DB(_dump_lru());
1321
1322 vfdP = &VfdCache[file];
1323
1324 vfdP->lruMoreRecently = 0;
1326 VfdCache[0].lruLessRecently = file;
1328
1329 DO_DB(_dump_lru());
1330}

References Assert, DO_DB, elog, LOG, vfd::lruLessRecently, vfd::lruMoreRecently, and VfdCache.

Referenced by AdvanceXLInsertBuffer(), CreateCheckPoint(), FileAccess(), GetXLogInsertRecPtr(), LruInsert(), PathNameOpenFilePerm(), ReserveXLogInsertLocation(), ReserveXLogSwitch(), StartupXLOG(), UpdateFullPageWrites(), WaitXLogInsertionsToFinish(), XLogInsertRecord(), and XLogWrite().

◆ looks_like_temp_rel_name()

bool looks_like_temp_rel_name ( const char *  name)

Definition at line 3472 of file fd.c.

3473{
3474 int pos;
3475 int savepos;
3476
3477 /* Must start with "t". */
3478 if (name[0] != 't')
3479 return false;
3480
3481 /* Followed by a non-empty string of digits and then an underscore. */
3482 for (pos = 1; isdigit((unsigned char) name[pos]); ++pos)
3483 ;
3484 if (pos == 1 || name[pos] != '_')
3485 return false;
3486
3487 /* Followed by another nonempty string of digits. */
3488 for (savepos = ++pos; isdigit((unsigned char) name[pos]); ++pos)
3489 ;
3490 if (savepos == pos)
3491 return false;
3492
3493 /* We might have _forkname or .segment or both. */
3494 if (name[pos] == '_')
3495 {
3496 int forkchar = forkname_chars(&name[pos + 1], NULL);
3497
3498 if (forkchar <= 0)
3499 return false;
3500 pos += forkchar + 1;
3501 }
3502 if (name[pos] == '.')
3503 {
3504 int segchar;
3505
3506 for (segchar = 1; isdigit((unsigned char) name[pos + segchar]); ++segchar)
3507 ;
3508 if (segchar <= 1)
3509 return false;
3510 pos += segchar;
3511 }
3512
3513 /* Now we should be at the end. */
3514 if (name[pos] != '\0')
3515 return false;
3516 return true;
3517}
int forkname_chars(const char *str, ForkNumber *fork)
Definition: relpath.c:81

References forkname_chars(), and name.

Referenced by RemovePgTempRelationFilesInDbspace(), and sendDir().

◆ LruDelete()

static void LruDelete ( File  file)
static

Definition at line 1286 of file fd.c.

1287{
1288 Vfd *vfdP;
1289
1290 Assert(file != 0);
1291
1292 DO_DB(elog(LOG, "LruDelete %d (%s)",
1293 file, VfdCache[file].fileName));
1294
1295 vfdP = &VfdCache[file];
1296
1297 /*
1298 * Close the file. We aren't expecting this to fail; if it does, better
1299 * to leak the FD than to mess up our internal state.
1300 */
1301 if (close(vfdP->fd) != 0)
1303 "could not close file \"%s\": %m", vfdP->fileName);
1304 vfdP->fd = VFD_CLOSED;
1305 --nfile;
1306
1307 /* delete the vfd record from the LRU ring */
1308 Delete(file);
1309}

References Assert, close, data_sync_elevel(), Delete(), DO_DB, elog, vfd::fd, FD_TEMP_FILE_LIMIT, vfd::fdstate, vfd::fileName, LOG, nfile, VFD_CLOSED, and VfdCache.

Referenced by closeAllVfds(), and ReleaseLruFile().

◆ LruInsert()

static int LruInsert ( File  file)
static

Definition at line 1334 of file fd.c.

1335{
1336 Vfd *vfdP;
1337
1338 Assert(file != 0);
1339
1340 DO_DB(elog(LOG, "LruInsert %d (%s)",
1341 file, VfdCache[file].fileName));
1342
1343 vfdP = &VfdCache[file];
1344
1345 if (FileIsNotOpen(file))
1346 {
1347 /* Close excess kernel FDs. */
1349
1350 /*
1351 * The open could still fail for lack of file descriptors, eg due to
1352 * overall system file table being full. So, be prepared to release
1353 * another FD if necessary...
1354 */
1355 vfdP->fd = BasicOpenFilePerm(vfdP->fileName, vfdP->fileFlags,
1356 vfdP->fileMode);
1357 if (vfdP->fd < 0)
1358 {
1359 DO_DB(elog(LOG, "re-open failed: %m"));
1360 return -1;
1361 }
1362 else
1363 {
1364 ++nfile;
1365 }
1366 }
1367
1368 /*
1369 * put it at the head of the Lru ring
1370 */
1371
1372 Insert(file);
1373
1374 return 0;
1375}

References Assert, BasicOpenFilePerm(), DO_DB, elog, vfd::fd, vfd::fileFlags, FileIsNotOpen, vfd::fileMode, vfd::fileName, Insert(), LOG, nfile, ReleaseLruFiles(), and VfdCache.

Referenced by FileAccess().

◆ MakePGDirectory()

int MakePGDirectory ( const char *  directoryName)

◆ OpenPipeStream()

FILE * OpenPipeStream ( const char *  command,
const char *  mode 
)

Definition at line 2708 of file fd.c.

2709{
2710 FILE *file;
2711 int save_errno;
2712
2713 DO_DB(elog(LOG, "OpenPipeStream: Allocated %d (%s)",
2714 numAllocatedDescs, command));
2715
2716 /* Can we allocate another non-virtual FD? */
2717 if (!reserveAllocatedDesc())
2718 ereport(ERROR,
2719 (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2720 errmsg("exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"",
2721 maxAllocatedDescs, command)));
2722
2723 /* Close excess kernel FDs. */
2725
2726TryAgain:
2727 fflush(NULL);
2728 pqsignal(SIGPIPE, SIG_DFL);
2729 errno = 0;
2730 file = popen(command, mode);
2731 save_errno = errno;
2732 pqsignal(SIGPIPE, SIG_IGN);
2733 errno = save_errno;
2734 if (file != NULL)
2735 {
2737
2738 desc->kind = AllocateDescPipe;
2739 desc->desc.file = file;
2742 return desc->desc.file;
2743 }
2744
2745 if (errno == EMFILE || errno == ENFILE)
2746 {
2747 ereport(LOG,
2748 (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2749 errmsg("out of file descriptors: %m; release and retry")));
2750 if (ReleaseLruFile())
2751 goto TryAgain;
2752 errno = save_errno;
2753 }
2754
2755 return NULL;
2756}
static void const char fflush(stdout)
#define pqsignal
Definition: port.h:521
#define SIGPIPE
Definition: win32_port.h:163

References allocatedDescs, AllocateDescPipe, AllocateDesc::create_subid, AllocateDesc::desc, DO_DB, elog, ereport, errcode(), errmsg(), ERROR, fflush(), AllocateDesc::file, GetCurrentSubTransactionId(), AllocateDesc::kind, LOG, maxAllocatedDescs, mode, numAllocatedDescs, pqsignal, ReleaseLruFile(), ReleaseLruFiles(), reserveAllocatedDesc(), and SIGPIPE.

Referenced by BeginCopyFrom(), BeginCopyTo(), pg_import_system_collations(), run_ssl_passphrase_command(), and shell_run_command().

◆ OpenTemporaryFile()

File OpenTemporaryFile ( bool  interXact)

Definition at line 1723 of file fd.c.

1724{
1725 File file = 0;
1726
1727 Assert(temporary_files_allowed); /* check temp file access is up */
1728
1729 /*
1730 * Make sure the current resource owner has space for this File before we
1731 * open it, if we'll be registering it below.
1732 */
1733 if (!interXact)
1735
1736 /*
1737 * If some temp tablespace(s) have been given to us, try to use the next
1738 * one. If a given tablespace can't be found, we silently fall back to
1739 * the database's default tablespace.
1740 *
1741 * BUT: if the temp file is slated to outlive the current transaction,
1742 * force it into the database's default tablespace, so that it will not
1743 * pose a threat to possible tablespace drop attempts.
1744 */
1745 if (numTempTableSpaces > 0 && !interXact)
1746 {
1747 Oid tblspcOid = GetNextTempTableSpace();
1748
1749 if (OidIsValid(tblspcOid))
1750 file = OpenTemporaryFileInTablespace(tblspcOid, false);
1751 }
1752
1753 /*
1754 * If not, or if tablespace is bad, create in database's default
1755 * tablespace. MyDatabaseTableSpace should normally be set before we get
1756 * here, but just in case it isn't, fall back to pg_default tablespace.
1757 */
1758 if (file <= 0)
1761 DEFAULTTABLESPACE_OID,
1762 true);
1763
1764 /* Mark it for deletion at close and temporary file size limit */
1766
1767 /* Register it with the current resource owner */
1768 if (!interXact)
1770
1771 return file;
1772}
#define OidIsValid(objectId)
Definition: c.h:732
Oid GetNextTempTableSpace(void)
Definition: fd.c:3133
static File OpenTemporaryFileInTablespace(Oid tblspcOid, bool rejectError)
Definition: fd.c:1803
static void RegisterTemporaryFile(File file)
Definition: fd.c:1546
Oid MyDatabaseTableSpace
Definition: globals.c:95
unsigned int Oid
Definition: postgres_ext.h:32
ResourceOwner CurrentResourceOwner
Definition: resowner.c:165
void ResourceOwnerEnlarge(ResourceOwner owner)
Definition: resowner.c:442

References Assert, CurrentResourceOwner, FD_DELETE_AT_CLOSE, FD_TEMP_FILE_LIMIT, vfd::fdstate, GetNextTempTableSpace(), MyDatabaseTableSpace, numTempTableSpaces, OidIsValid, OpenTemporaryFileInTablespace(), RegisterTemporaryFile(), ResourceOwnerEnlarge(), and VfdCache.

Referenced by BufFileCreateTemp(), and extendBufFile().

◆ OpenTemporaryFileInTablespace()

static File OpenTemporaryFileInTablespace ( Oid  tblspcOid,
bool  rejectError 
)
static

Definition at line 1803 of file fd.c.

1804{
1805 char tempdirpath[MAXPGPATH];
1806 char tempfilepath[MAXPGPATH];
1807 File file;
1808
1809 TempTablespacePath(tempdirpath, tblspcOid);
1810
1811 /*
1812 * Generate a tempfile name that should be unique within the current
1813 * database instance.
1814 */
1815 snprintf(tempfilepath, sizeof(tempfilepath), "%s/%s%d.%ld",
1817
1818 /*
1819 * Open the file. Note: we don't use O_EXCL, in case there is an orphaned
1820 * temp file that can be reused.
1821 */
1822 file = PathNameOpenFile(tempfilepath,
1823 O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1824 if (file <= 0)
1825 {
1826 /*
1827 * We might need to create the tablespace's tempfile directory, if no
1828 * one has yet done so.
1829 *
1830 * Don't check for an error from MakePGDirectory; it could fail if
1831 * someone else just did the same thing. If it doesn't work then
1832 * we'll bomb out on the second create attempt, instead.
1833 */
1834 (void) MakePGDirectory(tempdirpath);
1835
1836 file = PathNameOpenFile(tempfilepath,
1837 O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1838 if (file <= 0 && rejectError)
1839 elog(ERROR, "could not create temporary file \"%s\": %m",
1840 tempfilepath);
1841 }
1842
1843 return file;
1844}
int MakePGDirectory(const char *directoryName)
Definition: fd.c:3936
static long tempFileCounter
Definition: fd.c:279
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1574
void TempTablespacePath(char *path, Oid tablespace)
Definition: fd.c:1778
#define PG_TEMP_FILE_PREFIX
Definition: file_utils.h:63
int MyProcPid
Definition: globals.c:46
#define snprintf
Definition: port.h:239

References elog, ERROR, MakePGDirectory(), MAXPGPATH, MyProcPid, PathNameOpenFile(), PG_BINARY, PG_TEMP_FILE_PREFIX, snprintf, tempFileCounter, and TempTablespacePath().

Referenced by OpenTemporaryFile().

◆ OpenTransientFile()

◆ OpenTransientFilePerm()

int OpenTransientFilePerm ( const char *  fileName,
int  fileFlags,
mode_t  fileMode 
)

Definition at line 2664 of file fd.c.

2665{
2666 int fd;
2667
2668 DO_DB(elog(LOG, "OpenTransientFile: Allocated %d (%s)",
2669 numAllocatedDescs, fileName));
2670
2671 /* Can we allocate another non-virtual FD? */
2672 if (!reserveAllocatedDesc())
2673 ereport(ERROR,
2674 (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2675 errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2676 maxAllocatedDescs, fileName)));
2677
2678 /* Close excess kernel FDs. */
2680
2681 fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
2682
2683 if (fd >= 0)
2684 {
2686
2687 desc->kind = AllocateDescRawFD;
2688 desc->desc.fd = fd;
2691
2692 return fd;
2693 }
2694
2695 return -1; /* failure */
2696}

References allocatedDescs, AllocateDescRawFD, BasicOpenFilePerm(), AllocateDesc::create_subid, AllocateDesc::desc, DO_DB, elog, ereport, errcode(), errmsg(), ERROR, AllocateDesc::fd, fd(), GetCurrentSubTransactionId(), AllocateDesc::kind, LOG, maxAllocatedDescs, numAllocatedDescs, ReleaseLruFiles(), and reserveAllocatedDesc().

Referenced by be_lo_export(), and OpenTransientFile().

◆ PathNameCreateTemporaryDir()

void PathNameCreateTemporaryDir ( const char *  basedir,
const char *  directory 
)

Definition at line 1659 of file fd.c.

1660{
1661 if (MakePGDirectory(directory) < 0)
1662 {
1663 if (errno == EEXIST)
1664 return;
1665
1666 /*
1667 * Failed. Try to create basedir first in case it's missing. Tolerate
1668 * EEXIST to close a race against another process following the same
1669 * algorithm.
1670 */
1671 if (MakePGDirectory(basedir) < 0 && errno != EEXIST)
1672 ereport(ERROR,
1674 errmsg("cannot create temporary directory \"%s\": %m",
1675 basedir)));
1676
1677 /* Try again. */
1678 if (MakePGDirectory(directory) < 0 && errno != EEXIST)
1679 ereport(ERROR,
1681 errmsg("cannot create temporary subdirectory \"%s\": %m",
1682 directory)));
1683 }
1684}
static char * basedir
static const char * directory
Definition: zic.c:634

References basedir, directory, ereport, errcode_for_file_access(), errmsg(), ERROR, and MakePGDirectory().

Referenced by FileSetCreate().

◆ PathNameCreateTemporaryFile()

File PathNameCreateTemporaryFile ( const char *  path,
bool  error_on_failure 
)

Definition at line 1860 of file fd.c.

1861{
1862 File file;
1863
1864 Assert(temporary_files_allowed); /* check temp file access is up */
1865
1867
1868 /*
1869 * Open the file. Note: we don't use O_EXCL, in case there is an orphaned
1870 * temp file that can be reused.
1871 */
1872 file = PathNameOpenFile(path, O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1873 if (file <= 0)
1874 {
1875 if (error_on_failure)
1876 ereport(ERROR,
1878 errmsg("could not create temporary file \"%s\": %m",
1879 path)));
1880 else
1881 return file;
1882 }
1883
1884 /* Mark it for temp_file_limit accounting. */
1886
1887 /* Register it for automatic close. */
1889
1890 return file;
1891}

References Assert, CurrentResourceOwner, ereport, errcode_for_file_access(), errmsg(), ERROR, FD_TEMP_FILE_LIMIT, vfd::fdstate, PathNameOpenFile(), PG_BINARY, RegisterTemporaryFile(), ResourceOwnerEnlarge(), and VfdCache.

Referenced by FileSetCreate().

◆ PathNameDeleteTemporaryDir()

void PathNameDeleteTemporaryDir ( const char *  dirname)

Definition at line 1690 of file fd.c.

1691{
1692 struct stat statbuf;
1693
1694 /* Silently ignore missing directory. */
1695 if (stat(dirname, &statbuf) != 0 && errno == ENOENT)
1696 return;
1697
1698 /*
1699 * Currently, walkdir doesn't offer a way for our passed in function to
1700 * maintain state. Perhaps it should, so that we could tell the caller
1701 * whether this operation succeeded or failed. Since this operation is
1702 * used in a cleanup path, we wouldn't actually behave differently: we'll
1703 * just log failures.
1704 */
1705 walkdir(dirname, unlink_if_exists_fname, false, LOG);
1706}
static void unlink_if_exists_fname(const char *fname, bool isdir, int elevel)
Definition: fd.c:3795
static void walkdir(const char *path, void(*action)(const char *fname, bool isdir, int elevel), bool process_symlinks, int elevel)
Definition: fd.c:3681

References LOG, stat, unlink_if_exists_fname(), and walkdir().

Referenced by FileSetDeleteAll().

◆ PathNameDeleteTemporaryFile()

bool PathNameDeleteTemporaryFile ( const char *  path,
bool  error_on_failure 
)

Definition at line 1931 of file fd.c.

1932{
1933 struct stat filestats;
1934 int stat_errno;
1935
1936 /* Get the final size for pgstat reporting. */
1937 if (stat(path, &filestats) != 0)
1938 stat_errno = errno;
1939 else
1940 stat_errno = 0;
1941
1942 /*
1943 * Unlike FileClose's automatic file deletion code, we tolerate
1944 * non-existence to support BufFileDeleteFileSet which doesn't know how
1945 * many segments it has to delete until it runs out.
1946 */
1947 if (stat_errno == ENOENT)
1948 return false;
1949
1950 if (unlink(path) < 0)
1951 {
1952 if (errno != ENOENT)
1953 ereport(error_on_failure ? ERROR : LOG,
1955 errmsg("could not unlink temporary file \"%s\": %m",
1956 path)));
1957 return false;
1958 }
1959
1960 if (stat_errno == 0)
1961 ReportTemporaryFileUsage(path, filestats.st_size);
1962 else
1963 {
1964 errno = stat_errno;
1965 ereport(LOG,
1967 errmsg("could not stat file \"%s\": %m", path)));
1968 }
1969
1970 return true;
1971}

References ereport, errcode_for_file_access(), errmsg(), ERROR, LOG, ReportTemporaryFileUsage(), stat::st_size, and stat.

Referenced by FileSetDelete(), and unlink_if_exists_fname().

◆ PathNameOpenFile()

File PathNameOpenFile ( const char *  fileName,
int  fileFlags 
)

◆ PathNameOpenFilePerm()

File PathNameOpenFilePerm ( const char *  fileName,
int  fileFlags,
mode_t  fileMode 
)

Definition at line 1587 of file fd.c.

1588{
1589 char *fnamecopy;
1590 File file;
1591 Vfd *vfdP;
1592
1593 DO_DB(elog(LOG, "PathNameOpenFilePerm: %s %x %o",
1594 fileName, fileFlags, fileMode));
1595
1596 /*
1597 * We need a malloc'd copy of the file name; fail cleanly if no room.
1598 */
1599 fnamecopy = strdup(fileName);
1600 if (fnamecopy == NULL)
1601 ereport(ERROR,
1602 (errcode(ERRCODE_OUT_OF_MEMORY),
1603 errmsg("out of memory")));
1604
1605 file = AllocateVfd();
1606 vfdP = &VfdCache[file];
1607
1608 /* Close excess kernel FDs. */
1610
1611 /*
1612 * Descriptors managed by VFDs are implicitly marked O_CLOEXEC. The
1613 * client shouldn't be expected to know which kernel descriptors are
1614 * currently open, so it wouldn't make sense for them to be inherited by
1615 * executed subprograms.
1616 */
1617 fileFlags |= O_CLOEXEC;
1618
1619 vfdP->fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
1620
1621 if (vfdP->fd < 0)
1622 {
1623 int save_errno = errno;
1624
1625 FreeVfd(file);
1626 free(fnamecopy);
1627 errno = save_errno;
1628 return -1;
1629 }
1630 ++nfile;
1631 DO_DB(elog(LOG, "PathNameOpenFile: success %d",
1632 vfdP->fd));
1633
1634 vfdP->fileName = fnamecopy;
1635 /* Saved flags are adjusted to be OK for re-opening file */
1636 vfdP->fileFlags = fileFlags & ~(O_CREAT | O_TRUNC | O_EXCL);
1637 vfdP->fileMode = fileMode;
1638 vfdP->fileSize = 0;
1639 vfdP->fdstate = 0x0;
1640 vfdP->resowner = NULL;
1641
1642 Insert(file);
1643
1644 return file;
1645}
static File AllocateVfd(void)
Definition: fd.c:1413

References AllocateVfd(), BasicOpenFilePerm(), DO_DB, elog, ereport, errcode(), errmsg(), ERROR, vfd::fd, vfd::fdstate, vfd::fileFlags, vfd::fileMode, vfd::fileName, vfd::fileSize, free, FreeVfd(), Insert(), LOG, nfile, O_CLOEXEC, ReleaseLruFiles(), vfd::resowner, and VfdCache.

Referenced by PathNameOpenFile().

◆ PathNameOpenTemporaryFile()

File PathNameOpenTemporaryFile ( const char *  path,
int  mode 
)

Definition at line 1900 of file fd.c.

1901{
1902 File file;
1903
1904 Assert(temporary_files_allowed); /* check temp file access is up */
1905
1907
1908 file = PathNameOpenFile(path, mode | PG_BINARY);
1909
1910 /* If no such file, then we don't raise an error. */
1911 if (file <= 0 && errno != ENOENT)
1912 ereport(ERROR,
1914 errmsg("could not open temporary file \"%s\": %m",
1915 path)));
1916
1917 if (file > 0)
1918 {
1919 /* Register it for automatic close. */
1921 }
1922
1923 return file;
1924}

References Assert, CurrentResourceOwner, ereport, errcode_for_file_access(), errmsg(), ERROR, mode, PathNameOpenFile(), PG_BINARY, RegisterTemporaryFile(), and ResourceOwnerEnlarge().

Referenced by FileSetOpen().

◆ pg_fdatasync()

int pg_fdatasync ( int  fd)

Definition at line 479 of file fd.c.

480{
481 int rc;
482
483 if (!enableFsync)
484 return 0;
485
486retry:
487 rc = fdatasync(fd);
488
489 if (rc == -1 && errno == EINTR)
490 goto retry;
491
492 return rc;
493}
int fdatasync(int fildes)
bool enableFsync
Definition: globals.c:128

References EINTR, enableFsync, fd(), and fdatasync().

Referenced by issue_xlog_fsync().

◆ pg_file_exists()

bool pg_file_exists ( const char *  name)

Definition at line 502 of file fd.c.

503{
504 struct stat st;
505
506 Assert(name != NULL);
507
508 if (stat(name, &st) == 0)
509 return !S_ISDIR(st.st_mode);
510 else if (!(errno == ENOENT || errno == ENOTDIR || errno == EACCES))
513 errmsg("could not access file \"%s\": %m", name)));
514
515 return false;
516}
#define S_ISDIR(m)
Definition: win32_port.h:315

References Assert, ereport, errcode_for_file_access(), errmsg(), ERROR, name, S_ISDIR, stat::st_mode, and stat.

Referenced by expand_dynamic_library_name(), find_in_dynamic_libpath(), and provider_init().

◆ pg_flush_data()

void pg_flush_data ( int  fd,
off_t  offset,
off_t  nbytes 
)

Definition at line 524 of file fd.c.

525{
526 /*
527 * Right now file flushing is primarily used to avoid making later
528 * fsync()/fdatasync() calls have less impact. Thus don't trigger flushes
529 * if fsyncs are disabled - that's a decision we might want to make
530 * configurable at some point.
531 */
532 if (!enableFsync)
533 return;
534
535 /*
536 * We compile all alternatives that are supported on the current platform,
537 * to find portability problems more easily.
538 */
539#if defined(HAVE_SYNC_FILE_RANGE)
540 {
541 int rc;
542 static bool not_implemented_by_kernel = false;
543
544 if (not_implemented_by_kernel)
545 return;
546
547retry:
548
549 /*
550 * sync_file_range(SYNC_FILE_RANGE_WRITE), currently linux specific,
551 * tells the OS that writeback for the specified blocks should be
552 * started, but that we don't want to wait for completion. Note that
553 * this call might block if too much dirty data exists in the range.
554 * This is the preferable method on OSs supporting it, as it works
555 * reliably when available (contrast to msync()) and doesn't flush out
556 * clean data (like FADV_DONTNEED).
557 */
558 rc = sync_file_range(fd, offset, nbytes,
559 SYNC_FILE_RANGE_WRITE);
560 if (rc != 0)
561 {
562 int elevel;
563
564 if (rc == EINTR)
565 goto retry;
566
567 /*
568 * For systems that don't have an implementation of
569 * sync_file_range() such as Windows WSL, generate only one
570 * warning and then suppress all further attempts by this process.
571 */
572 if (errno == ENOSYS)
573 {
574 elevel = WARNING;
575 not_implemented_by_kernel = true;
576 }
577 else
578 elevel = data_sync_elevel(WARNING);
579
580 ereport(elevel,
582 errmsg("could not flush dirty data: %m")));
583 }
584
585 return;
586 }
587#endif
588#if !defined(WIN32) && defined(MS_ASYNC)
589 {
590 void *p;
591 static int pagesize = 0;
592
593 /*
594 * On several OSs msync(MS_ASYNC) on a mmap'ed file triggers
595 * writeback. On linux it only does so if MS_SYNC is specified, but
596 * then it does the writeback synchronously. Luckily all common linux
597 * systems have sync_file_range(). This is preferable over
598 * FADV_DONTNEED because it doesn't flush out clean data.
599 *
600 * We map the file (mmap()), tell the kernel to sync back the contents
601 * (msync()), and then remove the mapping again (munmap()).
602 */
603
604 /* mmap() needs actual length if we want to map whole file */
605 if (offset == 0 && nbytes == 0)
606 {
607 nbytes = lseek(fd, 0, SEEK_END);
608 if (nbytes < 0)
609 {
612 errmsg("could not determine dirty data size: %m")));
613 return;
614 }
615 }
616
617 /*
618 * Some platforms reject partial-page mmap() attempts. To deal with
619 * that, just truncate the request to a page boundary. If any extra
620 * bytes don't get flushed, well, it's only a hint anyway.
621 */
622
623 /* fetch pagesize only once */
624 if (pagesize == 0)
625 pagesize = sysconf(_SC_PAGESIZE);
626
627 /* align length to pagesize, dropping any fractional page */
628 if (pagesize > 0)
629 nbytes = (nbytes / pagesize) * pagesize;
630
631 /* fractional-page request is a no-op */
632 if (nbytes <= 0)
633 return;
634
635 /*
636 * mmap could well fail, particularly on 32-bit platforms where there
637 * may simply not be enough address space. If so, silently fall
638 * through to the next implementation.
639 */
640 if (nbytes <= (off_t) SSIZE_MAX)
641 p = mmap(NULL, nbytes, PROT_READ, MAP_SHARED, fd, offset);
642 else
643 p = MAP_FAILED;
644
645 if (p != MAP_FAILED)
646 {
647 int rc;
648
649 rc = msync(p, (size_t) nbytes, MS_ASYNC);
650 if (rc != 0)
651 {
654 errmsg("could not flush dirty data: %m")));
655 /* NB: need to fall through to munmap()! */
656 }
657
658 rc = munmap(p, (size_t) nbytes);
659 if (rc != 0)
660 {
661 /* FATAL error because mapping would remain */
664 errmsg("could not munmap() while flushing data: %m")));
665 }
666
667 return;
668 }
669 }
670#endif
671#if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED)
672 {
673 int rc;
674
675 /*
676 * Signal the kernel that the passed in range should not be cached
677 * anymore. This has the, desired, side effect of writing out dirty
678 * data, and the, undesired, side effect of likely discarding useful
679 * clean cached blocks. For the latter reason this is the least
680 * preferable method.
681 */
682
683 rc = posix_fadvise(fd, offset, nbytes, POSIX_FADV_DONTNEED);
684
685 if (rc != 0)
686 {
687 /* don't error out, this is just a performance optimization */
690 errmsg("could not flush dirty data: %m")));
691 }
692
693 return;
694 }
695#endif
696}
#define MAP_FAILED
Definition: mem.h:45

References data_sync_elevel(), EINTR, enableFsync, ereport, errcode_for_file_access(), errmsg(), FATAL, fd(), MAP_FAILED, and WARNING.

Referenced by copy_file(), and FileWriteback().

◆ pg_fsync()

int pg_fsync ( int  fd)

Definition at line 385 of file fd.c.

386{
387#if !defined(WIN32) && defined(USE_ASSERT_CHECKING)
388 struct stat st;
389
390 /*
391 * Some operating system implementations of fsync() have requirements
392 * about the file access modes that were used when their file descriptor
393 * argument was opened, and these requirements differ depending on whether
394 * the file descriptor is for a directory.
395 *
396 * For any file descriptor that may eventually be handed to fsync(), we
397 * should have opened it with access modes that are compatible with
398 * fsync() on all supported systems, otherwise the code may not be
399 * portable, even if it runs ok on the current system.
400 *
401 * We assert here that a descriptor for a file was opened with write
402 * permissions (either O_RDWR or O_WRONLY) and for a directory without
403 * write permissions (O_RDONLY).
404 *
405 * Ignore any fstat errors and let the follow-up fsync() do its work.
406 * Doing this sanity check here counts for the case where fsync() is
407 * disabled.
408 */
409 if (fstat(fd, &st) == 0)
410 {
411 int desc_flags = fcntl(fd, F_GETFL);
412
413 /*
414 * O_RDONLY is historically 0, so just make sure that for directories
415 * no write flags are used.
416 */
417 if (S_ISDIR(st.st_mode))
418 Assert((desc_flags & (O_RDWR | O_WRONLY)) == 0);
419 else
420 Assert((desc_flags & (O_RDWR | O_WRONLY)) != 0);
421 }
422 errno = 0;
423#endif
424
425 /* #if is to skip the wal_sync_method test if there's no need for it */
426#if defined(HAVE_FSYNC_WRITETHROUGH)
429 else
430#endif
432}
int pg_fsync_no_writethrough(int fd)
Definition: fd.c:440
int pg_fsync_writethrough(int fd)
Definition: fd.c:460
#define fstat
Definition: win32_port.h:273
int wal_sync_method
Definition: xlog.c:130
@ WAL_SYNC_METHOD_FSYNC_WRITETHROUGH
Definition: xlog.h:27

References Assert, fd(), fstat, pg_fsync_no_writethrough(), pg_fsync_writethrough(), S_ISDIR, stat::st_mode, wal_sync_method, and WAL_SYNC_METHOD_FSYNC_WRITETHROUGH.

Referenced by AddToDataDirLockFile(), assign_wal_sync_method(), BootStrapXLOG(), CheckPointLogicalRewriteHeap(), CreateDirAndVersionFile(), CreateLockFile(), durable_rename(), FileSync(), fsync_fname_ext(), heap_xlog_logical_rewrite(), readRecoverySignalFile(), RecreateTwoPhaseFile(), RestoreSlotFromDisk(), SaveSlotToPath(), SlruPhysicalWritePage(), SlruSyncFileTag(), SnapBuildSerialize(), update_controlfile(), write_auto_conf_file(), WriteControlFile(), writeTimeLineHistory(), writeTimeLineHistoryFile(), XLogFileCopy(), and XLogFileInitInternal().

◆ pg_fsync_no_writethrough()

int pg_fsync_no_writethrough ( int  fd)

Definition at line 440 of file fd.c.

441{
442 int rc;
443
444 if (!enableFsync)
445 return 0;
446
447retry:
448 rc = fsync(fd);
449
450 if (rc == -1 && errno == EINTR)
451 goto retry;
452
453 return rc;
454}
#define fsync(fd)
Definition: win32_port.h:83

References EINTR, enableFsync, fd(), and fsync.

Referenced by issue_xlog_fsync(), and pg_fsync().

◆ pg_fsync_writethrough()

int pg_fsync_writethrough ( int  fd)

Definition at line 460 of file fd.c.

461{
462 if (enableFsync)
463 {
464#if defined(F_FULLFSYNC)
465 return (fcntl(fd, F_FULLFSYNC, 0) == -1) ? -1 : 0;
466#else
467 errno = ENOSYS;
468 return -1;
469#endif
470 }
471 else
472 return 0;
473}

References enableFsync, and fd().

Referenced by issue_xlog_fsync(), pg_fsync(), and test_sync().

◆ pg_ftruncate()

static int pg_ftruncate ( int  fd,
off_t  length 
)
static

Definition at line 702 of file fd.c.

703{
704 int ret;
705
706retry:
707 ret = ftruncate(fd, length);
708
709 if (ret == -1 && errno == EINTR)
710 goto retry;
711
712 return ret;
713}

References EINTR, and fd().

Referenced by FileTruncate(), and pg_truncate().

◆ pg_truncate()

int pg_truncate ( const char *  path,
off_t  length 
)

Definition at line 719 of file fd.c.

720{
721 int ret;
722#ifdef WIN32
723 int save_errno;
724 int fd;
725
726 fd = OpenTransientFile(path, O_RDWR | PG_BINARY);
727 if (fd >= 0)
728 {
729 ret = pg_ftruncate(fd, length);
730 save_errno = errno;
732 errno = save_errno;
733 }
734 else
735 ret = -1;
736#else
737
738retry:
739 ret = truncate(path, length);
740
741 if (ret == -1 && errno == EINTR)
742 goto retry;
743#endif
744
745 return ret;
746}

References CloseTransientFile(), EINTR, fd(), OpenTransientFile(), PG_BINARY, and pg_ftruncate().

Referenced by do_truncate().

◆ ReadDir()

◆ ReadDirExtended()

struct dirent * ReadDirExtended ( DIR dir,
const char *  dirname,
int  elevel 
)

Definition at line 2946 of file fd.c.

2947{
2948 struct dirent *dent;
2949
2950 /* Give a generic message for AllocateDir failure, if caller didn't */
2951 if (dir == NULL)
2952 {
2953 ereport(elevel,
2955 errmsg("could not open directory \"%s\": %m",
2956 dirname)));
2957 return NULL;
2958 }
2959
2960 errno = 0;
2961 if ((dent = readdir(dir)) != NULL)
2962 return dent;
2963
2964 if (errno)
2965 ereport(elevel,
2967 errmsg("could not read directory \"%s\": %m",
2968 dirname)));
2969 return NULL;
2970}
struct dirent * readdir(DIR *)
Definition: dirent.c:78
Definition: dirent.h:10

References ereport, errcode_for_file_access(), errmsg(), and readdir().

Referenced by DeleteAllExportedSnapshotFiles(), ReadDir(), RelationCacheInitFileRemove(), RelationCacheInitFileRemoveInDir(), RemovePgTempFiles(), RemovePgTempFilesInDir(), RemovePgTempRelationFiles(), RemovePgTempRelationFilesInDbspace(), ReorderBufferCleanupSerializedTXNs(), scan_directory_ci(), SyncDataDirectory(), and walkdir().

◆ RegisterTemporaryFile()

static void RegisterTemporaryFile ( File  file)
static

Definition at line 1546 of file fd.c.

1547{
1550
1551 /* Backup mechanism for closing at end of xact. */
1554}
static void ResourceOwnerRememberFile(ResourceOwner owner, File file)
Definition: fd.c:371

References CurrentResourceOwner, FD_CLOSE_AT_EOXACT, vfd::fdstate, have_xact_temporary_files, ResourceOwnerRememberFile(), vfd::resowner, and VfdCache.

Referenced by OpenTemporaryFile(), PathNameCreateTemporaryFile(), and PathNameOpenTemporaryFile().

◆ ReleaseExternalFD()

◆ ReleaseLruFile()

static bool ReleaseLruFile ( void  )
static

Definition at line 1381 of file fd.c.

1382{
1383 DO_DB(elog(LOG, "ReleaseLruFile. Opened %d", nfile));
1384
1385 if (nfile > 0)
1386 {
1387 /*
1388 * There are opened files and so there should be at least one used vfd
1389 * in the ring.
1390 */
1391 Assert(VfdCache[0].lruMoreRecently != 0);
1392 LruDelete(VfdCache[0].lruMoreRecently);
1393 return true; /* freed a file */
1394 }
1395 return false; /* no files available to free */
1396}

References Assert, DO_DB, elog, LOG, LruDelete(), nfile, and VfdCache.

Referenced by AllocateDir(), AllocateFile(), BasicOpenFilePerm(), OpenPipeStream(), and ReleaseLruFiles().

◆ ReleaseLruFiles()

static void ReleaseLruFiles ( void  )
static

◆ RemovePgTempFiles()

void RemovePgTempFiles ( void  )

Definition at line 3296 of file fd.c.

3297{
3298 char temp_path[MAXPGPATH + sizeof(PG_TBLSPC_DIR) + sizeof(TABLESPACE_VERSION_DIRECTORY) + sizeof(PG_TEMP_FILES_DIR)];
3299 DIR *spc_dir;
3300 struct dirent *spc_de;
3301
3302 /*
3303 * First process temp files in pg_default ($PGDATA/base)
3304 */
3305 snprintf(temp_path, sizeof(temp_path), "base/%s", PG_TEMP_FILES_DIR);
3306 RemovePgTempFilesInDir(temp_path, true, false);
3308
3309 /*
3310 * Cycle through temp directories for all non-default tablespaces.
3311 */
3312 spc_dir = AllocateDir(PG_TBLSPC_DIR);
3313
3314 while ((spc_de = ReadDirExtended(spc_dir, PG_TBLSPC_DIR, LOG)) != NULL)
3315 {
3316 if (strcmp(spc_de->d_name, ".") == 0 ||
3317 strcmp(spc_de->d_name, "..") == 0)
3318 continue;
3319
3320 snprintf(temp_path, sizeof(temp_path), "%s/%s/%s/%s",
3323 RemovePgTempFilesInDir(temp_path, true, false);
3324
3325 snprintf(temp_path, sizeof(temp_path), "%s/%s/%s",
3327 RemovePgTempRelationFiles(temp_path);
3328 }
3329
3330 FreeDir(spc_dir);
3331
3332 /*
3333 * In EXEC_BACKEND case there is a pgsql_tmp directory at the top level of
3334 * DataDir as well. However, that is *not* cleaned here because doing so
3335 * would create a race condition. It's done separately, earlier in
3336 * postmaster startup.
3337 */
3338}
int FreeDir(DIR *dir)
Definition: fd.c:2983
static void RemovePgTempRelationFiles(const char *tsdirname)
Definition: fd.c:3416
void RemovePgTempFilesInDir(const char *tmpdirname, bool missing_ok, bool unlink_all)
Definition: fd.c:3356
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2865
#define PG_TEMP_FILES_DIR
Definition: file_utils.h:62
#define PG_TBLSPC_DIR
Definition: relpath.h:41
#define TABLESPACE_VERSION_DIRECTORY
Definition: relpath.h:33
char d_name[MAX_PATH]
Definition: dirent.h:15

References AllocateDir(), dirent::d_name, FreeDir(), LOG, MAXPGPATH, PG_TBLSPC_DIR, PG_TEMP_FILES_DIR, ReadDirExtended(), RemovePgTempFilesInDir(), RemovePgTempRelationFiles(), snprintf, and TABLESPACE_VERSION_DIRECTORY.

Referenced by PostmasterMain(), and PostmasterStateMachine().

◆ RemovePgTempFilesInDir()

void RemovePgTempFilesInDir ( const char *  tmpdirname,
bool  missing_ok,
bool  unlink_all 
)

Definition at line 3356 of file fd.c.

3357{
3358 DIR *temp_dir;
3359 struct dirent *temp_de;
3360 char rm_path[MAXPGPATH * 2];
3361
3362 temp_dir = AllocateDir(tmpdirname);
3363
3364 if (temp_dir == NULL && errno == ENOENT && missing_ok)
3365 return;
3366
3367 while ((temp_de = ReadDirExtended(temp_dir, tmpdirname, LOG)) != NULL)
3368 {
3369 if (strcmp(temp_de->d_name, ".") == 0 ||
3370 strcmp(temp_de->d_name, "..") == 0)
3371 continue;
3372
3373 snprintf(rm_path, sizeof(rm_path), "%s/%s",
3374 tmpdirname, temp_de->d_name);
3375
3376 if (unlink_all ||
3377 strncmp(temp_de->d_name,
3379 strlen(PG_TEMP_FILE_PREFIX)) == 0)
3380 {
3381 PGFileType type = get_dirent_type(rm_path, temp_de, false, LOG);
3382
3383 if (type == PGFILETYPE_ERROR)
3384 continue;
3385 else if (type == PGFILETYPE_DIR)
3386 {
3387 /* recursively remove contents, then directory itself */
3388 RemovePgTempFilesInDir(rm_path, false, true);
3389
3390 if (rmdir(rm_path) < 0)
3391 ereport(LOG,
3393 errmsg("could not remove directory \"%s\": %m",
3394 rm_path)));
3395 }
3396 else
3397 {
3398 if (unlink(rm_path) < 0)
3399 ereport(LOG,
3401 errmsg("could not remove file \"%s\": %m",
3402 rm_path)));
3403 }
3404 }
3405 else
3406 ereport(LOG,
3407 (errmsg("unexpected file found in temporary-files directory: \"%s\"",
3408 rm_path)));
3409 }
3410
3411 FreeDir(temp_dir);
3412}
PGFileType get_dirent_type(const char *path, const struct dirent *de, bool look_through_symlinks, int elevel)
Definition: file_utils.c:526
PGFileType
Definition: file_utils.h:19
@ PGFILETYPE_DIR
Definition: file_utils.h:23
@ PGFILETYPE_ERROR
Definition: file_utils.h:20
const char * type

References AllocateDir(), dirent::d_name, ereport, errcode_for_file_access(), errmsg(), FreeDir(), get_dirent_type(), LOG, MAXPGPATH, PG_TEMP_FILE_PREFIX, PGFILETYPE_DIR, PGFILETYPE_ERROR, ReadDirExtended(), RemovePgTempFilesInDir(), snprintf, and type.

Referenced by PostmasterMain(), RemovePgTempFiles(), and RemovePgTempFilesInDir().

◆ RemovePgTempRelationFiles()

static void RemovePgTempRelationFiles ( const char *  tsdirname)
static

Definition at line 3416 of file fd.c.

3417{
3418 DIR *ts_dir;
3419 struct dirent *de;
3420 char dbspace_path[MAXPGPATH * 2];
3421
3422 ts_dir = AllocateDir(tsdirname);
3423
3424 while ((de = ReadDirExtended(ts_dir, tsdirname, LOG)) != NULL)
3425 {
3426 /*
3427 * We're only interested in the per-database directories, which have
3428 * numeric names. Note that this code will also (properly) ignore "."
3429 * and "..".
3430 */
3431 if (strspn(de->d_name, "0123456789") != strlen(de->d_name))
3432 continue;
3433
3434 snprintf(dbspace_path, sizeof(dbspace_path), "%s/%s",
3435 tsdirname, de->d_name);
3437 }
3438
3439 FreeDir(ts_dir);
3440}
static void RemovePgTempRelationFilesInDbspace(const char *dbspacedirname)
Definition: fd.c:3444

References AllocateDir(), dirent::d_name, FreeDir(), LOG, MAXPGPATH, ReadDirExtended(), RemovePgTempRelationFilesInDbspace(), and snprintf.

Referenced by RemovePgTempFiles().

◆ RemovePgTempRelationFilesInDbspace()

static void RemovePgTempRelationFilesInDbspace ( const char *  dbspacedirname)
static

Definition at line 3444 of file fd.c.

3445{
3446 DIR *dbspace_dir;
3447 struct dirent *de;
3448 char rm_path[MAXPGPATH * 2];
3449
3450 dbspace_dir = AllocateDir(dbspacedirname);
3451
3452 while ((de = ReadDirExtended(dbspace_dir, dbspacedirname, LOG)) != NULL)
3453 {
3455 continue;
3456
3457 snprintf(rm_path, sizeof(rm_path), "%s/%s",
3458 dbspacedirname, de->d_name);
3459
3460 if (unlink(rm_path) < 0)
3461 ereport(LOG,
3463 errmsg("could not remove file \"%s\": %m",
3464 rm_path)));
3465 }
3466
3467 FreeDir(dbspace_dir);
3468}
bool looks_like_temp_rel_name(const char *name)
Definition: fd.c:3472

References AllocateDir(), dirent::d_name, ereport, errcode_for_file_access(), errmsg(), FreeDir(), LOG, looks_like_temp_rel_name(), MAXPGPATH, ReadDirExtended(), and snprintf.

Referenced by RemovePgTempRelationFiles().

◆ ReportTemporaryFileUsage()

static void ReportTemporaryFileUsage ( const char *  path,
off_t  size 
)
static

Definition at line 1527 of file fd.c.

1528{
1530
1531 if (log_temp_files >= 0)
1532 {
1533 if ((size / 1024) >= log_temp_files)
1534 ereport(LOG,
1535 (errmsg("temporary file: path \"%s\", size %lu",
1536 path, (unsigned long) size)));
1537 }
1538}
int log_temp_files
Definition: guc_tables.c:528
void pgstat_report_tempfile(size_t filesize)

References ereport, errmsg(), LOG, log_temp_files, pgstat_report_tempfile(), and size.

Referenced by FileClose(), and PathNameDeleteTemporaryFile().

◆ reserveAllocatedDesc()

static bool reserveAllocatedDesc ( void  )
static

Definition at line 2530 of file fd.c.

2531{
2532 AllocateDesc *newDescs;
2533 int newMax;
2534
2535 /* Quick out if array already has a free slot. */
2537 return true;
2538
2539 /*
2540 * If the array hasn't yet been created in the current process, initialize
2541 * it with FD_MINFREE / 3 elements. In many scenarios this is as many as
2542 * we will ever need, anyway. We don't want to look at max_safe_fds
2543 * immediately because set_max_safe_fds() may not have run yet.
2544 */
2545 if (allocatedDescs == NULL)
2546 {
2547 newMax = FD_MINFREE / 3;
2548 newDescs = (AllocateDesc *) malloc(newMax * sizeof(AllocateDesc));
2549 /* Out of memory already? Treat as fatal error. */
2550 if (newDescs == NULL)
2551 ereport(ERROR,
2552 (errcode(ERRCODE_OUT_OF_MEMORY),
2553 errmsg("out of memory")));
2554 allocatedDescs = newDescs;
2555 maxAllocatedDescs = newMax;
2556 return true;
2557 }
2558
2559 /*
2560 * Consider enlarging the array beyond the initial allocation used above.
2561 * By the time this happens, max_safe_fds should be known accurately.
2562 *
2563 * We mustn't let allocated descriptors hog all the available FDs, and in
2564 * practice we'd better leave a reasonable number of FDs for VFD use. So
2565 * set the maximum to max_safe_fds / 3. (This should certainly be at
2566 * least as large as the initial size, FD_MINFREE / 3, so we aren't
2567 * tightening the restriction here.) Recall that "external" FDs are
2568 * allowed to consume another third of max_safe_fds.
2569 */
2570 newMax = max_safe_fds / 3;
2571 if (newMax > maxAllocatedDescs)
2572 {
2573 newDescs = (AllocateDesc *) realloc(allocatedDescs,
2574 newMax * sizeof(AllocateDesc));
2575 /* Treat out-of-memory as a non-fatal error. */
2576 if (newDescs == NULL)
2577 return false;
2578 allocatedDescs = newDescs;
2579 maxAllocatedDescs = newMax;
2580 return true;
2581 }
2582
2583 /* Can't enlarge allocatedDescs[] any more. */
2584 return false;
2585}
#define FD_MINFREE
Definition: fd.c:137

References allocatedDescs, ereport, errcode(), errmsg(), ERROR, FD_MINFREE, malloc, max_safe_fds, maxAllocatedDescs, numAllocatedDescs, and realloc.

Referenced by AllocateDir(), AllocateFile(), OpenPipeStream(), and OpenTransientFilePerm().

◆ ReserveExternalFD()

void ReserveExternalFD ( void  )

Definition at line 1220 of file fd.c.

1221{
1222 /*
1223 * Release VFDs if needed to stay safe. Because we do this before
1224 * incrementing numExternalFDs, the final state will be as desired, i.e.,
1225 * nfile + numAllocatedDescs + numExternalFDs <= max_safe_fds.
1226 */
1228
1230}

References numExternalFDs, and ReleaseLruFiles().

Referenced by AcquireExternalFD(), BackendInitialize(), dsm_impl_posix(), InitializeLatchSupport(), InitPostmasterDeathWatchHandle(), and XLogWrite().

◆ ResourceOwnerForgetFile()

static void ResourceOwnerForgetFile ( ResourceOwner  owner,
File  file 
)
inlinestatic

Definition at line 376 of file fd.c.

377{
379}
static const ResourceOwnerDesc file_resowner_desc
Definition: fd.c:360
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:217
void ResourceOwnerForget(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition: resowner.c:554

References file_resowner_desc, Int32GetDatum(), and ResourceOwnerForget().

Referenced by FileClose().

◆ ResourceOwnerRememberFile()

static void ResourceOwnerRememberFile ( ResourceOwner  owner,
File  file 
)
inlinestatic

Definition at line 371 of file fd.c.

372{
374}
void ResourceOwnerRemember(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition: resowner.c:514

References file_resowner_desc, Int32GetDatum(), and ResourceOwnerRemember().

Referenced by RegisterTemporaryFile().

◆ ResOwnerPrintFile()

static char * ResOwnerPrintFile ( Datum  res)
static

Definition at line 4074 of file fd.c.

4075{
4076 return psprintf("File %d", DatumGetInt32(res));
4077}
static int32 DatumGetInt32(Datum X)
Definition: postgres.h:207
char * psprintf(const char *fmt,...)
Definition: psprintf.c:43

References DatumGetInt32(), psprintf(), and res.

◆ ResOwnerReleaseFile()

static void ResOwnerReleaseFile ( Datum  res)
static

Definition at line 4060 of file fd.c.

4061{
4062 File file = (File) DatumGetInt32(res);
4063 Vfd *vfdP;
4064
4065 Assert(FileIsValid(file));
4066
4067 vfdP = &VfdCache[file];
4068 vfdP->resowner = NULL;
4069
4070 FileClose(file);
4071}

References Assert, DatumGetInt32(), FileClose(), FileIsValid, res, vfd::resowner, and VfdCache.

◆ set_max_safe_fds()

void set_max_safe_fds ( void  )

Definition at line 1043 of file fd.c.

1044{
1045 int usable_fds;
1046 int already_open;
1047
1048 /*----------
1049 * We want to set max_safe_fds to
1050 * MIN(usable_fds, max_files_per_process - already_open)
1051 * less the slop factor for files that are opened without consulting
1052 * fd.c. This ensures that we won't exceed either max_files_per_process
1053 * or the experimentally-determined EMFILE limit.
1054 *----------
1055 */
1057 &usable_fds, &already_open);
1058
1059 max_safe_fds = Min(usable_fds, max_files_per_process - already_open);
1060
1061 /*
1062 * Take off the FDs reserved for system() etc.
1063 */
1065
1066 /*
1067 * Make sure we still have enough to get by.
1068 */
1070 ereport(FATAL,
1071 (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
1072 errmsg("insufficient file descriptors available to start server process"),
1073 errdetail("System allows %d, server needs at least %d.",
1076
1077 elog(DEBUG2, "max_safe_fds = %d, usable_fds = %d, already_open = %d",
1078 max_safe_fds, usable_fds, already_open);
1079}
#define Min(x, y)
Definition: c.h:961
int errdetail(const char *fmt,...)
Definition: elog.c:1203
#define DEBUG2
Definition: elog.h:29
int max_files_per_process
Definition: fd.c:145
static void count_usable_fds(int max_to_probe, int *usable_fds, int *already_open)
Definition: fd.c:963
#define NUM_RESERVED_FDS
Definition: fd.c:128

References count_usable_fds(), DEBUG2, elog, ereport, errcode(), errdetail(), errmsg(), FATAL, FD_MINFREE, max_files_per_process, max_safe_fds, Min, and NUM_RESERVED_FDS.

Referenced by BootstrapModeMain(), PostgresSingleUserMain(), and PostmasterMain().

◆ SetTempTablespaces()

void SetTempTablespaces ( Oid tableSpaces,
int  numSpaces 
)

Definition at line 3071 of file fd.c.

3072{
3073 Assert(numSpaces >= 0);
3074 tempTableSpaces = tableSpaces;
3075 numTempTableSpaces = numSpaces;
3076
3077 /*
3078 * Select a random starting point in the list. This is to minimize
3079 * conflicts between backends that are most likely sharing the same list
3080 * of temp tablespaces. Note that if we create multiple temp files in the
3081 * same transaction, we'll advance circularly through the list --- this
3082 * ensures that large temporary sort files are nicely spread across all
3083 * available tablespaces.
3084 */
3085 if (numSpaces > 1)
3087 0, numSpaces - 1);
3088 else
3090}
uint64 pg_prng_uint64_range(pg_prng_state *state, uint64 rmin, uint64 rmax)
Definition: pg_prng.c:144
pg_prng_state pg_global_prng_state
Definition: pg_prng.c:34

References Assert, nextTempTableSpace, numTempTableSpaces, pg_global_prng_state, pg_prng_uint64_range(), and tempTableSpaces.

Referenced by assign_temp_tablespaces(), and PrepareTempTablespaces().

◆ SyncDataDirectory()

void SyncDataDirectory ( void  )

Definition at line 3567 of file fd.c.

3568{
3569 bool xlog_is_symlink;
3570
3571 /* We can skip this whole thing if fsync is disabled. */
3572 if (!enableFsync)
3573 return;
3574
3575 /*
3576 * If pg_wal is a symlink, we'll need to recurse into it separately,
3577 * because the first walkdir below will ignore it.
3578 */
3579 xlog_is_symlink = false;
3580
3581 {
3582 struct stat st;
3583
3584 if (lstat("pg_wal", &st) < 0)
3585 ereport(LOG,
3587 errmsg("could not stat file \"%s\": %m",
3588 "pg_wal")));
3589 else if (S_ISLNK(st.st_mode))
3590 xlog_is_symlink = true;
3591 }
3592
3593#ifdef HAVE_SYNCFS
3595 {
3596 DIR *dir;
3597 struct dirent *de;
3598
3599 /*
3600 * On Linux, we don't have to open every single file one by one. We
3601 * can use syncfs() to sync whole filesystems. We only expect
3602 * filesystem boundaries to exist where we tolerate symlinks, namely
3603 * pg_wal and the tablespaces, so we call syncfs() for each of those
3604 * directories.
3605 */
3606
3607 /* Prepare to report progress syncing the data directory via syncfs. */
3609
3610 /* Sync the top level pgdata directory. */
3611 do_syncfs(".");
3612 /* If any tablespaces are configured, sync each of those. */
3614 while ((de = ReadDirExtended(dir, PG_TBLSPC_DIR, LOG)))
3615 {
3616 char path[MAXPGPATH];
3617
3618 if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
3619 continue;
3620
3621 snprintf(path, MAXPGPATH, "%s/%s", PG_TBLSPC_DIR, de->d_name);
3622 do_syncfs(path);
3623 }
3624 FreeDir(dir);
3625 /* If pg_wal is a symlink, process that too. */
3626 if (xlog_is_symlink)
3627 do_syncfs("pg_wal");
3628 return;
3629 }
3630#endif /* !HAVE_SYNCFS */
3631
3632#ifdef PG_FLUSH_DATA_WORKS
3633 /* Prepare to report progress of the pre-fsync phase. */
3635
3636 /*
3637 * If possible, hint to the kernel that we're soon going to fsync the data
3638 * directory and its contents. Errors in this step are even less
3639 * interesting than normal, so log them only at DEBUG1.
3640 */
3641 walkdir(".", pre_sync_fname, false, DEBUG1);
3642 if (xlog_is_symlink)
3643 walkdir("pg_wal", pre_sync_fname, false, DEBUG1);
3644 walkdir(PG_TBLSPC_DIR, pre_sync_fname, true, DEBUG1);
3645#endif
3646
3647 /* Prepare to report progress syncing the data directory via fsync. */
3649
3650 /*
3651 * Now we do the fsync()s in the same order.
3652 *
3653 * The main call ignores symlinks, so in addition to specially processing
3654 * pg_wal if it's a symlink, pg_tblspc has to be visited separately with
3655 * process_symlinks = true. Note that if there are any plain directories
3656 * in pg_tblspc, they'll get fsync'd twice. That's not an expected case
3657 * so we don't worry about optimizing it.
3658 */
3659 walkdir(".", datadir_fsync_fname, false, LOG);
3660 if (xlog_is_symlink)
3661 walkdir("pg_wal", datadir_fsync_fname, false, LOG);
3663}
void begin_startup_progress_phase(void)
Definition: startup.c:343
#define DEBUG1
Definition: elog.h:30
int recovery_init_sync_method
Definition: fd.c:164
static void datadir_fsync_fname(const char *fname, bool isdir, int elevel)
Definition: fd.c:3782
@ DATA_DIR_SYNC_METHOD_SYNCFS
Definition: file_utils.h:30
#define lstat(path, sb)
Definition: win32_port.h:275
#define S_ISLNK(m)
Definition: win32_port.h:334

References AllocateDir(), begin_startup_progress_phase(), dirent::d_name, DATA_DIR_SYNC_METHOD_SYNCFS, datadir_fsync_fname(), DEBUG1, enableFsync, ereport, errcode_for_file_access(), errmsg(), FreeDir(), LOG, lstat, MAXPGPATH, PG_TBLSPC_DIR, ReadDirExtended(), recovery_init_sync_method, S_ISLNK, snprintf, stat::st_mode, and walkdir().

Referenced by StartupXLOG().

◆ TempTablespacePath()

void TempTablespacePath ( char *  path,
Oid  tablespace 
)

Definition at line 1778 of file fd.c.

1779{
1780 /*
1781 * Identify the tempfile directory for this tablespace.
1782 *
1783 * If someone tries to specify pg_global, use pg_default instead.
1784 */
1785 if (tablespace == InvalidOid ||
1786 tablespace == DEFAULTTABLESPACE_OID ||
1787 tablespace == GLOBALTABLESPACE_OID)
1788 snprintf(path, MAXPGPATH, "base/%s", PG_TEMP_FILES_DIR);
1789 else
1790 {
1791 /* All other tablespaces are accessed via symlinks */
1792 snprintf(path, MAXPGPATH, "%s/%u/%s/%s",
1795 }
1796}
static char * tablespace
Definition: pgbench.c:217

References InvalidOid, MAXPGPATH, PG_TBLSPC_DIR, PG_TEMP_FILES_DIR, snprintf, tablespace, and TABLESPACE_VERSION_DIRECTORY.

Referenced by FileSetCreate(), FileSetPath(), OpenTemporaryFileInTablespace(), and pg_ls_tmpdir().

◆ TempTablespacesAreSet()

bool TempTablespacesAreSet ( void  )

Definition at line 3100 of file fd.c.

3101{
3102 return (numTempTableSpaces >= 0);
3103}

References numTempTableSpaces.

Referenced by GetTempTablespaces(), and PrepareTempTablespaces().

◆ unlink_if_exists_fname()

static void unlink_if_exists_fname ( const char *  fname,
bool  isdir,
int  elevel 
)
static

Definition at line 3795 of file fd.c.

3796{
3797 if (isdir)
3798 {
3799 if (rmdir(fname) != 0 && errno != ENOENT)
3800 ereport(elevel,
3802 errmsg("could not remove directory \"%s\": %m", fname)));
3803 }
3804 else
3805 {
3806 /* Use PathNameDeleteTemporaryFile to report filesize */
3807 PathNameDeleteTemporaryFile(fname, false);
3808 }
3809}
bool PathNameDeleteTemporaryFile(const char *path, bool error_on_failure)
Definition: fd.c:1931

References ereport, errcode_for_file_access(), errmsg(), and PathNameDeleteTemporaryFile().

Referenced by PathNameDeleteTemporaryDir().

◆ walkdir()

static void walkdir ( const char *  path,
void(*)(const char *fname, bool isdir, int elevel)  action,
bool  process_symlinks,
int  elevel 
)
static

Definition at line 3681 of file fd.c.

3685{
3686 DIR *dir;
3687 struct dirent *de;
3688
3689 dir = AllocateDir(path);
3690
3691 while ((de = ReadDirExtended(dir, path, elevel)) != NULL)
3692 {
3693 char subpath[MAXPGPATH * 2];
3694
3696
3697 if (strcmp(de->d_name, ".") == 0 ||
3698 strcmp(de->d_name, "..") == 0)
3699 continue;
3700
3701 snprintf(subpath, sizeof(subpath), "%s/%s", path, de->d_name);
3702
3703 switch (get_dirent_type(subpath, de, process_symlinks, elevel))
3704 {
3705 case PGFILETYPE_REG:
3706 (*action) (subpath, false, elevel);
3707 break;
3708 case PGFILETYPE_DIR:
3709 walkdir(subpath, action, false, elevel);
3710 break;
3711 default:
3712
3713 /*
3714 * Errors are already reported directly by get_dirent_type(),
3715 * and any remaining symlinks and unknown file types are
3716 * ignored.
3717 */
3718 break;
3719 }
3720 }
3721
3722 FreeDir(dir); /* we ignore any error here */
3723
3724 /*
3725 * It's important to fsync the destination directory itself as individual
3726 * file fsyncs don't guarantee that the directory entry for the file is
3727 * synced. However, skip this if AllocateDir failed; the action function
3728 * might not be robust against that.
3729 */
3730 if (dir)
3731 (*action) (path, true, elevel);
3732}
@ PGFILETYPE_REG
Definition: file_utils.h:22
Datum subpath(PG_FUNCTION_ARGS)
Definition: ltree_op.c:308
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:122

References generate_unaccent_rules::action, AllocateDir(), CHECK_FOR_INTERRUPTS, dirent::d_name, FreeDir(), get_dirent_type(), MAXPGPATH, PGFILETYPE_DIR, PGFILETYPE_REG, ReadDirExtended(), snprintf, subpath(), and walkdir().

Referenced by PathNameDeleteTemporaryDir(), SyncDataDirectory(), and walkdir().

Variable Documentation

◆ allocatedDescs

◆ data_sync_retry

bool data_sync_retry = false

Definition at line 161 of file fd.c.

Referenced by data_sync_elevel().

◆ file_resowner_desc

const ResourceOwnerDesc file_resowner_desc
static
Initial value:
=
{
.name = "File",
.release_phase = RESOURCE_RELEASE_AFTER_LOCKS,
.release_priority = RELEASE_PRIO_FILES,
.ReleaseResource = ResOwnerReleaseFile,
.DebugPrint = ResOwnerPrintFile
}
static char * ResOwnerPrintFile(Datum res)
Definition: fd.c:4074
static void ResOwnerReleaseFile(Datum res)
Definition: fd.c:4060
@ RESOURCE_RELEASE_AFTER_LOCKS
Definition: resowner.h:56
#define RELEASE_PRIO_FILES
Definition: resowner.h:76

Definition at line 360 of file fd.c.

Referenced by ResourceOwnerForgetFile(), and ResourceOwnerRememberFile().

◆ have_xact_temporary_files

bool have_xact_temporary_files = false
static

Definition at line 227 of file fd.c.

Referenced by CleanupTempFiles(), and RegisterTemporaryFile().

◆ io_direct_flags

◆ max_files_per_process

int max_files_per_process = 1000

Definition at line 145 of file fd.c.

Referenced by set_max_safe_fds().

◆ max_safe_fds

int max_safe_fds = FD_MINFREE

Definition at line 158 of file fd.c.

Referenced by AcquireExternalFD(), ReleaseLruFiles(), reserveAllocatedDesc(), and set_max_safe_fds().

◆ maxAllocatedDescs

int maxAllocatedDescs = 0
static

◆ nextTempTableSpace

int nextTempTableSpace = 0
static

Definition at line 289 of file fd.c.

Referenced by GetNextTempTableSpace(), and SetTempTablespaces().

◆ nfile

int nfile = 0
static

◆ numAllocatedDescs

◆ numExternalFDs

int numExternalFDs = 0
static

Definition at line 273 of file fd.c.

Referenced by AcquireExternalFD(), ReleaseExternalFD(), ReleaseLruFiles(), and ReserveExternalFD().

◆ numTempTableSpaces

int numTempTableSpaces = -1
static

◆ recovery_init_sync_method

int recovery_init_sync_method = DATA_DIR_SYNC_METHOD_FSYNC

Definition at line 164 of file fd.c.

Referenced by SyncDataDirectory().

◆ SizeVfdCache

Size SizeVfdCache = 0
static

◆ tempFileCounter

long tempFileCounter = 0
static

Definition at line 279 of file fd.c.

Referenced by OpenTemporaryFileInTablespace().

◆ temporary_files_size

uint64 temporary_files_size = 0
static

Definition at line 235 of file fd.c.

Referenced by FileClose(), FileTruncate(), and FileWriteV().

◆ tempTableSpaces

Oid* tempTableSpaces = NULL
static

◆ VfdCache