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/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 "miscadmin.h"
#include "pgstat.h"
#include "port/pg_iovec.h"
#include "portability/mem.h"
#include "storage/fd.h"
#include "storage/ipc.h"
#include "utils/guc.h"
#include "utils/resowner_private.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 AtProcExit_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)
 
int pg_fsync (int fd)
 
int pg_fsync_no_writethrough (int fd)
 
int pg_fsync_writethrough (int fd)
 
int pg_fdatasync (int fd)
 
void pg_flush_data (int fd, off_t offset, off_t nbytes)
 
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)
 
int durable_rename_excl (const char *oldfile, const char *newfile, int elevel)
 
void InitFileAccess (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, int amount, uint32 wait_event_info)
 
void FileWriteback (File file, off_t offset, off_t nbytes, uint32 wait_event_info)
 
int FileRead (File file, char *buffer, int amount, off_t offset, uint32 wait_event_info)
 
int FileWrite (File file, char *buffer, int amount, off_t offset, uint32 wait_event_info)
 
int FileSync (File file, 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)
 
ssize_t pg_pwritev_with_retry (int fd, const struct iovec *iov, int iovcnt, off_t offset)
 

Variables

int max_files_per_process = 1000
 
int max_safe_fds = FD_MINFREE
 
bool data_sync_retry = false
 
int recovery_init_sync_method = RECOVERY_INIT_SYNC_METHOD_FSYNC
 
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
 

Macro Definition Documentation

◆ DO_DB

◆ FD_CLOSE_AT_EOXACT

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

Definition at line 189 of file fd.c.

Referenced by CleanupTempFiles(), and RegisterTemporaryFile().

◆ FD_DELETE_AT_CLOSE

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

Definition at line 188 of file fd.c.

Referenced by CleanupTempFiles(), FileClose(), and OpenTemporaryFile().

◆ FD_MINFREE

#define FD_MINFREE   48

Definition at line 137 of file fd.c.

Referenced by reserveAllocatedDesc(), and set_max_safe_fds().

◆ FD_TEMP_FILE_LIMIT

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

◆ FileIsNotOpen

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

◆ FileIsValid

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

◆ NUM_RESERVED_FDS

#define NUM_RESERVED_FDS   10

Definition at line 128 of file fd.c.

Referenced by set_max_safe_fds().

◆ VFD_CLOSED

#define VFD_CLOSED   (-1)

Definition at line 180 of file fd.c.

Referenced by AllocateVfd(), FileClose(), InitFileAccess(), and LruDelete().

Typedef Documentation

◆ Vfd

typedef struct vfd Vfd

Enumeration Type Documentation

◆ AllocateDescKind

Enumerator
AllocateDescFile 
AllocateDescPipe 
AllocateDescDir 
AllocateDescRawFD 

Definition at line 238 of file fd.c.

Function Documentation

◆ AcquireExternalFD()

bool AcquireExternalFD ( void  )

Definition at line 1095 of file fd.c.

References max_safe_fds, numExternalFDs, and ReserveExternalFD().

Referenced by connect_pg_server(), CreateWaitEventSet(), dblink_connect(), and dblink_get_conn().

1096 {
1097  /*
1098  * We don't want more than max_safe_fds / 3 FDs to be consumed for
1099  * "external" FDs.
1100  */
1101  if (numExternalFDs < max_safe_fds / 3)
1102  {
1104  return true;
1105  }
1106  errno = EMFILE;
1107  return false;
1108 }
static int numExternalFDs
Definition: fd.c:265
int max_safe_fds
Definition: fd.c:158
void ReserveExternalFD(void)
Definition: fd.c:1130

◆ AllocateDir()

DIR* AllocateDir ( const char *  dirname)

Definition at line 2634 of file fd.c.

References 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(), CleanupBackupHistory(), copydir(), db_dir_size(), DeleteAllExportedSnapshotFiles(), destroy_tablespace_directories(), directory_is_empty(), do_pg_start_backup(), dsm_cleanup_for_mmap(), extension_file_exists(), get_ext_ver_list(), getInstallationPaths(), movedb(), ParseTzFile(), perform_base_backup(), pg_available_extension_versions(), pg_available_extensions(), pg_logdir_ls_internal(), pg_ls_dir(), pg_ls_dir_files(), pg_tablespace_databases(), pg_tzenumerate_next(), pg_tzenumerate_start(), pgarch_readyXlog(), pgstat_reset_remove_files(), RelationCacheInitFileRemove(), RelationCacheInitFileRemoveInDir(), RemoveNonParentXlogFiles(), RemoveOldXlogFiles(), RemovePgTempFiles(), RemovePgTempFilesInDir(), RemovePgTempRelationFiles(), RemovePgTempRelationFilesInDbspace(), RemoveTempXlogFiles(), ReorderBufferCleanupSerializedTXNs(), ResetUnloggedRelations(), ResetUnloggedRelationsInDbspaceDir(), ResetUnloggedRelationsInTablespaceDir(), restoreTwoPhaseData(), scan_directory_ci(), sendDir(), SlruScanDirectory(), StartupReorderBuffer(), StartupReplicationSlots(), SyncDataDirectory(), UpdateLogicalMappings(), and walkdir().

2635 {
2636  DIR *dir;
2637 
2638  DO_DB(elog(LOG, "AllocateDir: Allocated %d (%s)",
2639  numAllocatedDescs, dirname));
2640 
2641  /* Can we allocate another non-virtual FD? */
2642  if (!reserveAllocatedDesc())
2643  ereport(ERROR,
2644  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2645  errmsg("exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"",
2646  maxAllocatedDescs, dirname)));
2647 
2648  /* Close excess kernel FDs. */
2649  ReleaseLruFiles();
2650 
2651 TryAgain:
2652  if ((dir = opendir(dirname)) != NULL)
2653  {
2655 
2656  desc->kind = AllocateDescDir;
2657  desc->desc.dir = dir;
2660  return desc->desc.dir;
2661  }
2662 
2663  if (errno == EMFILE || errno == ENFILE)
2664  {
2665  int save_errno = errno;
2666 
2667  ereport(LOG,
2668  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2669  errmsg("out of file descriptors: %m; release and retry")));
2670  errno = 0;
2671  if (ReleaseLruFile())
2672  goto TryAgain;
2673  errno = save_errno;
2674  }
2675 
2676  return NULL;
2677 }
union AllocateDesc::@18 desc
static AllocateDesc * allocatedDescs
Definition: fd.c:260
DIR * dir
Definition: fd.c:253
#define DO_DB(A)
Definition: fd.c:176
int errcode(int sqlerrcode)
Definition: elog.c:698
static bool reserveAllocatedDesc(void)
Definition: fd.c:2298
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:248
static bool ReleaseLruFile(void)
Definition: fd.c:1291
Definition: dirent.c:25
#define ERROR
Definition: elog.h:46
DIR * opendir(const char *)
Definition: dirent.c:33
static void ReleaseLruFiles(void)
Definition: fd.c:1313
#define ereport(elevel,...)
Definition: elog.h:157
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:723
SubTransactionId create_subid
Definition: fd.c:249
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
static int maxAllocatedDescs
Definition: fd.c:259
static int numAllocatedDescs
Definition: fd.c:258

◆ AllocateFile()

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

Definition at line 2373 of file fd.c.

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

Referenced by _ShowOption(), AlterSystemSetConfigFile(), apw_dump_now(), apw_load_buffers(), BackendRun(), BeginCopyFrom(), BeginCopyTo(), checkControlFile(), do_pg_start_backup(), do_pg_stop_backup(), entry_reset(), existsTimeLineHistory(), ExportSnapshot(), fill_hba_view(), gc_qtexts(), ImportSnapshot(), load_dh_file(), load_hba(), load_ident(), load_relcache_init_file(), parse_extension_control_file(), ParseTzFile(), pg_backup_start_time(), pg_current_logfile(), pg_file_write_internal(), pg_promote(), PGSharedMemoryAttach(), pgss_shmem_shutdown(), pgss_shmem_startup(), pgstat_read_db_statsfile(), pgstat_read_db_statsfile_timestamp(), pgstat_read_statsfiles(), pgstat_write_db_statsfile(), pgstat_write_statsfiles(), PostmasterMarkPIDForWorkerNotify(), read_backup_label(), read_binary_file(), read_tablespace_map(), read_whole_file(), readTimeLineHistory(), tokenize_inc_file(), tsearch_readline_begin(), ValidatePgVersion(), write_relcache_init_file(), XLogArchiveForceDone(), and XLogArchiveNotify().

2374 {
2375  FILE *file;
2376 
2377  DO_DB(elog(LOG, "AllocateFile: Allocated %d (%s)",
2379 
2380  /* Can we allocate another non-virtual FD? */
2381  if (!reserveAllocatedDesc())
2382  ereport(ERROR,
2383  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2384  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2385  maxAllocatedDescs, name)));
2386 
2387  /* Close excess kernel FDs. */
2388  ReleaseLruFiles();
2389 
2390 TryAgain:
2391  if ((file = fopen(name, mode)) != NULL)
2392  {
2394 
2395  desc->kind = AllocateDescFile;
2396  desc->desc.file = file;
2399  return desc->desc.file;
2400  }
2401 
2402  if (errno == EMFILE || errno == ENFILE)
2403  {
2404  int save_errno = errno;
2405 
2406  ereport(LOG,
2407  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2408  errmsg("out of file descriptors: %m; release and retry")));
2409  errno = 0;
2410  if (ReleaseLruFile())
2411  goto TryAgain;
2412  errno = save_errno;
2413  }
2414 
2415  return NULL;
2416 }
static PgChecksumMode mode
Definition: pg_checksums.c:61
union AllocateDesc::@18 desc
static AllocateDesc * allocatedDescs
Definition: fd.c:260
#define DO_DB(A)
Definition: fd.c:176
int errcode(int sqlerrcode)
Definition: elog.c:698
static bool reserveAllocatedDesc(void)
Definition: fd.c:2298
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:248
static bool ReleaseLruFile(void)
Definition: fd.c:1291
#define ERROR
Definition: elog.h:46
static void ReleaseLruFiles(void)
Definition: fd.c:1313
FILE * file
Definition: fd.c:252
#define ereport(elevel,...)
Definition: elog.h:157
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:723
SubTransactionId create_subid
Definition: fd.c:249
const char * name
Definition: encode.c:515
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
static int maxAllocatedDescs
Definition: fd.c:259
static int numAllocatedDescs
Definition: fd.c:258

◆ AllocateVfd()

static File AllocateVfd ( void  )
static

Definition at line 1323 of file fd.c.

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

Referenced by PathNameOpenFilePerm().

1324 {
1325  Index i;
1326  File file;
1327 
1328  DO_DB(elog(LOG, "AllocateVfd. Size %zu", SizeVfdCache));
1329 
1330  Assert(SizeVfdCache > 0); /* InitFileAccess not called? */
1331 
1332  if (VfdCache[0].nextFree == 0)
1333  {
1334  /*
1335  * The free list is empty so it is time to increase the size of the
1336  * array. We choose to double it each time this happens. However,
1337  * there's not much point in starting *real* small.
1338  */
1339  Size newCacheSize = SizeVfdCache * 2;
1340  Vfd *newVfdCache;
1341 
1342  if (newCacheSize < 32)
1343  newCacheSize = 32;
1344 
1345  /*
1346  * Be careful not to clobber VfdCache ptr if realloc fails.
1347  */
1348  newVfdCache = (Vfd *) realloc(VfdCache, sizeof(Vfd) * newCacheSize);
1349  if (newVfdCache == NULL)
1350  ereport(ERROR,
1351  (errcode(ERRCODE_OUT_OF_MEMORY),
1352  errmsg("out of memory")));
1353  VfdCache = newVfdCache;
1354 
1355  /*
1356  * Initialize the new entries and link them into the free list.
1357  */
1358  for (i = SizeVfdCache; i < newCacheSize; i++)
1359  {
1360  MemSet((char *) &(VfdCache[i]), 0, sizeof(Vfd));
1361  VfdCache[i].nextFree = i + 1;
1362  VfdCache[i].fd = VFD_CLOSED;
1363  }
1364  VfdCache[newCacheSize - 1].nextFree = 0;
1366 
1367  /*
1368  * Record the new size
1369  */
1370  SizeVfdCache = newCacheSize;
1371  }
1372 
1373  file = VfdCache[0].nextFree;
1374 
1375  VfdCache[0].nextFree = VfdCache[file].nextFree;
1376 
1377  return file;
1378 }
File nextFree
Definition: fd.c:197
static Size SizeVfdCache
Definition: fd.c:213
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
int errcode(int sqlerrcode)
Definition: elog.c:698
#define MemSet(start, val, len)
Definition: c.h:1008
#define LOG
Definition: elog.h:26
#define ERROR
Definition: elog.h:46
Definition: fd.c:192
int fd
Definition: fd.c:194
unsigned int Index
Definition: c.h:549
#define VFD_CLOSED
Definition: fd.c:180
#define ereport(elevel,...)
Definition: elog.h:157
#define Assert(condition)
Definition: c.h:804
size_t Size
Definition: c.h:540
#define realloc(a, b)
Definition: header.h:60
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
int i
int File
Definition: fd.h:53

◆ AtEOSubXact_Files()

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

Definition at line 2922 of file fd.c.

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

2924 {
2925  Index i;
2926 
2927  for (i = 0; i < numAllocatedDescs; i++)
2928  {
2929  if (allocatedDescs[i].create_subid == mySubid)
2930  {
2931  if (isCommit)
2932  allocatedDescs[i].create_subid = parentSubid;
2933  else
2934  {
2935  /* have to recheck the item after FreeDesc (ugly) */
2936  FreeDesc(&allocatedDescs[i--]);
2937  }
2938  }
2939  }
2940 }
static AllocateDesc * allocatedDescs
Definition: fd.c:260
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2533
unsigned int Index
Definition: c.h:549
SubTransactionId create_subid
Definition: fd.c:249
int i
static int numAllocatedDescs
Definition: fd.c:258

◆ AtEOXact_Files()

void AtEOXact_Files ( bool  isCommit)

Definition at line 2955 of file fd.c.

References CleanupTempFiles(), numTempTableSpaces, and tempTableSpaces.

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

2956 {
2957  CleanupTempFiles(isCommit, false);
2958  tempTableSpaces = NULL;
2959  numTempTableSpaces = -1;
2960 }
static int numTempTableSpaces
Definition: fd.c:280
static Oid * tempTableSpaces
Definition: fd.c:279
static void CleanupTempFiles(bool isCommit, bool isProcExit)
Definition: fd.c:2987

◆ AtProcExit_Files()

static void AtProcExit_Files ( int  code,
Datum  arg 
)
static

Definition at line 2969 of file fd.c.

References CleanupTempFiles().

Referenced by InitFileAccess().

2970 {
2971  CleanupTempFiles(false, true);
2972 }
static void CleanupTempFiles(bool isCommit, bool isProcExit)
Definition: fd.c:2987

◆ BasicOpenFile()

int BasicOpenFile ( const char *  fileName,
int  fileFlags 
)

Definition at line 1033 of file fd.c.

References BasicOpenFilePerm(), and pg_file_create_mode.

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

1034 {
1035  return BasicOpenFilePerm(fileName, fileFlags, pg_file_create_mode);
1036 }
int pg_file_create_mode
Definition: file_perm.c:19
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1055

◆ BasicOpenFilePerm()

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

Definition at line 1055 of file fd.c.

References ereport, errcode(), errmsg(), vfd::fd, LOG, and ReleaseLruFile().

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

1056 {
1057  int fd;
1058 
1059 tryAgain:
1060  fd = open(fileName, fileFlags, fileMode);
1061 
1062  if (fd >= 0)
1063  return fd; /* success! */
1064 
1065  if (errno == EMFILE || errno == ENFILE)
1066  {
1067  int save_errno = errno;
1068 
1069  ereport(LOG,
1070  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
1071  errmsg("out of file descriptors: %m; release and retry")));
1072  errno = 0;
1073  if (ReleaseLruFile())
1074  goto tryAgain;
1075  errno = save_errno;
1076  }
1077 
1078  return -1; /* failure */
1079 }
int errcode(int sqlerrcode)
Definition: elog.c:698
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static bool ReleaseLruFile(void)
Definition: fd.c:1291
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ CleanupTempFiles()

static void CleanupTempFiles ( bool  isCommit,
bool  isProcExit 
)
static

Definition at line 2987 of file fd.c.

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

Referenced by AtEOXact_Files(), and AtProcExit_Files().

2988 {
2989  Index i;
2990 
2991  /*
2992  * Careful here: at proc_exit we need extra cleanup, not just
2993  * xact_temporary files.
2994  */
2995  if (isProcExit || have_xact_temporary_files)
2996  {
2997  Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
2998  for (i = 1; i < SizeVfdCache; i++)
2999  {
3000  unsigned short fdstate = VfdCache[i].fdstate;
3001 
3002  if (((fdstate & FD_DELETE_AT_CLOSE) || (fdstate & FD_CLOSE_AT_EOXACT)) &&
3003  VfdCache[i].fileName != NULL)
3004  {
3005  /*
3006  * If we're in the process of exiting a backend process, close
3007  * all temporary files. Otherwise, only close temporary files
3008  * local to the current transaction. They should be closed by
3009  * the ResourceOwner mechanism already, so this is just a
3010  * debugging cross-check.
3011  */
3012  if (isProcExit)
3013  FileClose(i);
3014  else if (fdstate & FD_CLOSE_AT_EOXACT)
3015  {
3016  elog(WARNING,
3017  "temporary file %s not closed at end-of-transaction",
3018  VfdCache[i].fileName);
3019  FileClose(i);
3020  }
3021  }
3022  }
3023 
3024  have_xact_temporary_files = false;
3025  }
3026 
3027  /* Complain if any allocated files remain open at commit. */
3028  if (isCommit && numAllocatedDescs > 0)
3029  elog(WARNING, "%d temporary files and directories not closed at end-of-transaction",
3031 
3032  /* Clean up "allocated" stdio files, dirs and fds. */
3033  while (numAllocatedDescs > 0)
3034  FreeDesc(&allocatedDescs[0]);
3035 }
static AllocateDesc * allocatedDescs
Definition: fd.c:260
static Size SizeVfdCache
Definition: fd.c:213
#define FD_DELETE_AT_CLOSE
Definition: fd.c:188
static Vfd * VfdCache
Definition: fd.c:212
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2533
static bool have_xact_temporary_files
Definition: fd.c:224
unsigned short fdstate
Definition: fd.c:195
#define WARNING
Definition: elog.h:40
#define FileIsNotOpen(file)
Definition: fd.c:185
unsigned int Index
Definition: c.h:549
void FileClose(File file)
Definition: fd.c:1873
#define Assert(condition)
Definition: c.h:804
#define elog(elevel,...)
Definition: elog.h:232
int i
#define FD_CLOSE_AT_EOXACT
Definition: fd.c:189
static int numAllocatedDescs
Definition: fd.c:258

◆ closeAllVfds()

void closeAllVfds ( void  )

Definition at line 2811 of file fd.c.

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

Referenced by standard_ProcessUtility().

2812 {
2813  Index i;
2814 
2815  if (SizeVfdCache > 0)
2816  {
2817  Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
2818  for (i = 1; i < SizeVfdCache; i++)
2819  {
2820  if (!FileIsNotOpen(i))
2821  LruDelete(i);
2822  }
2823  }
2824 }
static Size SizeVfdCache
Definition: fd.c:213
static void LruDelete(File file)
Definition: fd.c:1196
#define FileIsNotOpen(file)
Definition: fd.c:185
unsigned int Index
Definition: c.h:549
#define Assert(condition)
Definition: c.h:804
int i

◆ ClosePipeStream()

int ClosePipeStream ( FILE *  file)

Definition at line 2782 of file fd.c.

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

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

2783 {
2784  int i;
2785 
2786  DO_DB(elog(LOG, "ClosePipeStream: Allocated %d", numAllocatedDescs));
2787 
2788  /* Remove file from list of allocated files, if it's present */
2789  for (i = numAllocatedDescs; --i >= 0;)
2790  {
2791  AllocateDesc *desc = &allocatedDescs[i];
2792 
2793  if (desc->kind == AllocateDescPipe && desc->desc.file == file)
2794  return FreeDesc(desc);
2795  }
2796 
2797  /* Only get here if someone passes us a file not in allocatedDescs */
2798  elog(WARNING, "file passed to ClosePipeStream was not obtained from OpenPipeStream");
2799 
2800  return pclose(file);
2801 }
union AllocateDesc::@18 desc
static AllocateDesc * allocatedDescs
Definition: fd.c:260
#define DO_DB(A)
Definition: fd.c:176
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:248
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2533
#define WARNING
Definition: elog.h:40
FILE * file
Definition: fd.c:252
#define elog(elevel,...)
Definition: elog.h:232
int i
static int numAllocatedDescs
Definition: fd.c:258

◆ CloseTransientFile()

int CloseTransientFile ( int  fd)

Definition at line 2600 of file fd.c.

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

Referenced by ApplyLogicalMappingFile(), be_lo_export(), CheckPointLogicalRewriteHeap(), CheckPointReplicationOrigin(), copy_file(), dsm_impl_mmap(), durable_rename(), fsync_fname_ext(), get_controlfile(), heap_xlog_logical_rewrite(), lo_import_internal(), load_relmap_file(), looks_like_temp_rel_name(), perform_base_backup(), pg_truncate(), qtext_load_file(), qtext_store(), ReadTwoPhaseFile(), RecreateTwoPhaseFile(), ReorderBufferSerializeChange(), ReorderBufferSerializeTXN(), RestoreSlotFromDisk(), SaveSlotToPath(), sendFile(), SendTimeLineHistory(), SimpleLruDoesPhysicalPageExist(), SimpleLruWriteAll(), SlruInternalWritePage(), SlruPhysicalReadPage(), SlruPhysicalWritePage(), SlruSyncFileTag(), SnapBuildRestore(), SnapBuildSerialize(), StartupReplicationOrigin(), walkdir(), write_relmap_file(), writeTimeLineHistory(), writeTimeLineHistoryFile(), and XLogFileCopy().

2601 {
2602  int i;
2603 
2604  DO_DB(elog(LOG, "CloseTransientFile: Allocated %d", numAllocatedDescs));
2605 
2606  /* Remove fd from list of allocated files, if it's present */
2607  for (i = numAllocatedDescs; --i >= 0;)
2608  {
2609  AllocateDesc *desc = &allocatedDescs[i];
2610 
2611  if (desc->kind == AllocateDescRawFD && desc->desc.fd == fd)
2612  return FreeDesc(desc);
2613  }
2614 
2615  /* Only get here if someone passes us a file not in allocatedDescs */
2616  elog(WARNING, "fd passed to CloseTransientFile was not obtained from OpenTransientFile");
2617 
2618  return close(fd);
2619 }
union AllocateDesc::@18 desc
static AllocateDesc * allocatedDescs
Definition: fd.c:260
#define DO_DB(A)
Definition: fd.c:176
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:248
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2533
#define WARNING
Definition: elog.h:40
int fd
Definition: fd.c:254
#define elog(elevel,...)
Definition: elog.h:232
int i
#define close(a)
Definition: win32.h:12
static int numAllocatedDescs
Definition: fd.c:258

◆ count_usable_fds()

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

Definition at line 906 of file fd.c.

References close, elog, ereport, errmsg(), vfd::fd, palloc(), pfree(), repalloc(), and WARNING.

Referenced by set_max_safe_fds().

907 {
908  int *fd;
909  int size;
910  int used = 0;
911  int highestfd = 0;
912  int j;
913 
914 #ifdef HAVE_GETRLIMIT
915  struct rlimit rlim;
916  int getrlimit_status;
917 #endif
918 
919  size = 1024;
920  fd = (int *) palloc(size * sizeof(int));
921 
922 #ifdef HAVE_GETRLIMIT
923 #ifdef RLIMIT_NOFILE /* most platforms use RLIMIT_NOFILE */
924  getrlimit_status = getrlimit(RLIMIT_NOFILE, &rlim);
925 #else /* but BSD doesn't ... */
926  getrlimit_status = getrlimit(RLIMIT_OFILE, &rlim);
927 #endif /* RLIMIT_NOFILE */
928  if (getrlimit_status != 0)
929  ereport(WARNING, (errmsg("getrlimit failed: %m")));
930 #endif /* HAVE_GETRLIMIT */
931 
932  /* dup until failure or probe limit reached */
933  for (;;)
934  {
935  int thisfd;
936 
937 #ifdef HAVE_GETRLIMIT
938 
939  /*
940  * don't go beyond RLIMIT_NOFILE; causes irritating kernel logs on
941  * some platforms
942  */
943  if (getrlimit_status == 0 && highestfd >= rlim.rlim_cur - 1)
944  break;
945 #endif
946 
947  thisfd = dup(0);
948  if (thisfd < 0)
949  {
950  /* Expect EMFILE or ENFILE, else it's fishy */
951  if (errno != EMFILE && errno != ENFILE)
952  elog(WARNING, "dup(0) failed after %d successes: %m", used);
953  break;
954  }
955 
956  if (used >= size)
957  {
958  size *= 2;
959  fd = (int *) repalloc(fd, size * sizeof(int));
960  }
961  fd[used++] = thisfd;
962 
963  if (highestfd < thisfd)
964  highestfd = thisfd;
965 
966  if (used >= max_to_probe)
967  break;
968  }
969 
970  /* release the files we opened */
971  for (j = 0; j < used; j++)
972  close(fd[j]);
973 
974  pfree(fd);
975 
976  /*
977  * Return results. usable_fds is just the number of successful dups. We
978  * assume that the system limit is highestfd+1 (remember 0 is a legal FD
979  * number) and so already_open is highestfd+1 - usable_fds.
980  */
981  *usable_fds = used;
982  *already_open = highestfd + 1 - used;
983 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
void pfree(void *pointer)
Definition: mcxt.c:1169
#define WARNING
Definition: elog.h:40
#define ereport(elevel,...)
Definition: elog.h:157
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1182
void * palloc(Size size)
Definition: mcxt.c:1062
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
#define close(a)
Definition: win32.h:12

◆ data_sync_elevel()

◆ datadir_fsync_fname()

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

Definition at line 3540 of file fd.c.

References fsync_fname_ext().

Referenced by SyncDataDirectory().

3541 {
3542  /*
3543  * We want to silently ignoring errors about unreadable files. Pass that
3544  * desire on to fsync_fname_ext().
3545  */
3546  fsync_fname_ext(fname, isdir, true, elevel);
3547 }
static int elevel
Definition: vacuumlazy.c:400
int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3575

◆ Delete()

static void Delete ( File  file)
static

Definition at line 1177 of file fd.c.

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

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

1178 {
1179  Vfd *vfdP;
1180 
1181  Assert(file != 0);
1182 
1183  DO_DB(elog(LOG, "Delete %d (%s)",
1184  file, VfdCache[file].fileName));
1185  DO_DB(_dump_lru());
1186 
1187  vfdP = &VfdCache[file];
1188 
1191 
1192  DO_DB(_dump_lru());
1193 }
File lruLessRecently
Definition: fd.c:199
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
#define LOG
Definition: elog.h:26
Definition: fd.c:192
#define Assert(condition)
Definition: c.h:804
File lruMoreRecently
Definition: fd.c:198
#define elog(elevel,...)
Definition: elog.h:232

◆ durable_rename()

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

Definition at line 692 of file fd.c.

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

Referenced by AlterSystemSetConfigFile(), apw_dump_now(), BaseBackup(), CancelBackup(), CheckPointReplicationOrigin(), dir_close(), KeepFileRestoredFromArchive(), pgarch_archiveDone(), pgss_shmem_shutdown(), StartupXLOG(), and XLogArchiveForceDone().

693 {
694  int fd;
695 
696  /*
697  * First fsync the old and target path (if it exists), to ensure that they
698  * are properly persistent on disk. Syncing the target file is not
699  * strictly necessary, but it makes it easier to reason about crashes;
700  * because it's then guaranteed that either source or target file exists
701  * after a crash.
702  */
703  if (fsync_fname_ext(oldfile, false, false, elevel) != 0)
704  return -1;
705 
706  fd = OpenTransientFile(newfile, PG_BINARY | O_RDWR);
707  if (fd < 0)
708  {
709  if (errno != ENOENT)
710  {
711  ereport(elevel,
713  errmsg("could not open file \"%s\": %m", newfile)));
714  return -1;
715  }
716  }
717  else
718  {
719  if (pg_fsync(fd) != 0)
720  {
721  int save_errno;
722 
723  /* close file upon error, might not be in transaction context */
724  save_errno = errno;
725  CloseTransientFile(fd);
726  errno = save_errno;
727 
728  ereport(elevel,
730  errmsg("could not fsync file \"%s\": %m", newfile)));
731  return -1;
732  }
733 
734  if (CloseTransientFile(fd) != 0)
735  {
736  ereport(elevel,
738  errmsg("could not close file \"%s\": %m", newfile)));
739  return -1;
740  }
741  }
742 
743  /* Time to do the real deal... */
744  if (rename(oldfile, newfile) < 0)
745  {
746  ereport(elevel,
748  errmsg("could not rename file \"%s\" to \"%s\": %m",
749  oldfile, newfile)));
750  return -1;
751  }
752 
753  /*
754  * To guarantee renaming the file is persistent, fsync the file with its
755  * new name, and its containing directory.
756  */
757  if (fsync_fname_ext(newfile, false, false, elevel) != 0)
758  return -1;
759 
760  if (fsync_parent_path(newfile, elevel) != 0)
761  return -1;
762 
763  return 0;
764 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1271
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2423
int errcode_for_file_access(void)
Definition: elog.c:721
int CloseTransientFile(int fd)
Definition: fd.c:2600
static int elevel
Definition: vacuumlazy.c:400
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909
int pg_fsync(int fd)
Definition: fd.c:352
int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3575
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3651

◆ durable_rename_excl()

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

Definition at line 822 of file fd.c.

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

Referenced by InstallXLogFileSegment(), writeTimeLineHistory(), and writeTimeLineHistoryFile().

823 {
824  /*
825  * Ensure that, if we crash directly after the rename/link, a file with
826  * valid contents is moved into place.
827  */
828  if (fsync_fname_ext(oldfile, false, false, elevel) != 0)
829  return -1;
830 
831 #ifdef HAVE_WORKING_LINK
832  if (link(oldfile, newfile) < 0)
833  {
834  ereport(elevel,
836  errmsg("could not link file \"%s\" to \"%s\": %m",
837  oldfile, newfile)));
838  return -1;
839  }
840  unlink(oldfile);
841 #else
842  if (rename(oldfile, newfile) < 0)
843  {
844  ereport(elevel,
846  errmsg("could not rename file \"%s\" to \"%s\": %m",
847  oldfile, newfile)));
848  return -1;
849  }
850 #endif
851 
852  /*
853  * Make change persistent in case of an OS crash, both the new entry and
854  * its parent directory need to be flushed.
855  */
856  if (fsync_fname_ext(newfile, false, false, elevel) != 0)
857  return -1;
858 
859  /* Same for parent directory */
860  if (fsync_parent_path(newfile, elevel) != 0)
861  return -1;
862 
863  return 0;
864 }
int errcode_for_file_access(void)
Definition: elog.c:721
static int elevel
Definition: vacuumlazy.c:400
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909
int link(const char *src, const char *dst)
int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3575
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3651

◆ durable_unlink()

int durable_unlink ( const char *  fname,
int  elevel 
)

Definition at line 782 of file fd.c.

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

Referenced by do_pg_stop_backup(), exitArchiveRecovery(), InstallXLogFileSegment(), and RemoveXlogFile().

783 {
784  if (unlink(fname) < 0)
785  {
786  ereport(elevel,
788  errmsg("could not remove file \"%s\": %m",
789  fname)));
790  return -1;
791  }
792 
793  /*
794  * To guarantee that the removal of the file is persistent, fsync its
795  * parent directory.
796  */
797  if (fsync_parent_path(fname, elevel) != 0)
798  return -1;
799 
800  return 0;
801 }
int errcode_for_file_access(void)
Definition: elog.c:721
static int elevel
Definition: vacuumlazy.c:400
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3651

◆ FileAccess()

static int FileAccess ( File  file)
static

Definition at line 1401 of file fd.c.

References Delete(), DO_DB, elog, FileIsNotOpen, vfd::fileName, Insert(), LOG, LruInsert(), and vfd::lruLessRecently.

Referenced by FilePrefetch(), FileRead(), FileSize(), FileSync(), FileTruncate(), FileWrite(), and FileWriteback().

1402 {
1403  int returnValue;
1404 
1405  DO_DB(elog(LOG, "FileAccess %d (%s)",
1406  file, VfdCache[file].fileName));
1407 
1408  /*
1409  * Is the file open? If not, open it and put it at the head of the LRU
1410  * ring (possibly closing the least recently used file to get an FD).
1411  */
1412 
1413  if (FileIsNotOpen(file))
1414  {
1415  returnValue = LruInsert(file);
1416  if (returnValue != 0)
1417  return returnValue;
1418  }
1419  else if (VfdCache[0].lruLessRecently != file)
1420  {
1421  /*
1422  * We now know that the file is open and that it is not the last one
1423  * accessed, so we need to move it to the head of the Lru ring.
1424  */
1425 
1426  Delete(file);
1427  Insert(file);
1428  }
1429 
1430  return 0;
1431 }
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
static void Delete(File file)
Definition: fd.c:1177
#define LOG
Definition: elog.h:26
static int LruInsert(File file)
Definition: fd.c:1244
static void Insert(File file)
Definition: fd.c:1222
#define FileIsNotOpen(file)
Definition: fd.c:185
#define elog(elevel,...)
Definition: elog.h:232

◆ FileClose()

void FileClose ( File  file)

Definition at line 1873 of file fd.c.

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, and VFD_CLOSED.

Referenced by BufFileClose(), BufFileTruncateShared(), CleanupTempFiles(), logical_end_heap_rewrite(), mdclose(), mdimmedsync(), mdsyncfiletag(), mdtruncate(), ReorderBufferIterTXNFinish(), ReorderBufferRestoreChanges(), and ResourceOwnerReleaseInternal().

1874 {
1875  Vfd *vfdP;
1876 
1877  Assert(FileIsValid(file));
1878 
1879  DO_DB(elog(LOG, "FileClose: %d (%s)",
1880  file, VfdCache[file].fileName));
1881 
1882  vfdP = &VfdCache[file];
1883 
1884  if (!FileIsNotOpen(file))
1885  {
1886  /* close the file */
1887  if (close(vfdP->fd) != 0)
1888  {
1889  /*
1890  * We may need to panic on failure to close non-temporary files;
1891  * see LruDelete.
1892  */
1894  "could not close file \"%s\": %m", vfdP->fileName);
1895  }
1896 
1897  --nfile;
1898  vfdP->fd = VFD_CLOSED;
1899 
1900  /* remove the file from the lru ring */
1901  Delete(file);
1902  }
1903 
1904  if (vfdP->fdstate & FD_TEMP_FILE_LIMIT)
1905  {
1906  /* Subtract its size from current usage (do first in case of error) */
1907  temporary_files_size -= vfdP->fileSize;
1908  vfdP->fileSize = 0;
1909  }
1910 
1911  /*
1912  * Delete the file if it was temporary, and make a log entry if wanted
1913  */
1914  if (vfdP->fdstate & FD_DELETE_AT_CLOSE)
1915  {
1916  struct stat filestats;
1917  int stat_errno;
1918 
1919  /*
1920  * If we get an error, as could happen within the ereport/elog calls,
1921  * we'll come right back here during transaction abort. Reset the
1922  * flag to ensure that we can't get into an infinite loop. This code
1923  * is arranged to ensure that the worst-case consequence is failing to
1924  * emit log message(s), not failing to attempt the unlink.
1925  */
1926  vfdP->fdstate &= ~FD_DELETE_AT_CLOSE;
1927 
1928 
1929  /* first try the stat() */
1930  if (stat(vfdP->fileName, &filestats))
1931  stat_errno = errno;
1932  else
1933  stat_errno = 0;
1934 
1935  /* in any case do the unlink */
1936  if (unlink(vfdP->fileName))
1937  ereport(LOG,
1939  errmsg("could not delete file \"%s\": %m", vfdP->fileName)));
1940 
1941  /* and last report the stat results */
1942  if (stat_errno == 0)
1943  ReportTemporaryFileUsage(vfdP->fileName, filestats.st_size);
1944  else
1945  {
1946  errno = stat_errno;
1947  ereport(LOG,
1949  errmsg("could not stat file \"%s\": %m", vfdP->fileName)));
1950  }
1951  }
1952 
1953  /* Unregister it from the resource owner */
1954  if (vfdP->resowner)
1955  ResourceOwnerForgetFile(vfdP->resowner, file);
1956 
1957  /*
1958  * Return the Vfd slot to the free list
1959  */
1960  FreeVfd(file);
1961 }
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:190
#define DO_DB(A)
Definition: fd.c:176
#define FD_DELETE_AT_CLOSE
Definition: fd.c:188
static Vfd * VfdCache
Definition: fd.c:212
static void Delete(File file)
Definition: fd.c:1177
#define LOG
Definition: elog.h:26
char * fileName
Definition: fd.c:201
int errcode_for_file_access(void)
Definition: elog.c:721
static int nfile
Definition: fd.c:218
unsigned short fdstate
Definition: fd.c:195
Definition: fd.c:192
off_t fileSize
Definition: fd.c:200
int fd
Definition: fd.c:194
ResourceOwner resowner
Definition: fd.c:196
static void ReportTemporaryFileUsage(const char *path, off_t size)
Definition: fd.c:1437
#define FileIsNotOpen(file)
Definition: fd.c:185
int data_sync_elevel(int elevel)
Definition: fd.c:3714
#define FileIsValid(file)
Definition: fd.c:182
#define VFD_CLOSED
Definition: fd.c:180
static uint64 temporary_files_size
Definition: fd.c:232
#define ereport(elevel,...)
Definition: elog.h:157
#define Assert(condition)
Definition: c.h:804
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
static void FreeVfd(File file)
Definition: fd.c:1381
#define close(a)
Definition: win32.h:12
void ResourceOwnerForgetFile(ResourceOwner owner, File file)
Definition: resowner.c:1306
#define stat
Definition: win32_port.h:275

◆ FileGetRawDesc()

int FileGetRawDesc ( File  file)

Definition at line 2267 of file fd.c.

References Assert, vfd::fd, and FileIsValid.

2268 {
2269  Assert(FileIsValid(file));
2270  return VfdCache[file].fd;
2271 }
static Vfd * VfdCache
Definition: fd.c:212
int fd
Definition: fd.c:194
#define FileIsValid(file)
Definition: fd.c:182
#define Assert(condition)
Definition: c.h:804

◆ FileGetRawFlags()

int FileGetRawFlags ( File  file)

Definition at line 2277 of file fd.c.

References Assert, vfd::fileFlags, and FileIsValid.

2278 {
2279  Assert(FileIsValid(file));
2280  return VfdCache[file].fileFlags;
2281 }
static Vfd * VfdCache
Definition: fd.c:212
#define FileIsValid(file)
Definition: fd.c:182
#define Assert(condition)
Definition: c.h:804
int fileFlags
Definition: fd.c:203

◆ FileGetRawMode()

mode_t FileGetRawMode ( File  file)

Definition at line 2287 of file fd.c.

References Assert, FileIsValid, and vfd::fileMode.

2288 {
2289  Assert(FileIsValid(file));
2290  return VfdCache[file].fileMode;
2291 }
static Vfd * VfdCache
Definition: fd.c:212
mode_t fileMode
Definition: fd.c:204
#define FileIsValid(file)
Definition: fd.c:182
#define Assert(condition)
Definition: c.h:804

◆ FilePathName()

char* FilePathName ( File  file)

Definition at line 2251 of file fd.c.

References Assert, FileIsValid, and vfd::fileName.

Referenced by _mdnblocks(), BufFileDumpBuffer(), BufFileLoadBuffer(), BufFileSeek(), BufFileSize(), BufFileTruncateShared(), mdextend(), mdimmedsync(), mdread(), mdsyncfiletag(), mdtruncate(), mdwrite(), and register_dirty_segment().

2252 {
2253  Assert(FileIsValid(file));
2254 
2255  return VfdCache[file].fileName;
2256 }
static Vfd * VfdCache
Definition: fd.c:212
char * fileName
Definition: fd.c:201
#define FileIsValid(file)
Definition: fd.c:182
#define Assert(condition)
Definition: c.h:804

◆ FilePrefetch()

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

Definition at line 1973 of file fd.c.

References Assert, DO_DB, elog, vfd::fd, FileAccess(), FileIsValid, vfd::fileName, INT64_FORMAT, LOG, pgstat_report_wait_end(), and pgstat_report_wait_start().

Referenced by mdprefetch().

1974 {
1975 #if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
1976  int returnCode;
1977 
1978  Assert(FileIsValid(file));
1979 
1980  DO_DB(elog(LOG, "FilePrefetch: %d (%s) " INT64_FORMAT " %d",
1981  file, VfdCache[file].fileName,
1982  (int64) offset, amount));
1983 
1984  returnCode = FileAccess(file);
1985  if (returnCode < 0)
1986  return returnCode;
1987 
1988  pgstat_report_wait_start(wait_event_info);
1989  returnCode = posix_fadvise(VfdCache[file].fd, offset, amount,
1990  POSIX_FADV_WILLNEED);
1992 
1993  return returnCode;
1994 #else
1995  Assert(FileIsValid(file));
1996  return 0;
1997 #endif
1998 }
static void pgstat_report_wait_end(void)
Definition: wait_event.h:277
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:261
#define FileIsValid(file)
Definition: fd.c:182
static int FileAccess(File file)
Definition: fd.c:1401
#define Assert(condition)
Definition: c.h:804
#define INT64_FORMAT
Definition: c.h:483
#define elog(elevel,...)
Definition: elog.h:232

◆ FileRead()

int FileRead ( File  file,
char *  buffer,
int  amount,
off_t  offset,
uint32  wait_event_info 
)

Definition at line 2024 of file fd.c.

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

Referenced by BufFileLoadBuffer(), mdread(), and ReorderBufferRestoreChanges().

2026 {
2027  int returnCode;
2028  Vfd *vfdP;
2029 
2030  Assert(FileIsValid(file));
2031 
2032  DO_DB(elog(LOG, "FileRead: %d (%s) " INT64_FORMAT " %d %p",
2033  file, VfdCache[file].fileName,
2034  (int64) offset,
2035  amount, buffer));
2036 
2037  returnCode = FileAccess(file);
2038  if (returnCode < 0)
2039  return returnCode;
2040 
2041  vfdP = &VfdCache[file];
2042 
2043 retry:
2044  pgstat_report_wait_start(wait_event_info);
2045  returnCode = pg_pread(vfdP->fd, buffer, amount, offset);
2047 
2048  if (returnCode < 0)
2049  {
2050  /*
2051  * Windows may run out of kernel buffers and return "Insufficient
2052  * system resources" error. Wait a bit and retry to solve it.
2053  *
2054  * It is rumored that EINTR is also possible on some Unix filesystems,
2055  * in which case immediate retry is indicated.
2056  */
2057 #ifdef WIN32
2058  DWORD error = GetLastError();
2059 
2060  switch (error)
2061  {
2062  case ERROR_NO_SYSTEM_RESOURCES:
2063  pg_usleep(1000L);
2064  errno = EINTR;
2065  break;
2066  default:
2067  _dosmaperr(error);
2068  break;
2069  }
2070 #endif
2071  /* OK to retry if interrupted */
2072  if (errno == EINTR)
2073  goto retry;
2074  }
2075 
2076  return returnCode;
2077 }
static void pgstat_report_wait_end(void)
Definition: wait_event.h:277
static void error(void)
Definition: sql-dyntest.c:147
#define DO_DB(A)
Definition: fd.c:176
void _dosmaperr(unsigned long)
Definition: win32error.c:171
static Vfd * VfdCache
Definition: fd.c:212
#define LOG
Definition: elog.h:26
ssize_t pg_pread(int fd, void *buf, size_t nbyte, off_t offset)
Definition: pread.c:27
void pg_usleep(long microsec)
Definition: signal.c:53
Definition: fd.c:192
int fd
Definition: fd.c:194
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:261
#define FileIsValid(file)
Definition: fd.c:182
static int FileAccess(File file)
Definition: fd.c:1401
#define Assert(condition)
Definition: c.h:804
#define INT64_FORMAT
Definition: c.h:483
#define elog(elevel,...)
Definition: elog.h:232
#define EINTR
Definition: win32_port.h:343

◆ FileSize()

off_t FileSize ( File  file)

Definition at line 2199 of file fd.c.

References Assert, DO_DB, elog, vfd::fd, FileAccess(), FileIsNotOpen, FileIsValid, vfd::fileName, and LOG.

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

2200 {
2201  Assert(FileIsValid(file));
2202 
2203  DO_DB(elog(LOG, "FileSize %d (%s)",
2204  file, VfdCache[file].fileName));
2205 
2206  if (FileIsNotOpen(file))
2207  {
2208  if (FileAccess(file) < 0)
2209  return (off_t) -1;
2210  }
2211 
2212  return lseek(VfdCache[file].fd, 0, SEEK_END);
2213 }
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define FileIsNotOpen(file)
Definition: fd.c:185
#define FileIsValid(file)
Definition: fd.c:182
static int FileAccess(File file)
Definition: fd.c:1401
#define Assert(condition)
Definition: c.h:804
#define elog(elevel,...)
Definition: elog.h:232

◆ FileSync()

int FileSync ( File  file,
uint32  wait_event_info 
)

Definition at line 2178 of file fd.c.

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

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

2179 {
2180  int returnCode;
2181 
2182  Assert(FileIsValid(file));
2183 
2184  DO_DB(elog(LOG, "FileSync: %d (%s)",
2185  file, VfdCache[file].fileName));
2186 
2187  returnCode = FileAccess(file);
2188  if (returnCode < 0)
2189  return returnCode;
2190 
2191  pgstat_report_wait_start(wait_event_info);
2192  returnCode = pg_fsync(VfdCache[file].fd);
2194 
2195  return returnCode;
2196 }
static void pgstat_report_wait_end(void)
Definition: wait_event.h:277
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:261
#define FileIsValid(file)
Definition: fd.c:182
static int FileAccess(File file)
Definition: fd.c:1401
#define Assert(condition)
Definition: c.h:804
#define elog(elevel,...)
Definition: elog.h:232
int pg_fsync(int fd)
Definition: fd.c:352

◆ FileTruncate()

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

Definition at line 2216 of file fd.c.

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

Referenced by BufFileTruncateShared(), and mdtruncate().

2217 {
2218  int returnCode;
2219 
2220  Assert(FileIsValid(file));
2221 
2222  DO_DB(elog(LOG, "FileTruncate %d (%s)",
2223  file, VfdCache[file].fileName));
2224 
2225  returnCode = FileAccess(file);
2226  if (returnCode < 0)
2227  return returnCode;
2228 
2229  pgstat_report_wait_start(wait_event_info);
2230  returnCode = ftruncate(VfdCache[file].fd, offset);
2232 
2233  if (returnCode == 0 && VfdCache[file].fileSize > offset)
2234  {
2235  /* adjust our state for truncation of a temp file */
2236  Assert(VfdCache[file].fdstate & FD_TEMP_FILE_LIMIT);
2237  temporary_files_size -= VfdCache[file].fileSize - offset;
2238  VfdCache[file].fileSize = offset;
2239  }
2240 
2241  return returnCode;
2242 }
static void pgstat_report_wait_end(void)
Definition: wait_event.h:277
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:190
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
off_t fileSize
Definition: fd.c:200
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:261
#define FileIsValid(file)
Definition: fd.c:182
static uint64 temporary_files_size
Definition: fd.c:232
static int FileAccess(File file)
Definition: fd.c:1401
#define Assert(condition)
Definition: c.h:804
#define elog(elevel,...)
Definition: elog.h:232
#define ftruncate(a, b)
Definition: win32_port.h:65

◆ FileWrite()

int FileWrite ( File  file,
char *  buffer,
int  amount,
off_t  offset,
uint32  wait_event_info 
)

Definition at line 2080 of file fd.c.

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

Referenced by BufFileDumpBuffer(), logical_heap_rewrite_flush_mappings(), mdextend(), and mdwrite().

2082 {
2083  int returnCode;
2084  Vfd *vfdP;
2085 
2086  Assert(FileIsValid(file));
2087 
2088  DO_DB(elog(LOG, "FileWrite: %d (%s) " INT64_FORMAT " %d %p",
2089  file, VfdCache[file].fileName,
2090  (int64) offset,
2091  amount, buffer));
2092 
2093  returnCode = FileAccess(file);
2094  if (returnCode < 0)
2095  return returnCode;
2096 
2097  vfdP = &VfdCache[file];
2098 
2099  /*
2100  * If enforcing temp_file_limit and it's a temp file, check to see if the
2101  * write would overrun temp_file_limit, and throw error if so. Note: it's
2102  * really a modularity violation to throw error here; we should set errno
2103  * and return -1. However, there's no way to report a suitable error
2104  * message if we do that. All current callers would just throw error
2105  * immediately anyway, so this is safe at present.
2106  */
2107  if (temp_file_limit >= 0 && (vfdP->fdstate & FD_TEMP_FILE_LIMIT))
2108  {
2109  off_t past_write = offset + amount;
2110 
2111  if (past_write > vfdP->fileSize)
2112  {
2113  uint64 newTotal = temporary_files_size;
2114 
2115  newTotal += past_write - vfdP->fileSize;
2116  if (newTotal > (uint64) temp_file_limit * (uint64) 1024)
2117  ereport(ERROR,
2118  (errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED),
2119  errmsg("temporary file size exceeds temp_file_limit (%dkB)",
2120  temp_file_limit)));
2121  }
2122  }
2123 
2124 retry:
2125  errno = 0;
2126  pgstat_report_wait_start(wait_event_info);
2127  returnCode = pg_pwrite(VfdCache[file].fd, buffer, amount, offset);
2129 
2130  /* if write didn't set errno, assume problem is no disk space */
2131  if (returnCode != amount && errno == 0)
2132  errno = ENOSPC;
2133 
2134  if (returnCode >= 0)
2135  {
2136  /*
2137  * Maintain fileSize and temporary_files_size if it's a temp file.
2138  */
2139  if (vfdP->fdstate & FD_TEMP_FILE_LIMIT)
2140  {
2141  off_t past_write = offset + amount;
2142 
2143  if (past_write > vfdP->fileSize)
2144  {
2145  temporary_files_size += past_write - vfdP->fileSize;
2146  vfdP->fileSize = past_write;
2147  }
2148  }
2149  }
2150  else
2151  {
2152  /*
2153  * See comments in FileRead()
2154  */
2155 #ifdef WIN32
2156  DWORD error = GetLastError();
2157 
2158  switch (error)
2159  {
2160  case ERROR_NO_SYSTEM_RESOURCES:
2161  pg_usleep(1000L);
2162  errno = EINTR;
2163  break;
2164  default:
2165  _dosmaperr(error);
2166  break;
2167  }
2168 #endif
2169  /* OK to retry if interrupted */
2170  if (errno == EINTR)
2171  goto retry;
2172  }
2173 
2174  return returnCode;
2175 }
static void pgstat_report_wait_end(void)
Definition: wait_event.h:277
static void error(void)
Definition: sql-dyntest.c:147
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:190
#define DO_DB(A)
Definition: fd.c:176
void _dosmaperr(unsigned long)
Definition: win32error.c:171
static Vfd * VfdCache
Definition: fd.c:212
int errcode(int sqlerrcode)
Definition: elog.c:698
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ssize_t pg_pwrite(int fd, const void *buf, size_t nbyte, off_t offset)
Definition: pwrite.c:27
void pg_usleep(long microsec)
Definition: signal.c:53
#define ERROR
Definition: elog.h:46
unsigned short fdstate
Definition: fd.c:195
Definition: fd.c:192
off_t fileSize
Definition: fd.c:200
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:261
#define FileIsValid(file)
Definition: fd.c:182
static uint64 temporary_files_size
Definition: fd.c:232
#define ereport(elevel,...)
Definition: elog.h:157
static int FileAccess(File file)
Definition: fd.c:1401
#define Assert(condition)
Definition: c.h:804
#define INT64_FORMAT
Definition: c.h:483
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
#define EINTR
Definition: win32_port.h:343
int temp_file_limit
Definition: guc.c:578

◆ FileWriteback()

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

Definition at line 2001 of file fd.c.

References Assert, DO_DB, elog, vfd::fd, FileAccess(), FileIsValid, vfd::fileName, INT64_FORMAT, LOG, pg_flush_data(), pgstat_report_wait_end(), and pgstat_report_wait_start().

Referenced by mdwriteback().

2002 {
2003  int returnCode;
2004 
2005  Assert(FileIsValid(file));
2006 
2007  DO_DB(elog(LOG, "FileWriteback: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
2008  file, VfdCache[file].fileName,
2009  (int64) offset, (int64) nbytes));
2010 
2011  if (nbytes <= 0)
2012  return;
2013 
2014  returnCode = FileAccess(file);
2015  if (returnCode < 0)
2016  return;
2017 
2018  pgstat_report_wait_start(wait_event_info);
2019  pg_flush_data(VfdCache[file].fd, offset, nbytes);
2021 }
static void pgstat_report_wait_end(void)
Definition: wait_event.h:277
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:261
void pg_flush_data(int fd, off_t offset, off_t nbytes)
Definition: fd.c:462
#define FileIsValid(file)
Definition: fd.c:182
static int FileAccess(File file)
Definition: fd.c:1401
#define Assert(condition)
Definition: c.h:804
#define INT64_FORMAT
Definition: c.h:483
#define elog(elevel,...)
Definition: elog.h:232

◆ FreeDesc()

static int FreeDesc ( AllocateDesc desc)
static

Definition at line 2533 of file fd.c.

References 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().

2534 {
2535  int result;
2536 
2537  /* Close the underlying object */
2538  switch (desc->kind)
2539  {
2540  case AllocateDescFile:
2541  result = fclose(desc->desc.file);
2542  break;
2543  case AllocateDescPipe:
2544  result = pclose(desc->desc.file);
2545  break;
2546  case AllocateDescDir:
2547  result = closedir(desc->desc.dir);
2548  break;
2549  case AllocateDescRawFD:
2550  result = close(desc->desc.fd);
2551  break;
2552  default:
2553  elog(ERROR, "AllocateDesc kind not recognized");
2554  result = 0; /* keep compiler quiet */
2555  break;
2556  }
2557 
2558  /* Compact storage in the allocatedDescs array */
2561 
2562  return result;
2563 }
union AllocateDesc::@18 desc
static AllocateDesc * allocatedDescs
Definition: fd.c:260
DIR * dir
Definition: fd.c:253
int closedir(DIR *)
Definition: dirent.c:123
AllocateDescKind kind
Definition: fd.c:248
#define ERROR
Definition: elog.h:46
FILE * file
Definition: fd.c:252
int fd
Definition: fd.c:254
#define elog(elevel,...)
Definition: elog.h:232
#define close(a)
Definition: win32.h:12
static int numAllocatedDescs
Definition: fd.c:258

◆ FreeDir()

int FreeDir ( DIR dir)

Definition at line 2752 of file fd.c.

References 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_start_backup(), dsm_cleanup_for_mmap(), extension_file_exists(), get_ext_ver_list(), getInstallationPaths(), movedb(), ParseTzFile(), perform_base_backup(), pg_available_extension_versions(), pg_available_extensions(), pg_logdir_ls_internal(), pg_ls_dir(), pg_ls_dir_files(), pg_tablespace_databases(), pg_tzenumerate_end(), pg_tzenumerate_next(), pgarch_readyXlog(), pgstat_reset_remove_files(), RelationCacheInitFileRemove(), RelationCacheInitFileRemoveInDir(), RemoveNonParentXlogFiles(), RemoveOldXlogFiles(), RemovePgTempFiles(), RemovePgTempFilesInDir(), RemovePgTempRelationFiles(), RemovePgTempRelationFilesInDbspace(), RemoveTempXlogFiles(), ReorderBufferCleanupSerializedTXNs(), ResetUnloggedRelations(), ResetUnloggedRelationsInDbspaceDir(), ResetUnloggedRelationsInTablespaceDir(), restoreTwoPhaseData(), scan_directory_ci(), sendDir(), SlruScanDirectory(), StartupReorderBuffer(), StartupReplicationSlots(), SyncDataDirectory(), UpdateLogicalMappings(), and walkdir().

2753 {
2754  int i;
2755 
2756  /* Nothing to do if AllocateDir failed */
2757  if (dir == NULL)
2758  return 0;
2759 
2760  DO_DB(elog(LOG, "FreeDir: Allocated %d", numAllocatedDescs));
2761 
2762  /* Remove dir from list of allocated dirs, if it's present */
2763  for (i = numAllocatedDescs; --i >= 0;)
2764  {
2765  AllocateDesc *desc = &allocatedDescs[i];
2766 
2767  if (desc->kind == AllocateDescDir && desc->desc.dir == dir)
2768  return FreeDesc(desc);
2769  }
2770 
2771  /* Only get here if someone passes us a dir not in allocatedDescs */
2772  elog(WARNING, "dir passed to FreeDir was not obtained from AllocateDir");
2773 
2774  return closedir(dir);
2775 }
union AllocateDesc::@18 desc
static AllocateDesc * allocatedDescs
Definition: fd.c:260
DIR * dir
Definition: fd.c:253
#define DO_DB(A)
Definition: fd.c:176
int closedir(DIR *)
Definition: dirent.c:123
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:248
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2533
#define WARNING
Definition: elog.h:40
#define elog(elevel,...)
Definition: elog.h:232
int i
static int numAllocatedDescs
Definition: fd.c:258

◆ FreeFile()

int FreeFile ( FILE *  file)

Definition at line 2572 of file fd.c.

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

Referenced by _ShowOption(), AlterSystemSetConfigFile(), apw_dump_now(), apw_load_buffers(), BackendRun(), checkControlFile(), do_pg_start_backup(), do_pg_stop_backup(), EndCopy(), EndCopyFrom(), entry_reset(), existsTimeLineHistory(), ExportSnapshot(), fill_hba_view(), gc_qtexts(), ImportSnapshot(), load_dh_file(), load_hba(), load_ident(), load_relcache_init_file(), parse_extension_control_file(), ParseTzFile(), pg_backup_start_time(), pg_current_logfile(), pg_file_write_internal(), pg_promote(), PGSharedMemoryAttach(), pgss_shmem_shutdown(), pgss_shmem_startup(), pgstat_read_db_statsfile(), pgstat_read_db_statsfile_timestamp(), pgstat_read_statsfiles(), pgstat_write_db_statsfile(), pgstat_write_statsfiles(), PostmasterMarkPIDForWorkerNotify(), read_backup_label(), read_binary_file(), read_tablespace_map(), read_whole_file(), readTimeLineHistory(), tokenize_inc_file(), tsearch_readline_end(), ValidatePgVersion(), write_relcache_init_file(), XLogArchiveForceDone(), and XLogArchiveNotify().

2573 {
2574  int i;
2575 
2576  DO_DB(elog(LOG, "FreeFile: Allocated %d", numAllocatedDescs));
2577 
2578  /* Remove file from list of allocated files, if it's present */
2579  for (i = numAllocatedDescs; --i >= 0;)
2580  {
2581  AllocateDesc *desc = &allocatedDescs[i];
2582 
2583  if (desc->kind == AllocateDescFile && desc->desc.file == file)
2584  return FreeDesc(desc);
2585  }
2586 
2587  /* Only get here if someone passes us a file not in allocatedDescs */
2588  elog(WARNING, "file passed to FreeFile was not obtained from AllocateFile");
2589 
2590  return fclose(file);
2591 }
union AllocateDesc::@18 desc
static AllocateDesc * allocatedDescs
Definition: fd.c:260
#define DO_DB(A)
Definition: fd.c:176
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:248
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2533
#define WARNING
Definition: elog.h:40
FILE * file
Definition: fd.c:252
#define elog(elevel,...)
Definition: elog.h:232
int i
static int numAllocatedDescs
Definition: fd.c:258

◆ FreeVfd()

static void FreeVfd ( File  file)
static

Definition at line 1381 of file fd.c.

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

Referenced by FileClose(), and PathNameOpenFilePerm().

1382 {
1383  Vfd *vfdP = &VfdCache[file];
1384 
1385  DO_DB(elog(LOG, "FreeVfd: %d (%s)",
1386  file, vfdP->fileName ? vfdP->fileName : ""));
1387 
1388  if (vfdP->fileName != NULL)
1389  {
1390  free(vfdP->fileName);
1391  vfdP->fileName = NULL;
1392  }
1393  vfdP->fdstate = 0x0;
1394 
1395  vfdP->nextFree = VfdCache[0].nextFree;
1396  VfdCache[0].nextFree = file;
1397 }
File nextFree
Definition: fd.c:197
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
#define LOG
Definition: elog.h:26
char * fileName
Definition: fd.c:201
unsigned short fdstate
Definition: fd.c:195
Definition: fd.c:192
#define free(a)
Definition: header.h:65
#define elog(elevel,...)
Definition: elog.h:232

◆ fsync_fname()

void fsync_fname ( const char *  fname,
bool  isdir 
)

Definition at line 666 of file fd.c.

References data_sync_elevel(), ERROR, and fsync_fname_ext().

Referenced by _CloseArchive(), CheckPointTwoPhase(), copydir(), CreateSlotOnDisk(), dir_close(), dir_finish(), dir_open_for_write(), main(), ReplicationSlotDropPtr(), ResetUnloggedRelationsInDbspaceDir(), RestoreSlotFromDisk(), SaveSlotToPath(), SimpleLruWriteAll(), SnapBuildRestore(), SnapBuildSerialize(), StartupReplicationSlots(), and tar_finish().

667 {
668  fsync_fname_ext(fname, isdir, false, data_sync_elevel(ERROR));
669 }
#define ERROR
Definition: elog.h:46
int data_sync_elevel(int elevel)
Definition: fd.c:3714
int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3575

◆ fsync_fname_ext()

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

Definition at line 3575 of file fd.c.

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

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

3576 {
3577  int fd;
3578  int flags;
3579  int returncode;
3580 
3581  /*
3582  * Some OSs require directories to be opened read-only whereas other
3583  * systems don't allow us to fsync files opened read-only; so we need both
3584  * cases here. Using O_RDWR will cause us to fail to fsync files that are
3585  * not writable by our userid, but we assume that's OK.
3586  */
3587  flags = PG_BINARY;
3588  if (!isdir)
3589  flags |= O_RDWR;
3590  else
3591  flags |= O_RDONLY;
3592 
3593  fd = OpenTransientFile(fname, flags);
3594 
3595  /*
3596  * Some OSs don't allow us to open directories at all (Windows returns
3597  * EACCES), just ignore the error in that case. If desired also silently
3598  * ignoring errors about unreadable files. Log others.
3599  */
3600  if (fd < 0 && isdir && (errno == EISDIR || errno == EACCES))
3601  return 0;
3602  else if (fd < 0 && ignore_perm && errno == EACCES)
3603  return 0;
3604  else if (fd < 0)
3605  {
3606  ereport(elevel,
3608  errmsg("could not open file \"%s\": %m", fname)));
3609  return -1;
3610  }
3611 
3612  returncode = pg_fsync(fd);
3613 
3614  /*
3615  * Some OSes don't allow us to fsync directories at all, so we can ignore
3616  * those errors. Anything else needs to be logged.
3617  */
3618  if (returncode != 0 && !(isdir && (errno == EBADF || errno == EINVAL)))
3619  {
3620  int save_errno;
3621 
3622  /* close file upon error, might not be in transaction context */
3623  save_errno = errno;
3624  (void) CloseTransientFile(fd);
3625  errno = save_errno;
3626 
3627  ereport(elevel,
3629  errmsg("could not fsync file \"%s\": %m", fname)));
3630  return -1;
3631  }
3632 
3633  if (CloseTransientFile(fd) != 0)
3634  {
3635  ereport(elevel,
3637  errmsg("could not close file \"%s\": %m", fname)));
3638  return -1;
3639  }
3640 
3641  return 0;
3642 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1271
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2423
int errcode_for_file_access(void)
Definition: elog.c:721
int CloseTransientFile(int fd)
Definition: fd.c:2600
static int elevel
Definition: vacuumlazy.c:400
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909
int pg_fsync(int fd)
Definition: fd.c:352

◆ fsync_parent_path()

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

Definition at line 3651 of file fd.c.

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

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

3652 {
3653  char parentpath[MAXPGPATH];
3654 
3655  strlcpy(parentpath, fname, MAXPGPATH);
3656  get_parent_directory(parentpath);
3657 
3658  /*
3659  * get_parent_directory() returns an empty string if the input argument is
3660  * just a file name (see comments in path.c), so handle that as being the
3661  * current directory.
3662  */
3663  if (strlen(parentpath) == 0)
3664  strlcpy(parentpath, ".", MAXPGPATH);
3665 
3666  if (fsync_fname_ext(parentpath, true, false, elevel) != 0)
3667  return -1;
3668 
3669  return 0;
3670 }
#define MAXPGPATH
void get_parent_directory(char *path)
Definition: path.c:854
static int elevel
Definition: vacuumlazy.c:400
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3575

◆ GetNextTempTableSpace()

Oid GetNextTempTableSpace ( void  )

Definition at line 2901 of file fd.c.

References InvalidOid, nextTempTableSpace, numTempTableSpaces, and tempTableSpaces.

Referenced by GetDefaultTablespace(), and OpenTemporaryFile().

2902 {
2903  if (numTempTableSpaces > 0)
2904  {
2905  /* Advance nextTempTableSpace counter with wraparound */
2907  nextTempTableSpace = 0;
2909  }
2910  return InvalidOid;
2911 }
static int numTempTableSpaces
Definition: fd.c:280
static int nextTempTableSpace
Definition: fd.c:281
#define InvalidOid
Definition: postgres_ext.h:36
static Oid * tempTableSpaces
Definition: fd.c:279

◆ GetTempTablespaces()

int GetTempTablespaces ( Oid tableSpaces,
int  numSpaces 
)

Definition at line 2883 of file fd.c.

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

Referenced by SharedFileSetInit().

2884 {
2885  int i;
2886 
2888  for (i = 0; i < numTempTableSpaces && i < numSpaces; ++i)
2889  tableSpaces[i] = tempTableSpaces[i];
2890 
2891  return i;
2892 }
static int numTempTableSpaces
Definition: fd.c:280
bool TempTablespacesAreSet(void)
Definition: fd.c:2868
#define Assert(condition)
Definition: c.h:804
static Oid * tempTableSpaces
Definition: fd.c:279
int i

◆ InitFileAccess()

void InitFileAccess ( void  )

Definition at line 873 of file fd.c.

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

Referenced by BaseInit().

874 {
875  Assert(SizeVfdCache == 0); /* call me only once */
876 
877  /* initialize cache header entry */
878  VfdCache = (Vfd *) malloc(sizeof(Vfd));
879  if (VfdCache == NULL)
880  ereport(FATAL,
881  (errcode(ERRCODE_OUT_OF_MEMORY),
882  errmsg("out of memory")));
883 
884  MemSet((char *) &(VfdCache[0]), 0, sizeof(Vfd));
886 
887  SizeVfdCache = 1;
888 
889  /* register proc-exit hook to ensure temp files are dropped at exit */
891 }
static void AtProcExit_Files(int code, Datum arg)
Definition: fd.c:2969
static Size SizeVfdCache
Definition: fd.c:213
void on_proc_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:305
static Vfd * VfdCache
Definition: fd.c:212
int errcode(int sqlerrcode)
Definition: elog.c:698
#define MemSet(start, val, len)
Definition: c.h:1008
#define malloc(a)
Definition: header.h:50
#define FATAL
Definition: elog.h:49
Definition: fd.c:192
int fd
Definition: fd.c:194
#define VFD_CLOSED
Definition: fd.c:180
#define ereport(elevel,...)
Definition: elog.h:157
#define Assert(condition)
Definition: c.h:804
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ Insert()

static void Insert ( File  file)
static

Definition at line 1222 of file fd.c.

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

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

1223 {
1224  Vfd *vfdP;
1225 
1226  Assert(file != 0);
1227 
1228  DO_DB(elog(LOG, "Insert %d (%s)",
1229  file, VfdCache[file].fileName));
1230  DO_DB(_dump_lru());
1231 
1232  vfdP = &VfdCache[file];
1233 
1234  vfdP->lruMoreRecently = 0;
1236  VfdCache[0].lruLessRecently = file;
1238 
1239  DO_DB(_dump_lru());
1240 }
File lruLessRecently
Definition: fd.c:199
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
#define LOG
Definition: elog.h:26
Definition: fd.c:192
#define Assert(condition)
Definition: c.h:804
File lruMoreRecently
Definition: fd.c:198
#define elog(elevel,...)
Definition: elog.h:232

◆ looks_like_temp_rel_name()

bool looks_like_temp_rel_name ( const char *  name)

Definition at line 3240 of file fd.c.

References CloseTransientFile(), ereport, errcode_for_file_access(), errmsg(), vfd::fd, forkname_chars(), LOG, and OpenTransientFile().

Referenced by RemovePgTempRelationFilesInDbspace(), and sendDir().

3241 {
3242  int pos;
3243  int savepos;
3244 
3245  /* Must start with "t". */
3246  if (name[0] != 't')
3247  return false;
3248 
3249  /* Followed by a non-empty string of digits and then an underscore. */
3250  for (pos = 1; isdigit((unsigned char) name[pos]); ++pos)
3251  ;
3252  if (pos == 1 || name[pos] != '_')
3253  return false;
3254 
3255  /* Followed by another nonempty string of digits. */
3256  for (savepos = ++pos; isdigit((unsigned char) name[pos]); ++pos)
3257  ;
3258  if (savepos == pos)
3259  return false;
3260 
3261  /* We might have _forkname or .segment or both. */
3262  if (name[pos] == '_')
3263  {
3264  int forkchar = forkname_chars(&name[pos + 1], NULL);
3265 
3266  if (forkchar <= 0)
3267  return false;
3268  pos += forkchar + 1;
3269  }
3270  if (name[pos] == '.')
3271  {
3272  int segchar;
3273 
3274  for (segchar = 1; isdigit((unsigned char) name[pos + segchar]); ++segchar)
3275  ;
3276  if (segchar <= 1)
3277  return false;
3278  pos += segchar;
3279  }
3280 
3281  /* Now we should be at the end. */
3282  if (name[pos] != '\0')
3283  return false;
3284  return true;
3285 }
int forkname_chars(const char *str, ForkNumber *fork)
Definition: relpath.c:81
const char * name
Definition: encode.c:515

◆ LruDelete()

static void LruDelete ( File  file)
static

Definition at line 1196 of file fd.c.

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

Referenced by closeAllVfds(), RegisterTemporaryFile(), and ReleaseLruFile().

1197 {
1198  Vfd *vfdP;
1199 
1200  Assert(file != 0);
1201 
1202  DO_DB(elog(LOG, "LruDelete %d (%s)",
1203  file, VfdCache[file].fileName));
1204 
1205  vfdP = &VfdCache[file];
1206 
1207  /*
1208  * Close the file. We aren't expecting this to fail; if it does, better
1209  * to leak the FD than to mess up our internal state.
1210  */
1211  if (close(vfdP->fd) != 0)
1213  "could not close file \"%s\": %m", vfdP->fileName);
1214  vfdP->fd = VFD_CLOSED;
1215  --nfile;
1216 
1217  /* delete the vfd record from the LRU ring */
1218  Delete(file);
1219 }
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:190
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
static void Delete(File file)
Definition: fd.c:1177
#define LOG
Definition: elog.h:26
char * fileName
Definition: fd.c:201
static int nfile
Definition: fd.c:218
unsigned short fdstate
Definition: fd.c:195
Definition: fd.c:192
int fd
Definition: fd.c:194
int data_sync_elevel(int elevel)
Definition: fd.c:3714
#define VFD_CLOSED
Definition: fd.c:180
#define Assert(condition)
Definition: c.h:804
#define elog(elevel,...)
Definition: elog.h:232
#define close(a)
Definition: win32.h:12

◆ LruInsert()

static int LruInsert ( File  file)
static

Definition at line 1244 of file fd.c.

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

Referenced by FileAccess().

1245 {
1246  Vfd *vfdP;
1247 
1248  Assert(file != 0);
1249 
1250  DO_DB(elog(LOG, "LruInsert %d (%s)",
1251  file, VfdCache[file].fileName));
1252 
1253  vfdP = &VfdCache[file];
1254 
1255  if (FileIsNotOpen(file))
1256  {
1257  /* Close excess kernel FDs. */
1258  ReleaseLruFiles();
1259 
1260  /*
1261  * The open could still fail for lack of file descriptors, eg due to
1262  * overall system file table being full. So, be prepared to release
1263  * another FD if necessary...
1264  */
1265  vfdP->fd = BasicOpenFilePerm(vfdP->fileName, vfdP->fileFlags,
1266  vfdP->fileMode);
1267  if (vfdP->fd < 0)
1268  {
1269  DO_DB(elog(LOG, "re-open failed: %m"));
1270  return -1;
1271  }
1272  else
1273  {
1274  ++nfile;
1275  }
1276  }
1277 
1278  /*
1279  * put it at the head of the Lru ring
1280  */
1281 
1282  Insert(file);
1283 
1284  return 0;
1285 }
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
#define LOG
Definition: elog.h:26
mode_t fileMode
Definition: fd.c:204
char * fileName
Definition: fd.c:201
static int nfile
Definition: fd.c:218
Definition: fd.c:192
int fd
Definition: fd.c:194
static void Insert(File file)
Definition: fd.c:1222
static void ReleaseLruFiles(void)
Definition: fd.c:1313
#define FileIsNotOpen(file)
Definition: fd.c:185
#define Assert(condition)
Definition: c.h:804
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1055
#define elog(elevel,...)
Definition: elog.h:232
int fileFlags
Definition: fd.c:203

◆ MakePGDirectory()

int MakePGDirectory ( const char *  directoryName)

◆ OpenPipeStream()

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

Definition at line 2476 of file fd.c.

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

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

2477 {
2478  FILE *file;
2479  int save_errno;
2480 
2481  DO_DB(elog(LOG, "OpenPipeStream: Allocated %d (%s)",
2482  numAllocatedDescs, command));
2483 
2484  /* Can we allocate another non-virtual FD? */
2485  if (!reserveAllocatedDesc())
2486  ereport(ERROR,
2487  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2488  errmsg("exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"",
2489  maxAllocatedDescs, command)));
2490 
2491  /* Close excess kernel FDs. */
2492  ReleaseLruFiles();
2493 
2494 TryAgain:
2495  fflush(stdout);
2496  fflush(stderr);
2498  errno = 0;
2499  file = popen(command, mode);
2500  save_errno = errno;
2502  errno = save_errno;
2503  if (file != NULL)
2504  {
2506 
2507  desc->kind = AllocateDescPipe;
2508  desc->desc.file = file;
2511  return desc->desc.file;
2512  }
2513 
2514  if (errno == EMFILE || errno == ENFILE)
2515  {
2516  ereport(LOG,
2517  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2518  errmsg("out of file descriptors: %m; release and retry")));
2519  if (ReleaseLruFile())
2520  goto TryAgain;
2521  errno = save_errno;
2522  }
2523 
2524  return NULL;
2525 }
static PgChecksumMode mode
Definition: pg_checksums.c:61
union AllocateDesc::@18 desc
static AllocateDesc * allocatedDescs
Definition: fd.c:260
#define DO_DB(A)
Definition: fd.c:176
int errcode(int sqlerrcode)
Definition: elog.c:698
static bool reserveAllocatedDesc(void)
Definition: fd.c:2298
#define SIGPIPE
Definition: win32_port.h:164
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:248
static bool ReleaseLruFile(void)
Definition: fd.c:1291
#define ERROR
Definition: elog.h:46
#define SIG_IGN
Definition: win32_port.h:156
static void ReleaseLruFiles(void)
Definition: fd.c:1313
FILE * file
Definition: fd.c:252
#define ereport(elevel,...)
Definition: elog.h:157
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:170
#define SIG_DFL
Definition: win32_port.h:154
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:723
SubTransactionId create_subid
Definition: fd.c:249
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
static int maxAllocatedDescs
Definition: fd.c:259
static int numAllocatedDescs
Definition: fd.c:258

◆ OpenTemporaryFile()

File OpenTemporaryFile ( bool  interXact)

Definition at line 1625 of file fd.c.

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

Referenced by BufFileCreateTemp(), and extendBufFile().

1626 {
1627  File file = 0;
1628 
1629  /*
1630  * Make sure the current resource owner has space for this File before we
1631  * open it, if we'll be registering it below.
1632  */
1633  if (!interXact)
1635 
1636  /*
1637  * If some temp tablespace(s) have been given to us, try to use the next
1638  * one. If a given tablespace can't be found, we silently fall back to
1639  * the database's default tablespace.
1640  *
1641  * BUT: if the temp file is slated to outlive the current transaction,
1642  * force it into the database's default tablespace, so that it will not
1643  * pose a threat to possible tablespace drop attempts.
1644  */
1645  if (numTempTableSpaces > 0 && !interXact)
1646  {
1647  Oid tblspcOid = GetNextTempTableSpace();
1648 
1649  if (OidIsValid(tblspcOid))
1650  file = OpenTemporaryFileInTablespace(tblspcOid, false);
1651  }
1652 
1653  /*
1654  * If not, or if tablespace is bad, create in database's default
1655  * tablespace. MyDatabaseTableSpace should normally be set before we get
1656  * here, but just in case it isn't, fall back to pg_default tablespace.
1657  */
1658  if (file <= 0)
1661  DEFAULTTABLESPACE_OID,
1662  true);
1663 
1664  /* Mark it for deletion at close and temporary file size limit */
1666 
1667  /* Register it with the current resource owner */
1668  if (!interXact)
1669  RegisterTemporaryFile(file);
1670 
1671  return file;
1672 }
static File OpenTemporaryFileInTablespace(Oid tblspcOid, bool rejectError)
Definition: fd.c:1703
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:190
ResourceOwner CurrentResourceOwner
Definition: resowner.c:146
#define FD_DELETE_AT_CLOSE
Definition: fd.c:188
static Vfd * VfdCache
Definition: fd.c:212
static int numTempTableSpaces
Definition: fd.c:280
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
Oid MyDatabaseTableSpace
Definition: globals.c:90
Oid GetNextTempTableSpace(void)
Definition: fd.c:2901
unsigned short fdstate
Definition: fd.c:195
static void RegisterTemporaryFile(File file)
Definition: fd.c:1456
void ResourceOwnerEnlargeFiles(ResourceOwner owner)
Definition: resowner.c:1286
int File
Definition: fd.h:53

◆ OpenTemporaryFileInTablespace()

static File OpenTemporaryFileInTablespace ( Oid  tblspcOid,
bool  rejectError 
)
static

Definition at line 1703 of file fd.c.

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

Referenced by OpenTemporaryFile().

1704 {
1705  char tempdirpath[MAXPGPATH];
1706  char tempfilepath[MAXPGPATH];
1707  File file;
1708 
1709  TempTablespacePath(tempdirpath, tblspcOid);
1710 
1711  /*
1712  * Generate a tempfile name that should be unique within the current
1713  * database instance.
1714  */
1715  snprintf(tempfilepath, sizeof(tempfilepath), "%s/%s%d.%ld",
1716  tempdirpath, PG_TEMP_FILE_PREFIX, MyProcPid, tempFileCounter++);
1717 
1718  /*
1719  * Open the file. Note: we don't use O_EXCL, in case there is an orphaned
1720  * temp file that can be reused.
1721  */
1722  file = PathNameOpenFile(tempfilepath,
1723  O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1724  if (file <= 0)
1725  {
1726  /*
1727  * We might need to create the tablespace's tempfile directory, if no
1728  * one has yet done so.
1729  *
1730  * Don't check for an error from MakePGDirectory; it could fail if
1731  * someone else just did the same thing. If it doesn't work then
1732  * we'll bomb out on the second create attempt, instead.
1733  */
1734  (void) MakePGDirectory(tempdirpath);
1735 
1736  file = PathNameOpenFile(tempfilepath,
1737  O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1738  if (file <= 0 && rejectError)
1739  elog(ERROR, "could not create temporary file \"%s\": %m",
1740  tempfilepath);
1741  }
1742 
1743  return file;
1744 }
int MyProcPid
Definition: globals.c:43
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1484
void TempTablespacePath(char *path, Oid tablespace)
Definition: fd.c:1678
#define PG_BINARY
Definition: c.h:1271
#define ERROR
Definition: elog.h:46
#define PG_TEMP_FILE_PREFIX
Definition: pg_checksums.c:59
#define MAXPGPATH
int MakePGDirectory(const char *directoryName)
Definition: fd.c:3691
static long tempFileCounter
Definition: fd.c:271
#define elog(elevel,...)
Definition: elog.h:232
#define snprintf
Definition: port.h:216
int File
Definition: fd.h:53

◆ OpenTransientFile()

◆ OpenTransientFilePerm()

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

Definition at line 2432 of file fd.c.

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

Referenced by be_lo_export(), and OpenTransientFile().

2433 {
2434  int fd;
2435 
2436  DO_DB(elog(LOG, "OpenTransientFile: Allocated %d (%s)",
2437  numAllocatedDescs, fileName));
2438 
2439  /* Can we allocate another non-virtual FD? */
2440  if (!reserveAllocatedDesc())
2441  ereport(ERROR,
2442  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2443  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2444  maxAllocatedDescs, fileName)));
2445 
2446  /* Close excess kernel FDs. */
2447  ReleaseLruFiles();
2448 
2449  fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
2450 
2451  if (fd >= 0)
2452  {
2454 
2455  desc->kind = AllocateDescRawFD;
2456  desc->desc.fd = fd;
2459 
2460  return fd;
2461  }
2462 
2463  return -1; /* failure */
2464 }
union AllocateDesc::@18 desc
static AllocateDesc * allocatedDescs
Definition: fd.c:260
#define DO_DB(A)
Definition: fd.c:176
int errcode(int sqlerrcode)
Definition: elog.c:698
static bool reserveAllocatedDesc(void)
Definition: fd.c:2298
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:248
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define ERROR
Definition: elog.h:46
static void ReleaseLruFiles(void)
Definition: fd.c:1313
#define ereport(elevel,...)
Definition: elog.h:157
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:723
SubTransactionId create_subid
Definition: fd.c:249
int fd
Definition: fd.c:254
int errmsg(const char *fmt,...)
Definition: elog.c:909
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1055
#define elog(elevel,...)
Definition: elog.h:232
static int maxAllocatedDescs
Definition: fd.c:259
static int numAllocatedDescs
Definition: fd.c:258

◆ PathNameCreateTemporaryDir()

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

Definition at line 1561 of file fd.c.

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

Referenced by SharedFileSetCreate().

1562 {
1563  if (MakePGDirectory(directory) < 0)
1564  {
1565  if (errno == EEXIST)
1566  return;
1567 
1568  /*
1569  * Failed. Try to create basedir first in case it's missing. Tolerate
1570  * EEXIST to close a race against another process following the same
1571  * algorithm.
1572  */
1573  if (MakePGDirectory(basedir) < 0 && errno != EEXIST)
1574  ereport(ERROR,
1576  errmsg("cannot create temporary directory \"%s\": %m",
1577  basedir)));
1578 
1579  /* Try again. */
1580  if (MakePGDirectory(directory) < 0 && errno != EEXIST)
1581  ereport(ERROR,
1583  errmsg("cannot create temporary subdirectory \"%s\": %m",
1584  directory)));
1585  }
1586 }
static char * basedir
#define ERROR
Definition: elog.h:46
int errcode_for_file_access(void)
Definition: elog.c:721
#define ereport(elevel,...)
Definition: elog.h:157
int MakePGDirectory(const char *directoryName)
Definition: fd.c:3691
static const char * directory
Definition: zic.c:632
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ PathNameCreateTemporaryFile()

File PathNameCreateTemporaryFile ( const char *  path,
bool  error_on_failure 
)

Definition at line 1760 of file fd.c.

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

Referenced by SharedFileSetCreate().

1761 {
1762  File file;
1763 
1765 
1766  /*
1767  * Open the file. Note: we don't use O_EXCL, in case there is an orphaned
1768  * temp file that can be reused.
1769  */
1770  file = PathNameOpenFile(path, O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1771  if (file <= 0)
1772  {
1773  if (error_on_failure)
1774  ereport(ERROR,
1776  errmsg("could not create temporary file \"%s\": %m",
1777  path)));
1778  else
1779  return file;
1780  }
1781 
1782  /* Mark it for temp_file_limit accounting. */
1784 
1785  /* Register it for automatic close. */
1786  RegisterTemporaryFile(file);
1787 
1788  return file;
1789 }
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1484
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:190
ResourceOwner CurrentResourceOwner
Definition: resowner.c:146
static Vfd * VfdCache
Definition: fd.c:212
#define PG_BINARY
Definition: c.h:1271
#define ERROR
Definition: elog.h:46
int errcode_for_file_access(void)
Definition: elog.c:721
unsigned short fdstate
Definition: fd.c:195
#define ereport(elevel,...)
Definition: elog.h:157
static void RegisterTemporaryFile(File file)
Definition: fd.c:1456
int errmsg(const char *fmt,...)
Definition: elog.c:909
void ResourceOwnerEnlargeFiles(ResourceOwner owner)
Definition: resowner.c:1286
int File
Definition: fd.h:53

◆ PathNameDeleteTemporaryDir()

void PathNameDeleteTemporaryDir ( const char *  dirname)

Definition at line 1592 of file fd.c.

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

Referenced by SharedFileSetDeleteAll().

1593 {
1594  struct stat statbuf;
1595 
1596  /* Silently ignore missing directory. */
1597  if (stat(dirname, &statbuf) != 0 && errno == ENOENT)
1598  return;
1599 
1600  /*
1601  * Currently, walkdir doesn't offer a way for our passed in function to
1602  * maintain state. Perhaps it should, so that we could tell the caller
1603  * whether this operation succeeded or failed. Since this operation is
1604  * used in a cleanup path, we wouldn't actually behave differently: we'll
1605  * just log failures.
1606  */
1607  walkdir(dirname, unlink_if_exists_fname, false, LOG);
1608 }
static void walkdir(const char *path, void(*action)(const char *fname, bool isdir, int elevel), bool process_symlinks, int elevel)
Definition: fd.c:3442
#define LOG
Definition: elog.h:26
static void unlink_if_exists_fname(const char *fname, bool isdir, int elevel)
Definition: fd.c:3550
#define stat
Definition: win32_port.h:275

◆ PathNameDeleteTemporaryFile()

bool PathNameDeleteTemporaryFile ( const char *  path,
bool  error_on_failure 
)

Definition at line 1827 of file fd.c.

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

Referenced by SharedFileSetDelete(), and unlink_if_exists_fname().

1828 {
1829  struct stat filestats;
1830  int stat_errno;
1831 
1832  /* Get the final size for pgstat reporting. */
1833  if (stat(path, &filestats) != 0)
1834  stat_errno = errno;
1835  else
1836  stat_errno = 0;
1837 
1838  /*
1839  * Unlike FileClose's automatic file deletion code, we tolerate
1840  * non-existence to support BufFileDeleteShared which doesn't know how
1841  * many segments it has to delete until it runs out.
1842  */
1843  if (stat_errno == ENOENT)
1844  return false;
1845 
1846  if (unlink(path) < 0)
1847  {
1848  if (errno != ENOENT)
1849  ereport(error_on_failure ? ERROR : LOG,
1851  errmsg("could not unlink temporary file \"%s\": %m",
1852  path)));
1853  return false;
1854  }
1855 
1856  if (stat_errno == 0)
1857  ReportTemporaryFileUsage(path, filestats.st_size);
1858  else
1859  {
1860  errno = stat_errno;
1861  ereport(LOG,
1863  errmsg("could not stat file \"%s\": %m", path)));
1864  }
1865 
1866  return true;
1867 }
#define LOG
Definition: elog.h:26
#define ERROR
Definition: elog.h:46
int errcode_for_file_access(void)
Definition: elog.c:721
static void ReportTemporaryFileUsage(const char *path, off_t size)
Definition: fd.c:1437
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define stat
Definition: win32_port.h:275

◆ PathNameOpenFile()

File PathNameOpenFile ( const char *  fileName,
int  fileFlags 
)

Definition at line 1484 of file fd.c.

References PathNameOpenFilePerm(), and pg_file_create_mode.

Referenced by _mdfd_openseg(), logical_rewrite_log_mapping(), mdcreate(), mdopenfork(), mdsyncfiletag(), OpenTemporaryFileInTablespace(), PathNameCreateTemporaryFile(), PathNameOpenTemporaryFile(), and ReorderBufferRestoreChanges().

1485 {
1486  return PathNameOpenFilePerm(fileName, fileFlags, pg_file_create_mode);
1487 }
File PathNameOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1497
int pg_file_create_mode
Definition: file_perm.c:19

◆ PathNameOpenFilePerm()

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

Definition at line 1497 of file fd.c.

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, ReleaseLruFiles(), and vfd::resowner.

Referenced by PathNameOpenFile().

1498 {
1499  char *fnamecopy;
1500  File file;
1501  Vfd *vfdP;
1502 
1503  DO_DB(elog(LOG, "PathNameOpenFilePerm: %s %x %o",
1504  fileName, fileFlags, fileMode));
1505 
1506  /*
1507  * We need a malloc'd copy of the file name; fail cleanly if no room.
1508  */
1509  fnamecopy = strdup(fileName);
1510  if (fnamecopy == NULL)
1511  ereport(ERROR,
1512  (errcode(ERRCODE_OUT_OF_MEMORY),
1513  errmsg("out of memory")));
1514 
1515  file = AllocateVfd();
1516  vfdP = &VfdCache[file];
1517 
1518  /* Close excess kernel FDs. */
1519  ReleaseLruFiles();
1520 
1521  vfdP->fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
1522 
1523  if (vfdP->fd < 0)
1524  {
1525  int save_errno = errno;
1526 
1527  FreeVfd(file);
1528  free(fnamecopy);
1529  errno = save_errno;
1530  return -1;
1531  }
1532  ++nfile;
1533  DO_DB(elog(LOG, "PathNameOpenFile: success %d",
1534  vfdP->fd));
1535 
1536  vfdP->fileName = fnamecopy;
1537  /* Saved flags are adjusted to be OK for re-opening file */
1538  vfdP->fileFlags = fileFlags & ~(O_CREAT | O_TRUNC | O_EXCL);
1539  vfdP->fileMode = fileMode;
1540  vfdP->fileSize = 0;
1541  vfdP->fdstate = 0x0;
1542  vfdP->resowner = NULL;
1543 
1544  Insert(file);
1545 
1546  return file;
1547 }
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
int errcode(int sqlerrcode)
Definition: elog.c:698
#define LOG
Definition: elog.h:26
mode_t fileMode
Definition: fd.c:204
#define ERROR
Definition: elog.h:46
char * fileName
Definition: fd.c:201
static int nfile
Definition: fd.c:218
static File AllocateVfd(void)
Definition: fd.c:1323
unsigned short fdstate
Definition: fd.c:195
Definition: fd.c:192
off_t fileSize
Definition: fd.c:200
int fd
Definition: fd.c:194
static void Insert(File file)
Definition: fd.c:1222
ResourceOwner resowner
Definition: fd.c:196
static void ReleaseLruFiles(void)
Definition: fd.c:1313
#define ereport(elevel,...)
Definition: elog.h:157
#define free(a)
Definition: header.h:65
int errmsg(const char *fmt,...)
Definition: elog.c:909
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1055
#define elog(elevel,...)
Definition: elog.h:232
static void FreeVfd(File file)
Definition: fd.c:1381
int fileFlags
Definition: fd.c:203
int File
Definition: fd.h:53

◆ PathNameOpenTemporaryFile()

File PathNameOpenTemporaryFile ( const char *  path,
int  mode 
)

Definition at line 1798 of file fd.c.

References CurrentResourceOwner, ereport, errcode_for_file_access(), errmsg(), ERROR, PathNameOpenFile(), PG_BINARY, RegisterTemporaryFile(), and ResourceOwnerEnlargeFiles().

Referenced by SharedFileSetOpen().

1799 {
1800  File file;
1801 
1803 
1804  file = PathNameOpenFile(path, mode | PG_BINARY);
1805 
1806  /* If no such file, then we don't raise an error. */
1807  if (file <= 0 && errno != ENOENT)
1808  ereport(ERROR,
1810  errmsg("could not open temporary file \"%s\": %m",
1811  path)));
1812 
1813  if (file > 0)
1814  {
1815  /* Register it for automatic close. */
1816  RegisterTemporaryFile(file);
1817  }
1818 
1819  return file;
1820 }
static PgChecksumMode mode
Definition: pg_checksums.c:61
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1484
ResourceOwner CurrentResourceOwner
Definition: resowner.c:146
#define PG_BINARY
Definition: c.h:1271
#define ERROR
Definition: elog.h:46
int errcode_for_file_access(void)
Definition: elog.c:721
#define ereport(elevel,...)
Definition: elog.h:157
static void RegisterTemporaryFile(File file)
Definition: fd.c:1456
int errmsg(const char *fmt,...)
Definition: elog.c:909
void ResourceOwnerEnlargeFiles(ResourceOwner owner)
Definition: resowner.c:1286
int File
Definition: fd.h:53

◆ pg_fdatasync()

int pg_fdatasync ( int  fd)

Definition at line 442 of file fd.c.

References enableFsync, and fsync.

Referenced by issue_xlog_fsync().

443 {
444  if (enableFsync)
445  {
446 #ifdef HAVE_FDATASYNC
447  return fdatasync(fd);
448 #else
449  return fsync(fd);
450 #endif
451  }
452  else
453  return 0;
454 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define fsync(fd)
Definition: win32_port.h:68
bool enableFsync
Definition: globals.c:122

◆ pg_flush_data()

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

Definition at line 462 of file fd.c.

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

Referenced by copy_file(), FileWriteback(), and walkdir().

463 {
464  /*
465  * Right now file flushing is primarily used to avoid making later
466  * fsync()/fdatasync() calls have less impact. Thus don't trigger flushes
467  * if fsyncs are disabled - that's a decision we might want to make
468  * configurable at some point.
469  */
470  if (!enableFsync)
471  return;
472 
473  /*
474  * We compile all alternatives that are supported on the current platform,
475  * to find portability problems more easily.
476  */
477 #if defined(HAVE_SYNC_FILE_RANGE)
478  {
479  int rc;
480  static bool not_implemented_by_kernel = false;
481 
482  if (not_implemented_by_kernel)
483  return;
484 
485  /*
486  * sync_file_range(SYNC_FILE_RANGE_WRITE), currently linux specific,
487  * tells the OS that writeback for the specified blocks should be
488  * started, but that we don't want to wait for completion. Note that
489  * this call might block if too much dirty data exists in the range.
490  * This is the preferable method on OSs supporting it, as it works
491  * reliably when available (contrast to msync()) and doesn't flush out
492  * clean data (like FADV_DONTNEED).
493  */
494  rc = sync_file_range(fd, offset, nbytes,
495  SYNC_FILE_RANGE_WRITE);
496  if (rc != 0)
497  {
498  int elevel;
499 
500  /*
501  * For systems that don't have an implementation of
502  * sync_file_range() such as Windows WSL, generate only one
503  * warning and then suppress all further attempts by this process.
504  */
505  if (errno == ENOSYS)
506  {
507  elevel = WARNING;
508  not_implemented_by_kernel = true;
509  }
510  else
511  elevel = data_sync_elevel(WARNING);
512 
513  ereport(elevel,
515  errmsg("could not flush dirty data: %m")));
516  }
517 
518  return;
519  }
520 #endif
521 #if !defined(WIN32) && defined(MS_ASYNC)
522  {
523  void *p;
524  static int pagesize = 0;
525 
526  /*
527  * On several OSs msync(MS_ASYNC) on a mmap'ed file triggers
528  * writeback. On linux it only does so if MS_SYNC is specified, but
529  * then it does the writeback synchronously. Luckily all common linux
530  * systems have sync_file_range(). This is preferable over
531  * FADV_DONTNEED because it doesn't flush out clean data.
532  *
533  * We map the file (mmap()), tell the kernel to sync back the contents
534  * (msync()), and then remove the mapping again (munmap()).
535  */
536 
537  /* mmap() needs actual length if we want to map whole file */
538  if (offset == 0 && nbytes == 0)
539  {
540  nbytes = lseek(fd, 0, SEEK_END);
541  if (nbytes < 0)
542  {
545  errmsg("could not determine dirty data size: %m")));
546  return;
547  }
548  }
549 
550  /*
551  * Some platforms reject partial-page mmap() attempts. To deal with
552  * that, just truncate the request to a page boundary. If any extra
553  * bytes don't get flushed, well, it's only a hint anyway.
554  */
555 
556  /* fetch pagesize only once */
557  if (pagesize == 0)
558  pagesize = sysconf(_SC_PAGESIZE);
559 
560  /* align length to pagesize, dropping any fractional page */
561  if (pagesize > 0)
562  nbytes = (nbytes / pagesize) * pagesize;
563 
564  /* fractional-page request is a no-op */
565  if (nbytes <= 0)
566  return;
567 
568  /*
569  * mmap could well fail, particularly on 32-bit platforms where there
570  * may simply not be enough address space. If so, silently fall
571  * through to the next implementation.
572  */
573  if (nbytes <= (off_t) SSIZE_MAX)
574  p = mmap(NULL, nbytes, PROT_READ, MAP_SHARED, fd, offset);
575  else
576  p = MAP_FAILED;
577 
578  if (p != MAP_FAILED)
579  {
580  int rc;
581 
582  rc = msync(p, (size_t) nbytes, MS_ASYNC);
583  if (rc != 0)
584  {
587  errmsg("could not flush dirty data: %m")));
588  /* NB: need to fall through to munmap()! */
589  }
590 
591  rc = munmap(p, (size_t) nbytes);
592  if (rc != 0)
593  {
594  /* FATAL error because mapping would remain */
595  ereport(FATAL,
597  errmsg("could not munmap() while flushing data: %m")));
598  }
599 
600  return;
601  }
602  }
603 #endif
604 #if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED)
605  {
606  int rc;
607 
608  /*
609  * Signal the kernel that the passed in range should not be cached
610  * anymore. This has the, desired, side effect of writing out dirty
611  * data, and the, undesired, side effect of likely discarding useful
612  * clean cached blocks. For the latter reason this is the least
613  * preferable method.
614  */
615 
616  rc = posix_fadvise(fd, offset, nbytes, POSIX_FADV_DONTNEED);
617 
618  if (rc != 0)
619  {
620  /* don't error out, this is just a performance optimization */
623  errmsg("could not flush dirty data: %m")));
624  }
625 
626  return;
627  }
628 #endif
629 }
#define MAP_FAILED
Definition: mem.h:45
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define FATAL
Definition: elog.h:49
int errcode_for_file_access(void)
Definition: elog.c:721
#define WARNING
Definition: elog.h:40
static int elevel
Definition: vacuumlazy.c:400
int data_sync_elevel(int elevel)
Definition: fd.c:3714
#define ereport(elevel,...)
Definition: elog.h:157
bool enableFsync
Definition: globals.c:122
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ pg_fsync()

int pg_fsync ( int  fd)

Definition at line 352 of file fd.c.

References Assert, fstat, pg_fsync_no_writethrough(), pg_fsync_writethrough(), S_ISDIR, stat::st_mode, sync_method, and SYNC_METHOD_FSYNC_WRITETHROUGH.

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

353 {
354 #if !defined(WIN32) && defined(USE_ASSERT_CHECKING)
355  struct stat st;
356 
357  /*
358  * Some operating system implementations of fsync() have requirements
359  * about the file access modes that were used when their file descriptor
360  * argument was opened, and these requirements differ depending on whether
361  * the file descriptor is for a directory.
362  *
363  * For any file descriptor that may eventually be handed to fsync(), we
364  * should have opened it with access modes that are compatible with
365  * fsync() on all supported systems, otherwise the code may not be
366  * portable, even if it runs ok on the current system.
367  *
368  * We assert here that a descriptor for a file was opened with write
369  * permissions (either O_RDWR or O_WRONLY) and for a directory without
370  * write permissions (O_RDONLY).
371  *
372  * Ignore any fstat errors and let the follow-up fsync() do its work.
373  * Doing this sanity check here counts for the case where fsync() is
374  * disabled.
375  */
376  if (fstat(fd, &st) == 0)
377  {
378  int desc_flags = fcntl(fd, F_GETFL);
379 
380  /*
381  * O_RDONLY is historically 0, so just make sure that for directories
382  * no write flags are used.
383  */
384  if (S_ISDIR(st.st_mode))
385  Assert((desc_flags & (O_RDWR | O_WRONLY)) == 0);
386  else
387  Assert((desc_flags & (O_RDWR | O_WRONLY)) != 0);
388  }
389  errno = 0;
390 #endif
391 
392  /* #if is to skip the sync_method test if there's no need for it */
393 #if defined(HAVE_FSYNC_WRITETHROUGH) && !defined(FSYNC_WRITETHROUGH_IS_FSYNC)
395  return pg_fsync_writethrough(fd);
396  else
397 #endif
399 }
#define SYNC_METHOD_FSYNC_WRITETHROUGH
Definition: xlog.h:28
int pg_fsync_writethrough(int fd)
Definition: fd.c:419
int pg_fsync_no_writethrough(int fd)
Definition: fd.c:407
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define fstat
Definition: win32_port.h:274
#define Assert(condition)
Definition: c.h:804
int sync_method
Definition: xlog.c:108
#define S_ISDIR(m)
Definition: win32_port.h:316

◆ pg_fsync_no_writethrough()

int pg_fsync_no_writethrough ( int  fd)

Definition at line 407 of file fd.c.

References enableFsync, and fsync.

Referenced by issue_xlog_fsync(), and pg_fsync().

408 {
409  if (enableFsync)
410  return fsync(fd);
411  else
412  return 0;
413 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define fsync(fd)
Definition: win32_port.h:68
bool enableFsync
Definition: globals.c:122

◆ pg_fsync_writethrough()

int pg_fsync_writethrough ( int  fd)

Definition at line 419 of file fd.c.

References enableFsync.

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

420 {
421  if (enableFsync)
422  {
423 #ifdef WIN32
424  return _commit(fd);
425 #elif defined(F_FULLFSYNC)
426  return (fcntl(fd, F_FULLFSYNC, 0) == -1) ? -1 : 0;
427 #else
428  errno = ENOSYS;
429  return -1;
430 #endif
431  }
432  else
433  return 0;
434 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
bool enableFsync
Definition: globals.c:122

◆ pg_pwritev_with_retry()

ssize_t pg_pwritev_with_retry ( int  fd,
const struct iovec iov,
int  iovcnt,
off_t  offset 
)

Definition at line 3724 of file fd.c.

References Assert, iovec::iov_base, iovec::iov_len, Min, and pg_pwritev().

Referenced by XLogFileInit().

3725 {
3726  struct iovec iov_copy[PG_IOV_MAX];
3727  ssize_t sum = 0;
3728  ssize_t part;
3729 
3730  /* We'd better have space to make a copy, in case we need to retry. */
3731  if (iovcnt > PG_IOV_MAX)
3732  {
3733  errno = EINVAL;
3734  return -1;
3735  }
3736 
3737  for (;;)
3738  {
3739  /* Write as much as we can. */
3740  part = pg_pwritev(fd, iov, iovcnt, offset);
3741  if (part < 0)
3742  return -1;
3743 
3744 #ifdef SIMULATE_SHORT_WRITE
3745  part = Min(part, 4096);
3746 #endif
3747 
3748  /* Count our progress. */
3749  sum += part;
3750  offset += part;
3751 
3752  /* Step over iovecs that are done. */
3753  while (iovcnt > 0 && iov->iov_len <= part)
3754  {
3755  part -= iov->iov_len;
3756  ++iov;
3757  --iovcnt;
3758  }
3759 
3760  /* Are they all done? */
3761  if (iovcnt == 0)
3762  {
3763  /* We don't expect the kernel to write more than requested. */
3764  Assert(part == 0);
3765  break;
3766  }
3767 
3768  /*
3769  * Move whatever's left to the front of our mutable copy and adjust
3770  * the leading iovec.
3771  */
3772  Assert(iovcnt > 0);
3773  memmove(iov_copy, iov, sizeof(*iov) * iovcnt);
3774  Assert(iov->iov_len > part);
3775  iov_copy[0].iov_base = (char *) iov_copy[0].iov_base + part;
3776  iov_copy[0].iov_len -= part;
3777  iov = iov_copy;
3778  }
3779 
3780  return sum;
3781 }
size_t iov_len
Definition: pg_iovec.h:27
void * iov_base
Definition: pg_iovec.h:26
#define Min(x, y)
Definition: c.h:986
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ssize_t pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
Definition: pwritev.c:29
#define PG_IOV_MAX
Definition: pg_iovec.h:40
Definition: pg_iovec.h:24
#define Assert(condition)
Definition: c.h:804

◆ pg_truncate()

int pg_truncate ( const char *  path,
off_t  length 
)

Definition at line 635 of file fd.c.

References CloseTransientFile(), vfd::fd, ftruncate, OpenTransientFile(), and PG_BINARY.

Referenced by do_truncate().

636 {
637 #ifdef WIN32
638  int save_errno;
639  int ret;
640  int fd;
641 
642  fd = OpenTransientFile(path, O_RDWR | PG_BINARY);
643  if (fd >= 0)
644  {
645  ret = ftruncate(fd, 0);
646  save_errno = errno;
647  CloseTransientFile(fd);
648  errno = save_errno;
649  }
650  else
651  ret = -1;
652 
653  return ret;
654 #else
655  return truncate(path, length);
656 #endif
657 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1271
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2423
int CloseTransientFile(int fd)
Definition: fd.c:2600
#define ftruncate(a, b)
Definition: win32_port.h:65

◆ ReadDir()

◆ ReadDirExtended()

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

Definition at line 2715 of file fd.c.

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().

2716 {
2717  struct dirent *dent;
2718 
2719  /* Give a generic message for AllocateDir failure, if caller didn't */
2720  if (dir == NULL)
2721  {
2722  ereport(elevel,
2724  errmsg("could not open directory \"%s\": %m",
2725  dirname)));
2726  return NULL;
2727  }
2728 
2729  errno = 0;
2730  if ((dent = readdir(dir)) != NULL)
2731  return dent;
2732 
2733  if (errno)
2734  ereport(elevel,
2736  errmsg("could not read directory \"%s\": %m",
2737  dirname)));
2738  return NULL;
2739 }
Definition: dirent.h:9
int errcode_for_file_access(void)
Definition: elog.c:721
static int elevel
Definition: vacuumlazy.c:400
#define ereport(elevel,...)
Definition: elog.h:157
struct dirent * readdir(DIR *)
Definition: dirent.c:78
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ RegisterTemporaryFile()

static void RegisterTemporaryFile ( File  file)
static

Definition at line 1456 of file fd.c.

References Assert, CurrentResourceOwner, FD_CLOSE_AT_EOXACT, vfd::fdstate, FileIsNotOpen, FileIsValid, have_xact_temporary_files, LruDelete(), ResourceOwnerRememberFile(), and vfd::resowner.

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

1457 {
1460 
1461  /* Backup mechanism for closing at end of xact. */
1464 }
ResourceOwner CurrentResourceOwner
Definition: resowner.c:146
static Vfd * VfdCache
Definition: fd.c:212
static bool have_xact_temporary_files
Definition: fd.c:224
void ResourceOwnerRememberFile(ResourceOwner owner, File file)
Definition: resowner.c:1297
unsigned short fdstate
Definition: fd.c:195
ResourceOwner resowner
Definition: fd.c:196
#define FD_CLOSE_AT_EOXACT
Definition: fd.c:189

◆ ReleaseExternalFD()

◆ ReleaseLruFile()

static bool ReleaseLruFile ( void  )
static

Definition at line 1291 of file fd.c.

References Assert, DO_DB, elog, LOG, LruDelete(), vfd::lruMoreRecently, and nfile.

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

1292 {
1293  DO_DB(elog(LOG, "ReleaseLruFile. Opened %d", nfile));
1294 
1295  if (nfile > 0)
1296  {
1297  /*
1298  * There are opened files and so there should be at least one used vfd
1299  * in the ring.
1300  */
1301  Assert(VfdCache[0].lruMoreRecently != 0);
1302  LruDelete(VfdCache[0].lruMoreRecently);
1303  return true; /* freed a file */
1304  }
1305  return false; /* no files available to free */
1306 }
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
#define LOG
Definition: elog.h:26
static void LruDelete(File file)
Definition: fd.c:1196
static int nfile
Definition: fd.c:218
#define Assert(condition)
Definition: c.h:804
#define elog(elevel,...)
Definition: elog.h:232

◆ ReleaseLruFiles()

static void ReleaseLruFiles ( void  )
static

Definition at line 1313 of file fd.c.

References max_safe_fds, nfile, numAllocatedDescs, numExternalFDs, and ReleaseLruFile().

Referenced by AllocateDir(), AllocateFile(), LruInsert(), OpenPipeStream(), OpenTransientFilePerm(), PathNameOpenFilePerm(), and ReserveExternalFD().

1314 {
1316  {
1317  if (!ReleaseLruFile())
1318  break;
1319  }
1320 }
static int numExternalFDs
Definition: fd.c:265
int max_safe_fds
Definition: fd.c:158
static bool ReleaseLruFile(void)
Definition: fd.c:1291
static int nfile
Definition: fd.c:218
static int numAllocatedDescs
Definition: fd.c:258

◆ RemovePgTempFiles()

void RemovePgTempFiles ( void  )

Definition at line 3059 of file fd.c.

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

Referenced by PostmasterMain(), and PostmasterStateMachine().

3060 {
3061  char temp_path[MAXPGPATH + 10 + sizeof(TABLESPACE_VERSION_DIRECTORY) + sizeof(PG_TEMP_FILES_DIR)];
3062  DIR *spc_dir;
3063  struct dirent *spc_de;
3064 
3065  /*
3066  * First process temp files in pg_default ($PGDATA/base)
3067  */
3068  snprintf(temp_path, sizeof(temp_path), "base/%s", PG_TEMP_FILES_DIR);
3069  RemovePgTempFilesInDir(temp_path, true, false);
3070  RemovePgTempRelationFiles("base");
3071 
3072  /*
3073  * Cycle through temp directories for all non-default tablespaces.
3074  */
3075  spc_dir = AllocateDir("pg_tblspc");
3076 
3077  while ((spc_de = ReadDirExtended(spc_dir, "pg_tblspc", LOG)) != NULL)
3078  {
3079  if (strcmp(spc_de->d_name, ".") == 0 ||
3080  strcmp(spc_de->d_name, "..") == 0)
3081  continue;
3082 
3083  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s/%s",
3085  RemovePgTempFilesInDir(temp_path, true, false);
3086 
3087  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s",
3089  RemovePgTempRelationFiles(temp_path);
3090  }
3091 
3092  FreeDir(spc_dir);
3093 
3094  /*
3095  * In EXEC_BACKEND case there is a pgsql_tmp directory at the top level of
3096  * DataDir as well. However, that is *not* cleaned here because doing so
3097  * would create a race condition. It's done separately, earlier in
3098  * postmaster startup.
3099  */
3100 }
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2715
#define PG_TEMP_FILES_DIR
Definition: pg_checksums.c:58
#define LOG
Definition: elog.h:26
Definition: dirent.h:9
static void RemovePgTempRelationFiles(const char *tsdirname)
Definition: fd.c:3184
Definition: dirent.c:25
#define MAXPGPATH
#define TABLESPACE_VERSION_DIRECTORY
Definition: relpath.h:26
void RemovePgTempFilesInDir(const char *tmpdirname, bool missing_ok, bool unlink_all)
Definition: fd.c:3118
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2634
char d_name[MAX_PATH]
Definition: dirent.h:15
#define snprintf
Definition: port.h:216
int FreeDir(DIR *dir)
Definition: fd.c:2752

◆ RemovePgTempFilesInDir()

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

Definition at line 3118 of file fd.c.

References AllocateDir(), dirent::d_name, ereport, errcode_for_file_access(), errmsg(), FreeDir(), LOG, lstat, MAXPGPATH, PG_TEMP_FILE_PREFIX, ReadDirExtended(), RemovePgTempFilesInDir(), S_ISDIR, snprintf, and stat::st_mode.

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

3119 {
3120  DIR *temp_dir;
3121  struct dirent *temp_de;
3122  char rm_path[MAXPGPATH * 2];
3123 
3124  temp_dir = AllocateDir(tmpdirname);
3125 
3126  if (temp_dir == NULL && errno == ENOENT && missing_ok)
3127  return;
3128 
3129  while ((temp_de = ReadDirExtended(temp_dir, tmpdirname, LOG)) != NULL)
3130  {
3131  if (strcmp(temp_de->d_name, ".") == 0 ||
3132  strcmp(temp_de->d_name, "..") == 0)
3133  continue;
3134 
3135  snprintf(rm_path, sizeof(rm_path), "%s/%s",
3136  tmpdirname, temp_de->d_name);
3137 
3138  if (unlink_all ||
3139  strncmp(temp_de->d_name,
3141  strlen(PG_TEMP_FILE_PREFIX)) == 0)
3142  {
3143  struct stat statbuf;
3144 
3145  if (lstat(rm_path, &statbuf) < 0)
3146  {
3147  ereport(LOG,
3149  errmsg("could not stat file \"%s\": %m", rm_path)));
3150  continue;
3151  }
3152 
3153  if (S_ISDIR(statbuf.st_mode))
3154  {
3155  /* recursively remove contents, then directory itself */
3156  RemovePgTempFilesInDir(rm_path, false, true);
3157 
3158  if (rmdir(rm_path) < 0)
3159  ereport(LOG,
3161  errmsg("could not remove directory \"%s\": %m",
3162  rm_path)));
3163  }
3164  else
3165  {
3166  if (unlink(rm_path) < 0)
3167  ereport(LOG,
3169  errmsg("could not remove file \"%s\": %m",
3170  rm_path)));
3171  }
3172  }
3173  else
3174  ereport(LOG,
3175  (errmsg("unexpected file found in temporary-files directory: \"%s\"",
3176  rm_path)));
3177  }
3178 
3179  FreeDir(temp_dir);
3180 }
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2715
#define LOG
Definition: elog.h:26
Definition: dirent.h:9
Definition: dirent.c:25
#define PG_TEMP_FILE_PREFIX
Definition: pg_checksums.c:59
#define MAXPGPATH
void RemovePgTempFilesInDir(const char *tmpdirname, bool missing_ok, bool unlink_all)
Definition: fd.c:3118
int errcode_for_file_access(void)
Definition: elog.c:721
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2634
#define ereport(elevel,...)
Definition: elog.h:157
#define S_ISDIR(m)
Definition: win32_port.h:316
#define lstat(path, sb)
Definition: win32_port.h:276
int errmsg(const char *fmt,...)
Definition: elog.c:909
char d_name[MAX_PATH]
Definition: dirent.h:15
#define snprintf
Definition: port.h:216
int FreeDir(DIR *dir)
Definition: fd.c:2752

◆ RemovePgTempRelationFiles()

static void RemovePgTempRelationFiles ( const char *  tsdirname)
static

Definition at line 3184 of file fd.c.

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

Referenced by RemovePgTempFiles().

3185 {
3186  DIR *ts_dir;
3187  struct dirent *de;
3188  char dbspace_path[MAXPGPATH * 2];
3189 
3190  ts_dir = AllocateDir(tsdirname);
3191 
3192  while ((de = ReadDirExtended(ts_dir, tsdirname, LOG)) != NULL)
3193  {
3194  /*
3195  * We're only interested in the per-database directories, which have
3196  * numeric names. Note that this code will also (properly) ignore "."
3197  * and "..".
3198  */
3199  if (strspn(de->d_name, "0123456789") != strlen(de->d_name))
3200  continue;
3201 
3202  snprintf(dbspace_path, sizeof(dbspace_path), "%s/%s",
3203  tsdirname, de->d_name);
3204  RemovePgTempRelationFilesInDbspace(dbspace_path);
3205  }
3206 
3207  FreeDir(ts_dir);
3208 }
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2715
static void RemovePgTempRelationFilesInDbspace(const char *dbspacedirname)
Definition: fd.c:3212
#define LOG
Definition: elog.h:26
Definition: dirent.h:9
Definition: dirent.c:25
#define MAXPGPATH
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2634
char d_name[MAX_PATH]
Definition: dirent.h:15
#define snprintf
Definition: port.h:216
int FreeDir(DIR *dir)
Definition: fd.c:2752

◆ RemovePgTempRelationFilesInDbspace()

static void RemovePgTempRelationFilesInDbspace ( const char *  dbspacedirname)
static

Definition at line 3212 of file fd.c.

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().

3213 {
3214  DIR *dbspace_dir;
3215  struct dirent *de;
3216  char rm_path[MAXPGPATH * 2];
3217 
3218  dbspace_dir = AllocateDir(dbspacedirname);
3219 
3220  while ((de = ReadDirExtended(dbspace_dir, dbspacedirname, LOG)) != NULL)
3221  {
3222  if (!looks_like_temp_rel_name(de->d_name))
3223  continue;
3224 
3225  snprintf(rm_path, sizeof(rm_path), "%s/%s",
3226  dbspacedirname, de->d_name);
3227 
3228  if (unlink(rm_path) < 0)
3229  ereport(LOG,
3231  errmsg("could not remove file \"%s\": %m",
3232  rm_path)));
3233  }
3234 
3235  FreeDir(dbspace_dir);
3236 }
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2715
#define LOG
Definition: elog.h:26
Definition: dirent.h:9
Definition: dirent.c:25
#define MAXPGPATH
int errcode_for_file_access(void)
Definition: elog.c:721
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2634
#define ereport(elevel,...)
Definition: elog.h:157
bool looks_like_temp_rel_name(const char *name)
Definition: fd.c:3240
int errmsg(const char *fmt,...)
Definition: elog.c:909
char d_name[MAX_PATH]
Definition: dirent.h:15
#define snprintf
Definition: port.h:216
int FreeDir(DIR *dir)
Definition: fd.c:2752

◆ ReportTemporaryFileUsage()

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

Definition at line 1437 of file fd.c.

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

Referenced by FileClose(), and PathNameDeleteTemporaryFile().

1438 {
1439  pgstat_report_tempfile(size);
1440 
1441  if (log_temp_files >= 0)
1442  {
1443  if ((size / 1024) >= log_temp_files)
1444  ereport(LOG,
1445  (errmsg("temporary file: path \"%s\", size %lu",
1446  path, (unsigned long) size)));
1447  }
1448 }
int log_temp_files
Definition: guc.c:571
void pgstat_report_tempfile(size_t filesize)
Definition: pgstat.c:1796
#define LOG
Definition: elog.h:26
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ reserveAllocatedDesc()

static bool reserveAllocatedDesc ( void  )
static

Definition at line 2298 of file fd.c.

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

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

2299 {
2300  AllocateDesc *newDescs;
2301  int newMax;
2302 
2303  /* Quick out if array already has a free slot. */
2305  return true;
2306 
2307  /*
2308  * If the array hasn't yet been created in the current process, initialize
2309  * it with FD_MINFREE / 3 elements. In many scenarios this is as many as
2310  * we will ever need, anyway. We don't want to look at max_safe_fds
2311  * immediately because set_max_safe_fds() may not have run yet.
2312  */
2313  if (allocatedDescs == NULL)
2314  {
2315  newMax = FD_MINFREE / 3;
2316  newDescs = (AllocateDesc *) malloc(newMax * sizeof(AllocateDesc));
2317  /* Out of memory already? Treat as fatal error. */
2318  if (newDescs == NULL)
2319  ereport(ERROR,
2320  (errcode(ERRCODE_OUT_OF_MEMORY),
2321  errmsg("out of memory")));
2322  allocatedDescs = newDescs;
2323  maxAllocatedDescs = newMax;
2324  return true;
2325  }
2326 
2327  /*
2328  * Consider enlarging the array beyond the initial allocation used above.
2329  * By the time this happens, max_safe_fds should be known accurately.
2330  *
2331  * We mustn't let allocated descriptors hog all the available FDs, and in
2332  * practice we'd better leave a reasonable number of FDs for VFD use. So
2333  * set the maximum to max_safe_fds / 3. (This should certainly be at
2334  * least as large as the initial size, FD_MINFREE / 3, so we aren't
2335  * tightening the restriction here.) Recall that "external" FDs are
2336  * allowed to consume another third of max_safe_fds.
2337  */
2338  newMax = max_safe_fds / 3;
2339  if (newMax > maxAllocatedDescs)
2340  {
2341  newDescs = (AllocateDesc *) realloc(allocatedDescs,
2342  newMax * sizeof(AllocateDesc));
2343  /* Treat out-of-memory as a non-fatal error. */
2344  if (newDescs == NULL)
2345  return false;
2346  allocatedDescs = newDescs;
2347  maxAllocatedDescs = newMax;
2348  return true;
2349  }
2350 
2351  /* Can't enlarge allocatedDescs[] any more. */
2352  return false;
2353 }
static AllocateDesc * allocatedDescs
Definition: fd.c:260
int max_safe_fds
Definition: fd.c:158
int errcode(int sqlerrcode)
Definition: elog.c:698
#define malloc(a)
Definition: header.h:50
#define ERROR
Definition: elog.h:46
#define ereport(elevel,...)
Definition: elog.h:157
#define FD_MINFREE
Definition: fd.c:137
#define realloc(a, b)
Definition: header.h:60
int errmsg(const char *fmt,...)
Definition: elog.c:909
static int maxAllocatedDescs
Definition: fd.c:259
static int numAllocatedDescs
Definition: fd.c:258

◆ ReserveExternalFD()

void ReserveExternalFD ( void  )

Definition at line 1130 of file fd.c.

References numExternalFDs, and ReleaseLruFiles().

Referenced by AcquireExternalFD(), BackendInitialize(), dsm_impl_op(), InitializeLatchSupport(), InitPostmasterDeathWatchHandle(), pgstat_init(), PostmasterMarkPIDForWorkerNotify(), and XLogWrite().

1131 {
1132  /*
1133  * Release VFDs if needed to stay safe. Because we do this before
1134  * incrementing numExternalFDs, the final state will be as desired, i.e.,
1135  * nfile + numAllocatedDescs + numExternalFDs <= max_safe_fds.
1136  */
1137  ReleaseLruFiles();
1138 
1139  numExternalFDs++;
1140 }
static int numExternalFDs
Definition: fd.c:265
static void ReleaseLruFiles(void)
Definition: fd.c:1313

◆ set_max_safe_fds()

void set_max_safe_fds ( void  )

Definition at line 990 of file fd.c.

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 PostmasterMain().

991 {
992  int usable_fds;
993  int already_open;
994 
995  /*----------
996  * We want to set max_safe_fds to
997  * MIN(usable_fds, max_files_per_process - already_open)
998  * less the slop factor for files that are opened without consulting
999  * fd.c. This ensures that we won't exceed either max_files_per_process
1000  * or the experimentally-determined EMFILE limit.
1001  *----------
1002  */
1004  &usable_fds, &already_open);
1005 
1006  max_safe_fds = Min(usable_fds, max_files_per_process - already_open);
1007 
1008  /*
1009  * Take off the FDs reserved for system() etc.
1010  */
1012 
1013  /*
1014  * Make sure we still have enough to get by.
1015  */
1016  if (max_safe_fds < FD_MINFREE)
1017  ereport(FATAL,
1018  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
1019  errmsg("insufficient file descriptors available to start server process"),
1020  errdetail("System allows %d, we need at least %d.",
1023 
1024  elog(DEBUG2, "max_safe_fds = %d, usable_fds = %d, already_open = %d",
1025  max_safe_fds, usable_fds, already_open);
1026 }
static void count_usable_fds(int max_to_probe, int *usable_fds, int *already_open)
Definition: fd.c:906
#define NUM_RESERVED_FDS
Definition: fd.c:128
int max_safe_fds
Definition: fd.c:158
#define Min(x, y)
Definition: c.h:986
int errcode(int sqlerrcode)
Definition: elog.c:698
#define FATAL
Definition: elog.h:49
#define DEBUG2
Definition: elog.h:24
int errdetail(const char *fmt,...)
Definition: elog.c:1042
int max_files_per_process
Definition: fd.c:145
#define ereport(elevel,...)
Definition: elog.h:157
#define FD_MINFREE
Definition: fd.c:137
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232

◆ SetTempTablespaces()

void SetTempTablespaces ( Oid tableSpaces,
int  numSpaces 
)

Definition at line 2840 of file fd.c.

References Assert, nextTempTableSpace, numTempTableSpaces, random(), and tempTableSpaces.

Referenced by assign_temp_tablespaces(), and PrepareTempTablespaces().

2841 {
2842  Assert(numSpaces >= 0);
2843  tempTableSpaces = tableSpaces;
2844  numTempTableSpaces = numSpaces;
2845 
2846  /*
2847  * Select a random starting point in the list. This is to minimize
2848  * conflicts between backends that are most likely sharing the same list
2849  * of temp tablespaces. Note that if we create multiple temp files in the
2850  * same transaction, we'll advance circularly through the list --- this
2851  * ensures that large temporary sort files are nicely spread across all
2852  * available tablespaces.
2853  */
2854  if (numSpaces > 1)
2855  nextTempTableSpace = random() % numSpaces;
2856  else
2857  nextTempTableSpace = 0;
2858 }
long random(void)
Definition: random.c:22
static int numTempTableSpaces
Definition: fd.c:280
static int nextTempTableSpace
Definition: fd.c:281
#define Assert(condition)
Definition: c.h:804
static Oid * tempTableSpaces
Definition: fd.c:279

◆ SyncDataDirectory()

void SyncDataDirectory ( void  )

Definition at line 3332 of file fd.c.

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

Referenced by StartupXLOG().

3333 {
3334  bool xlog_is_symlink;
3335 
3336  /* We can skip this whole thing if fsync is disabled. */
3337  if (!enableFsync)
3338  return;
3339 
3340  /*
3341  * If pg_wal is a symlink, we'll need to recurse into it separately,
3342  * because the first walkdir below will ignore it.
3343  */
3344  xlog_is_symlink = false;
3345 
3346 #ifndef WIN32
3347  {
3348  struct stat st;
3349 
3350  if (lstat("pg_wal", &st) < 0)
3351  ereport(LOG,
3353  errmsg("could not stat file \"%s\": %m",
3354  "pg_wal")));
3355  else if (S_ISLNK(st.st_mode))
3356  xlog_is_symlink = true;
3357  }
3358 #else
3359  if (pgwin32_is_junction("pg_wal"))
3360  xlog_is_symlink = true;
3361 #endif
3362 
3363 #ifdef HAVE_SYNCFS
3365  {
3366  DIR *dir;
3367  struct dirent *de;
3368 
3369  /*
3370  * On Linux, we don't have to open every single file one by one. We
3371  * can use syncfs() to sync whole filesystems. We only expect
3372  * filesystem boundaries to exist where we tolerate symlinks, namely
3373  * pg_wal and the tablespaces, so we call syncfs() for each of those
3374  * directories.
3375  */
3376 
3377  /* Sync the top level pgdata directory. */
3378  do_syncfs(".");
3379  /* If any tablespaces are configured, sync each of those. */
3380  dir = AllocateDir("pg_tblspc");
3381  while ((de = ReadDirExtended(dir, "pg_tblspc", LOG)))
3382  {
3383  char path[MAXPGPATH];
3384 
3385  if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
3386  continue;
3387 
3388  snprintf(path, MAXPGPATH, "pg_tblspc/%s", de->d_name);
3389  do_syncfs(path);
3390  }
3391  FreeDir(dir);
3392  /* If pg_wal is a symlink, process that too. */
3393  if (xlog_is_symlink)
3394  do_syncfs("pg_wal");
3395  return;
3396  }
3397 #endif /* !HAVE_SYNCFS */
3398 
3399  /*
3400  * If possible, hint to the kernel that we're soon going to fsync the data
3401  * directory and its contents. Errors in this step are even less
3402  * interesting than normal, so log them only at DEBUG1.
3403  */
3404 #ifdef PG_FLUSH_DATA_WORKS
3405  walkdir(".", pre_sync_fname, false, DEBUG1);
3406  if (xlog_is_symlink)
3407  walkdir("pg_wal", pre_sync_fname, false, DEBUG1);
3408  walkdir("pg_tblspc", pre_sync_fname, true, DEBUG1);
3409 #endif
3410 
3411  /*
3412  * Now we do the fsync()s in the same order.
3413  *
3414  * The main call ignores symlinks, so in addition to specially processing
3415  * pg_wal if it's a symlink, pg_tblspc has to be visited separately with
3416  * process_symlinks = true. Note that if there are any plain directories
3417  * in pg_tblspc, they'll get fsync'd twice. That's not an expected case
3418  * so we don't worry about optimizing it.
3419  */
3420  walkdir(".", datadir_fsync_fname, false, LOG);
3421  if (xlog_is_symlink)
3422  walkdir("pg_wal", datadir_fsync_fname, false, LOG);
3423  walkdir("pg_tblspc", datadir_fsync_fname, true, LOG);
3424 }
#define DEBUG1
Definition: elog.h:25
static void walkdir(const char *path, void(*action)(const char *fname, bool isdir, int elevel), bool process_symlinks, int elevel)
Definition: fd.c:3442
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2715
#define LOG
Definition: elog.h:26
Definition: dirent.h:9
Definition: dirent.c:25
int recovery_init_sync_method
Definition: fd.c:164
#define MAXPGPATH
int errcode_for_file_access(void)
Definition: elog.c:721
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2634
static void datadir_fsync_fname(const char *fname, bool isdir, int elevel)
Definition: fd.c:3540
#define ereport(elevel,...)
Definition: elog.h:157
#define lstat(path, sb)
Definition: win32_port.h:276
bool enableFsync
Definition: globals.c:122
int errmsg(const char *fmt,...)
Definition: elog.c:909
char d_name[MAX_PATH]
Definition: dirent.h:15
#define snprintf
Definition: port.h:216
int FreeDir(DIR *dir)
Definition: fd.c:2752
bool pgwin32_is_junction(const char *path)

◆ TempTablespacePath()

void TempTablespacePath ( char *  path,
Oid  tablespace 
)

Definition at line 1678 of file fd.c.

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

Referenced by OpenTemporaryFileInTablespace(), pg_ls_tmpdir(), SharedFileSetCreate(), and SharedFileSetPath().

1679 {
1680  /*
1681  * Identify the tempfile directory for this tablespace.
1682  *
1683  * If someone tries to specify pg_global, use pg_default instead.
1684  */
1685  if (tablespace == InvalidOid ||
1686  tablespace == DEFAULTTABLESPACE_OID ||
1687  tablespace == GLOBALTABLESPACE_OID)
1688  snprintf(path, MAXPGPATH, "base/%s", PG_TEMP_FILES_DIR);
1689  else
1690  {
1691  /* All other tablespaces are accessed via symlinks */
1692  snprintf(path, MAXPGPATH, "pg_tblspc/%u/%s/%s",
1695  }
1696 }
#define PG_TEMP_FILES_DIR
Definition: pg_checksums.c:58
#define MAXPGPATH
#define TABLESPACE_VERSION_DIRECTORY
Definition: relpath.h:26
char * tablespace
Definition: pgbench.c:224
#define InvalidOid
Definition: postgres_ext.h:36
#define snprintf
Definition: port.h:216

◆ TempTablespacesAreSet()

bool TempTablespacesAreSet ( void  )

Definition at line 2868 of file fd.c.

References numTempTableSpaces.

Referenced by GetTempTablespaces(), and PrepareTempTablespaces().

2869 {
2870  return (numTempTableSpaces >= 0);
2871 }
static int numTempTableSpaces
Definition: fd.c:280

◆ unlink_if_exists_fname()

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

Definition at line 3550 of file fd.c.

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

Referenced by PathNameDeleteTemporaryDir().

3551 {
3552  if (isdir)
3553  {
3554  if (rmdir(fname) != 0 && errno != ENOENT)
3555  ereport(elevel,
3557  errmsg("could not remove directory \"%s\": %m", fname)));
3558  }
3559  else
3560  {
3561  /* Use PathNameDeleteTemporaryFile to report filesize */
3562  PathNameDeleteTemporaryFile(fname, false);
3563  }
3564 }
bool PathNameDeleteTemporaryFile(const char *path, bool error_on_failure)
Definition: fd.c:1827
int errcode_for_file_access(void)
Definition: elog.c:721
static int elevel
Definition: vacuumlazy.c:400
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ 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 3442 of file fd.c.

References generate_unaccent_rules::action, AllocateDir(), CHECK_FOR_INTERRUPTS, CloseTransientFile(), dirent::d_name, elevel, ereport, errcode_for_file_access(), errmsg(), vfd::fd, FreeDir(), get_dirent_type(), MAXPGPATH, OpenTransientFile(), PG_BINARY, pg_flush_data(), PGFILETYPE_DIR, PGFILETYPE_REG, ReadDirExtended(), snprintf, and subpath().

Referenced by PathNameDeleteTemporaryDir(), and SyncDataDirectory().

3446 {
3447  DIR *dir;
3448  struct dirent *de;
3449 
3450  dir = AllocateDir(path);
3451 
3452  while ((de = ReadDirExtended(dir, path, elevel)) != NULL)
3453  {
3454  char subpath[MAXPGPATH * 2];
3455 
3457 
3458  if (strcmp(de->d_name, ".") == 0 ||
3459  strcmp(de->d_name, "..") == 0)
3460  continue;
3461 
3462  snprintf(subpath, sizeof(subpath), "%s/%s", path, de->d_name);
3463 
3464  switch (get_dirent_type(subpath, de, process_symlinks, elevel))
3465  {
3466  case PGFILETYPE_REG:
3467  (*action) (subpath, false, elevel);
3468  break;
3469  case PGFILETYPE_DIR:
3470  walkdir(subpath, action, false, elevel);
3471  break;
3472  default:
3473 
3474  /*
3475  * Errors are already reported directly by get_dirent_type(),
3476  * and any remaining symlinks and unknown file types are
3477  * ignored.
3478  */
3479  break;
3480  }
3481  }
3482 
3483  FreeDir(dir); /* we ignore any error here */
3484 
3485  /*
3486  * It's important to fsync the destination directory itself as individual
3487  * file fsyncs don't guarantee that the directory entry for the file is
3488  * synced. However, skip this if AllocateDir failed; the action function
3489  * might not be robust against that.
3490  */
3491  if (dir)
3492  (*action) (path, true, elevel);
3493 }
static void walkdir(const char *path, void(*action)(const char *fname, bool isdir, int elevel), bool process_symlinks, int elevel)
Definition: fd.c:3442
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2715
Definition: dirent.h:9
Definition: dirent.c:25
#define MAXPGPATH
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2634
PGFileType get_dirent_type(const char *path, const struct dirent *de, bool look_through_symlinks, int elevel)
Definition: file_utils.c:410
static int elevel
Definition: vacuumlazy.c:400
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:102
char d_name[MAX_PATH]
Definition: dirent.h:15
#define snprintf
Definition: port.h:216
int FreeDir(DIR *dir)
Definition: fd.c:2752
Datum subpath(PG_FUNCTION_ARGS)
Definition: ltree_op.c:241

Variable Documentation

◆ allocatedDescs

AllocateDesc* allocatedDescs = NULL
static

Definition at line 260 of file fd.c.

◆ data_sync_retry

bool data_sync_retry = false

Definition at line 161 of file fd.c.

Referenced by data_sync_elevel().

◆ have_xact_temporary_files

bool have_xact_temporary_files = false
static

Definition at line 224 of file fd.c.

Referenced by CleanupTempFiles(), and RegisterTemporaryFile().

◆ 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

◆ maxAllocatedDescs

int maxAllocatedDescs = 0
static

◆ nextTempTableSpace

int nextTempTableSpace = 0
static

Definition at line 281 of file fd.c.

Referenced by GetNextTempTableSpace(), and SetTempTablespaces().

◆ nfile

int nfile = 0
static

◆ numAllocatedDescs

◆ numExternalFDs

int numExternalFDs = 0
static

Definition at line 265 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 = RECOVERY_INIT_SYNC_METHOD_FSYNC

Definition at line 164 of file fd.c.

Referenced by SyncDataDirectory().

◆ SizeVfdCache

Size SizeVfdCache = 0
static

Definition at line 213 of file fd.c.

Referenced by AllocateVfd(), CleanupTempFiles(), closeAllVfds(), and InitFileAccess().

◆ tempFileCounter

long tempFileCounter = 0
static

Definition at line 271 of file fd.c.

Referenced by OpenTemporaryFileInTablespace().

◆ temporary_files_size

uint64 temporary_files_size = 0
static

Definition at line 232 of file fd.c.

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

◆ tempTableSpaces

Oid* tempTableSpaces = NULL
static

◆ VfdCache

Vfd* VfdCache
static

Definition at line 212 of file fd.c.