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, int amount, 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)
 
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 1099 of file fd.c.

1100 {
1101  /*
1102  * We don't want more than max_safe_fds / 3 FDs to be consumed for
1103  * "external" FDs.
1104  */
1105  if (numExternalFDs < max_safe_fds / 3)
1106  {
1108  return true;
1109  }
1110  errno = EMFILE;
1111  return false;
1112 }
int max_safe_fds
Definition: fd.c:157
void ReserveExternalFD(void)
Definition: fd.c:1134
static int numExternalFDs
Definition: fd.c:269

References max_safe_fds, numExternalFDs, and ReserveExternalFD().

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

◆ AllocateDir()

DIR* AllocateDir ( const char *  dirname)

Definition at line 2643 of file fd.c.

2644 {
2645  DIR *dir;
2646 
2647  DO_DB(elog(LOG, "AllocateDir: Allocated %d (%s)",
2648  numAllocatedDescs, dirname));
2649 
2650  /* Can we allocate another non-virtual FD? */
2651  if (!reserveAllocatedDesc())
2652  ereport(ERROR,
2653  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2654  errmsg("exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"",
2655  maxAllocatedDescs, dirname)));
2656 
2657  /* Close excess kernel FDs. */
2658  ReleaseLruFiles();
2659 
2660 TryAgain:
2661  if ((dir = opendir(dirname)) != NULL)
2662  {
2664 
2665  desc->kind = AllocateDescDir;
2666  desc->desc.dir = dir;
2669  return desc->desc.dir;
2670  }
2671 
2672  if (errno == EMFILE || errno == ENFILE)
2673  {
2674  int save_errno = errno;
2675 
2676  ereport(LOG,
2677  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2678  errmsg("out of file descriptors: %m; release and retry")));
2679  errno = 0;
2680  if (ReleaseLruFile())
2681  goto TryAgain;
2682  errno = save_errno;
2683  }
2684 
2685  return NULL;
2686 }
DIR * opendir(const char *)
Definition: dirent.c:33
int errcode(int sqlerrcode)
Definition: elog.c:695
int errmsg(const char *fmt,...)
Definition: elog.c:906
#define LOG
Definition: elog.h:27
#define ERROR
Definition: elog.h:35
#define ereport(elevel,...)
Definition: elog.h:145
static bool ReleaseLruFile(void)
Definition: fd.c:1295
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:2308
static void ReleaseLruFiles(void)
Definition: fd.c:1317
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:779

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

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

2934 {
2935  Index i;
2936 
2937  for (i = 0; i < numAllocatedDescs; i++)
2938  {
2939  if (allocatedDescs[i].create_subid == mySubid)
2940  {
2941  if (isCommit)
2942  allocatedDescs[i].create_subid = parentSubid;
2943  else
2944  {
2945  /* have to recheck the item after FreeDesc (ugly) */
2946  FreeDesc(&allocatedDescs[i--]);
2947  }
2948  }
2949  }
2950 }
unsigned int Index
Definition: c.h:550
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2542
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 2965 of file fd.c.

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

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_CREAT |
1029  O_EXCL |
1030  O_RDWR |
1031  O_RDONLY |
1032  O_SYNC |
1033  O_TRUNC |
1034  O_WRONLY)) == 0,
1035  "PG_O_DIRECT value collides with standard flag");
1036 #if defined(O_CLOEXEC)
1037  StaticAssertStmt((PG_O_DIRECT & O_CLOEXEC) == 0,
1038  "PG_O_DIRECT value collides with O_CLOEXEC");
1039 #endif
1040 #if defined(O_DSYNC)
1042  "PG_O_DIRECT value collides with O_DSYNC");
1043 #endif
1044 
1045  fd = open(fileName, fileFlags & ~PG_O_DIRECT, fileMode);
1046 #else
1047  fd = open(fileName, fileFlags, fileMode);
1048 #endif
1049 
1050  if (fd >= 0)
1051  {
1052 #ifdef PG_O_DIRECT_USE_F_NOCACHE
1053  if (fileFlags & PG_O_DIRECT)
1054  {
1055  if (fcntl(fd, F_NOCACHE, 1) < 0)
1056  {
1057  int save_errno = errno;
1058 
1059  close(fd);
1060  errno = save_errno;
1061  return -1;
1062  }
1063  }
1064 #endif
1065 
1066  return fd; /* success! */
1067  }
1068 
1069  if (errno == EMFILE || errno == ENFILE)
1070  {
1071  int save_errno = errno;
1072 
1073  ereport(LOG,
1074  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
1075  errmsg("out of file descriptors: %m; release and retry")));
1076  errno = 0;
1077  if (ReleaseLruFile())
1078  goto tryAgain;
1079  errno = save_errno;
1080  }
1081 
1082  return -1; /* failure */
1083 }
#define StaticAssertStmt(condition, errmessage)
Definition: c.h:869
#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_DSYNC
Definition: win32_port.h:354

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

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

◆ closeAllVfds()

void closeAllVfds ( void  )

Definition at line 2820 of file fd.c.

2821 {
2822  Index i;
2823 
2824  if (SizeVfdCache > 0)
2825  {
2826  Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
2827  for (i = 1; i < SizeVfdCache; i++)
2828  {
2829  if (!FileIsNotOpen(i))
2830  LruDelete(i);
2831  }
2832  }
2833 }
static void LruDelete(File file)
Definition: fd.c:1200
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 2791 of file fd.c.

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

2610 {
2611  int i;
2612 
2613  DO_DB(elog(LOG, "CloseTransientFile: Allocated %d", numAllocatedDescs));
2614 
2615  /* Remove fd from list of allocated files, if it's present */
2616  for (i = numAllocatedDescs; --i >= 0;)
2617  {
2618  AllocateDesc *desc = &allocatedDescs[i];
2619 
2620  if (desc->kind == AllocateDescRawFD && desc->desc.fd == fd)
2621  return FreeDesc(desc);
2622  }
2623 
2624  /* Only get here if someone passes us a file not in allocatedDescs */
2625  elog(WARNING, "fd passed to CloseTransientFile was not obtained from OpenTransientFile");
2626 
2627  return close(fd);
2628 }
@ 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:1209
int errcode_for_file_access(void)
Definition: elog.c:718
int CloseTransientFile(int fd)
Definition: fd.c:2609
int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3597
int pg_fsync(int fd)
Definition: fd.c:356
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3673
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2433

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

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

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

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

◆ FileGetRawFlags()

int FileGetRawFlags ( File  file)

Definition at line 2287 of file fd.c.

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

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

◆ FileGetRawMode()

mode_t FileGetRawMode ( File  file)

Definition at line 2297 of file fd.c.

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

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

◆ FilePathName()

◆ FilePrefetch()

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

Definition at line 1983 of file fd.c.

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

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,
char *  buffer,
int  amount,
off_t  offset,
uint32  wait_event_info 
)

Definition at line 2034 of file fd.c.

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

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

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

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

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

2227 {
2228  int returnCode;
2229 
2230  Assert(FileIsValid(file));
2231 
2232  DO_DB(elog(LOG, "FileTruncate %d (%s)",
2233  file, VfdCache[file].fileName));
2234 
2235  returnCode = FileAccess(file);
2236  if (returnCode < 0)
2237  return returnCode;
2238 
2239  pgstat_report_wait_start(wait_event_info);
2240  returnCode = ftruncate(VfdCache[file].fd, offset);
2242 
2243  if (returnCode == 0 && VfdCache[file].fileSize > offset)
2244  {
2245  /* adjust our state for truncation of a temp file */
2246  Assert(VfdCache[file].fdstate & FD_TEMP_FILE_LIMIT);
2247  temporary_files_size -= VfdCache[file].fileSize - offset;
2248  VfdCache[file].fileSize = offset;
2249  }
2250 
2251  return returnCode;
2252 }
#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,
char *  buffer,
int  amount,
off_t  offset,
uint32  wait_event_info 
)

Definition at line 2090 of file fd.c.

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

2012 {
2013  int returnCode;
2014 
2015  Assert(FileIsValid(file));
2016 
2017  DO_DB(elog(LOG, "FileWriteback: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
2018  file, VfdCache[file].fileName,
2019  (int64) offset, (int64) nbytes));
2020 
2021  if (nbytes <= 0)
2022  return;
2023 
2024  returnCode = FileAccess(file);
2025  if (returnCode < 0)
2026  return;
2027 
2028  pgstat_report_wait_start(wait_event_info);
2029  pg_flush_data(VfdCache[file].fd, offset, nbytes);
2031 }
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 2761 of file fd.c.

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

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

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

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

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

2912 {
2913  if (numTempTableSpaces > 0)
2914  {
2915  /* Advance nextTempTableSpace counter with wraparound */
2917  nextTempTableSpace = 0;
2919  }
2920  return InvalidOid;
2921 }
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 2893 of file fd.c.

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

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:953
#define FATAL
Definition: elog.h:37
#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:2979
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 3249 of file fd.c.

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

2487 {
2488  FILE *file;
2489  int save_errno;
2490 
2491  DO_DB(elog(LOG, "OpenPipeStream: Allocated %d (%s)",
2492  numAllocatedDescs, command));
2493 
2494  /* Can we allocate another non-virtual FD? */
2495  if (!reserveAllocatedDesc())
2496  ereport(ERROR,
2497  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2498  errmsg("exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"",
2499  maxAllocatedDescs, command)));
2500 
2501  /* Close excess kernel FDs. */
2502  ReleaseLruFiles();
2503 
2504 TryAgain:
2505  fflush(NULL);
2507  errno = 0;
2508  file = popen(command, mode);
2509  save_errno = errno;
2511  errno = save_errno;
2512  if (file != NULL)
2513  {
2515 
2516  desc->kind = AllocateDescPipe;
2517  desc->desc.file = file;
2520  return desc->desc.file;
2521  }
2522 
2523  if (errno == EMFILE || errno == ENFILE)
2524  {
2525  ereport(LOG,
2526  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2527  errmsg("out of file descriptors: %m; release and retry")));
2528  if (ReleaseLruFile())
2529  goto TryAgain;
2530  errno = save_errno;
2531  }
2532 
2533  return NULL;
2534 }
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 1629 of file fd.c.

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

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

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

1566 {
1567  if (MakePGDirectory(directory) < 0)
1568  {
1569  if (errno == EEXIST)
1570  return;
1571 
1572  /*
1573  * Failed. Try to create basedir first in case it's missing. Tolerate
1574  * EEXIST to close a race against another process following the same
1575  * algorithm.
1576  */
1577  if (MakePGDirectory(basedir) < 0 && errno != EEXIST)
1578  ereport(ERROR,
1580  errmsg("cannot create temporary directory \"%s\": %m",
1581  basedir)));
1582 
1583  /* Try again. */
1584  if (MakePGDirectory(directory) < 0 && errno != EEXIST)
1585  ereport(ERROR,
1587  errmsg("cannot create temporary subdirectory \"%s\": %m",
1588  directory)));
1589  }
1590 }
int MakePGDirectory(const char *directoryName)
Definition: fd.c:3713
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 1766 of file fd.c.

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

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

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

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

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

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

1502 {
1503  char *fnamecopy;
1504  File file;
1505  Vfd *vfdP;
1506 
1507  DO_DB(elog(LOG, "PathNameOpenFilePerm: %s %x %o",
1508  fileName, fileFlags, fileMode));
1509 
1510  /*
1511  * We need a malloc'd copy of the file name; fail cleanly if no room.
1512  */
1513  fnamecopy = strdup(fileName);
1514  if (fnamecopy == NULL)
1515  ereport(ERROR,
1516  (errcode(ERRCODE_OUT_OF_MEMORY),
1517  errmsg("out of memory")));
1518 
1519  file = AllocateVfd();
1520  vfdP = &VfdCache[file];
1521 
1522  /* Close excess kernel FDs. */
1523  ReleaseLruFiles();
1524 
1525  vfdP->fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
1526 
1527  if (vfdP->fd < 0)
1528  {
1529  int save_errno = errno;
1530 
1531  FreeVfd(file);
1532  free(fnamecopy);
1533  errno = save_errno;
1534  return -1;
1535  }
1536  ++nfile;
1537  DO_DB(elog(LOG, "PathNameOpenFile: success %d",
1538  vfdP->fd));
1539 
1540  vfdP->fileName = fnamecopy;
1541  /* Saved flags are adjusted to be OK for re-opening file */
1542  vfdP->fileFlags = fileFlags & ~(O_CREAT | O_TRUNC | O_EXCL);
1543  vfdP->fileMode = fileMode;
1544  vfdP->fileSize = 0;
1545  vfdP->fdstate = 0x0;
1546  vfdP->resowner = NULL;
1547 
1548  Insert(file);
1549 
1550  return file;
1551 }
static File AllocateVfd(void)
Definition: fd.c:1327
static void Insert(File file)
Definition: fd.c:1226
#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, ReleaseLruFiles(), vfd::resowner, and VfdCache.

Referenced by PathNameOpenFile().

◆ PathNameOpenTemporaryFile()

File PathNameOpenTemporaryFile ( const char *  path,
int  mode 
)

Definition at line 1806 of file fd.c.

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

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, 0);
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 2724 of file fd.c.

2725 {
2726  struct dirent *dent;
2727 
2728  /* Give a generic message for AllocateDir failure, if caller didn't */
2729  if (dir == NULL)
2730  {
2731  ereport(elevel,
2733  errmsg("could not open directory \"%s\": %m",
2734  dirname)));
2735  return NULL;
2736  }
2737 
2738  errno = 0;
2739  if ((dent = readdir(dir)) != NULL)
2740  return dent;
2741 
2742  if (errno)
2743  ereport(elevel,
2745  errmsg("could not read directory \"%s\": %m",
2746  dirname)));
2747  return NULL;
2748 }
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 3074 of file fd.c.

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

3134 {
3135  DIR *temp_dir;
3136  struct dirent *temp_de;
3137  char rm_path[MAXPGPATH * 2];
3138 
3139  temp_dir = AllocateDir(tmpdirname);
3140 
3141  if (temp_dir == NULL && errno == ENOENT && missing_ok)
3142  return;
3143 
3144  while ((temp_de = ReadDirExtended(temp_dir, tmpdirname, LOG)) != NULL)
3145  {
3146  if (strcmp(temp_de->d_name, ".") == 0 ||
3147  strcmp(temp_de->d_name, "..") == 0)
3148  continue;
3149 
3150  snprintf(rm_path, sizeof(rm_path), "%s/%s",
3151  tmpdirname, temp_de->d_name);
3152 
3153  if (unlink_all ||
3154  strncmp(temp_de->d_name,
3156  strlen(PG_TEMP_FILE_PREFIX)) == 0)
3157  {
3158  PGFileType type = get_dirent_type(rm_path, temp_de, false, LOG);
3159 
3160  if (type == PGFILETYPE_ERROR)
3161  continue;
3162  else if (type == PGFILETYPE_DIR)
3163  {
3164  /* recursively remove contents, then directory itself */
3165  RemovePgTempFilesInDir(rm_path, false, true);
3166 
3167  if (rmdir(rm_path) < 0)
3168  ereport(LOG,
3170  errmsg("could not remove directory \"%s\": %m",
3171  rm_path)));
3172  }
3173  else
3174  {
3175  if (unlink(rm_path) < 0)
3176  ereport(LOG,
3178  errmsg("could not remove file \"%s\": %m",
3179  rm_path)));
3180  }
3181  }
3182  else
3183  ereport(LOG,
3184  (errmsg("unexpected file found in temporary-files directory: \"%s\"",
3185  rm_path)));
3186  }
3187 
3188  FreeDir(temp_dir);
3189 }
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 1134 of file fd.c.

1135 {
1136  /*
1137  * Release VFDs if needed to stay safe. Because we do this before
1138  * incrementing numExternalFDs, the final state will be as desired, i.e.,
1139  * nfile + numAllocatedDescs + numExternalFDs <= max_safe_fds.
1140  */
1141  ReleaseLruFiles();
1142 
1143  numExternalFDs++;
1144 }

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:937
int errdetail(const char *fmt,...)
Definition: elog.c:1039
#define DEBUG2
Definition: elog.h:25
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 2849 of file fd.c.

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

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

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

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

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

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

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