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 *name, bool error_on_failure)
 
File PathNameOpenTemporaryFile (const char *path, int mode)
 
bool PathNameDeleteTemporaryFile (const char *name, bool error_on_failure)
 
void PathNameCreateTemporaryDir (const char *base, const char *name)
 
void PathNameDeleteTemporaryDir (const char *name)
 
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 amount)
 
ssize_t pg_pwritev_with_retry (int fd, const struct iovec *iov, int iovcnt, off_t offset)
 
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 loglevel)
 
int durable_unlink (const char *fname, int loglevel)
 
int durable_rename_excl (const char *oldfile, const char *newfile, int loglevel)
 
void SyncDataDirectory (void)
 
int data_sync_elevel (int elevel)
 

Variables

PGDLLIMPORT int max_files_per_process
 
PGDLLIMPORT bool data_sync_retry
 
int recovery_init_sync_method
 
int max_safe_fds
 

Macro Definition Documentation

◆ FILE_POSSIBLY_DELETED

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

Definition at line 77 of file fd.h.

◆ PG_O_DIRECT

#define PG_O_DIRECT   0

Definition at line 95 of file fd.h.

◆ PG_TEMP_FILE_PREFIX

#define PG_TEMP_FILE_PREFIX   "pgsql_tmp"

Definition at line 196 of file fd.h.

◆ PG_TEMP_FILES_DIR

#define PG_TEMP_FILES_DIR   "pgsql_tmp"

Definition at line 195 of file fd.h.

Typedef Documentation

◆ File

typedef int File

Definition at line 56 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 1177 of file fd.c.

1178 {
1179  /*
1180  * We don't want more than max_safe_fds / 3 FDs to be consumed for
1181  * "external" FDs.
1182  */
1183  if (numExternalFDs < max_safe_fds / 3)
1184  {
1186  return true;
1187  }
1188  errno = EMFILE;
1189  return false;
1190 }
int max_safe_fds
Definition: fd.c:160
void ReserveExternalFD(void)
Definition: fd.c:1212
static int numExternalFDs
Definition: fd.c:272

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

2723 {
2724  DIR *dir;
2725 
2726  DO_DB(elog(LOG, "AllocateDir: Allocated %d (%s)",
2727  numAllocatedDescs, dirname));
2728 
2729  /* Can we allocate another non-virtual FD? */
2730  if (!reserveAllocatedDesc())
2731  ereport(ERROR,
2732  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2733  errmsg("exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"",
2734  maxAllocatedDescs, dirname)));
2735 
2736  /* Close excess kernel FDs. */
2737  ReleaseLruFiles();
2738 
2739 TryAgain:
2740  if ((dir = opendir(dirname)) != NULL)
2741  {
2743 
2744  desc->kind = AllocateDescDir;
2745  desc->desc.dir = dir;
2748  return desc->desc.dir;
2749  }
2750 
2751  if (errno == EMFILE || errno == ENFILE)
2752  {
2753  int save_errno = errno;
2754 
2755  ereport(LOG,
2756  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2757  errmsg("out of file descriptors: %m; release and retry")));
2758  errno = 0;
2759  if (ReleaseLruFile())
2760  goto TryAgain;
2761  errno = save_errno;
2762  }
2763 
2764  return NULL;
2765 }
DIR * opendir(const char *)
Definition: dirent.c:33
int errcode(int sqlerrcode)
Definition: elog.c:693
int errmsg(const char *fmt,...)
Definition: elog.c:904
#define LOG
Definition: elog.h:25
#define ERROR
Definition: elog.h:33
#define elog(elevel,...)
Definition: elog.h:218
#define ereport(elevel,...)
Definition: elog.h:143
static bool ReleaseLruFile(void)
Definition: fd.c:1373
static int maxAllocatedDescs
Definition: fd.c:266
static int numAllocatedDescs
Definition: fd.c:265
#define DO_DB(A)
Definition: fd.c:178
static AllocateDesc * allocatedDescs
Definition: fd.c:267
@ AllocateDescDir
Definition: fd.c:249
static bool reserveAllocatedDesc(void)
Definition: fd.c:2386
static void ReleaseLruFiles(void)
Definition: fd.c:1395
SubTransactionId create_subid
Definition: fd.c:256
DIR * dir
Definition: fd.c:260
union AllocateDesc::@17 desc
AllocateDescKind kind
Definition: fd.c:255
Definition: dirent.c:26
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:775

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(), CleanupBackupHistory(), copydir(), db_dir_size(), DeleteAllExportedSnapshotFiles(), destroy_tablespace_directories(), directory_is_empty(), do_pg_start_backup(), dsm_cleanup_for_mmap(), extension_file_exists(), get_ext_ver_list(), getInstallationPaths(), movedb(), ParseTzFile(), perform_base_backup(), pg_available_extension_versions(), pg_available_extensions(), pg_logdir_ls_internal(), pg_ls_dir(), pg_ls_dir_files(), pg_tablespace_databases(), pg_tzenumerate_next(), pg_tzenumerate_start(), pgarch_readyXlog(), 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 2461 of file fd.c.

2462 {
2463  FILE *file;
2464 
2465  DO_DB(elog(LOG, "AllocateFile: Allocated %d (%s)",
2467 
2468  /* Can we allocate another non-virtual FD? */
2469  if (!reserveAllocatedDesc())
2470  ereport(ERROR,
2471  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2472  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2473  maxAllocatedDescs, name)));
2474 
2475  /* Close excess kernel FDs. */
2476  ReleaseLruFiles();
2477 
2478 TryAgain:
2479  if ((file = fopen(name, mode)) != NULL)
2480  {
2482 
2483  desc->kind = AllocateDescFile;
2484  desc->desc.file = file;
2487  return desc->desc.file;
2488  }
2489 
2490  if (errno == EMFILE || errno == ENFILE)
2491  {
2492  int save_errno = errno;
2493 
2494  ereport(LOG,
2495  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2496  errmsg("out of file descriptors: %m; release and retry")));
2497  errno = 0;
2498  if (ReleaseLruFile())
2499  goto TryAgain;
2500  errno = save_errno;
2501  }
2502 
2503  return NULL;
2504 }
const char * name
Definition: encode.c:561
@ AllocateDescFile
Definition: fd.c:247
static PgChecksumMode mode
Definition: pg_checksums.c:65
FILE * file
Definition: fd.c:259

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_start_backup(), do_pg_stop_backup(), entry_reset(), existsTimeLineHistory(), ExportSnapshot(), fill_hba_view(), gc_qtexts(), GetHugePageSize(), ImportSnapshot(), load_dh_file(), load_hba(), load_ident(), load_relcache_init_file(), parse_extension_control_file(), ParseTzFile(), pg_backup_start_time(), pg_current_logfile(), pg_file_write_internal(), pg_promote(), pgss_shmem_shutdown(), pgss_shmem_startup(), pgstat_read_db_statsfile(), pgstat_read_db_statsfile_timestamp(), pgstat_read_statsfiles(), pgstat_write_db_statsfile(), pgstat_write_statsfiles(), read_backup_label(), read_binary_file(), read_tablespace_map(), read_whole_file(), readTimeLineHistory(), tokenize_inc_file(), tsearch_readline_begin(), ValidatePgVersion(), write_relcache_init_file(), XLogArchiveForceDone(), and XLogArchiveNotify().

◆ AtEOSubXact_Files()

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

Definition at line 3011 of file fd.c.

3013 {
3014  Index i;
3015 
3016  for (i = 0; i < numAllocatedDescs; i++)
3017  {
3018  if (allocatedDescs[i].create_subid == mySubid)
3019  {
3020  if (isCommit)
3021  allocatedDescs[i].create_subid = parentSubid;
3022  else
3023  {
3024  /* have to recheck the item after FreeDesc (ugly) */
3025  FreeDesc(&allocatedDescs[i--]);
3026  }
3027  }
3028  }
3029 }
unsigned int Index
Definition: c.h:549
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2621
int i
Definition: isn.c:73

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

◆ AtEOXact_Files()

void AtEOXact_Files ( bool  isCommit)

Definition at line 3044 of file fd.c.

3045 {
3046  CleanupTempFiles(isCommit, false);
3047  tempTableSpaces = NULL;
3048  numTempTableSpaces = -1;
3049 }
static int numTempTableSpaces
Definition: fd.c:287
static Oid * tempTableSpaces
Definition: fd.c:286
static void CleanupTempFiles(bool isCommit, bool isProcExit)
Definition: fd.c:3081

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

1072 {
1073  return BasicOpenFilePerm(fileName, fileFlags, pg_file_create_mode);
1074 }
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1093
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 1093 of file fd.c.

1094 {
1095  int fd;
1096 
1097 tryAgain:
1098 #ifdef PG_O_DIRECT_USE_F_NOCACHE
1099 
1100  /*
1101  * The value we defined to stand in for O_DIRECT when simulating it with
1102  * F_NOCACHE had better not collide with any of the standard flags.
1103  */
1105  (O_APPEND |
1106  O_CREAT |
1107  O_EXCL |
1108  O_RDWR |
1109  O_RDONLY |
1110  O_SYNC |
1111  O_TRUNC |
1112  O_WRONLY)) == 0,
1113  "PG_O_DIRECT value collides with standard flag");
1114 #if defined(O_CLOEXEC)
1115  StaticAssertStmt((PG_O_DIRECT & O_CLOEXEC) == 0,
1116  "PG_O_DIRECT value collides with O_CLOEXEC");
1117 #endif
1118 #if defined(O_DSYNC)
1120  "PG_O_DIRECT value collides with O_DSYNC");
1121 #endif
1122 
1123  fd = open(fileName, fileFlags & ~PG_O_DIRECT, fileMode);
1124 #else
1125  fd = open(fileName, fileFlags, fileMode);
1126 #endif
1127 
1128  if (fd >= 0)
1129  {
1130 #ifdef PG_O_DIRECT_USE_F_NOCACHE
1131  if (fileFlags & PG_O_DIRECT)
1132  {
1133  if (fcntl(fd, F_NOCACHE, 1) < 0)
1134  {
1135  int save_errno = errno;
1136 
1137  close(fd);
1138  errno = save_errno;
1139  return -1;
1140  }
1141  }
1142 #endif
1143 
1144  return fd; /* success! */
1145  }
1146 
1147  if (errno == EMFILE || errno == ENFILE)
1148  {
1149  int save_errno = errno;
1150 
1151  ereport(LOG,
1152  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
1153  errmsg("out of file descriptors: %m; release and retry")));
1154  errno = 0;
1155  if (ReleaseLruFile())
1156  goto tryAgain;
1157  errno = save_errno;
1158  }
1159 
1160  return -1; /* failure */
1161 }
#define StaticAssertStmt(condition, errmessage)
Definition: c.h:918
#define PG_O_DIRECT
Definition: fd.h:95
#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:336

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

2900 {
2901  Index i;
2902 
2903  if (SizeVfdCache > 0)
2904  {
2905  Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
2906  for (i = 1; i < SizeVfdCache; i++)
2907  {
2908  if (!FileIsNotOpen(i))
2909  LruDelete(i);
2910  }
2911  }
2912 }
static void LruDelete(File file)
Definition: fd.c:1278
static Size SizeVfdCache
Definition: fd.c:215
#define FileIsNotOpen(file)
Definition: fd.c:187
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 2870 of file fd.c.

2871 {
2872  int i;
2873 
2874  DO_DB(elog(LOG, "ClosePipeStream: Allocated %d", numAllocatedDescs));
2875 
2876  /* Remove file from list of allocated files, if it's present */
2877  for (i = numAllocatedDescs; --i >= 0;)
2878  {
2879  AllocateDesc *desc = &allocatedDescs[i];
2880 
2881  if (desc->kind == AllocateDescPipe && desc->desc.file == file)
2882  return FreeDesc(desc);
2883  }
2884 
2885  /* Only get here if someone passes us a file not in allocatedDescs */
2886  elog(WARNING, "file passed to ClosePipeStream was not obtained from OpenPipeStream");
2887 
2888  return pclose(file);
2889 }
#define WARNING
Definition: elog.h:30
@ AllocateDescPipe
Definition: fd.c:248

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(), and run_ssl_passphrase_command().

◆ CloseTransientFile()

int CloseTransientFile ( int  fd)

Definition at line 2688 of file fd.c.

2689 {
2690  int i;
2691 
2692  DO_DB(elog(LOG, "CloseTransientFile: Allocated %d", numAllocatedDescs));
2693 
2694  /* Remove fd from list of allocated files, if it's present */
2695  for (i = numAllocatedDescs; --i >= 0;)
2696  {
2697  AllocateDesc *desc = &allocatedDescs[i];
2698 
2699  if (desc->kind == AllocateDescRawFD && desc->desc.fd == fd)
2700  return FreeDesc(desc);
2701  }
2702 
2703  /* Only get here if someone passes us a file not in allocatedDescs */
2704  elog(WARNING, "fd passed to CloseTransientFile was not obtained from OpenTransientFile");
2705 
2706  return close(fd);
2707 }
@ AllocateDescRawFD
Definition: fd.c:250
int fd
Definition: fd.c:261

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(), copy_file(), dsm_impl_mmap(), durable_rename(), fsync_fname_ext(), get_controlfile(), heap_xlog_logical_rewrite(), lo_import_internal(), load_relmap_file(), perform_base_backup(), pg_truncate(), qtext_load_file(), qtext_store(), ReadTwoPhaseFile(), RecreateTwoPhaseFile(), ReorderBufferSerializeChange(), ReorderBufferSerializeTXN(), RestoreSlotFromDisk(), SaveSlotToPath(), sendFile(), SendTimeLineHistory(), SimpleLruDoesPhysicalPageExist(), SimpleLruWriteAll(), SlruInternalWritePage(), SlruPhysicalReadPage(), SlruPhysicalWritePage(), SlruSyncFileTag(), SnapBuildRestore(), SnapBuildSerialize(), StartupReplicationOrigin(), write_relmap_file(), writeTimeLineHistory(), writeTimeLineHistoryFile(), and XLogFileCopy().

◆ data_sync_elevel()

◆ durable_rename()

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

Definition at line 699 of file fd.c.

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

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(), CancelBackup(), CheckPointReplicationOrigin(), CleanupAfterArchiveRecovery(), dir_close(), KeepFileRestoredFromArchive(), pgarch_archiveDone(), pgss_shmem_shutdown(), StartupXLOG(), and XLogArchiveForceDone().

◆ durable_rename_excl()

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

Definition at line 829 of file fd.c.

830 {
831  /*
832  * Ensure that, if we crash directly after the rename/link, a file with
833  * valid contents is moved into place.
834  */
835  if (fsync_fname_ext(oldfile, false, false, elevel) != 0)
836  return -1;
837 
838 #ifdef HAVE_WORKING_LINK
839  if (link(oldfile, newfile) < 0)
840  {
841  ereport(elevel,
843  errmsg("could not link file \"%s\" to \"%s\": %m",
844  oldfile, newfile)));
845  return -1;
846  }
847  unlink(oldfile);
848 #else
849  if (rename(oldfile, newfile) < 0)
850  {
851  ereport(elevel,
853  errmsg("could not rename file \"%s\" to \"%s\": %m",
854  oldfile, newfile)));
855  return -1;
856  }
857 #endif
858 
859  /*
860  * Make change persistent in case of an OS crash, both the new entry and
861  * its parent directory need to be flushed.
862  */
863  if (fsync_fname_ext(newfile, false, false, elevel) != 0)
864  return -1;
865 
866  /* Same for parent directory */
867  if (fsync_parent_path(newfile, elevel) != 0)
868  return -1;
869 
870  return 0;
871 }
int link(const char *src, const char *dst)

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

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

◆ durable_unlink()

int durable_unlink ( const char *  fname,
int  loglevel 
)

Definition at line 789 of file fd.c.

790 {
791  if (unlink(fname) < 0)
792  {
793  ereport(elevel,
795  errmsg("could not remove file \"%s\": %m",
796  fname)));
797  return -1;
798  }
799 
800  /*
801  * To guarantee that the removal of the file is persistent, fsync its
802  * parent directory.
803  */
804  if (fsync_parent_path(fname, elevel) != 0)
805  return -1;
806 
807  return 0;
808 }

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

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

◆ FileClose()

void FileClose ( File  file)

Definition at line 1961 of file fd.c.

1962 {
1963  Vfd *vfdP;
1964 
1965  Assert(FileIsValid(file));
1966 
1967  DO_DB(elog(LOG, "FileClose: %d (%s)",
1968  file, VfdCache[file].fileName));
1969 
1970  vfdP = &VfdCache[file];
1971 
1972  if (!FileIsNotOpen(file))
1973  {
1974  /* close the file */
1975  if (close(vfdP->fd) != 0)
1976  {
1977  /*
1978  * We may need to panic on failure to close non-temporary files;
1979  * see LruDelete.
1980  */
1982  "could not close file \"%s\": %m", vfdP->fileName);
1983  }
1984 
1985  --nfile;
1986  vfdP->fd = VFD_CLOSED;
1987 
1988  /* remove the file from the lru ring */
1989  Delete(file);
1990  }
1991 
1992  if (vfdP->fdstate & FD_TEMP_FILE_LIMIT)
1993  {
1994  /* Subtract its size from current usage (do first in case of error) */
1995  temporary_files_size -= vfdP->fileSize;
1996  vfdP->fileSize = 0;
1997  }
1998 
1999  /*
2000  * Delete the file if it was temporary, and make a log entry if wanted
2001  */
2002  if (vfdP->fdstate & FD_DELETE_AT_CLOSE)
2003  {
2004  struct stat filestats;
2005  int stat_errno;
2006 
2007  /*
2008  * If we get an error, as could happen within the ereport/elog calls,
2009  * we'll come right back here during transaction abort. Reset the
2010  * flag to ensure that we can't get into an infinite loop. This code
2011  * is arranged to ensure that the worst-case consequence is failing to
2012  * emit log message(s), not failing to attempt the unlink.
2013  */
2014  vfdP->fdstate &= ~FD_DELETE_AT_CLOSE;
2015 
2016 
2017  /* first try the stat() */
2018  if (stat(vfdP->fileName, &filestats))
2019  stat_errno = errno;
2020  else
2021  stat_errno = 0;
2022 
2023  /* in any case do the unlink */
2024  if (unlink(vfdP->fileName))
2025  ereport(LOG,
2027  errmsg("could not delete file \"%s\": %m", vfdP->fileName)));
2028 
2029  /* and last report the stat results */
2030  if (stat_errno == 0)
2031  ReportTemporaryFileUsage(vfdP->fileName, filestats.st_size);
2032  else
2033  {
2034  errno = stat_errno;
2035  ereport(LOG,
2037  errmsg("could not stat file \"%s\": %m", vfdP->fileName)));
2038  }
2039  }
2040 
2041  /* Unregister it from the resource owner */
2042  if (vfdP->resowner)
2043  ResourceOwnerForgetFile(vfdP->resowner, file);
2044 
2045  /*
2046  * Return the Vfd slot to the free list
2047  */
2048  FreeVfd(file);
2049 }
#define FD_DELETE_AT_CLOSE
Definition: fd.c:190
static void Delete(File file)
Definition: fd.c:1259
#define FileIsValid(file)
Definition: fd.c:184
static int nfile
Definition: fd.c:220
static void FreeVfd(File file)
Definition: fd.c:1463
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:192
int data_sync_elevel(int elevel)
Definition: fd.c:3826
static void ReportTemporaryFileUsage(const char *path, off_t size)
Definition: fd.c:1519
static uint64 temporary_files_size
Definition: fd.c:234
#define VFD_CLOSED
Definition: fd.c:182
static Vfd * VfdCache
Definition: fd.c:214
void ResourceOwnerForgetFile(ResourceOwner owner, File file)
Definition: resowner.c:1306
Definition: fd.c:195
int fd
Definition: fd.c:196
char * fileName
Definition: fd.c:203
ResourceOwner resowner
Definition: fd.c:198
unsigned short fdstate
Definition: fd.c:197
off_t fileSize
Definition: fd.c:202
#define stat
Definition: win32_port.h:283

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 BufFileClose(), BufFileTruncateFileSet(), CleanupTempFiles(), logical_end_heap_rewrite(), mdclose(), mdimmedsync(), mdsyncfiletag(), mdtruncate(), ReorderBufferIterTXNFinish(), ReorderBufferRestoreChanges(), and ResourceOwnerReleaseInternal().

◆ FileGetRawDesc()

int FileGetRawDesc ( File  file)

Definition at line 2355 of file fd.c.

2356 {
2357  Assert(FileIsValid(file));
2358  return VfdCache[file].fd;
2359 }

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

◆ FileGetRawFlags()

int FileGetRawFlags ( File  file)

Definition at line 2365 of file fd.c.

2366 {
2367  Assert(FileIsValid(file));
2368  return VfdCache[file].fileFlags;
2369 }
int fileFlags
Definition: fd.c:205

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

◆ FileGetRawMode()

mode_t FileGetRawMode ( File  file)

Definition at line 2375 of file fd.c.

2376 {
2377  Assert(FileIsValid(file));
2378  return VfdCache[file].fileMode;
2379 }
mode_t fileMode
Definition: fd.c:206

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

◆ FilePathName()

char* FilePathName ( File  file)

◆ FilePrefetch()

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

Definition at line 2061 of file fd.c.

2062 {
2063 #if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
2064  int returnCode;
2065 
2066  Assert(FileIsValid(file));
2067 
2068  DO_DB(elog(LOG, "FilePrefetch: %d (%s) " INT64_FORMAT " %d",
2069  file, VfdCache[file].fileName,
2070  (int64) offset, amount));
2071 
2072  returnCode = FileAccess(file);
2073  if (returnCode < 0)
2074  return returnCode;
2075 
2076  pgstat_report_wait_start(wait_event_info);
2077  returnCode = posix_fadvise(VfdCache[file].fd, offset, amount,
2078  POSIX_FADV_WILLNEED);
2080 
2081  return returnCode;
2082 #else
2083  Assert(FileIsValid(file));
2084  return 0;
2085 #endif
2086 }
#define INT64_FORMAT
Definition: c.h:483
static int FileAccess(File file)
Definition: fd.c:1483
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:262
static void pgstat_report_wait_end(void)
Definition: wait_event.h:278

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

2114 {
2115  int returnCode;
2116  Vfd *vfdP;
2117 
2118  Assert(FileIsValid(file));
2119 
2120  DO_DB(elog(LOG, "FileRead: %d (%s) " INT64_FORMAT " %d %p",
2121  file, VfdCache[file].fileName,
2122  (int64) offset,
2123  amount, buffer));
2124 
2125  returnCode = FileAccess(file);
2126  if (returnCode < 0)
2127  return returnCode;
2128 
2129  vfdP = &VfdCache[file];
2130 
2131 retry:
2132  pgstat_report_wait_start(wait_event_info);
2133  returnCode = pg_pread(vfdP->fd, buffer, amount, offset);
2135 
2136  if (returnCode < 0)
2137  {
2138  /*
2139  * Windows may run out of kernel buffers and return "Insufficient
2140  * system resources" error. Wait a bit and retry to solve it.
2141  *
2142  * It is rumored that EINTR is also possible on some Unix filesystems,
2143  * in which case immediate retry is indicated.
2144  */
2145 #ifdef WIN32
2146  DWORD error = GetLastError();
2147 
2148  switch (error)
2149  {
2150  case ERROR_NO_SYSTEM_RESOURCES:
2151  pg_usleep(1000L);
2152  errno = EINTR;
2153  break;
2154  default:
2155  _dosmaperr(error);
2156  break;
2157  }
2158 #endif
2159  /* OK to retry if interrupted */
2160  if (errno == EINTR)
2161  goto retry;
2162  }
2163 
2164  return returnCode;
2165 }
ssize_t pg_pread(int fd, void *buf, size_t nbyte, off_t offset)
Definition: pread.c:27
void pg_usleep(long microsec)
Definition: signal.c:53
static void error(void)
Definition: sql-dyntest.c:147
#define EINTR
Definition: win32_port.h:351
void _dosmaperr(unsigned long)
Definition: win32error.c:171

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

2288 {
2289  Assert(FileIsValid(file));
2290 
2291  DO_DB(elog(LOG, "FileSize %d (%s)",
2292  file, VfdCache[file].fileName));
2293 
2294  if (FileIsNotOpen(file))
2295  {
2296  if (FileAccess(file) < 0)
2297  return (off_t) -1;
2298  }
2299 
2300  return lseek(VfdCache[file].fd, 0, SEEK_END);
2301 }

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

2267 {
2268  int returnCode;
2269 
2270  Assert(FileIsValid(file));
2271 
2272  DO_DB(elog(LOG, "FileSync: %d (%s)",
2273  file, VfdCache[file].fileName));
2274 
2275  returnCode = FileAccess(file);
2276  if (returnCode < 0)
2277  return returnCode;
2278 
2279  pgstat_report_wait_start(wait_event_info);
2280  returnCode = pg_fsync(VfdCache[file].fd);
2282 
2283  return returnCode;
2284 }

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

Referenced by 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 2304 of file fd.c.

2305 {
2306  int returnCode;
2307 
2308  Assert(FileIsValid(file));
2309 
2310  DO_DB(elog(LOG, "FileTruncate %d (%s)",
2311  file, VfdCache[file].fileName));
2312 
2313  returnCode = FileAccess(file);
2314  if (returnCode < 0)
2315  return returnCode;
2316 
2317  pgstat_report_wait_start(wait_event_info);
2318  returnCode = ftruncate(VfdCache[file].fd, offset);
2320 
2321  if (returnCode == 0 && VfdCache[file].fileSize > offset)
2322  {
2323  /* adjust our state for truncation of a temp file */
2324  Assert(VfdCache[file].fdstate & FD_TEMP_FILE_LIMIT);
2325  temporary_files_size -= VfdCache[file].fileSize - offset;
2326  VfdCache[file].fileSize = offset;
2327  }
2328 
2329  return returnCode;
2330 }
#define ftruncate(a, b)
Definition: win32_port.h:73

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

2170 {
2171  int returnCode;
2172  Vfd *vfdP;
2173 
2174  Assert(FileIsValid(file));
2175 
2176  DO_DB(elog(LOG, "FileWrite: %d (%s) " INT64_FORMAT " %d %p",
2177  file, VfdCache[file].fileName,
2178  (int64) offset,
2179  amount, buffer));
2180 
2181  returnCode = FileAccess(file);
2182  if (returnCode < 0)
2183  return returnCode;
2184 
2185  vfdP = &VfdCache[file];
2186 
2187  /*
2188  * If enforcing temp_file_limit and it's a temp file, check to see if the
2189  * write would overrun temp_file_limit, and throw error if so. Note: it's
2190  * really a modularity violation to throw error here; we should set errno
2191  * and return -1. However, there's no way to report a suitable error
2192  * message if we do that. All current callers would just throw error
2193  * immediately anyway, so this is safe at present.
2194  */
2195  if (temp_file_limit >= 0 && (vfdP->fdstate & FD_TEMP_FILE_LIMIT))
2196  {
2197  off_t past_write = offset + amount;
2198 
2199  if (past_write > vfdP->fileSize)
2200  {
2201  uint64 newTotal = temporary_files_size;
2202 
2203  newTotal += past_write - vfdP->fileSize;
2204  if (newTotal > (uint64) temp_file_limit * (uint64) 1024)
2205  ereport(ERROR,
2206  (errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED),
2207  errmsg("temporary file size exceeds temp_file_limit (%dkB)",
2208  temp_file_limit)));
2209  }
2210  }
2211 
2212 retry:
2213  errno = 0;
2214  pgstat_report_wait_start(wait_event_info);
2215  returnCode = pg_pwrite(VfdCache[file].fd, buffer, amount, offset);
2217 
2218  /* if write didn't set errno, assume problem is no disk space */
2219  if (returnCode != amount && errno == 0)
2220  errno = ENOSPC;
2221 
2222  if (returnCode >= 0)
2223  {
2224  /*
2225  * Maintain fileSize and temporary_files_size if it's a temp file.
2226  */
2227  if (vfdP->fdstate & FD_TEMP_FILE_LIMIT)
2228  {
2229  off_t past_write = offset + amount;
2230 
2231  if (past_write > vfdP->fileSize)
2232  {
2233  temporary_files_size += past_write - vfdP->fileSize;
2234  vfdP->fileSize = past_write;
2235  }
2236  }
2237  }
2238  else
2239  {
2240  /*
2241  * See comments in FileRead()
2242  */
2243 #ifdef WIN32
2244  DWORD error = GetLastError();
2245 
2246  switch (error)
2247  {
2248  case ERROR_NO_SYSTEM_RESOURCES:
2249  pg_usleep(1000L);
2250  errno = EINTR;
2251  break;
2252  default:
2253  _dosmaperr(error);
2254  break;
2255  }
2256 #endif
2257  /* OK to retry if interrupted */
2258  if (errno == EINTR)
2259  goto retry;
2260  }
2261 
2262  return returnCode;
2263 }
int temp_file_limit
Definition: guc.c:611
ssize_t pg_pwrite(int fd, const void *buf, size_t nbyte, off_t offset)
Definition: pwrite.c:27

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

2090 {
2091  int returnCode;
2092 
2093  Assert(FileIsValid(file));
2094 
2095  DO_DB(elog(LOG, "FileWriteback: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
2096  file, VfdCache[file].fileName,
2097  (int64) offset, (int64) nbytes));
2098 
2099  if (nbytes <= 0)
2100  return;
2101 
2102  returnCode = FileAccess(file);
2103  if (returnCode < 0)
2104  return;
2105 
2106  pgstat_report_wait_start(wait_event_info);
2107  pg_flush_data(VfdCache[file].fd, offset, nbytes);
2109 }
void pg_flush_data(int fd, off_t offset, off_t nbytes)
Definition: fd.c:469

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

2841 {
2842  int i;
2843 
2844  /* Nothing to do if AllocateDir failed */
2845  if (dir == NULL)
2846  return 0;
2847 
2848  DO_DB(elog(LOG, "FreeDir: Allocated %d", numAllocatedDescs));
2849 
2850  /* Remove dir from list of allocated dirs, if it's present */
2851  for (i = numAllocatedDescs; --i >= 0;)
2852  {
2853  AllocateDesc *desc = &allocatedDescs[i];
2854 
2855  if (desc->kind == AllocateDescDir && desc->desc.dir == dir)
2856  return FreeDesc(desc);
2857  }
2858 
2859  /* Only get here if someone passes us a dir not in allocatedDescs */
2860  elog(WARNING, "dir passed to FreeDir was not obtained from AllocateDir");
2861 
2862  return closedir(dir);
2863 }
int closedir(DIR *)
Definition: dirent.c:123

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_start_backup(), dsm_cleanup_for_mmap(), extension_file_exists(), get_ext_ver_list(), getInstallationPaths(), movedb(), ParseTzFile(), perform_base_backup(), pg_available_extension_versions(), pg_available_extensions(), pg_logdir_ls_internal(), pg_ls_dir(), pg_ls_dir_files(), pg_tablespace_databases(), pg_tzenumerate_end(), pg_tzenumerate_next(), pgarch_readyXlog(), 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 2660 of file fd.c.

2661 {
2662  int i;
2663 
2664  DO_DB(elog(LOG, "FreeFile: Allocated %d", numAllocatedDescs));
2665 
2666  /* Remove file from list of allocated files, if it's present */
2667  for (i = numAllocatedDescs; --i >= 0;)
2668  {
2669  AllocateDesc *desc = &allocatedDescs[i];
2670 
2671  if (desc->kind == AllocateDescFile && desc->desc.file == file)
2672  return FreeDesc(desc);
2673  }
2674 
2675  /* Only get here if someone passes us a file not in allocatedDescs */
2676  elog(WARNING, "file passed to FreeFile was not obtained from AllocateFile");
2677 
2678  return fclose(file);
2679 }

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_start_backup(), do_pg_stop_backup(), EndCopy(), EndCopyFrom(), entry_reset(), existsTimeLineHistory(), ExportSnapshot(), fill_hba_view(), gc_qtexts(), GetHugePageSize(), ImportSnapshot(), load_dh_file(), load_hba(), load_ident(), load_relcache_init_file(), parse_extension_control_file(), ParseTzFile(), pg_backup_start_time(), pg_current_logfile(), pg_file_write_internal(), pg_promote(), pgss_shmem_shutdown(), pgss_shmem_startup(), pgstat_read_db_statsfile(), pgstat_read_db_statsfile_timestamp(), pgstat_read_statsfiles(), pgstat_write_db_statsfile(), pgstat_write_statsfiles(), read_backup_label(), read_binary_file(), read_tablespace_map(), read_whole_file(), readTimeLineHistory(), tokenize_inc_file(), tsearch_readline_end(), ValidatePgVersion(), write_relcache_init_file(), XLogArchiveForceDone(), and XLogArchiveNotify().

◆ fsync_fname()

◆ fsync_fname_ext()

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

Definition at line 3687 of file fd.c.

3688 {
3689  int fd;
3690  int flags;
3691  int returncode;
3692 
3693  /*
3694  * Some OSs require directories to be opened read-only whereas other
3695  * systems don't allow us to fsync files opened read-only; so we need both
3696  * cases here. Using O_RDWR will cause us to fail to fsync files that are
3697  * not writable by our userid, but we assume that's OK.
3698  */
3699  flags = PG_BINARY;
3700  if (!isdir)
3701  flags |= O_RDWR;
3702  else
3703  flags |= O_RDONLY;
3704 
3705  fd = OpenTransientFile(fname, flags);
3706 
3707  /*
3708  * Some OSs don't allow us to open directories at all (Windows returns
3709  * EACCES), just ignore the error in that case. If desired also silently
3710  * ignoring errors about unreadable files. Log others.
3711  */
3712  if (fd < 0 && isdir && (errno == EISDIR || errno == EACCES))
3713  return 0;
3714  else if (fd < 0 && ignore_perm && errno == EACCES)
3715  return 0;
3716  else if (fd < 0)
3717  {
3718  ereport(elevel,
3720  errmsg("could not open file \"%s\": %m", fname)));
3721  return -1;
3722  }
3723 
3724  returncode = pg_fsync(fd);
3725 
3726  /*
3727  * Some OSes don't allow us to fsync directories at all, so we can ignore
3728  * those errors. Anything else needs to be logged.
3729  */
3730  if (returncode != 0 && !(isdir && (errno == EBADF || errno == EINVAL)))
3731  {
3732  int save_errno;
3733 
3734  /* close file upon error, might not be in transaction context */
3735  save_errno = errno;
3736  (void) CloseTransientFile(fd);
3737  errno = save_errno;
3738 
3739  ereport(elevel,
3741  errmsg("could not fsync file \"%s\": %m", fname)));
3742  return -1;
3743  }
3744 
3745  if (CloseTransientFile(fd) != 0)
3746  {
3747  ereport(elevel,
3749  errmsg("could not close file \"%s\": %m", fname)));
3750  return -1;
3751  }
3752 
3753  return 0;
3754 }

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

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

◆ GetNextTempTableSpace()

Oid GetNextTempTableSpace ( void  )

Definition at line 2990 of file fd.c.

2991 {
2992  if (numTempTableSpaces > 0)
2993  {
2994  /* Advance nextTempTableSpace counter with wraparound */
2996  nextTempTableSpace = 0;
2998  }
2999  return InvalidOid;
3000 }
static int nextTempTableSpace
Definition: fd.c:288
#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 2972 of file fd.c.

2973 {
2974  int i;
2975 
2977  for (i = 0; i < numTempTableSpaces && i < numSpaces; ++i)
2978  tableSpaces[i] = tempTableSpaces[i];
2979 
2980  return i;
2981 }
bool TempTablespacesAreSet(void)
Definition: fd.c:2957

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

Referenced by FileSetInit().

◆ InitFileAccess()

void InitFileAccess ( void  )

Definition at line 883 of file fd.c.

884 {
885  Assert(SizeVfdCache == 0); /* call me only once */
886 
887  /* initialize cache header entry */
888  VfdCache = (Vfd *) malloc(sizeof(Vfd));
889  if (VfdCache == NULL)
890  ereport(FATAL,
891  (errcode(ERRCODE_OUT_OF_MEMORY),
892  errmsg("out of memory")));
893 
894  MemSet((char *) &(VfdCache[0]), 0, sizeof(Vfd));
896 
897  SizeVfdCache = 1;
898 }
#define MemSet(start, val, len)
Definition: c.h:1008
#define FATAL
Definition: elog.h:35
#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 913 of file fd.c.

914 {
915  Assert(SizeVfdCache != 0); /* InitFileAccess() needs to have run*/
916  Assert(!temporary_files_allowed); /* call me only once */
917 
918  /*
919  * Register before-shmem-exit hook to ensure temp files are dropped while
920  * we can still report stats.
921  */
923 
924 #ifdef USE_ASSERT_CHECKING
925  temporary_files_allowed = true;
926 #endif
927 }
static void BeforeShmemExit_Files(int code, Datum arg)
Definition: fd.c:3058
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 3334 of file fd.c.

3335 {
3336  int pos;
3337  int savepos;
3338 
3339  /* Must start with "t". */
3340  if (name[0] != 't')
3341  return false;
3342 
3343  /* Followed by a non-empty string of digits and then an underscore. */
3344  for (pos = 1; isdigit((unsigned char) name[pos]); ++pos)
3345  ;
3346  if (pos == 1 || name[pos] != '_')
3347  return false;
3348 
3349  /* Followed by another nonempty string of digits. */
3350  for (savepos = ++pos; isdigit((unsigned char) name[pos]); ++pos)
3351  ;
3352  if (savepos == pos)
3353  return false;
3354 
3355  /* We might have _forkname or .segment or both. */
3356  if (name[pos] == '_')
3357  {
3358  int forkchar = forkname_chars(&name[pos + 1], NULL);
3359 
3360  if (forkchar <= 0)
3361  return false;
3362  pos += forkchar + 1;
3363  }
3364  if (name[pos] == '.')
3365  {
3366  int segchar;
3367 
3368  for (segchar = 1; isdigit((unsigned char) name[pos + segchar]); ++segchar)
3369  ;
3370  if (segchar <= 1)
3371  return false;
3372  pos += segchar;
3373  }
3374 
3375  /* Now we should be at the end. */
3376  if (name[pos] != '\0')
3377  return false;
3378  return true;
3379 }
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 2564 of file fd.c.

2565 {
2566  FILE *file;
2567  int save_errno;
2568 
2569  DO_DB(elog(LOG, "OpenPipeStream: Allocated %d (%s)",
2570  numAllocatedDescs, command));
2571 
2572  /* Can we allocate another non-virtual FD? */
2573  if (!reserveAllocatedDesc())
2574  ereport(ERROR,
2575  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2576  errmsg("exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"",
2577  maxAllocatedDescs, command)));
2578 
2579  /* Close excess kernel FDs. */
2580  ReleaseLruFiles();
2581 
2582 TryAgain:
2583  fflush(stdout);
2584  fflush(stderr);
2586  errno = 0;
2587  file = popen(command, mode);
2588  save_errno = errno;
2590  errno = save_errno;
2591  if (file != NULL)
2592  {
2594 
2595  desc->kind = AllocateDescPipe;
2596  desc->desc.file = file;
2599  return desc->desc.file;
2600  }
2601 
2602  if (errno == EMFILE || errno == ENFILE)
2603  {
2604  ereport(LOG,
2605  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2606  errmsg("out of file descriptors: %m; release and retry")));
2607  if (ReleaseLruFile())
2608  goto TryAgain;
2609  errno = save_errno;
2610  }
2611 
2612  return NULL;
2613 }
static void const char fflush(stdout)
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:180
#define SIG_DFL
Definition: win32_port.h:162
#define SIGPIPE
Definition: win32_port.h:172
#define SIG_IGN
Definition: win32_port.h:164

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, SIGPIPE, and generate_unaccent_rules::stdout.

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

◆ OpenTemporaryFile()

File OpenTemporaryFile ( bool  interXact)

Definition at line 1707 of file fd.c.

1708 {
1709  File file = 0;
1710 
1711  Assert(temporary_files_allowed); /* check temp file access is up */
1712 
1713  /*
1714  * Make sure the current resource owner has space for this File before we
1715  * open it, if we'll be registering it below.
1716  */
1717  if (!interXact)
1719 
1720  /*
1721  * If some temp tablespace(s) have been given to us, try to use the next
1722  * one. If a given tablespace can't be found, we silently fall back to
1723  * the database's default tablespace.
1724  *
1725  * BUT: if the temp file is slated to outlive the current transaction,
1726  * force it into the database's default tablespace, so that it will not
1727  * pose a threat to possible tablespace drop attempts.
1728  */
1729  if (numTempTableSpaces > 0 && !interXact)
1730  {
1731  Oid tblspcOid = GetNextTempTableSpace();
1732 
1733  if (OidIsValid(tblspcOid))
1734  file = OpenTemporaryFileInTablespace(tblspcOid, false);
1735  }
1736 
1737  /*
1738  * If not, or if tablespace is bad, create in database's default
1739  * tablespace. MyDatabaseTableSpace should normally be set before we get
1740  * here, but just in case it isn't, fall back to pg_default tablespace.
1741  */
1742  if (file <= 0)
1745  DEFAULTTABLESPACE_OID,
1746  true);
1747 
1748  /* Mark it for deletion at close and temporary file size limit */
1750 
1751  /* Register it with the current resource owner */
1752  if (!interXact)
1753  RegisterTemporaryFile(file);
1754 
1755  return file;
1756 }
#define OidIsValid(objectId)
Definition: c.h:710
Oid GetNextTempTableSpace(void)
Definition: fd.c:2990
static File OpenTemporaryFileInTablespace(Oid tblspcOid, bool rejectError)
Definition: fd.c:1787
static void RegisterTemporaryFile(File file)
Definition: fd.c:1538
int File
Definition: fd.h:54
Oid MyDatabaseTableSpace
Definition: globals.c:90
unsigned int Oid
Definition: postgres_ext.h:31
void ResourceOwnerEnlargeFiles(ResourceOwner owner)
Definition: resowner.c:1286
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 2520 of file fd.c.

2521 {
2522  int fd;
2523 
2524  DO_DB(elog(LOG, "OpenTransientFile: Allocated %d (%s)",
2525  numAllocatedDescs, fileName));
2526 
2527  /* Can we allocate another non-virtual FD? */
2528  if (!reserveAllocatedDesc())
2529  ereport(ERROR,
2530  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2531  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2532  maxAllocatedDescs, fileName)));
2533 
2534  /* Close excess kernel FDs. */
2535  ReleaseLruFiles();
2536 
2537  fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
2538 
2539  if (fd >= 0)
2540  {
2542 
2543  desc->kind = AllocateDescRawFD;
2544  desc->desc.fd = fd;
2547 
2548  return fd;
2549  }
2550 
2551  return -1; /* failure */
2552 }

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 *  base,
const char *  name 
)

Definition at line 1643 of file fd.c.

1644 {
1645  if (MakePGDirectory(directory) < 0)
1646  {
1647  if (errno == EEXIST)
1648  return;
1649 
1650  /*
1651  * Failed. Try to create basedir first in case it's missing. Tolerate
1652  * EEXIST to close a race against another process following the same
1653  * algorithm.
1654  */
1655  if (MakePGDirectory(basedir) < 0 && errno != EEXIST)
1656  ereport(ERROR,
1658  errmsg("cannot create temporary directory \"%s\": %m",
1659  basedir)));
1660 
1661  /* Try again. */
1662  if (MakePGDirectory(directory) < 0 && errno != EEXIST)
1663  ereport(ERROR,
1665  errmsg("cannot create temporary subdirectory \"%s\": %m",
1666  directory)));
1667  }
1668 }
int MakePGDirectory(const char *directoryName)
Definition: fd.c:3803
static char * basedir
static const char * directory
Definition: zic.c:632

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

Referenced by FileSetCreate().

◆ PathNameCreateTemporaryFile()

File PathNameCreateTemporaryFile ( const char *  name,
bool  error_on_failure 
)

Definition at line 1844 of file fd.c.

1845 {
1846  File file;
1847 
1848  Assert(temporary_files_allowed); /* check temp file access is up */
1849 
1851 
1852  /*
1853  * Open the file. Note: we don't use O_EXCL, in case there is an orphaned
1854  * temp file that can be reused.
1855  */
1856  file = PathNameOpenFile(path, O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1857  if (file <= 0)
1858  {
1859  if (error_on_failure)
1860  ereport(ERROR,
1862  errmsg("could not create temporary file \"%s\": %m",
1863  path)));
1864  else
1865  return file;
1866  }
1867 
1868  /* Mark it for temp_file_limit accounting. */
1870 
1871  /* Register it for automatic close. */
1872  RegisterTemporaryFile(file);
1873 
1874  return file;
1875 }
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1566

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 *  name)

Definition at line 1674 of file fd.c.

1675 {
1676  struct stat statbuf;
1677 
1678  /* Silently ignore missing directory. */
1679  if (stat(dirname, &statbuf) != 0 && errno == ENOENT)
1680  return;
1681 
1682  /*
1683  * Currently, walkdir doesn't offer a way for our passed in function to
1684  * maintain state. Perhaps it should, so that we could tell the caller
1685  * whether this operation succeeded or failed. Since this operation is
1686  * used in a cleanup path, we wouldn't actually behave differently: we'll
1687  * just log failures.
1688  */
1689  walkdir(dirname, unlink_if_exists_fname, false, LOG);
1690 }
static void unlink_if_exists_fname(const char *fname, bool isdir, int elevel)
Definition: fd.c:3662
static void walkdir(const char *path, void(*action)(const char *fname, bool isdir, int elevel), bool process_symlinks, int elevel)
Definition: fd.c:3548

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

Referenced by FileSetDeleteAll().

◆ PathNameDeleteTemporaryFile()

bool PathNameDeleteTemporaryFile ( const char *  name,
bool  error_on_failure 
)

Definition at line 1915 of file fd.c.

1916 {
1917  struct stat filestats;
1918  int stat_errno;
1919 
1920  /* Get the final size for pgstat reporting. */
1921  if (stat(path, &filestats) != 0)
1922  stat_errno = errno;
1923  else
1924  stat_errno = 0;
1925 
1926  /*
1927  * Unlike FileClose's automatic file deletion code, we tolerate
1928  * non-existence to support BufFileDeleteFileSet which doesn't know how
1929  * many segments it has to delete until it runs out.
1930  */
1931  if (stat_errno == ENOENT)
1932  return false;
1933 
1934  if (unlink(path) < 0)
1935  {
1936  if (errno != ENOENT)
1937  ereport(error_on_failure ? ERROR : LOG,
1939  errmsg("could not unlink temporary file \"%s\": %m",
1940  path)));
1941  return false;
1942  }
1943 
1944  if (stat_errno == 0)
1945  ReportTemporaryFileUsage(path, filestats.st_size);
1946  else
1947  {
1948  errno = stat_errno;
1949  ereport(LOG,
1951  errmsg("could not stat file \"%s\": %m", path)));
1952  }
1953 
1954  return true;
1955 }

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 
)

Definition at line 1566 of file fd.c.

1567 {
1568  return PathNameOpenFilePerm(fileName, fileFlags, pg_file_create_mode);
1569 }
File PathNameOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1579

References PathNameOpenFilePerm(), and pg_file_create_mode.

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

◆ PathNameOpenFilePerm()

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

Definition at line 1579 of file fd.c.

1580 {
1581  char *fnamecopy;
1582  File file;
1583  Vfd *vfdP;
1584 
1585  DO_DB(elog(LOG, "PathNameOpenFilePerm: %s %x %o",
1586  fileName, fileFlags, fileMode));
1587 
1588  /*
1589  * We need a malloc'd copy of the file name; fail cleanly if no room.
1590  */
1591  fnamecopy = strdup(fileName);
1592  if (fnamecopy == NULL)
1593  ereport(ERROR,
1594  (errcode(ERRCODE_OUT_OF_MEMORY),
1595  errmsg("out of memory")));
1596 
1597  file = AllocateVfd();
1598  vfdP = &VfdCache[file];
1599 
1600  /* Close excess kernel FDs. */
1601  ReleaseLruFiles();
1602 
1603  vfdP->fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
1604 
1605  if (vfdP->fd < 0)
1606  {
1607  int save_errno = errno;
1608 
1609  FreeVfd(file);
1610  free(fnamecopy);
1611  errno = save_errno;
1612  return -1;
1613  }
1614  ++nfile;
1615  DO_DB(elog(LOG, "PathNameOpenFile: success %d",
1616  vfdP->fd));
1617 
1618  vfdP->fileName = fnamecopy;
1619  /* Saved flags are adjusted to be OK for re-opening file */
1620  vfdP->fileFlags = fileFlags & ~(O_CREAT | O_TRUNC | O_EXCL);
1621  vfdP->fileMode = fileMode;
1622  vfdP->fileSize = 0;
1623  vfdP->fdstate = 0x0;
1624  vfdP->resowner = NULL;
1625 
1626  Insert(file);
1627 
1628  return file;
1629 }
static File AllocateVfd(void)
Definition: fd.c:1405
static void Insert(File file)
Definition: fd.c:1304
#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 1884 of file fd.c.

1885 {
1886  File file;
1887 
1888  Assert(temporary_files_allowed); /* check temp file access is up */
1889 
1891 
1892  file = PathNameOpenFile(path, mode | PG_BINARY);
1893 
1894  /* If no such file, then we don't raise an error. */
1895  if (file <= 0 && errno != ENOENT)
1896  ereport(ERROR,
1898  errmsg("could not open temporary file \"%s\": %m",
1899  path)));
1900 
1901  if (file > 0)
1902  {
1903  /* Register it for automatic close. */
1904  RegisterTemporaryFile(file);
1905  }
1906 
1907  return file;
1908 }

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

450 {
451  if (enableFsync)
452  {
453 #ifdef HAVE_FDATASYNC
454  return fdatasync(fd);
455 #else
456  return fsync(fd);
457 #endif
458  }
459  else
460  return 0;
461 }
bool enableFsync
Definition: globals.c:122
#define fsync(fd)
Definition: win32_port.h:76

References enableFsync, fd(), and fsync.

Referenced by issue_xlog_fsync().

◆ pg_flush_data()

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

Definition at line 469 of file fd.c.

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

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

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

◆ pg_fsync_no_writethrough()

int pg_fsync_no_writethrough ( int  fd)

Definition at line 414 of file fd.c.

415 {
416  if (enableFsync)
417  return fsync(fd);
418  else
419  return 0;
420 }

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

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

References enableFsync, and fd().

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

◆ pg_pwritev_with_retry()

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

Definition at line 3836 of file fd.c.

3837 {
3838  struct iovec iov_copy[PG_IOV_MAX];
3839  ssize_t sum = 0;
3840  ssize_t part;
3841 
3842  /* We'd better have space to make a copy, in case we need to retry. */
3843  if (iovcnt > PG_IOV_MAX)
3844  {
3845  errno = EINVAL;
3846  return -1;
3847  }
3848 
3849  for (;;)
3850  {
3851  /* Write as much as we can. */
3852  part = pg_pwritev(fd, iov, iovcnt, offset);
3853  if (part < 0)
3854  return -1;
3855 
3856 #ifdef SIMULATE_SHORT_WRITE
3857  part = Min(part, 4096);
3858 #endif
3859 
3860  /* Count our progress. */
3861  sum += part;
3862  offset += part;
3863 
3864  /* Step over iovecs that are done. */
3865  while (iovcnt > 0 && iov->iov_len <= part)
3866  {
3867  part -= iov->iov_len;
3868  ++iov;
3869  --iovcnt;
3870  }
3871 
3872  /* Are they all done? */
3873  if (iovcnt == 0)
3874  {
3875  /* We don't expect the kernel to write more than requested. */
3876  Assert(part == 0);
3877  break;
3878  }
3879 
3880  /*
3881  * Move whatever's left to the front of our mutable copy and adjust
3882  * the leading iovec.
3883  */
3884  Assert(iovcnt > 0);
3885  memmove(iov_copy, iov, sizeof(*iov) * iovcnt);
3886  Assert(iov->iov_len > part);
3887  iov_copy[0].iov_base = (char *) iov_copy[0].iov_base + part;
3888  iov_copy[0].iov_len -= part;
3889  iov = iov_copy;
3890  }
3891 
3892  return sum;
3893 }
#define Min(x, y)
Definition: c.h:986
ssize_t pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
Definition: pwritev.c:29
#define PG_IOV_MAX
Definition: pg_iovec.h:40
Definition: pg_iovec.h:25
void * iov_base
Definition: pg_iovec.h:26
size_t iov_len
Definition: pg_iovec.h:27

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

Referenced by XLogFileInitInternal().

◆ pg_truncate()

int pg_truncate ( const char *  path,
off_t  length 
)

Definition at line 642 of file fd.c.

643 {
644 #ifdef WIN32
645  int save_errno;
646  int ret;
647  int fd;
648 
649  fd = OpenTransientFile(path, O_RDWR | PG_BINARY);
650  if (fd >= 0)
651  {
652  ret = ftruncate(fd, 0);
653  save_errno = errno;
655  errno = save_errno;
656  }
657  else
658  ret = -1;
659 
660  return ret;
661 #else
662  return truncate(path, length);
663 #endif
664 }

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

2804 {
2805  struct dirent *dent;
2806 
2807  /* Give a generic message for AllocateDir failure, if caller didn't */
2808  if (dir == NULL)
2809  {
2810  ereport(elevel,
2812  errmsg("could not open directory \"%s\": %m",
2813  dirname)));
2814  return NULL;
2815  }
2816 
2817  errno = 0;
2818  if ((dent = readdir(dir)) != NULL)
2819  return dent;
2820 
2821  if (errno)
2822  ereport(elevel,
2824  errmsg("could not read directory \"%s\": %m",
2825  dirname)));
2826  return NULL;
2827 }
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 3153 of file fd.c.

3154 {
3155  char temp_path[MAXPGPATH + 10 + sizeof(TABLESPACE_VERSION_DIRECTORY) + sizeof(PG_TEMP_FILES_DIR)];
3156  DIR *spc_dir;
3157  struct dirent *spc_de;
3158 
3159  /*
3160  * First process temp files in pg_default ($PGDATA/base)
3161  */
3162  snprintf(temp_path, sizeof(temp_path), "base/%s", PG_TEMP_FILES_DIR);
3163  RemovePgTempFilesInDir(temp_path, true, false);
3164  RemovePgTempRelationFiles("base");
3165 
3166  /*
3167  * Cycle through temp directories for all non-default tablespaces.
3168  */
3169  spc_dir = AllocateDir("pg_tblspc");
3170 
3171  while ((spc_de = ReadDirExtended(spc_dir, "pg_tblspc", LOG)) != NULL)
3172  {
3173  if (strcmp(spc_de->d_name, ".") == 0 ||
3174  strcmp(spc_de->d_name, "..") == 0)
3175  continue;
3176 
3177  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s/%s",
3179  RemovePgTempFilesInDir(temp_path, true, false);
3180 
3181  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s",
3183  RemovePgTempRelationFiles(temp_path);
3184  }
3185 
3186  FreeDir(spc_dir);
3187 
3188  /*
3189  * In EXEC_BACKEND case there is a pgsql_tmp directory at the top level of
3190  * DataDir as well. However, that is *not* cleaned here because doing so
3191  * would create a race condition. It's done separately, earlier in
3192  * postmaster startup.
3193  */
3194 }
int FreeDir(DIR *dir)
Definition: fd.c:2840
static void RemovePgTempRelationFiles(const char *tsdirname)
Definition: fd.c:3278
void RemovePgTempFilesInDir(const char *tmpdirname, bool missing_ok, bool unlink_all)
Definition: fd.c:3212
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2722
#define PG_TEMP_FILES_DIR
Definition: pg_checksums.c:62
#define MAXPGPATH
#define snprintf
Definition: port.h:225
#define TABLESPACE_VERSION_DIRECTORY
Definition: relpath.h:26
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 3212 of file fd.c.

3213 {
3214  DIR *temp_dir;
3215  struct dirent *temp_de;
3216  char rm_path[MAXPGPATH * 2];
3217 
3218  temp_dir = AllocateDir(tmpdirname);
3219 
3220  if (temp_dir == NULL && errno == ENOENT && missing_ok)
3221  return;
3222 
3223  while ((temp_de = ReadDirExtended(temp_dir, tmpdirname, LOG)) != NULL)
3224  {
3225  if (strcmp(temp_de->d_name, ".") == 0 ||
3226  strcmp(temp_de->d_name, "..") == 0)
3227  continue;
3228 
3229  snprintf(rm_path, sizeof(rm_path), "%s/%s",
3230  tmpdirname, temp_de->d_name);
3231 
3232  if (unlink_all ||
3233  strncmp(temp_de->d_name,
3235  strlen(PG_TEMP_FILE_PREFIX)) == 0)
3236  {
3237  struct stat statbuf;
3238 
3239  if (lstat(rm_path, &statbuf) < 0)
3240  {
3241  ereport(LOG,
3243  errmsg("could not stat file \"%s\": %m", rm_path)));
3244  continue;
3245  }
3246 
3247  if (S_ISDIR(statbuf.st_mode))
3248  {
3249  /* recursively remove contents, then directory itself */
3250  RemovePgTempFilesInDir(rm_path, false, true);
3251 
3252  if (rmdir(rm_path) < 0)
3253  ereport(LOG,
3255  errmsg("could not remove directory \"%s\": %m",
3256  rm_path)));
3257  }
3258  else
3259  {
3260  if (unlink(rm_path) < 0)
3261  ereport(LOG,
3263  errmsg("could not remove file \"%s\": %m",
3264  rm_path)));
3265  }
3266  }
3267  else
3268  ereport(LOG,
3269  (errmsg("unexpected file found in temporary-files directory: \"%s\"",
3270  rm_path)));
3271  }
3272 
3273  FreeDir(temp_dir);
3274 }
#define PG_TEMP_FILE_PREFIX
Definition: pg_checksums.c:63
#define lstat(path, sb)
Definition: win32_port.h:284

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

Referenced by PostmasterMain(), and RemovePgTempFiles().

◆ ReserveExternalFD()

void ReserveExternalFD ( void  )

Definition at line 1212 of file fd.c.

1213 {
1214  /*
1215  * Release VFDs if needed to stay safe. Because we do this before
1216  * incrementing numExternalFDs, the final state will be as desired, i.e.,
1217  * nfile + numAllocatedDescs + numExternalFDs <= max_safe_fds.
1218  */
1219  ReleaseLruFiles();
1220 
1221  numExternalFDs++;
1222 }

References numExternalFDs, and ReleaseLruFiles().

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

◆ set_max_safe_fds()

void set_max_safe_fds ( void  )

Definition at line 1028 of file fd.c.

1029 {
1030  int usable_fds;
1031  int already_open;
1032 
1033  /*----------
1034  * We want to set max_safe_fds to
1035  * MIN(usable_fds, max_files_per_process - already_open)
1036  * less the slop factor for files that are opened without consulting
1037  * fd.c. This ensures that we won't exceed either max_files_per_process
1038  * or the experimentally-determined EMFILE limit.
1039  *----------
1040  */
1042  &usable_fds, &already_open);
1043 
1044  max_safe_fds = Min(usable_fds, max_files_per_process - already_open);
1045 
1046  /*
1047  * Take off the FDs reserved for system() etc.
1048  */
1050 
1051  /*
1052  * Make sure we still have enough to get by.
1053  */
1054  if (max_safe_fds < FD_MINFREE)
1055  ereport(FATAL,
1056  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
1057  errmsg("insufficient file descriptors available to start server process"),
1058  errdetail("System allows %d, we need at least %d.",
1061 
1062  elog(DEBUG2, "max_safe_fds = %d, usable_fds = %d, already_open = %d",
1063  max_safe_fds, usable_fds, already_open);
1064 }
int errdetail(const char *fmt,...)
Definition: elog.c:1037
#define DEBUG2
Definition: elog.h:23
int max_files_per_process
Definition: fd.c:147
#define FD_MINFREE
Definition: fd.c:139
static void count_usable_fds(int max_to_probe, int *usable_fds, int *already_open)
Definition: fd.c:944
#define NUM_RESERVED_FDS
Definition: fd.c:130

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

2929 {
2930  Assert(numSpaces >= 0);
2931  tempTableSpaces = tableSpaces;
2932  numTempTableSpaces = numSpaces;
2933 
2934  /*
2935  * Select a random starting point in the list. This is to minimize
2936  * conflicts between backends that are most likely sharing the same list
2937  * of temp tablespaces. Note that if we create multiple temp files in the
2938  * same transaction, we'll advance circularly through the list --- this
2939  * ensures that large temporary sort files are nicely spread across all
2940  * available tablespaces.
2941  */
2942  if (numSpaces > 1)
2944  0, numSpaces - 1);
2945  else
2946  nextTempTableSpace = 0;
2947 }
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 3429 of file fd.c.

3430 {
3431  bool xlog_is_symlink;
3432 
3433  /* We can skip this whole thing if fsync is disabled. */
3434  if (!enableFsync)
3435  return;
3436 
3437  /*
3438  * If pg_wal is a symlink, we'll need to recurse into it separately,
3439  * because the first walkdir below will ignore it.
3440  */
3441  xlog_is_symlink = false;
3442 
3443 #ifndef WIN32
3444  {
3445  struct stat st;
3446 
3447  if (lstat("pg_wal", &st) < 0)
3448  ereport(LOG,
3450  errmsg("could not stat file \"%s\": %m",
3451  "pg_wal")));
3452  else if (S_ISLNK(st.st_mode))
3453  xlog_is_symlink = true;
3454  }
3455 #else
3456  if (pgwin32_is_junction("pg_wal"))
3457  xlog_is_symlink = true;
3458 #endif
3459 
3460 #ifdef HAVE_SYNCFS
3462  {
3463  DIR *dir;
3464  struct dirent *de;
3465 
3466  /*
3467  * On Linux, we don't have to open every single file one by one. We
3468  * can use syncfs() to sync whole filesystems. We only expect
3469  * filesystem boundaries to exist where we tolerate symlinks, namely
3470  * pg_wal and the tablespaces, so we call syncfs() for each of those
3471  * directories.
3472  */
3473 
3474  /* Prepare to report progress syncing the data directory via syncfs. */
3476 
3477  /* Sync the top level pgdata directory. */
3478  do_syncfs(".");
3479  /* If any tablespaces are configured, sync each of those. */
3480  dir = AllocateDir("pg_tblspc");
3481  while ((de = ReadDirExtended(dir, "pg_tblspc", LOG)))
3482  {
3483  char path[MAXPGPATH];
3484 
3485  if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
3486  continue;
3487 
3488  snprintf(path, MAXPGPATH, "pg_tblspc/%s", de->d_name);
3489  do_syncfs(path);
3490  }
3491  FreeDir(dir);
3492  /* If pg_wal is a symlink, process that too. */
3493  if (xlog_is_symlink)
3494  do_syncfs("pg_wal");
3495  return;
3496  }
3497 #endif /* !HAVE_SYNCFS */
3498 
3499 #ifdef PG_FLUSH_DATA_WORKS
3500  /* Prepare to report progress of the pre-fsync phase. */
3502 
3503  /*
3504  * If possible, hint to the kernel that we're soon going to fsync the data
3505  * directory and its contents. Errors in this step are even less
3506  * interesting than normal, so log them only at DEBUG1.
3507  */
3508  walkdir(".", pre_sync_fname, false, DEBUG1);
3509  if (xlog_is_symlink)
3510  walkdir("pg_wal", pre_sync_fname, false, DEBUG1);
3511  walkdir("pg_tblspc", pre_sync_fname, true, DEBUG1);
3512 #endif
3513 
3514  /* Prepare to report progress syncing the data directory via fsync. */
3516 
3517  /*
3518  * Now we do the fsync()s in the same order.
3519  *
3520  * The main call ignores symlinks, so in addition to specially processing
3521  * pg_wal if it's a symlink, pg_tblspc has to be visited separately with
3522  * process_symlinks = true. Note that if there are any plain directories
3523  * in pg_tblspc, they'll get fsync'd twice. That's not an expected case
3524  * so we don't worry about optimizing it.
3525  */
3526  walkdir(".", datadir_fsync_fname, false, LOG);
3527  if (xlog_is_symlink)
3528  walkdir("pg_wal", datadir_fsync_fname, false, LOG);
3529  walkdir("pg_tblspc", datadir_fsync_fname, true, LOG);
3530 }
void begin_startup_progress_phase(void)
Definition: startup.c:320
#define DEBUG1
Definition: elog.h:24
int recovery_init_sync_method
Definition: fd.c:166
static void datadir_fsync_fname(const char *fname, bool isdir, int elevel)
Definition: fd.c:3649
bool pgwin32_is_junction(const char *path)

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

Referenced by StartupXLOG().

◆ TempTablespacePath()

void TempTablespacePath ( char *  path,
Oid  tablespace 
)

Definition at line 1762 of file fd.c.

1763 {
1764  /*
1765  * Identify the tempfile directory for this tablespace.
1766  *
1767  * If someone tries to specify pg_global, use pg_default instead.
1768  */
1769  if (tablespace == InvalidOid ||
1770  tablespace == DEFAULTTABLESPACE_OID ||
1771  tablespace == GLOBALTABLESPACE_OID)
1772  snprintf(path, MAXPGPATH, "base/%s", PG_TEMP_FILES_DIR);
1773  else
1774  {
1775  /* All other tablespaces are accessed via symlinks */
1776  snprintf(path, MAXPGPATH, "pg_tblspc/%u/%s/%s",
1779  }
1780 }
char * tablespace
Definition: pgbench.c:227

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

2958 {
2959  return (numTempTableSpaces >= 0);
2960 }

References numTempTableSpaces.

Referenced by GetTempTablespaces(), and PrepareTempTablespaces().

Variable Documentation

◆ data_sync_retry

PGDLLIMPORT bool data_sync_retry
extern

Definition at line 163 of file fd.c.

Referenced by data_sync_elevel().

◆ max_files_per_process

PGDLLIMPORT int max_files_per_process
extern

Definition at line 147 of file fd.c.

Referenced by set_max_safe_fds().

◆ max_safe_fds

int max_safe_fds
extern

Definition at line 160 of file fd.c.

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

◆ recovery_init_sync_method

int recovery_init_sync_method
extern

Definition at line 166 of file fd.c.

Referenced by SyncDataDirectory().