PostgreSQL Source Code  git master
fd.h File Reference
#include <dirent.h>
Include dependency graph for fd.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define FILE_POSSIBLY_DELETED(err)   ((err) == ENOENT)
 
#define PG_O_DIRECT   0
 
#define PG_TEMP_FILES_DIR   "pgsql_tmp"
 
#define PG_TEMP_FILE_PREFIX   "pgsql_tmp"
 

Typedefs

typedef enum RecoveryInitSyncMethod RecoveryInitSyncMethod
 
typedef int File
 

Enumerations

enum  RecoveryInitSyncMethod { RECOVERY_INIT_SYNC_METHOD_FSYNC , RECOVERY_INIT_SYNC_METHOD_SYNCFS }
 

Functions

File PathNameOpenFile (const char *fileName, int fileFlags)
 
File PathNameOpenFilePerm (const char *fileName, int fileFlags, mode_t fileMode)
 
File OpenTemporaryFile (bool interXact)
 
void FileClose (File file)
 
int FilePrefetch (File file, off_t offset, off_t amount, uint32 wait_event_info)
 
int FileRead (File file, void *buffer, size_t amount, off_t offset, uint32 wait_event_info)
 
int FileWrite (File file, const void *buffer, size_t 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)
 
void FileWriteback (File file, off_t offset, off_t nbytes, uint32 wait_event_info)
 
char * FilePathName (File file)
 
int FileGetRawDesc (File file)
 
int FileGetRawFlags (File file)
 
mode_t FileGetRawMode (File file)
 
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 PathNameCreateTemporaryDir (const char *basedir, const char *directory)
 
void PathNameDeleteTemporaryDir (const char *dirname)
 
void TempTablespacePath (char *path, Oid tablespace)
 
FILE * AllocateFile (const char *name, const char *mode)
 
int FreeFile (FILE *file)
 
FILE * OpenPipeStream (const char *command, const char *mode)
 
int ClosePipeStream (FILE *file)
 
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 OpenTransientFile (const char *fileName, int fileFlags)
 
int OpenTransientFilePerm (const char *fileName, int fileFlags, mode_t fileMode)
 
int CloseTransientFile (int fd)
 
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)
 
int MakePGDirectory (const char *directoryName)
 
void InitFileAccess (void)
 
void InitTemporaryFileAccess (void)
 
void set_max_safe_fds (void)
 
void closeAllVfds (void)
 
void SetTempTablespaces (Oid *tableSpaces, int numSpaces)
 
bool TempTablespacesAreSet (void)
 
int GetTempTablespaces (Oid *tableSpaces, int numSpaces)
 
Oid GetNextTempTableSpace (void)
 
void AtEOXact_Files (bool isCommit)
 
void AtEOSubXact_Files (bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
 
void RemovePgTempFiles (void)
 
void RemovePgTempFilesInDir (const char *tmpdirname, bool missing_ok, bool unlink_all)
 
bool looks_like_temp_rel_name (const char *name)
 
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 fsync_fname_ext (const char *fname, bool isdir, bool ignore_perm, int elevel)
 
int durable_rename (const char *oldfile, const char *newfile, int elevel)
 
int durable_unlink (const char *fname, int elevel)
 
void SyncDataDirectory (void)
 
int data_sync_elevel (int elevel)
 

Variables

PGDLLIMPORT int max_files_per_process
 
PGDLLIMPORT bool data_sync_retry
 
PGDLLIMPORT int recovery_init_sync_method
 
PGDLLIMPORT int max_safe_fds
 

Macro Definition Documentation

◆ FILE_POSSIBLY_DELETED

#define FILE_POSSIBLY_DELETED (   err)    ((err) == ENOENT)

Definition at line 75 of file fd.h.

◆ PG_O_DIRECT

#define PG_O_DIRECT   0

Definition at line 93 of file fd.h.

◆ PG_TEMP_FILE_PREFIX

#define PG_TEMP_FILE_PREFIX   "pgsql_tmp"

Definition at line 189 of file fd.h.

◆ PG_TEMP_FILES_DIR

#define PG_TEMP_FILES_DIR   "pgsql_tmp"

Definition at line 188 of file fd.h.

Typedef Documentation

◆ File

typedef int File

Definition at line 54 of file fd.h.

◆ RecoveryInitSyncMethod

Enumeration Type Documentation

◆ RecoveryInitSyncMethod

Enumerator
RECOVERY_INIT_SYNC_METHOD_FSYNC 
RECOVERY_INIT_SYNC_METHOD_SYNCFS 

Definition at line 48 of file fd.h.

49 {
RecoveryInitSyncMethod
Definition: fd.h:49
@ RECOVERY_INIT_SYNC_METHOD_SYNCFS
Definition: fd.h:51
@ RECOVERY_INIT_SYNC_METHOD_FSYNC
Definition: fd.h:50

Function Documentation

◆ AcquireExternalFD()

bool AcquireExternalFD ( void  )

Definition at line 1092 of file fd.c.

1093 {
1094  /*
1095  * We don't want more than max_safe_fds / 3 FDs to be consumed for
1096  * "external" FDs.
1097  */
1098  if (numExternalFDs < max_safe_fds / 3)
1099  {
1101  return true;
1102  }
1103  errno = EMFILE;
1104  return false;
1105 }
int max_safe_fds
Definition: fd.c:157
void ReserveExternalFD(void)
Definition: fd.c:1127
static int numExternalFDs
Definition: fd.c:269

References max_safe_fds, numExternalFDs, and ReserveExternalFD().

Referenced by CreateWaitEventSet(), and libpqsrv_connect_prepare().

◆ AllocateDir()

DIR* AllocateDir ( const char *  dirname)

Definition at line 2644 of file fd.c.

2645 {
2646  DIR *dir;
2647 
2648  DO_DB(elog(LOG, "AllocateDir: Allocated %d (%s)",
2649  numAllocatedDescs, dirname));
2650 
2651  /* Can we allocate another non-virtual FD? */
2652  if (!reserveAllocatedDesc())
2653  ereport(ERROR,
2654  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2655  errmsg("exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"",
2656  maxAllocatedDescs, dirname)));
2657 
2658  /* Close excess kernel FDs. */
2659  ReleaseLruFiles();
2660 
2661 TryAgain:
2662  if ((dir = opendir(dirname)) != NULL)
2663  {
2665 
2666  desc->kind = AllocateDescDir;
2667  desc->desc.dir = dir;
2670  return desc->desc.dir;
2671  }
2672 
2673  if (errno == EMFILE || errno == ENFILE)
2674  {
2675  int save_errno = errno;
2676 
2677  ereport(LOG,
2678  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2679  errmsg("out of file descriptors: %m; release and retry")));
2680  errno = 0;
2681  if (ReleaseLruFile())
2682  goto TryAgain;
2683  errno = save_errno;
2684  }
2685 
2686  return NULL;
2687 }
DIR * opendir(const char *)
Definition: dirent.c:33
int errcode(int sqlerrcode)
Definition: elog.c:858
int errmsg(const char *fmt,...)
Definition: elog.c:1069
#define LOG
Definition: elog.h:31
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
static bool ReleaseLruFile(void)
Definition: fd.c:1288
static int maxAllocatedDescs
Definition: fd.c:263
static int numAllocatedDescs
Definition: fd.c:262
#define DO_DB(A)
Definition: fd.c:175
static AllocateDesc * allocatedDescs
Definition: fd.c:264
@ AllocateDescDir
Definition: fd.c:246
static bool reserveAllocatedDesc(void)
Definition: fd.c:2309
static void ReleaseLruFiles(void)
Definition: fd.c:1310
SubTransactionId create_subid
Definition: fd.c:253
DIR * dir
Definition: fd.c:257
union AllocateDesc::@19 desc
AllocateDescKind kind
Definition: fd.c:252
Definition: dirent.c:26
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:780

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

Referenced by calculate_database_size(), calculate_tablespace_size(), CheckPointLogicalRewriteHeap(), CheckPointSnapBuild(), CheckTablespaceDirectory(), CleanupBackupHistory(), copydir(), db_dir_size(), DeleteAllExportedSnapshotFiles(), destroy_tablespace_directories(), directory_is_empty(), do_pg_backup_start(), dsm_cleanup_for_mmap(), extension_file_exists(), get_ext_ver_list(), GetConfFilesInDir(), getInstallationPaths(), 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(), 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().

◆ AllocateFile()

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

Definition at line 2384 of file fd.c.

2385 {
2386  FILE *file;
2387 
2388  DO_DB(elog(LOG, "AllocateFile: Allocated %d (%s)",
2390 
2391  /* Can we allocate another non-virtual FD? */
2392  if (!reserveAllocatedDesc())
2393  ereport(ERROR,
2394  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2395  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2396  maxAllocatedDescs, name)));
2397 
2398  /* Close excess kernel FDs. */
2399  ReleaseLruFiles();
2400 
2401 TryAgain:
2402  if ((file = fopen(name, mode)) != NULL)
2403  {
2405 
2406  desc->kind = AllocateDescFile;
2407  desc->desc.file = file;
2410  return desc->desc.file;
2411  }
2412 
2413  if (errno == EMFILE || errno == ENFILE)
2414  {
2415  int save_errno = errno;
2416 
2417  ereport(LOG,
2418  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2419  errmsg("out of file descriptors: %m; release and retry")));
2420  errno = 0;
2421  if (ReleaseLruFile())
2422  goto TryAgain;
2423  errno = save_errno;
2424  }
2425 
2426  return NULL;
2427 }
const char * name
Definition: encode.c:571
@ AllocateDescFile
Definition: fd.c:244
static PgChecksumMode mode
Definition: pg_checksums.c:65
FILE * file
Definition: fd.c:256

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

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

◆ AtEOSubXact_Files()

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

Definition at line 2933 of file fd.c.

2935 {
2936  Index i;
2937 
2938  for (i = 0; i < numAllocatedDescs; i++)
2939  {
2940  if (allocatedDescs[i].create_subid == mySubid)
2941  {
2942  if (isCommit)
2943  allocatedDescs[i].create_subid = parentSubid;
2944  else
2945  {
2946  /* have to recheck the item after FreeDesc (ugly) */
2947  FreeDesc(&allocatedDescs[i--]);
2948  }
2949  }
2950  }
2951 }
unsigned int Index
Definition: c.h:598
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2543
int i
Definition: isn.c:73

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

Referenced by AbortSubTransaction(), basic_archive_file(), and CommitSubTransaction().

◆ AtEOXact_Files()

void AtEOXact_Files ( bool  isCommit)

Definition at line 2966 of file fd.c.

2967 {
2968  CleanupTempFiles(isCommit, false);
2969  tempTableSpaces = NULL;
2970  numTempTableSpaces = -1;
2971 }
static int numTempTableSpaces
Definition: fd.c:284
static Oid * tempTableSpaces
Definition: fd.c:283
static void CleanupTempFiles(bool isCommit, bool isProcExit)
Definition: fd.c:3003

References CleanupTempFiles(), numTempTableSpaces, and tempTableSpaces.

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

◆ BasicOpenFile()

int BasicOpenFile ( const char *  fileName,
int  fileFlags 
)

Definition at line 993 of file fd.c.

994 {
995  return BasicOpenFilePerm(fileName, fileFlags, pg_file_create_mode);
996 }
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1015
int pg_file_create_mode
Definition: file_perm.c:19

References BasicOpenFilePerm(), and pg_file_create_mode.

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

◆ BasicOpenFilePerm()

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

Definition at line 1015 of file fd.c.

1016 {
1017  int fd;
1018 
1019 tryAgain:
1020 #ifdef PG_O_DIRECT_USE_F_NOCACHE
1021 
1022  /*
1023  * The value we defined to stand in for O_DIRECT when simulating it with
1024  * F_NOCACHE had better not collide with any of the standard flags.
1025  */
1027  (O_APPEND |
1028  O_CLOEXEC |
1029  O_CREAT |
1030  O_DSYNC |
1031  O_EXCL |
1032  O_RDWR |
1033  O_RDONLY |
1034  O_SYNC |
1035  O_TRUNC |
1036  O_WRONLY)) == 0,
1037  "PG_O_DIRECT value collides with standard flag");
1038  fd = open(fileName, fileFlags & ~PG_O_DIRECT, fileMode);
1039 #else
1040  fd = open(fileName, fileFlags, fileMode);
1041 #endif
1042 
1043  if (fd >= 0)
1044  {
1045 #ifdef PG_O_DIRECT_USE_F_NOCACHE
1046  if (fileFlags & PG_O_DIRECT)
1047  {
1048  if (fcntl(fd, F_NOCACHE, 1) < 0)
1049  {
1050  int save_errno = errno;
1051 
1052  close(fd);
1053  errno = save_errno;
1054  return -1;
1055  }
1056  }
1057 #endif
1058 
1059  return fd; /* success! */
1060  }
1061 
1062  if (errno == EMFILE || errno == ENFILE)
1063  {
1064  int save_errno = errno;
1065 
1066  ereport(LOG,
1067  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
1068  errmsg("out of file descriptors: %m; release and retry")));
1069  errno = 0;
1070  if (ReleaseLruFile())
1071  goto tryAgain;
1072  errno = save_errno;
1073  }
1074 
1075  return -1; /* failure */
1076 }
#define StaticAssertStmt(condition, errmessage)
Definition: c.h:922
#define PG_O_DIRECT
Definition: fd.h:93
#define close(a)
Definition: win32.h:12
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define O_CLOEXEC
Definition: win32_port.h:361
#define O_DSYNC
Definition: win32_port.h:354

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

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

◆ closeAllVfds()

void closeAllVfds ( void  )

Definition at line 2821 of file fd.c.

2822 {
2823  Index i;
2824 
2825  if (SizeVfdCache > 0)
2826  {
2827  Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
2828  for (i = 1; i < SizeVfdCache; i++)
2829  {
2830  if (!FileIsNotOpen(i))
2831  LruDelete(i);
2832  }
2833  }
2834 }
static void LruDelete(File file)
Definition: fd.c:1193
static Size SizeVfdCache
Definition: fd.c:212
#define FileIsNotOpen(file)
Definition: fd.c:184
Assert(fmt[strlen(fmt) - 1] !='\n')

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

Referenced by standard_ProcessUtility().

◆ ClosePipeStream()

int ClosePipeStream ( FILE *  file)

Definition at line 2792 of file fd.c.

2793 {
2794  int i;
2795 
2796  DO_DB(elog(LOG, "ClosePipeStream: Allocated %d", numAllocatedDescs));
2797 
2798  /* Remove file from list of allocated files, if it's present */
2799  for (i = numAllocatedDescs; --i >= 0;)
2800  {
2801  AllocateDesc *desc = &allocatedDescs[i];
2802 
2803  if (desc->kind == AllocateDescPipe && desc->desc.file == file)
2804  return FreeDesc(desc);
2805  }
2806 
2807  /* Only get here if someone passes us a file not in allocatedDescs */
2808  elog(WARNING, "file passed to ClosePipeStream was not obtained from OpenPipeStream");
2809 
2810  return pclose(file);
2811 }
#define WARNING
Definition: elog.h:36
@ AllocateDescPipe
Definition: fd.c:245

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

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

◆ CloseTransientFile()

int CloseTransientFile ( int  fd)

Definition at line 2610 of file fd.c.

2611 {
2612  int i;
2613 
2614  DO_DB(elog(LOG, "CloseTransientFile: Allocated %d", numAllocatedDescs));
2615 
2616  /* Remove fd from list of allocated files, if it's present */
2617  for (i = numAllocatedDescs; --i >= 0;)
2618  {
2619  AllocateDesc *desc = &allocatedDescs[i];
2620 
2621  if (desc->kind == AllocateDescRawFD && desc->desc.fd == fd)
2622  return FreeDesc(desc);
2623  }
2624 
2625  /* Only get here if someone passes us a file not in allocatedDescs */
2626  elog(WARNING, "fd passed to CloseTransientFile was not obtained from OpenTransientFile");
2627 
2628  return close(fd);
2629 }
@ AllocateDescRawFD
Definition: fd.c:247
int fd
Definition: fd.c:258

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

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

◆ data_sync_elevel()

◆ durable_rename()

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

Definition at line 688 of file fd.c.

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

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

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

◆ durable_unlink()

int durable_unlink ( const char *  fname,
int  elevel 
)

Definition at line 778 of file fd.c.

779 {
780  if (unlink(fname) < 0)
781  {
782  ereport(elevel,
784  errmsg("could not remove file \"%s\": %m",
785  fname)));
786  return -1;
787  }
788 
789  /*
790  * To guarantee that the removal of the file is persistent, fsync its
791  * parent directory.
792  */
793  if (fsync_parent_path(fname, elevel) != 0)
794  return -1;
795 
796  return 0;
797 }

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

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

◆ FileClose()

void FileClose ( File  file)

Definition at line 1884 of file fd.c.

1885 {
1886  Vfd *vfdP;
1887 
1888  Assert(FileIsValid(file));
1889 
1890  DO_DB(elog(LOG, "FileClose: %d (%s)",
1891  file, VfdCache[file].fileName));
1892 
1893  vfdP = &VfdCache[file];
1894 
1895  if (!FileIsNotOpen(file))
1896  {
1897  /* close the file */
1898  if (close(vfdP->fd) != 0)
1899  {
1900  /*
1901  * We may need to panic on failure to close non-temporary files;
1902  * see LruDelete.
1903  */
1905  "could not close file \"%s\": %m", vfdP->fileName);
1906  }
1907 
1908  --nfile;
1909  vfdP->fd = VFD_CLOSED;
1910 
1911  /* remove the file from the lru ring */
1912  Delete(file);
1913  }
1914 
1915  if (vfdP->fdstate & FD_TEMP_FILE_LIMIT)
1916  {
1917  /* Subtract its size from current usage (do first in case of error) */
1918  temporary_files_size -= vfdP->fileSize;
1919  vfdP->fileSize = 0;
1920  }
1921 
1922  /*
1923  * Delete the file if it was temporary, and make a log entry if wanted
1924  */
1925  if (vfdP->fdstate & FD_DELETE_AT_CLOSE)
1926  {
1927  struct stat filestats;
1928  int stat_errno;
1929 
1930  /*
1931  * If we get an error, as could happen within the ereport/elog calls,
1932  * we'll come right back here during transaction abort. Reset the
1933  * flag to ensure that we can't get into an infinite loop. This code
1934  * is arranged to ensure that the worst-case consequence is failing to
1935  * emit log message(s), not failing to attempt the unlink.
1936  */
1937  vfdP->fdstate &= ~FD_DELETE_AT_CLOSE;
1938 
1939 
1940  /* first try the stat() */
1941  if (stat(vfdP->fileName, &filestats))
1942  stat_errno = errno;
1943  else
1944  stat_errno = 0;
1945 
1946  /* in any case do the unlink */
1947  if (unlink(vfdP->fileName))
1948  ereport(LOG,
1950  errmsg("could not delete file \"%s\": %m", vfdP->fileName)));
1951 
1952  /* and last report the stat results */
1953  if (stat_errno == 0)
1954  ReportTemporaryFileUsage(vfdP->fileName, filestats.st_size);
1955  else
1956  {
1957  errno = stat_errno;
1958  ereport(LOG,
1960  errmsg("could not stat file \"%s\": %m", vfdP->fileName)));
1961  }
1962  }
1963 
1964  /* Unregister it from the resource owner */
1965  if (vfdP->resowner)
1966  ResourceOwnerForgetFile(vfdP->resowner, file);
1967 
1968  /*
1969  * Return the Vfd slot to the free list
1970  */
1971  FreeVfd(file);
1972 }
#define FD_DELETE_AT_CLOSE
Definition: fd.c:187
static void Delete(File file)
Definition: fd.c:1174
#define FileIsValid(file)
Definition: fd.c:181
static int nfile
Definition: fd.c:217
static void FreeVfd(File file)
Definition: fd.c:1378
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:189
int data_sync_elevel(int elevel)
Definition: fd.c:3737
static void ReportTemporaryFileUsage(const char *path, off_t size)
Definition: fd.c:1434
static uint64 temporary_files_size
Definition: fd.c:231
#define VFD_CLOSED
Definition: fd.c:179
static Vfd * VfdCache
Definition: fd.c:211
void ResourceOwnerForgetFile(ResourceOwner owner, File file)
Definition: resowner.c:1310
Definition: fd.c:192
int fd
Definition: fd.c:193
char * fileName
Definition: fd.c:200
ResourceOwner resowner
Definition: fd.c:195
unsigned short fdstate
Definition: fd.c:194
off_t fileSize
Definition: fd.c:199
#define stat
Definition: win32_port.h:286

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

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

◆ FileGetRawDesc()

int FileGetRawDesc ( File  file)

Definition at line 2278 of file fd.c.

2279 {
2280  Assert(FileIsValid(file));
2281  return VfdCache[file].fd;
2282 }

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

◆ FileGetRawFlags()

int FileGetRawFlags ( File  file)

Definition at line 2288 of file fd.c.

2289 {
2290  Assert(FileIsValid(file));
2291  return VfdCache[file].fileFlags;
2292 }
int fileFlags
Definition: fd.c:202

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

◆ FileGetRawMode()

mode_t FileGetRawMode ( File  file)

Definition at line 2298 of file fd.c.

2299 {
2300  Assert(FileIsValid(file));
2301  return VfdCache[file].fileMode;
2302 }
mode_t fileMode
Definition: fd.c:203

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

◆ FilePathName()

◆ FilePrefetch()

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

Definition at line 1984 of file fd.c.

1985 {
1986 #if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
1987  int returnCode;
1988 
1989  Assert(FileIsValid(file));
1990 
1991  DO_DB(elog(LOG, "FilePrefetch: %d (%s) " INT64_FORMAT " %d",
1992  file, VfdCache[file].fileName,
1993  (int64) offset, amount));
1994 
1995  returnCode = FileAccess(file);
1996  if (returnCode < 0)
1997  return returnCode;
1998 
1999  pgstat_report_wait_start(wait_event_info);
2000  returnCode = posix_fadvise(VfdCache[file].fd, offset, amount,
2001  POSIX_FADV_WILLNEED);
2003 
2004  return returnCode;
2005 #else
2006  Assert(FileIsValid(file));
2007  return 0;
2008 #endif
2009 }
#define INT64_FORMAT
Definition: c.h:532
static int FileAccess(File file)
Definition: fd.c:1398
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:271
static void pgstat_report_wait_end(void)
Definition: wait_event.h:287

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

Referenced by mdprefetch().

◆ FileRead()

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

Definition at line 2035 of file fd.c.

2037 {
2038  int returnCode;
2039  Vfd *vfdP;
2040 
2041  Assert(FileIsValid(file));
2042 
2043  DO_DB(elog(LOG, "FileRead: %d (%s) " INT64_FORMAT " %zu %p",
2044  file, VfdCache[file].fileName,
2045  (int64) offset,
2046  amount, buffer));
2047 
2048  returnCode = FileAccess(file);
2049  if (returnCode < 0)
2050  return returnCode;
2051 
2052  vfdP = &VfdCache[file];
2053 
2054 retry:
2055  pgstat_report_wait_start(wait_event_info);
2056  returnCode = pg_pread(vfdP->fd, buffer, amount, offset);
2058 
2059  if (returnCode < 0)
2060  {
2061  /*
2062  * Windows may run out of kernel buffers and return "Insufficient
2063  * system resources" error. Wait a bit and retry to solve it.
2064  *
2065  * It is rumored that EINTR is also possible on some Unix filesystems,
2066  * in which case immediate retry is indicated.
2067  */
2068 #ifdef WIN32
2069  DWORD error = GetLastError();
2070 
2071  switch (error)
2072  {
2073  case ERROR_NO_SYSTEM_RESOURCES:
2074  pg_usleep(1000L);
2075  errno = EINTR;
2076  break;
2077  default:
2078  _dosmaperr(error);
2079  break;
2080  }
2081 #endif
2082  /* OK to retry if interrupted */
2083  if (errno == EINTR)
2084  goto retry;
2085  }
2086 
2087  return returnCode;
2088 }
#define pg_pread
Definition: port.h:225
void pg_usleep(long microsec)
Definition: signal.c:53
static void error(void)
Definition: sql-dyntest.c:147
#define EINTR
Definition: win32_port.h:376
void _dosmaperr(unsigned long)
Definition: win32error.c:177

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

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

◆ FileSize()

off_t FileSize ( File  file)

Definition at line 2210 of file fd.c.

2211 {
2212  Assert(FileIsValid(file));
2213 
2214  DO_DB(elog(LOG, "FileSize %d (%s)",
2215  file, VfdCache[file].fileName));
2216 
2217  if (FileIsNotOpen(file))
2218  {
2219  if (FileAccess(file) < 0)
2220  return (off_t) -1;
2221  }
2222 
2223  return lseek(VfdCache[file].fd, 0, SEEK_END);
2224 }

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

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

◆ FileSync()

int FileSync ( File  file,
uint32  wait_event_info 
)

Definition at line 2189 of file fd.c.

2190 {
2191  int returnCode;
2192 
2193  Assert(FileIsValid(file));
2194 
2195  DO_DB(elog(LOG, "FileSync: %d (%s)",
2196  file, VfdCache[file].fileName));
2197 
2198  returnCode = FileAccess(file);
2199  if (returnCode < 0)
2200  return returnCode;
2201 
2202  pgstat_report_wait_start(wait_event_info);
2203  returnCode = pg_fsync(VfdCache[file].fd);
2205 
2206  return returnCode;
2207 }

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

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

◆ FileTruncate()

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

Definition at line 2227 of file fd.c.

2228 {
2229  int returnCode;
2230 
2231  Assert(FileIsValid(file));
2232 
2233  DO_DB(elog(LOG, "FileTruncate %d (%s)",
2234  file, VfdCache[file].fileName));
2235 
2236  returnCode = FileAccess(file);
2237  if (returnCode < 0)
2238  return returnCode;
2239 
2240  pgstat_report_wait_start(wait_event_info);
2241  returnCode = ftruncate(VfdCache[file].fd, offset);
2243 
2244  if (returnCode == 0 && VfdCache[file].fileSize > offset)
2245  {
2246  /* adjust our state for truncation of a temp file */
2247  Assert(VfdCache[file].fdstate & FD_TEMP_FILE_LIMIT);
2248  temporary_files_size -= VfdCache[file].fileSize - offset;
2249  VfdCache[file].fileSize = offset;
2250  }
2251 
2252  return returnCode;
2253 }
#define ftruncate(a, b)
Definition: win32_port.h:82

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

Referenced by BufFileTruncateFileSet(), and mdtruncate().

◆ FileWrite()

int FileWrite ( File  file,
const void *  buffer,
size_t  amount,
off_t  offset,
uint32  wait_event_info 
)

Definition at line 2091 of file fd.c.

2093 {
2094  int returnCode;
2095  Vfd *vfdP;
2096 
2097  Assert(FileIsValid(file));
2098 
2099  DO_DB(elog(LOG, "FileWrite: %d (%s) " INT64_FORMAT " %d %p",
2100  file, VfdCache[file].fileName,
2101  (int64) offset,
2102  amount, buffer));
2103 
2104  returnCode = FileAccess(file);
2105  if (returnCode < 0)
2106  return returnCode;
2107 
2108  vfdP = &VfdCache[file];
2109 
2110  /*
2111  * If enforcing temp_file_limit and it's a temp file, check to see if the
2112  * write would overrun temp_file_limit, and throw error if so. Note: it's
2113  * really a modularity violation to throw error here; we should set errno
2114  * and return -1. However, there's no way to report a suitable error
2115  * message if we do that. All current callers would just throw error
2116  * immediately anyway, so this is safe at present.
2117  */
2118  if (temp_file_limit >= 0 && (vfdP->fdstate & FD_TEMP_FILE_LIMIT))
2119  {
2120  off_t past_write = offset + amount;
2121 
2122  if (past_write > vfdP->fileSize)
2123  {
2124  uint64 newTotal = temporary_files_size;
2125 
2126  newTotal += past_write - vfdP->fileSize;
2127  if (newTotal > (uint64) temp_file_limit * (uint64) 1024)
2128  ereport(ERROR,
2129  (errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED),
2130  errmsg("temporary file size exceeds temp_file_limit (%dkB)",
2131  temp_file_limit)));
2132  }
2133  }
2134 
2135 retry:
2136  errno = 0;
2137  pgstat_report_wait_start(wait_event_info);
2138  returnCode = pg_pwrite(VfdCache[file].fd, buffer, amount, offset);
2140 
2141  /* if write didn't set errno, assume problem is no disk space */
2142  if (returnCode != amount && errno == 0)
2143  errno = ENOSPC;
2144 
2145  if (returnCode >= 0)
2146  {
2147  /*
2148  * Maintain fileSize and temporary_files_size if it's a temp file.
2149  */
2150  if (vfdP->fdstate & FD_TEMP_FILE_LIMIT)
2151  {
2152  off_t past_write = offset + amount;
2153 
2154  if (past_write > vfdP->fileSize)
2155  {
2156  temporary_files_size += past_write - vfdP->fileSize;
2157  vfdP->fileSize = past_write;
2158  }
2159  }
2160  }
2161  else
2162  {
2163  /*
2164  * See comments in FileRead()
2165  */
2166 #ifdef WIN32
2167  DWORD error = GetLastError();
2168 
2169  switch (error)
2170  {
2171  case ERROR_NO_SYSTEM_RESOURCES:
2172  pg_usleep(1000L);
2173  errno = EINTR;
2174  break;
2175  default:
2176  _dosmaperr(error);
2177  break;
2178  }
2179 #endif
2180  /* OK to retry if interrupted */
2181  if (errno == EINTR)
2182  goto retry;
2183  }
2184 
2185  return returnCode;
2186 }
int temp_file_limit
Definition: guc_tables.c:523
#define pg_pwrite
Definition: port.h:226

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

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

◆ FileWriteback()

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

Definition at line 2012 of file fd.c.

2013 {
2014  int returnCode;
2015 
2016  Assert(FileIsValid(file));
2017 
2018  DO_DB(elog(LOG, "FileWriteback: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
2019  file, VfdCache[file].fileName,
2020  (int64) offset, (int64) nbytes));
2021 
2022  if (nbytes <= 0)
2023  return;
2024 
2025  returnCode = FileAccess(file);
2026  if (returnCode < 0)
2027  return;
2028 
2029  pgstat_report_wait_start(wait_event_info);
2030  pg_flush_data(VfdCache[file].fd, offset, nbytes);
2032 }
void pg_flush_data(int fd, off_t offset, off_t nbytes)
Definition: fd.c:458

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

Referenced by mdwriteback().

◆ FreeDir()

int FreeDir ( DIR dir)

Definition at line 2762 of file fd.c.

2763 {
2764  int i;
2765 
2766  /* Nothing to do if AllocateDir failed */
2767  if (dir == NULL)
2768  return 0;
2769 
2770  DO_DB(elog(LOG, "FreeDir: Allocated %d", numAllocatedDescs));
2771 
2772  /* Remove dir from list of allocated dirs, if it's present */
2773  for (i = numAllocatedDescs; --i >= 0;)
2774  {
2775  AllocateDesc *desc = &allocatedDescs[i];
2776 
2777  if (desc->kind == AllocateDescDir && desc->desc.dir == dir)
2778  return FreeDesc(desc);
2779  }
2780 
2781  /* Only get here if someone passes us a dir not in allocatedDescs */
2782  elog(WARNING, "dir passed to FreeDir was not obtained from AllocateDir");
2783 
2784  return closedir(dir);
2785 }
int closedir(DIR *)
Definition: dirent.c:127

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

Referenced by calculate_database_size(), calculate_tablespace_size(), CheckPointLogicalRewriteHeap(), CheckPointSnapBuild(), CleanupBackupHistory(), copydir(), db_dir_size(), DeleteAllExportedSnapshotFiles(), destroy_tablespace_directories(), directory_is_empty(), do_pg_backup_start(), dsm_cleanup_for_mmap(), extension_file_exists(), get_ext_ver_list(), GetConfFilesInDir(), getInstallationPaths(), 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(), 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().

◆ FreeFile()

int FreeFile ( FILE *  file)

Definition at line 2582 of file fd.c.

2583 {
2584  int i;
2585 
2586  DO_DB(elog(LOG, "FreeFile: Allocated %d", numAllocatedDescs));
2587 
2588  /* Remove file from list of allocated files, if it's present */
2589  for (i = numAllocatedDescs; --i >= 0;)
2590  {
2591  AllocateDesc *desc = &allocatedDescs[i];
2592 
2593  if (desc->kind == AllocateDescFile && desc->desc.file == file)
2594  return FreeDesc(desc);
2595  }
2596 
2597  /* Only get here if someone passes us a file not in allocatedDescs */
2598  elog(WARNING, "file passed to FreeFile was not obtained from AllocateFile");
2599 
2600  return fclose(file);
2601 }

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

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

◆ fsync_fname()

◆ fsync_fname_ext()

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

Definition at line 3598 of file fd.c.

3599 {
3600  int fd;
3601  int flags;
3602  int returncode;
3603 
3604  /*
3605  * Some OSs require directories to be opened read-only whereas other
3606  * systems don't allow us to fsync files opened read-only; so we need both
3607  * cases here. Using O_RDWR will cause us to fail to fsync files that are
3608  * not writable by our userid, but we assume that's OK.
3609  */
3610  flags = PG_BINARY;
3611  if (!isdir)
3612  flags |= O_RDWR;
3613  else
3614  flags |= O_RDONLY;
3615 
3616  fd = OpenTransientFile(fname, flags);
3617 
3618  /*
3619  * Some OSs don't allow us to open directories at all (Windows returns
3620  * EACCES), just ignore the error in that case. If desired also silently
3621  * ignoring errors about unreadable files. Log others.
3622  */
3623  if (fd < 0 && isdir && (errno == EISDIR || errno == EACCES))
3624  return 0;
3625  else if (fd < 0 && ignore_perm && errno == EACCES)
3626  return 0;
3627  else if (fd < 0)
3628  {
3629  ereport(elevel,
3631  errmsg("could not open file \"%s\": %m", fname)));
3632  return -1;
3633  }
3634 
3635  returncode = pg_fsync(fd);
3636 
3637  /*
3638  * Some OSes don't allow us to fsync directories at all, so we can ignore
3639  * those errors. Anything else needs to be logged.
3640  */
3641  if (returncode != 0 && !(isdir && (errno == EBADF || errno == EINVAL)))
3642  {
3643  int save_errno;
3644 
3645  /* close file upon error, might not be in transaction context */
3646  save_errno = errno;
3647  (void) CloseTransientFile(fd);
3648  errno = save_errno;
3649 
3650  ereport(elevel,
3652  errmsg("could not fsync file \"%s\": %m", fname)));
3653  return -1;
3654  }
3655 
3656  if (CloseTransientFile(fd) != 0)
3657  {
3658  ereport(elevel,
3660  errmsg("could not close file \"%s\": %m", fname)));
3661  return -1;
3662  }
3663 
3664  return 0;
3665 }

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

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

◆ GetNextTempTableSpace()

Oid GetNextTempTableSpace ( void  )

Definition at line 2912 of file fd.c.

2913 {
2914  if (numTempTableSpaces > 0)
2915  {
2916  /* Advance nextTempTableSpace counter with wraparound */
2918  nextTempTableSpace = 0;
2920  }
2921  return InvalidOid;
2922 }
static int nextTempTableSpace
Definition: fd.c:285
#define InvalidOid
Definition: postgres_ext.h:36

References InvalidOid, nextTempTableSpace, numTempTableSpaces, and tempTableSpaces.

Referenced by GetDefaultTablespace(), and OpenTemporaryFile().

◆ GetTempTablespaces()

int GetTempTablespaces ( Oid tableSpaces,
int  numSpaces 
)

Definition at line 2894 of file fd.c.

2895 {
2896  int i;
2897 
2899  for (i = 0; i < numTempTableSpaces && i < numSpaces; ++i)
2900  tableSpaces[i] = tempTableSpaces[i];
2901 
2902  return i;
2903 }
bool TempTablespacesAreSet(void)
Definition: fd.c:2879

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

Referenced by FileSetInit().

◆ InitFileAccess()

void InitFileAccess ( void  )

Definition at line 809 of file fd.c.

810 {
811  Assert(SizeVfdCache == 0); /* call me only once */
812 
813  /* initialize cache header entry */
814  VfdCache = (Vfd *) malloc(sizeof(Vfd));
815  if (VfdCache == NULL)
816  ereport(FATAL,
817  (errcode(ERRCODE_OUT_OF_MEMORY),
818  errmsg("out of memory")));
819 
820  MemSet((char *) &(VfdCache[0]), 0, sizeof(Vfd));
822 
823  SizeVfdCache = 1;
824 }
#define MemSet(start, val, len)
Definition: c.h:1004
#define FATAL
Definition: elog.h:41
#define malloc(a)
Definition: header.h:50

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

Referenced by BaseInit().

◆ InitTemporaryFileAccess()

void InitTemporaryFileAccess ( void  )

Definition at line 839 of file fd.c.

840 {
841  Assert(SizeVfdCache != 0); /* InitFileAccess() needs to have run */
842  Assert(!temporary_files_allowed); /* call me only once */
843 
844  /*
845  * Register before-shmem-exit hook to ensure temp files are dropped while
846  * we can still report stats.
847  */
849 
850 #ifdef USE_ASSERT_CHECKING
851  temporary_files_allowed = true;
852 #endif
853 }
static void BeforeShmemExit_Files(int code, Datum arg)
Definition: fd.c:2980
void before_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:333

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

Referenced by BaseInit().

◆ looks_like_temp_rel_name()

bool looks_like_temp_rel_name ( const char *  name)

Definition at line 3250 of file fd.c.

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

References forkname_chars(), and name.

Referenced by RemovePgTempRelationFilesInDbspace(), and sendDir().

◆ MakePGDirectory()

int MakePGDirectory ( const char *  directoryName)

◆ OpenPipeStream()

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

Definition at line 2487 of file fd.c.

2488 {
2489  FILE *file;
2490  int save_errno;
2491 
2492  DO_DB(elog(LOG, "OpenPipeStream: Allocated %d (%s)",
2493  numAllocatedDescs, command));
2494 
2495  /* Can we allocate another non-virtual FD? */
2496  if (!reserveAllocatedDesc())
2497  ereport(ERROR,
2498  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2499  errmsg("exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"",
2500  maxAllocatedDescs, command)));
2501 
2502  /* Close excess kernel FDs. */
2503  ReleaseLruFiles();
2504 
2505 TryAgain:
2506  fflush(NULL);
2508  errno = 0;
2509  file = popen(command, mode);
2510  save_errno = errno;
2512  errno = save_errno;
2513  if (file != NULL)
2514  {
2516 
2517  desc->kind = AllocateDescPipe;
2518  desc->desc.file = file;
2521  return desc->desc.file;
2522  }
2523 
2524  if (errno == EMFILE || errno == ENFILE)
2525  {
2526  ereport(LOG,
2527  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2528  errmsg("out of file descriptors: %m; release and retry")));
2529  if (ReleaseLruFile())
2530  goto TryAgain;
2531  errno = save_errno;
2532  }
2533 
2534  return NULL;
2535 }
static void const char fflush(stdout)
pqsigfunc pqsignal(int signo, pqsigfunc func)
#define SIG_DFL
Definition: win32_port.h:171
#define SIGPIPE
Definition: win32_port.h:181
#define SIG_IGN
Definition: win32_port.h:173

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

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

◆ OpenTemporaryFile()

File OpenTemporaryFile ( bool  interXact)

Definition at line 1630 of file fd.c.

1631 {
1632  File file = 0;
1633 
1634  Assert(temporary_files_allowed); /* check temp file access is up */
1635 
1636  /*
1637  * Make sure the current resource owner has space for this File before we
1638  * open it, if we'll be registering it below.
1639  */
1640  if (!interXact)
1642 
1643  /*
1644  * If some temp tablespace(s) have been given to us, try to use the next
1645  * one. If a given tablespace can't be found, we silently fall back to
1646  * the database's default tablespace.
1647  *
1648  * BUT: if the temp file is slated to outlive the current transaction,
1649  * force it into the database's default tablespace, so that it will not
1650  * pose a threat to possible tablespace drop attempts.
1651  */
1652  if (numTempTableSpaces > 0 && !interXact)
1653  {
1654  Oid tblspcOid = GetNextTempTableSpace();
1655 
1656  if (OidIsValid(tblspcOid))
1657  file = OpenTemporaryFileInTablespace(tblspcOid, false);
1658  }
1659 
1660  /*
1661  * If not, or if tablespace is bad, create in database's default
1662  * tablespace. MyDatabaseTableSpace should normally be set before we get
1663  * here, but just in case it isn't, fall back to pg_default tablespace.
1664  */
1665  if (file <= 0)
1668  DEFAULTTABLESPACE_OID,
1669  true);
1670 
1671  /* Mark it for deletion at close and temporary file size limit */
1673 
1674  /* Register it with the current resource owner */
1675  if (!interXact)
1676  RegisterTemporaryFile(file);
1677 
1678  return file;
1679 }
#define OidIsValid(objectId)
Definition: c.h:759
Oid GetNextTempTableSpace(void)
Definition: fd.c:2912
static File OpenTemporaryFileInTablespace(Oid tblspcOid, bool rejectError)
Definition: fd.c:1710
static void RegisterTemporaryFile(File file)
Definition: fd.c:1453
int File
Definition: fd.h:54
Oid MyDatabaseTableSpace
Definition: globals.c:91
unsigned int Oid
Definition: postgres_ext.h:31
void ResourceOwnerEnlargeFiles(ResourceOwner owner)
Definition: resowner.c:1290
ResourceOwner CurrentResourceOwner
Definition: resowner.c:146

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

Referenced by BufFileCreateTemp(), and extendBufFile().

◆ OpenTransientFile()

◆ OpenTransientFilePerm()

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

Definition at line 2443 of file fd.c.

2444 {
2445  int fd;
2446 
2447  DO_DB(elog(LOG, "OpenTransientFile: Allocated %d (%s)",
2448  numAllocatedDescs, fileName));
2449 
2450  /* Can we allocate another non-virtual FD? */
2451  if (!reserveAllocatedDesc())
2452  ereport(ERROR,
2453  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2454  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2455  maxAllocatedDescs, fileName)));
2456 
2457  /* Close excess kernel FDs. */
2458  ReleaseLruFiles();
2459 
2460  fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
2461 
2462  if (fd >= 0)
2463  {
2465 
2466  desc->kind = AllocateDescRawFD;
2467  desc->desc.fd = fd;
2470 
2471  return fd;
2472  }
2473 
2474  return -1; /* failure */
2475 }

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

Referenced by be_lo_export(), and OpenTransientFile().

◆ PathNameCreateTemporaryDir()

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

Definition at line 1566 of file fd.c.

1567 {
1568  if (MakePGDirectory(directory) < 0)
1569  {
1570  if (errno == EEXIST)
1571  return;
1572 
1573  /*
1574  * Failed. Try to create basedir first in case it's missing. Tolerate
1575  * EEXIST to close a race against another process following the same
1576  * algorithm.
1577  */
1578  if (MakePGDirectory(basedir) < 0 && errno != EEXIST)
1579  ereport(ERROR,
1581  errmsg("cannot create temporary directory \"%s\": %m",
1582  basedir)));
1583 
1584  /* Try again. */
1585  if (MakePGDirectory(directory) < 0 && errno != EEXIST)
1586  ereport(ERROR,
1588  errmsg("cannot create temporary subdirectory \"%s\": %m",
1589  directory)));
1590  }
1591 }
int MakePGDirectory(const char *directoryName)
Definition: fd.c:3714
static char * basedir
static const char * directory
Definition: zic.c:634

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

Referenced by FileSetCreate().

◆ PathNameCreateTemporaryFile()

File PathNameCreateTemporaryFile ( const char *  path,
bool  error_on_failure 
)

Definition at line 1767 of file fd.c.

1768 {
1769  File file;
1770 
1771  Assert(temporary_files_allowed); /* check temp file access is up */
1772 
1774 
1775  /*
1776  * Open the file. Note: we don't use O_EXCL, in case there is an orphaned
1777  * temp file that can be reused.
1778  */
1779  file = PathNameOpenFile(path, O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1780  if (file <= 0)
1781  {
1782  if (error_on_failure)
1783  ereport(ERROR,
1785  errmsg("could not create temporary file \"%s\": %m",
1786  path)));
1787  else
1788  return file;
1789  }
1790 
1791  /* Mark it for temp_file_limit accounting. */
1793 
1794  /* Register it for automatic close. */
1795  RegisterTemporaryFile(file);
1796 
1797  return file;
1798 }
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1481

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

Referenced by FileSetCreate().

◆ PathNameDeleteTemporaryDir()

void PathNameDeleteTemporaryDir ( const char *  dirname)

Definition at line 1597 of file fd.c.

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

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

Referenced by FileSetDeleteAll().

◆ PathNameDeleteTemporaryFile()

bool PathNameDeleteTemporaryFile ( const char *  path,
bool  error_on_failure 
)

Definition at line 1838 of file fd.c.

1839 {
1840  struct stat filestats;
1841  int stat_errno;
1842 
1843  /* Get the final size for pgstat reporting. */
1844  if (stat(path, &filestats) != 0)
1845  stat_errno = errno;
1846  else
1847  stat_errno = 0;
1848 
1849  /*
1850  * Unlike FileClose's automatic file deletion code, we tolerate
1851  * non-existence to support BufFileDeleteFileSet which doesn't know how
1852  * many segments it has to delete until it runs out.
1853  */
1854  if (stat_errno == ENOENT)
1855  return false;
1856 
1857  if (unlink(path) < 0)
1858  {
1859  if (errno != ENOENT)
1860  ereport(error_on_failure ? ERROR : LOG,
1862  errmsg("could not unlink temporary file \"%s\": %m",
1863  path)));
1864  return false;
1865  }
1866 
1867  if (stat_errno == 0)
1868  ReportTemporaryFileUsage(path, filestats.st_size);
1869  else
1870  {
1871  errno = stat_errno;
1872  ereport(LOG,
1874  errmsg("could not stat file \"%s\": %m", path)));
1875  }
1876 
1877  return true;
1878 }

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

Referenced by FileSetDelete(), and unlink_if_exists_fname().

◆ PathNameOpenFile()

File PathNameOpenFile ( const char *  fileName,
int  fileFlags 
)

◆ PathNameOpenFilePerm()

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

Definition at line 1494 of file fd.c.

1495 {
1496  char *fnamecopy;
1497  File file;
1498  Vfd *vfdP;
1499 
1500  DO_DB(elog(LOG, "PathNameOpenFilePerm: %s %x %o",
1501  fileName, fileFlags, fileMode));
1502 
1503  /*
1504  * We need a malloc'd copy of the file name; fail cleanly if no room.
1505  */
1506  fnamecopy = strdup(fileName);
1507  if (fnamecopy == NULL)
1508  ereport(ERROR,
1509  (errcode(ERRCODE_OUT_OF_MEMORY),
1510  errmsg("out of memory")));
1511 
1512  file = AllocateVfd();
1513  vfdP = &VfdCache[file];
1514 
1515  /* Close excess kernel FDs. */
1516  ReleaseLruFiles();
1517 
1518  /*
1519  * Descriptors managed by VFDs are implicitly marked O_CLOEXEC. The
1520  * client shouldn't be expected to know which kernel descriptors are
1521  * currently open, so it wouldn't make sense for them to be inherited by
1522  * executed subprograms.
1523  */
1524  fileFlags |= O_CLOEXEC;
1525 
1526  vfdP->fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
1527 
1528  if (vfdP->fd < 0)
1529  {
1530  int save_errno = errno;
1531 
1532  FreeVfd(file);
1533  free(fnamecopy);
1534  errno = save_errno;
1535  return -1;
1536  }
1537  ++nfile;
1538  DO_DB(elog(LOG, "PathNameOpenFile: success %d",
1539  vfdP->fd));
1540 
1541  vfdP->fileName = fnamecopy;
1542  /* Saved flags are adjusted to be OK for re-opening file */
1543  vfdP->fileFlags = fileFlags & ~(O_CREAT | O_TRUNC | O_EXCL);
1544  vfdP->fileMode = fileMode;
1545  vfdP->fileSize = 0;
1546  vfdP->fdstate = 0x0;
1547  vfdP->resowner = NULL;
1548 
1549  Insert(file);
1550 
1551  return file;
1552 }
static File AllocateVfd(void)
Definition: fd.c:1320
static void Insert(File file)
Definition: fd.c:1219
#define free(a)
Definition: header.h:65

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

Referenced by PathNameOpenFile().

◆ PathNameOpenTemporaryFile()

File PathNameOpenTemporaryFile ( const char *  path,
int  mode 
)

Definition at line 1807 of file fd.c.

1808 {
1809  File file;
1810 
1811  Assert(temporary_files_allowed); /* check temp file access is up */
1812 
1814 
1815  file = PathNameOpenFile(path, mode | PG_BINARY);
1816 
1817  /* If no such file, then we don't raise an error. */
1818  if (file <= 0 && errno != ENOENT)
1819  ereport(ERROR,
1821  errmsg("could not open temporary file \"%s\": %m",
1822  path)));
1823 
1824  if (file > 0)
1825  {
1826  /* Register it for automatic close. */
1827  RegisterTemporaryFile(file);
1828  }
1829 
1830  return file;
1831 }

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

Referenced by FileSetOpen().

◆ pg_fdatasync()

int pg_fdatasync ( int  fd)

Definition at line 444 of file fd.c.

445 {
446  if (enableFsync)
447  return fdatasync(fd);
448  else
449  return 0;
450 }
int fdatasync(int fildes)
bool enableFsync
Definition: globals.c:123

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

Referenced by issue_xlog_fsync().

◆ pg_flush_data()

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

Definition at line 458 of file fd.c.

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

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

Referenced by copy_file(), and FileWriteback().

◆ pg_fsync()

int pg_fsync ( int  fd)

Definition at line 356 of file fd.c.

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

References Assert(), fd(), 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(), durable_rename(), FileSync(), fsync_fname_ext(), heap_xlog_logical_rewrite(), readRecoverySignalFile(), RecreateTwoPhaseFile(), RestoreSlotFromDisk(), SaveSlotToPath(), SlruPhysicalWritePage(), SlruSyncFileTag(), SnapBuildSerialize(), update_controlfile(), write_auto_conf_file(), WriteControlFile(), writeTimeLineHistory(), writeTimeLineHistoryFile(), XLogFileCopy(), and XLogFileInitInternal().

◆ pg_fsync_no_writethrough()

int pg_fsync_no_writethrough ( int  fd)

Definition at line 411 of file fd.c.

412 {
413  if (enableFsync)
414  return fsync(fd);
415  else
416  return 0;
417 }
#define fsync(fd)
Definition: win32_port.h:85

References enableFsync, fd(), and fsync.

Referenced by issue_xlog_fsync(), and pg_fsync().

◆ pg_fsync_writethrough()

int pg_fsync_writethrough ( int  fd)

Definition at line 423 of file fd.c.

424 {
425  if (enableFsync)
426  {
427 #ifdef WIN32
428  return _commit(fd);
429 #elif defined(F_FULLFSYNC)
430  return (fcntl(fd, F_FULLFSYNC, 0) == -1) ? -1 : 0;
431 #else
432  errno = ENOSYS;
433  return -1;
434 #endif
435  }
436  else
437  return 0;
438 }

References enableFsync, and fd().

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

◆ pg_truncate()

int pg_truncate ( const char *  path,
off_t  length 
)

Definition at line 631 of file fd.c.

632 {
633 #ifdef WIN32
634  int save_errno;
635  int ret;
636  int fd;
637 
638  fd = OpenTransientFile(path, O_RDWR | PG_BINARY);
639  if (fd >= 0)
640  {
641  ret = ftruncate(fd, length);
642  save_errno = errno;
644  errno = save_errno;
645  }
646  else
647  ret = -1;
648 
649  return ret;
650 #else
651  return truncate(path, length);
652 #endif
653 }

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

Referenced by do_truncate().

◆ ReadDir()

◆ ReadDirExtended()

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

Definition at line 2725 of file fd.c.

2726 {
2727  struct dirent *dent;
2728 
2729  /* Give a generic message for AllocateDir failure, if caller didn't */
2730  if (dir == NULL)
2731  {
2732  ereport(elevel,
2734  errmsg("could not open directory \"%s\": %m",
2735  dirname)));
2736  return NULL;
2737  }
2738 
2739  errno = 0;
2740  if ((dent = readdir(dir)) != NULL)
2741  return dent;
2742 
2743  if (errno)
2744  ereport(elevel,
2746  errmsg("could not read directory \"%s\": %m",
2747  dirname)));
2748  return NULL;
2749 }
struct dirent * readdir(DIR *)
Definition: dirent.c:78
Definition: dirent.h:10

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

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

◆ ReleaseExternalFD()

◆ RemovePgTempFiles()

void RemovePgTempFiles ( void  )

Definition at line 3075 of file fd.c.

3076 {
3077  char temp_path[MAXPGPATH + 10 + sizeof(TABLESPACE_VERSION_DIRECTORY) + sizeof(PG_TEMP_FILES_DIR)];
3078  DIR *spc_dir;
3079  struct dirent *spc_de;
3080 
3081  /*
3082  * First process temp files in pg_default ($PGDATA/base)
3083  */
3084  snprintf(temp_path, sizeof(temp_path), "base/%s", PG_TEMP_FILES_DIR);
3085  RemovePgTempFilesInDir(temp_path, true, false);
3086  RemovePgTempRelationFiles("base");
3087 
3088  /*
3089  * Cycle through temp directories for all non-default tablespaces.
3090  */
3091  spc_dir = AllocateDir("pg_tblspc");
3092 
3093  while ((spc_de = ReadDirExtended(spc_dir, "pg_tblspc", LOG)) != NULL)
3094  {
3095  if (strcmp(spc_de->d_name, ".") == 0 ||
3096  strcmp(spc_de->d_name, "..") == 0)
3097  continue;
3098 
3099  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s/%s",
3101  RemovePgTempFilesInDir(temp_path, true, false);
3102 
3103  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s",
3105  RemovePgTempRelationFiles(temp_path);
3106  }
3107 
3108  FreeDir(spc_dir);
3109 
3110  /*
3111  * In EXEC_BACKEND case there is a pgsql_tmp directory at the top level of
3112  * DataDir as well. However, that is *not* cleaned here because doing so
3113  * would create a race condition. It's done separately, earlier in
3114  * postmaster startup.
3115  */
3116 }
int FreeDir(DIR *dir)
Definition: fd.c:2762
static void RemovePgTempRelationFiles(const char *tsdirname)
Definition: fd.c:3194
void RemovePgTempFilesInDir(const char *tmpdirname, bool missing_ok, bool unlink_all)
Definition: fd.c:3134
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2644
#define PG_TEMP_FILES_DIR
Definition: pg_checksums.c:62
#define MAXPGPATH
#define snprintf
Definition: port.h:238
#define TABLESPACE_VERSION_DIRECTORY
Definition: relpath.h:33
char d_name[MAX_PATH]
Definition: dirent.h:15

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

Referenced by PostmasterMain(), and PostmasterStateMachine().

◆ RemovePgTempFilesInDir()

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

Definition at line 3134 of file fd.c.

3135 {
3136  DIR *temp_dir;
3137  struct dirent *temp_de;
3138  char rm_path[MAXPGPATH * 2];
3139 
3140  temp_dir = AllocateDir(tmpdirname);
3141 
3142  if (temp_dir == NULL && errno == ENOENT && missing_ok)
3143  return;
3144 
3145  while ((temp_de = ReadDirExtended(temp_dir, tmpdirname, LOG)) != NULL)
3146  {
3147  if (strcmp(temp_de->d_name, ".") == 0 ||
3148  strcmp(temp_de->d_name, "..") == 0)
3149  continue;
3150 
3151  snprintf(rm_path, sizeof(rm_path), "%s/%s",
3152  tmpdirname, temp_de->d_name);
3153 
3154  if (unlink_all ||
3155  strncmp(temp_de->d_name,
3157  strlen(PG_TEMP_FILE_PREFIX)) == 0)
3158  {
3159  PGFileType type = get_dirent_type(rm_path, temp_de, false, LOG);
3160 
3161  if (type == PGFILETYPE_ERROR)
3162  continue;
3163  else if (type == PGFILETYPE_DIR)
3164  {
3165  /* recursively remove contents, then directory itself */
3166  RemovePgTempFilesInDir(rm_path, false, true);
3167 
3168  if (rmdir(rm_path) < 0)
3169  ereport(LOG,
3171  errmsg("could not remove directory \"%s\": %m",
3172  rm_path)));
3173  }
3174  else
3175  {
3176  if (unlink(rm_path) < 0)
3177  ereport(LOG,
3179  errmsg("could not remove file \"%s\": %m",
3180  rm_path)));
3181  }
3182  }
3183  else
3184  ereport(LOG,
3185  (errmsg("unexpected file found in temporary-files directory: \"%s\"",
3186  rm_path)));
3187  }
3188 
3189  FreeDir(temp_dir);
3190 }
PGFileType get_dirent_type(const char *path, const struct dirent *de, bool look_through_symlinks, int elevel)
Definition: file_utils.c:406
PGFileType
Definition: file_utils.h:19
@ PGFILETYPE_DIR
Definition: file_utils.h:23
@ PGFILETYPE_ERROR
Definition: file_utils.h:20
#define PG_TEMP_FILE_PREFIX
Definition: pg_checksums.c:63

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

Referenced by PostmasterMain(), and RemovePgTempFiles().

◆ ReserveExternalFD()

void ReserveExternalFD ( void  )

Definition at line 1127 of file fd.c.

1128 {
1129  /*
1130  * Release VFDs if needed to stay safe. Because we do this before
1131  * incrementing numExternalFDs, the final state will be as desired, i.e.,
1132  * nfile + numAllocatedDescs + numExternalFDs <= max_safe_fds.
1133  */
1134  ReleaseLruFiles();
1135 
1136  numExternalFDs++;
1137 }

References numExternalFDs, and ReleaseLruFiles().

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

◆ set_max_safe_fds()

void set_max_safe_fds ( void  )

Definition at line 950 of file fd.c.

951 {
952  int usable_fds;
953  int already_open;
954 
955  /*----------
956  * We want to set max_safe_fds to
957  * MIN(usable_fds, max_files_per_process - already_open)
958  * less the slop factor for files that are opened without consulting
959  * fd.c. This ensures that we won't exceed either max_files_per_process
960  * or the experimentally-determined EMFILE limit.
961  *----------
962  */
964  &usable_fds, &already_open);
965 
966  max_safe_fds = Min(usable_fds, max_files_per_process - already_open);
967 
968  /*
969  * Take off the FDs reserved for system() etc.
970  */
972 
973  /*
974  * Make sure we still have enough to get by.
975  */
976  if (max_safe_fds < FD_MINFREE)
977  ereport(FATAL,
978  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
979  errmsg("insufficient file descriptors available to start server process"),
980  errdetail("System allows %d, server needs at least %d.",
983 
984  elog(DEBUG2, "max_safe_fds = %d, usable_fds = %d, already_open = %d",
985  max_safe_fds, usable_fds, already_open);
986 }
#define Min(x, y)
Definition: c.h:988
int errdetail(const char *fmt,...)
Definition: elog.c:1202
#define DEBUG2
Definition: elog.h:29
int max_files_per_process
Definition: fd.c:144
#define FD_MINFREE
Definition: fd.c:136
static void count_usable_fds(int max_to_probe, int *usable_fds, int *already_open)
Definition: fd.c:870
#define NUM_RESERVED_FDS
Definition: fd.c:127

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

◆ SetTempTablespaces()

void SetTempTablespaces ( Oid tableSpaces,
int  numSpaces 
)

Definition at line 2850 of file fd.c.

2851 {
2852  Assert(numSpaces >= 0);
2853  tempTableSpaces = tableSpaces;
2854  numTempTableSpaces = numSpaces;
2855 
2856  /*
2857  * Select a random starting point in the list. This is to minimize
2858  * conflicts between backends that are most likely sharing the same list
2859  * of temp tablespaces. Note that if we create multiple temp files in the
2860  * same transaction, we'll advance circularly through the list --- this
2861  * ensures that large temporary sort files are nicely spread across all
2862  * available tablespaces.
2863  */
2864  if (numSpaces > 1)
2866  0, numSpaces - 1);
2867  else
2868  nextTempTableSpace = 0;
2869 }
uint64 pg_prng_uint64_range(pg_prng_state *state, uint64 rmin, uint64 rmax)
Definition: pg_prng.c:144
pg_prng_state pg_global_prng_state
Definition: pg_prng.c:34

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

Referenced by assign_temp_tablespaces(), and PrepareTempTablespaces().

◆ SyncDataDirectory()

void SyncDataDirectory ( void  )

Definition at line 3345 of file fd.c.

3346 {
3347  bool xlog_is_symlink;
3348 
3349  /* We can skip this whole thing if fsync is disabled. */
3350  if (!enableFsync)
3351  return;
3352 
3353  /*
3354  * If pg_wal is a symlink, we'll need to recurse into it separately,
3355  * because the first walkdir below will ignore it.
3356  */
3357  xlog_is_symlink = false;
3358 
3359  {
3360  struct stat st;
3361 
3362  if (lstat("pg_wal", &st) < 0)
3363  ereport(LOG,
3365  errmsg("could not stat file \"%s\": %m",
3366  "pg_wal")));
3367  else if (S_ISLNK(st.st_mode))
3368  xlog_is_symlink = true;
3369  }
3370 
3371 #ifdef HAVE_SYNCFS
3373  {
3374  DIR *dir;
3375  struct dirent *de;
3376 
3377  /*
3378  * On Linux, we don't have to open every single file one by one. We
3379  * can use syncfs() to sync whole filesystems. We only expect
3380  * filesystem boundaries to exist where we tolerate symlinks, namely
3381  * pg_wal and the tablespaces, so we call syncfs() for each of those
3382  * directories.
3383  */
3384 
3385  /* Prepare to report progress syncing the data directory via syncfs. */
3387 
3388  /* Sync the top level pgdata directory. */
3389  do_syncfs(".");
3390  /* If any tablespaces are configured, sync each of those. */
3391  dir = AllocateDir("pg_tblspc");
3392  while ((de = ReadDirExtended(dir, "pg_tblspc", LOG)))
3393  {
3394  char path[MAXPGPATH];
3395 
3396  if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
3397  continue;
3398 
3399  snprintf(path, MAXPGPATH, "pg_tblspc/%s", de->d_name);
3400  do_syncfs(path);
3401  }
3402  FreeDir(dir);
3403  /* If pg_wal is a symlink, process that too. */
3404  if (xlog_is_symlink)
3405  do_syncfs("pg_wal");
3406  return;
3407  }
3408 #endif /* !HAVE_SYNCFS */
3409 
3410 #ifdef PG_FLUSH_DATA_WORKS
3411  /* Prepare to report progress of the pre-fsync phase. */
3413 
3414  /*
3415  * If possible, hint to the kernel that we're soon going to fsync the data
3416  * directory and its contents. Errors in this step are even less
3417  * interesting than normal, so log them only at DEBUG1.
3418  */
3419  walkdir(".", pre_sync_fname, false, DEBUG1);
3420  if (xlog_is_symlink)
3421  walkdir("pg_wal", pre_sync_fname, false, DEBUG1);
3422  walkdir("pg_tblspc", pre_sync_fname, true, DEBUG1);
3423 #endif
3424 
3425  /* Prepare to report progress syncing the data directory via fsync. */
3427 
3428  /*
3429  * Now we do the fsync()s in the same order.
3430  *
3431  * The main call ignores symlinks, so in addition to specially processing
3432  * pg_wal if it's a symlink, pg_tblspc has to be visited separately with
3433  * process_symlinks = true. Note that if there are any plain directories
3434  * in pg_tblspc, they'll get fsync'd twice. That's not an expected case
3435  * so we don't worry about optimizing it.
3436  */
3437  walkdir(".", datadir_fsync_fname, false, LOG);
3438  if (xlog_is_symlink)
3439  walkdir("pg_wal", datadir_fsync_fname, false, LOG);
3440  walkdir("pg_tblspc", datadir_fsync_fname, true, LOG);
3441 }
void begin_startup_progress_phase(void)
Definition: startup.c:352
#define DEBUG1
Definition: elog.h:30
int recovery_init_sync_method
Definition: fd.c:163
static void datadir_fsync_fname(const char *fname, bool isdir, int elevel)
Definition: fd.c:3560
#define lstat(path, sb)
Definition: win32_port.h:287
#define S_ISLNK(m)
Definition: win32_port.h:346

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

Referenced by StartupXLOG().

◆ TempTablespacePath()

void TempTablespacePath ( char *  path,
Oid  tablespace 
)

Definition at line 1685 of file fd.c.

1686 {
1687  /*
1688  * Identify the tempfile directory for this tablespace.
1689  *
1690  * If someone tries to specify pg_global, use pg_default instead.
1691  */
1692  if (tablespace == InvalidOid ||
1693  tablespace == DEFAULTTABLESPACE_OID ||
1694  tablespace == GLOBALTABLESPACE_OID)
1695  snprintf(path, MAXPGPATH, "base/%s", PG_TEMP_FILES_DIR);
1696  else
1697  {
1698  /* All other tablespaces are accessed via symlinks */
1699  snprintf(path, MAXPGPATH, "pg_tblspc/%u/%s/%s",
1702  }
1703 }
char * tablespace
Definition: pgbench.c:226

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

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

◆ TempTablespacesAreSet()

bool TempTablespacesAreSet ( void  )

Definition at line 2879 of file fd.c.

2880 {
2881  return (numTempTableSpaces >= 0);
2882 }

References numTempTableSpaces.

Referenced by GetTempTablespaces(), and PrepareTempTablespaces().

Variable Documentation

◆ data_sync_retry

PGDLLIMPORT bool data_sync_retry
extern

Definition at line 160 of file fd.c.

Referenced by data_sync_elevel().

◆ max_files_per_process

PGDLLIMPORT int max_files_per_process
extern

Definition at line 144 of file fd.c.

Referenced by set_max_safe_fds().

◆ max_safe_fds

PGDLLIMPORT int max_safe_fds
extern

Definition at line 157 of file fd.c.

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

◆ recovery_init_sync_method

PGDLLIMPORT int recovery_init_sync_method
extern

Definition at line 163 of file fd.c.

Referenced by SyncDataDirectory().