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.

Referenced by _mdfd_getseg(), mdopenfork(), and ProcessSyncRequests().

◆ PG_O_DIRECT

#define PG_O_DIRECT   0

Definition at line 95 of file fd.h.

Referenced by BasicOpenFilePerm(), and get_sync_bit().

◆ 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 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.

Function Documentation

◆ AcquireExternalFD()

bool AcquireExternalFD ( void  )

Definition at line 1175 of file fd.c.

References max_safe_fds, numExternalFDs, and ReserveExternalFD().

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

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

◆ AllocateDir()

DIR* AllocateDir ( const char *  dirname)

Definition at line 2720 of file fd.c.

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

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

2721 {
2722  DIR *dir;
2723 
2724  DO_DB(elog(LOG, "AllocateDir: Allocated %d (%s)",
2725  numAllocatedDescs, dirname));
2726 
2727  /* Can we allocate another non-virtual FD? */
2728  if (!reserveAllocatedDesc())
2729  ereport(ERROR,
2730  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2731  errmsg("exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"",
2732  maxAllocatedDescs, dirname)));
2733 
2734  /* Close excess kernel FDs. */
2735  ReleaseLruFiles();
2736 
2737 TryAgain:
2738  if ((dir = opendir(dirname)) != NULL)
2739  {
2741 
2742  desc->kind = AllocateDescDir;
2743  desc->desc.dir = dir;
2746  return desc->desc.dir;
2747  }
2748 
2749  if (errno == EMFILE || errno == ENFILE)
2750  {
2751  int save_errno = errno;
2752 
2753  ereport(LOG,
2754  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2755  errmsg("out of file descriptors: %m; release and retry")));
2756  errno = 0;
2757  if (ReleaseLruFile())
2758  goto TryAgain;
2759  errno = save_errno;
2760  }
2761 
2762  return NULL;
2763 }
union AllocateDesc::@18 desc
static AllocateDesc * allocatedDescs
Definition: fd.c:265
DIR * dir
Definition: fd.c:258
#define DO_DB(A)
Definition: fd.c:176
int errcode(int sqlerrcode)
Definition: elog.c:698
static bool reserveAllocatedDesc(void)
Definition: fd.c:2384
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:253
static bool ReleaseLruFile(void)
Definition: fd.c:1371
Definition: dirent.c:25
#define ERROR
Definition: elog.h:46
DIR * opendir(const char *)
Definition: dirent.c:33
static void ReleaseLruFiles(void)
Definition: fd.c:1393
#define ereport(elevel,...)
Definition: elog.h:157
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:724
SubTransactionId create_subid
Definition: fd.c:254
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
static int maxAllocatedDescs
Definition: fd.c:264
static int numAllocatedDescs
Definition: fd.c:263

◆ AllocateFile()

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

Definition at line 2459 of file fd.c.

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

Referenced by _ShowOption(), AlterSystemSetConfigFile(), apw_dump_now(), apw_load_buffers(), BackendRun(), BeginCopyFrom(), BeginCopyTo(), checkControlFile(), do_pg_start_backup(), do_pg_stop_backup(), entry_reset(), existsTimeLineHistory(), ExportSnapshot(), fill_hba_view(), gc_qtexts(), 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(), PostmasterMarkPIDForWorkerNotify(), read_backup_label(), read_binary_file(), read_tablespace_map(), read_whole_file(), readTimeLineHistory(), tokenize_inc_file(), tsearch_readline_begin(), ValidatePgVersion(), write_relcache_init_file(), XLogArchiveForceDone(), and XLogArchiveNotify().

2460 {
2461  FILE *file;
2462 
2463  DO_DB(elog(LOG, "AllocateFile: Allocated %d (%s)",
2465 
2466  /* Can we allocate another non-virtual FD? */
2467  if (!reserveAllocatedDesc())
2468  ereport(ERROR,
2469  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2470  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2471  maxAllocatedDescs, name)));
2472 
2473  /* Close excess kernel FDs. */
2474  ReleaseLruFiles();
2475 
2476 TryAgain:
2477  if ((file = fopen(name, mode)) != NULL)
2478  {
2480 
2481  desc->kind = AllocateDescFile;
2482  desc->desc.file = file;
2485  return desc->desc.file;
2486  }
2487 
2488  if (errno == EMFILE || errno == ENFILE)
2489  {
2490  int save_errno = errno;
2491 
2492  ereport(LOG,
2493  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2494  errmsg("out of file descriptors: %m; release and retry")));
2495  errno = 0;
2496  if (ReleaseLruFile())
2497  goto TryAgain;
2498  errno = save_errno;
2499  }
2500 
2501  return NULL;
2502 }
static PgChecksumMode mode
Definition: pg_checksums.c:65
union AllocateDesc::@18 desc
static AllocateDesc * allocatedDescs
Definition: fd.c:265
#define DO_DB(A)
Definition: fd.c:176
int errcode(int sqlerrcode)
Definition: elog.c:698
static bool reserveAllocatedDesc(void)
Definition: fd.c:2384
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:253
static bool ReleaseLruFile(void)
Definition: fd.c:1371
#define ERROR
Definition: elog.h:46
static void ReleaseLruFiles(void)
Definition: fd.c:1393
FILE * file
Definition: fd.c:257
#define ereport(elevel,...)
Definition: elog.h:157
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:724
SubTransactionId create_subid
Definition: fd.c:254
const char * name
Definition: encode.c:561
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
static int maxAllocatedDescs
Definition: fd.c:264
static int numAllocatedDescs
Definition: fd.c:263

◆ AtEOSubXact_Files()

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

Definition at line 3008 of file fd.c.

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

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

◆ AtEOXact_Files()

void AtEOXact_Files ( bool  isCommit)

Definition at line 3041 of file fd.c.

References CleanupTempFiles(), numTempTableSpaces, and tempTableSpaces.

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

3042 {
3043  CleanupTempFiles(isCommit, false);
3044  tempTableSpaces = NULL;
3045  numTempTableSpaces = -1;
3046 }
static int numTempTableSpaces
Definition: fd.c:285
static Oid * tempTableSpaces
Definition: fd.c:284
static void CleanupTempFiles(bool isCommit, bool isProcExit)
Definition: fd.c:3078

◆ BasicOpenFile()

int BasicOpenFile ( const char *  fileName,
int  fileFlags 
)

Definition at line 1069 of file fd.c.

References BasicOpenFilePerm(), and pg_file_create_mode.

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

1070 {
1071  return BasicOpenFilePerm(fileName, fileFlags, pg_file_create_mode);
1072 }
int pg_file_create_mode
Definition: file_perm.c:19
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1091

◆ BasicOpenFilePerm()

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

Definition at line 1091 of file fd.c.

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

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

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

◆ closeAllVfds()

void closeAllVfds ( void  )

Definition at line 2897 of file fd.c.

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

Referenced by standard_ProcessUtility().

2898 {
2899  Index i;
2900 
2901  if (SizeVfdCache > 0)
2902  {
2903  Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
2904  for (i = 1; i < SizeVfdCache; i++)
2905  {
2906  if (!FileIsNotOpen(i))
2907  LruDelete(i);
2908  }
2909  }
2910 }
static Size SizeVfdCache
Definition: fd.c:213
static void LruDelete(File file)
Definition: fd.c:1276
#define FileIsNotOpen(file)
Definition: fd.c:185
unsigned int Index
Definition: c.h:549
#define Assert(condition)
Definition: c.h:804
int i

◆ ClosePipeStream()

int ClosePipeStream ( FILE *  file)

Definition at line 2868 of file fd.c.

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

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

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

◆ CloseTransientFile()

int CloseTransientFile ( int  fd)

Definition at line 2686 of file fd.c.

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

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

2687 {
2688  int i;
2689 
2690  DO_DB(elog(LOG, "CloseTransientFile: Allocated %d", numAllocatedDescs));
2691 
2692  /* Remove fd from list of allocated files, if it's present */
2693  for (i = numAllocatedDescs; --i >= 0;)
2694  {
2695  AllocateDesc *desc = &allocatedDescs[i];
2696 
2697  if (desc->kind == AllocateDescRawFD && desc->desc.fd == fd)
2698  return FreeDesc(desc);
2699  }
2700 
2701  /* Only get here if someone passes us a file not in allocatedDescs */
2702  elog(WARNING, "fd passed to CloseTransientFile was not obtained from OpenTransientFile");
2703 
2704  return close(fd);
2705 }
union AllocateDesc::@18 desc
static AllocateDesc * allocatedDescs
Definition: fd.c:265
#define DO_DB(A)
Definition: fd.c:176
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:253
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2619
#define WARNING
Definition: elog.h:40
int fd
Definition: fd.c:259
#define elog(elevel,...)
Definition: elog.h:232
int i
#define close(a)
Definition: win32.h:12
static int numAllocatedDescs
Definition: fd.c:263

◆ data_sync_elevel()

◆ durable_rename()

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

Definition at line 697 of file fd.c.

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

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

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

◆ durable_rename_excl()

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

Definition at line 827 of file fd.c.

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

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

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

◆ durable_unlink()

int durable_unlink ( const char *  fname,
int  loglevel 
)

Definition at line 787 of file fd.c.

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

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

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

◆ FileClose()

void FileClose ( File  file)

Definition at line 1959 of file fd.c.

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

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

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

◆ FileGetRawDesc()

int FileGetRawDesc ( File  file)

Definition at line 2353 of file fd.c.

References Assert, vfd::fd, and FileIsValid.

2354 {
2355  Assert(FileIsValid(file));
2356  return VfdCache[file].fd;
2357 }
static Vfd * VfdCache
Definition: fd.c:212
int fd
Definition: fd.c:194
#define FileIsValid(file)
Definition: fd.c:182
#define Assert(condition)
Definition: c.h:804

◆ FileGetRawFlags()

int FileGetRawFlags ( File  file)

Definition at line 2363 of file fd.c.

References Assert, vfd::fileFlags, and FileIsValid.

2364 {
2365  Assert(FileIsValid(file));
2366  return VfdCache[file].fileFlags;
2367 }
static Vfd * VfdCache
Definition: fd.c:212
#define FileIsValid(file)
Definition: fd.c:182
#define Assert(condition)
Definition: c.h:804
int fileFlags
Definition: fd.c:203

◆ FileGetRawMode()

mode_t FileGetRawMode ( File  file)

Definition at line 2373 of file fd.c.

References Assert, FileIsValid, and vfd::fileMode.

2374 {
2375  Assert(FileIsValid(file));
2376  return VfdCache[file].fileMode;
2377 }
static Vfd * VfdCache
Definition: fd.c:212
mode_t fileMode
Definition: fd.c:204
#define FileIsValid(file)
Definition: fd.c:182
#define Assert(condition)
Definition: c.h:804

◆ FilePathName()

char* FilePathName ( File  file)

Definition at line 2337 of file fd.c.

References Assert, FileIsValid, and vfd::fileName.

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

2338 {
2339  Assert(FileIsValid(file));
2340 
2341  return VfdCache[file].fileName;
2342 }
static Vfd * VfdCache
Definition: fd.c:212
char * fileName
Definition: fd.c:201
#define FileIsValid(file)
Definition: fd.c:182
#define Assert(condition)
Definition: c.h:804

◆ FilePrefetch()

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

Definition at line 2059 of file fd.c.

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

Referenced by mdprefetch().

2060 {
2061 #if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
2062  int returnCode;
2063 
2064  Assert(FileIsValid(file));
2065 
2066  DO_DB(elog(LOG, "FilePrefetch: %d (%s) " INT64_FORMAT " %d",
2067  file, VfdCache[file].fileName,
2068  (int64) offset, amount));
2069 
2070  returnCode = FileAccess(file);
2071  if (returnCode < 0)
2072  return returnCode;
2073 
2074  pgstat_report_wait_start(wait_event_info);
2075  returnCode = posix_fadvise(VfdCache[file].fd, offset, amount,
2076  POSIX_FADV_WILLNEED);
2078 
2079  return returnCode;
2080 #else
2081  Assert(FileIsValid(file));
2082  return 0;
2083 #endif
2084 }
static void pgstat_report_wait_end(void)
Definition: wait_event.h:274
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:258
#define FileIsValid(file)
Definition: fd.c:182
static int FileAccess(File file)
Definition: fd.c:1481
#define Assert(condition)
Definition: c.h:804
#define INT64_FORMAT
Definition: c.h:483
#define elog(elevel,...)
Definition: elog.h:232

◆ FileRead()

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

Definition at line 2110 of file fd.c.

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

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

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

◆ FileSize()

off_t FileSize ( File  file)

Definition at line 2285 of file fd.c.

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

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

2286 {
2287  Assert(FileIsValid(file));
2288 
2289  DO_DB(elog(LOG, "FileSize %d (%s)",
2290  file, VfdCache[file].fileName));
2291 
2292  if (FileIsNotOpen(file))
2293  {
2294  if (FileAccess(file) < 0)
2295  return (off_t) -1;
2296  }
2297 
2298  return lseek(VfdCache[file].fd, 0, SEEK_END);
2299 }
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define FileIsNotOpen(file)
Definition: fd.c:185
#define FileIsValid(file)
Definition: fd.c:182
static int FileAccess(File file)
Definition: fd.c:1481
#define Assert(condition)
Definition: c.h:804
#define elog(elevel,...)
Definition: elog.h:232

◆ FileSync()

int FileSync ( File  file,
uint32  wait_event_info 
)

Definition at line 2264 of file fd.c.

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

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

2265 {
2266  int returnCode;
2267 
2268  Assert(FileIsValid(file));
2269 
2270  DO_DB(elog(LOG, "FileSync: %d (%s)",
2271  file, VfdCache[file].fileName));
2272 
2273  returnCode = FileAccess(file);
2274  if (returnCode < 0)
2275  return returnCode;
2276 
2277  pgstat_report_wait_start(wait_event_info);
2278  returnCode = pg_fsync(VfdCache[file].fd);
2280 
2281  return returnCode;
2282 }
static void pgstat_report_wait_end(void)
Definition: wait_event.h:274
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:258
#define FileIsValid(file)
Definition: fd.c:182
static int FileAccess(File file)
Definition: fd.c:1481
#define Assert(condition)
Definition: c.h:804
#define elog(elevel,...)
Definition: elog.h:232
int pg_fsync(int fd)
Definition: fd.c:357

◆ FileTruncate()

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

Definition at line 2302 of file fd.c.

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

Referenced by BufFileTruncateFileSet(), and mdtruncate().

2303 {
2304  int returnCode;
2305 
2306  Assert(FileIsValid(file));
2307 
2308  DO_DB(elog(LOG, "FileTruncate %d (%s)",
2309  file, VfdCache[file].fileName));
2310 
2311  returnCode = FileAccess(file);
2312  if (returnCode < 0)
2313  return returnCode;
2314 
2315  pgstat_report_wait_start(wait_event_info);
2316  returnCode = ftruncate(VfdCache[file].fd, offset);
2318 
2319  if (returnCode == 0 && VfdCache[file].fileSize > offset)
2320  {
2321  /* adjust our state for truncation of a temp file */
2322  Assert(VfdCache[file].fdstate & FD_TEMP_FILE_LIMIT);
2323  temporary_files_size -= VfdCache[file].fileSize - offset;
2324  VfdCache[file].fileSize = offset;
2325  }
2326 
2327  return returnCode;
2328 }
static void pgstat_report_wait_end(void)
Definition: wait_event.h:274
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:190
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
off_t fileSize
Definition: fd.c:200
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:258
#define FileIsValid(file)
Definition: fd.c:182
static uint64 temporary_files_size
Definition: fd.c:232
static int FileAccess(File file)
Definition: fd.c:1481
#define Assert(condition)
Definition: c.h:804
#define elog(elevel,...)
Definition: elog.h:232
#define ftruncate(a, b)
Definition: win32_port.h:73

◆ FileWrite()

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

Definition at line 2166 of file fd.c.

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

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

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

◆ FileWriteback()

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

Definition at line 2087 of file fd.c.

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

Referenced by mdwriteback().

2088 {
2089  int returnCode;
2090 
2091  Assert(FileIsValid(file));
2092 
2093  DO_DB(elog(LOG, "FileWriteback: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
2094  file, VfdCache[file].fileName,
2095  (int64) offset, (int64) nbytes));
2096 
2097  if (nbytes <= 0)
2098  return;
2099 
2100  returnCode = FileAccess(file);
2101  if (returnCode < 0)
2102  return;
2103 
2104  pgstat_report_wait_start(wait_event_info);
2105  pg_flush_data(VfdCache[file].fd, offset, nbytes);
2107 }
static void pgstat_report_wait_end(void)
Definition: wait_event.h:274
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:258
void pg_flush_data(int fd, off_t offset, off_t nbytes)
Definition: fd.c:467
#define FileIsValid(file)
Definition: fd.c:182
static int FileAccess(File file)
Definition: fd.c:1481
#define Assert(condition)
Definition: c.h:804
#define INT64_FORMAT
Definition: c.h:483
#define elog(elevel,...)
Definition: elog.h:232

◆ FreeDir()

int FreeDir ( DIR dir)

Definition at line 2838 of file fd.c.

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

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

2839 {
2840  int i;
2841 
2842  /* Nothing to do if AllocateDir failed */
2843  if (dir == NULL)
2844  return 0;
2845 
2846  DO_DB(elog(LOG, "FreeDir: Allocated %d", numAllocatedDescs));
2847 
2848  /* Remove dir from list of allocated dirs, if it's present */
2849  for (i = numAllocatedDescs; --i >= 0;)
2850  {
2851  AllocateDesc *desc = &allocatedDescs[i];
2852 
2853  if (desc->kind == AllocateDescDir && desc->desc.dir == dir)
2854  return FreeDesc(desc);
2855  }
2856 
2857  /* Only get here if someone passes us a dir not in allocatedDescs */
2858  elog(WARNING, "dir passed to FreeDir was not obtained from AllocateDir");
2859 
2860  return closedir(dir);
2861 }
union AllocateDesc::@18 desc
static AllocateDesc * allocatedDescs
Definition: fd.c:265
DIR * dir
Definition: fd.c:258
#define DO_DB(A)
Definition: fd.c:176
int closedir(DIR *)
Definition: dirent.c:123
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:253
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2619
#define WARNING
Definition: elog.h:40
#define elog(elevel,...)
Definition: elog.h:232
int i
static int numAllocatedDescs
Definition: fd.c:263

◆ FreeFile()

int FreeFile ( FILE *  file)

Definition at line 2658 of file fd.c.

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

Referenced by _ShowOption(), AlterSystemSetConfigFile(), apw_dump_now(), apw_load_buffers(), BackendRun(), checkControlFile(), do_pg_start_backup(), do_pg_stop_backup(), EndCopy(), EndCopyFrom(), entry_reset(), existsTimeLineHistory(), ExportSnapshot(), fill_hba_view(), gc_qtexts(), 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(), PostmasterMarkPIDForWorkerNotify(), read_backup_label(), read_binary_file(), read_tablespace_map(), read_whole_file(), readTimeLineHistory(), tokenize_inc_file(), tsearch_readline_end(), ValidatePgVersion(), write_relcache_init_file(), XLogArchiveForceDone(), and XLogArchiveNotify().

2659 {
2660  int i;
2661 
2662  DO_DB(elog(LOG, "FreeFile: Allocated %d", numAllocatedDescs));
2663 
2664  /* Remove file from list of allocated files, if it's present */
2665  for (i = numAllocatedDescs; --i >= 0;)
2666  {
2667  AllocateDesc *desc = &allocatedDescs[i];
2668 
2669  if (desc->kind == AllocateDescFile && desc->desc.file == file)
2670  return FreeDesc(desc);
2671  }
2672 
2673  /* Only get here if someone passes us a file not in allocatedDescs */
2674  elog(WARNING, "file passed to FreeFile was not obtained from AllocateFile");
2675 
2676  return fclose(file);
2677 }
union AllocateDesc::@18 desc
static AllocateDesc * allocatedDescs
Definition: fd.c:265
#define DO_DB(A)
Definition: fd.c:176
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:253
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2619
#define WARNING
Definition: elog.h:40
FILE * file
Definition: fd.c:257
#define elog(elevel,...)
Definition: elog.h:232
int i
static int numAllocatedDescs
Definition: fd.c:263

◆ fsync_fname()

void fsync_fname ( const char *  fname,
bool  isdir 
)

Definition at line 671 of file fd.c.

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

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

672 {
673  fsync_fname_ext(fname, isdir, false, data_sync_elevel(ERROR));
674 }
#define ERROR
Definition: elog.h:46
int data_sync_elevel(int elevel)
Definition: fd.c:3805
int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3666

◆ fsync_fname_ext()

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

Definition at line 3666 of file fd.c.

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

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

3667 {
3668  int fd;
3669  int flags;
3670  int returncode;
3671 
3672  /*
3673  * Some OSs require directories to be opened read-only whereas other
3674  * systems don't allow us to fsync files opened read-only; so we need both
3675  * cases here. Using O_RDWR will cause us to fail to fsync files that are
3676  * not writable by our userid, but we assume that's OK.
3677  */
3678  flags = PG_BINARY;
3679  if (!isdir)
3680  flags |= O_RDWR;
3681  else
3682  flags |= O_RDONLY;
3683 
3684  fd = OpenTransientFile(fname, flags);
3685 
3686  /*
3687  * Some OSs don't allow us to open directories at all (Windows returns
3688  * EACCES), just ignore the error in that case. If desired also silently
3689  * ignoring errors about unreadable files. Log others.
3690  */
3691  if (fd < 0 && isdir && (errno == EISDIR || errno == EACCES))
3692  return 0;
3693  else if (fd < 0 && ignore_perm && errno == EACCES)
3694  return 0;
3695  else if (fd < 0)
3696  {
3697  ereport(elevel,
3699  errmsg("could not open file \"%s\": %m", fname)));
3700  return -1;
3701  }
3702 
3703  returncode = pg_fsync(fd);
3704 
3705  /*
3706  * Some OSes don't allow us to fsync directories at all, so we can ignore
3707  * those errors. Anything else needs to be logged.
3708  */
3709  if (returncode != 0 && !(isdir && (errno == EBADF || errno == EINVAL)))
3710  {
3711  int save_errno;
3712 
3713  /* close file upon error, might not be in transaction context */
3714  save_errno = errno;
3715  (void) CloseTransientFile(fd);
3716  errno = save_errno;
3717 
3718  ereport(elevel,
3720  errmsg("could not fsync file \"%s\": %m", fname)));
3721  return -1;
3722  }
3723 
3724  if (CloseTransientFile(fd) != 0)
3725  {
3726  ereport(elevel,
3728  errmsg("could not close file \"%s\": %m", fname)));
3729  return -1;
3730  }
3731 
3732  return 0;
3733 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1271
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2509
int errcode_for_file_access(void)
Definition: elog.c:721
int CloseTransientFile(int fd)
Definition: fd.c:2686
static int elevel
Definition: vacuumlazy.c:401
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909
int pg_fsync(int fd)
Definition: fd.c:357

◆ GetNextTempTableSpace()

Oid GetNextTempTableSpace ( void  )

Definition at line 2987 of file fd.c.

References InvalidOid, nextTempTableSpace, numTempTableSpaces, and tempTableSpaces.

Referenced by GetDefaultTablespace(), and OpenTemporaryFile().

2988 {
2989  if (numTempTableSpaces > 0)
2990  {
2991  /* Advance nextTempTableSpace counter with wraparound */
2993  nextTempTableSpace = 0;
2995  }
2996  return InvalidOid;
2997 }
static int numTempTableSpaces
Definition: fd.c:285
static int nextTempTableSpace
Definition: fd.c:286
#define InvalidOid
Definition: postgres_ext.h:36
static Oid * tempTableSpaces
Definition: fd.c:284

◆ GetTempTablespaces()

int GetTempTablespaces ( Oid tableSpaces,
int  numSpaces 
)

Definition at line 2969 of file fd.c.

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

Referenced by FileSetInit().

2970 {
2971  int i;
2972 
2974  for (i = 0; i < numTempTableSpaces && i < numSpaces; ++i)
2975  tableSpaces[i] = tempTableSpaces[i];
2976 
2977  return i;
2978 }
static int numTempTableSpaces
Definition: fd.c:285
bool TempTablespacesAreSet(void)
Definition: fd.c:2954
#define Assert(condition)
Definition: c.h:804
static Oid * tempTableSpaces
Definition: fd.c:284
int i

◆ InitFileAccess()

void InitFileAccess ( void  )

Definition at line 881 of file fd.c.

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

Referenced by BaseInit().

882 {
883  Assert(SizeVfdCache == 0); /* call me only once */
884 
885  /* initialize cache header entry */
886  VfdCache = (Vfd *) malloc(sizeof(Vfd));
887  if (VfdCache == NULL)
888  ereport(FATAL,
889  (errcode(ERRCODE_OUT_OF_MEMORY),
890  errmsg("out of memory")));
891 
892  MemSet((char *) &(VfdCache[0]), 0, sizeof(Vfd));
894 
895  SizeVfdCache = 1;
896 }
static Size SizeVfdCache
Definition: fd.c:213
static Vfd * VfdCache
Definition: fd.c:212
int errcode(int sqlerrcode)
Definition: elog.c:698
#define MemSet(start, val, len)
Definition: c.h:1008
#define malloc(a)
Definition: header.h:50
#define FATAL
Definition: elog.h:49
Definition: fd.c:192
int fd
Definition: fd.c:194
#define VFD_CLOSED
Definition: fd.c:180
#define ereport(elevel,...)
Definition: elog.h:157
#define Assert(condition)
Definition: c.h:804
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ InitTemporaryFileAccess()

void InitTemporaryFileAccess ( void  )

Definition at line 911 of file fd.c.

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

Referenced by BaseInit().

912 {
913  Assert(SizeVfdCache != 0); /* InitFileAccess() needs to have run*/
914  Assert(!temporary_files_allowed); /* call me only once */
915 
916  /*
917  * Register before-shmem-exit hook to ensure temp files are dropped while
918  * we can still report stats.
919  */
921 
922 #ifdef USE_ASSERT_CHECKING
923  temporary_files_allowed = true;
924 #endif
925 }
static void BeforeShmemExit_Files(int code, Datum arg)
Definition: fd.c:3055
static Size SizeVfdCache
Definition: fd.c:213
void before_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:333
#define Assert(condition)
Definition: c.h:804

◆ looks_like_temp_rel_name()

bool looks_like_temp_rel_name ( const char *  name)

Definition at line 3331 of file fd.c.

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

Referenced by RemovePgTempRelationFilesInDbspace(), and sendDir().

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

◆ MakePGDirectory()

int MakePGDirectory ( const char *  directoryName)

◆ OpenPipeStream()

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

Definition at line 2562 of file fd.c.

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

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

2563 {
2564  FILE *file;
2565  int save_errno;
2566 
2567  DO_DB(elog(LOG, "OpenPipeStream: Allocated %d (%s)",
2568  numAllocatedDescs, command));
2569 
2570  /* Can we allocate another non-virtual FD? */
2571  if (!reserveAllocatedDesc())
2572  ereport(ERROR,
2573  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2574  errmsg("exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"",
2575  maxAllocatedDescs, command)));
2576 
2577  /* Close excess kernel FDs. */
2578  ReleaseLruFiles();
2579 
2580 TryAgain:
2581  fflush(stdout);
2582  fflush(stderr);
2584  errno = 0;
2585  file = popen(command, mode);
2586  save_errno = errno;
2588  errno = save_errno;
2589  if (file != NULL)
2590  {
2592 
2593  desc->kind = AllocateDescPipe;
2594  desc->desc.file = file;
2597  return desc->desc.file;
2598  }
2599 
2600  if (errno == EMFILE || errno == ENFILE)
2601  {
2602  ereport(LOG,
2603  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2604  errmsg("out of file descriptors: %m; release and retry")));
2605  if (ReleaseLruFile())
2606  goto TryAgain;
2607  errno = save_errno;
2608  }
2609 
2610  return NULL;
2611 }
static PgChecksumMode mode
Definition: pg_checksums.c:65
union AllocateDesc::@18 desc
static AllocateDesc * allocatedDescs
Definition: fd.c:265
#define DO_DB(A)
Definition: fd.c:176
int errcode(int sqlerrcode)
Definition: elog.c:698
static bool reserveAllocatedDesc(void)
Definition: fd.c:2384
#define SIGPIPE
Definition: win32_port.h:172
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:253
static bool ReleaseLruFile(void)
Definition: fd.c:1371
#define ERROR
Definition: elog.h:46
#define SIG_IGN
Definition: win32_port.h:164
static void ReleaseLruFiles(void)
Definition: fd.c:1393
FILE * file
Definition: fd.c:257
#define ereport(elevel,...)
Definition: elog.h:157
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:170
#define SIG_DFL
Definition: win32_port.h:162
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:724
SubTransactionId create_subid
Definition: fd.c:254
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
static int maxAllocatedDescs
Definition: fd.c:264
static int numAllocatedDescs
Definition: fd.c:263

◆ OpenTemporaryFile()

File OpenTemporaryFile ( bool  interXact)

Definition at line 1705 of file fd.c.

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

Referenced by BufFileCreateTemp(), and extendBufFile().

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

◆ OpenTransientFile()

◆ OpenTransientFilePerm()

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

Definition at line 2518 of file fd.c.

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

Referenced by be_lo_export(), and OpenTransientFile().

2519 {
2520  int fd;
2521 
2522  DO_DB(elog(LOG, "OpenTransientFile: Allocated %d (%s)",
2523  numAllocatedDescs, fileName));
2524 
2525  /* Can we allocate another non-virtual FD? */
2526  if (!reserveAllocatedDesc())
2527  ereport(ERROR,
2528  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2529  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2530  maxAllocatedDescs, fileName)));
2531 
2532  /* Close excess kernel FDs. */
2533  ReleaseLruFiles();
2534 
2535  fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
2536 
2537  if (fd >= 0)
2538  {
2540 
2541  desc->kind = AllocateDescRawFD;
2542  desc->desc.fd = fd;
2545 
2546  return fd;
2547  }
2548 
2549  return -1; /* failure */
2550 }
union AllocateDesc::@18 desc
static AllocateDesc * allocatedDescs
Definition: fd.c:265
#define DO_DB(A)
Definition: fd.c:176
int errcode(int sqlerrcode)
Definition: elog.c:698
static bool reserveAllocatedDesc(void)
Definition: fd.c:2384
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:253
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define ERROR
Definition: elog.h:46
static void ReleaseLruFiles(void)
Definition: fd.c:1393
#define ereport(elevel,...)
Definition: elog.h:157
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:724
SubTransactionId create_subid
Definition: fd.c:254
int fd
Definition: fd.c:259
int errmsg(const char *fmt,...)
Definition: elog.c:909
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1091
#define elog(elevel,...)
Definition: elog.h:232
static int maxAllocatedDescs
Definition: fd.c:264
static int numAllocatedDescs
Definition: fd.c:263

◆ PathNameCreateTemporaryDir()

void PathNameCreateTemporaryDir ( const char *  base,
const char *  name 
)

Definition at line 1641 of file fd.c.

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

Referenced by FileSetCreate().

1642 {
1643  if (MakePGDirectory(directory) < 0)
1644  {
1645  if (errno == EEXIST)
1646  return;
1647 
1648  /*
1649  * Failed. Try to create basedir first in case it's missing. Tolerate
1650  * EEXIST to close a race against another process following the same
1651  * algorithm.
1652  */
1653  if (MakePGDirectory(basedir) < 0 && errno != EEXIST)
1654  ereport(ERROR,
1656  errmsg("cannot create temporary directory \"%s\": %m",
1657  basedir)));
1658 
1659  /* Try again. */
1660  if (MakePGDirectory(directory) < 0 && errno != EEXIST)
1661  ereport(ERROR,
1663  errmsg("cannot create temporary subdirectory \"%s\": %m",
1664  directory)));
1665  }
1666 }
static char * basedir
#define ERROR
Definition: elog.h:46
int errcode_for_file_access(void)
Definition: elog.c:721
#define ereport(elevel,...)
Definition: elog.h:157
int MakePGDirectory(const char *directoryName)
Definition: fd.c:3782
static const char * directory
Definition: zic.c:632
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ PathNameCreateTemporaryFile()

File PathNameCreateTemporaryFile ( const char *  name,
bool  error_on_failure 
)

Definition at line 1842 of file fd.c.

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

Referenced by FileSetCreate().

1843 {
1844  File file;
1845 
1846  Assert(temporary_files_allowed); /* check temp file access is up */
1847 
1849 
1850  /*
1851  * Open the file. Note: we don't use O_EXCL, in case there is an orphaned
1852  * temp file that can be reused.
1853  */
1854  file = PathNameOpenFile(path, O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1855  if (file <= 0)
1856  {
1857  if (error_on_failure)
1858  ereport(ERROR,
1860  errmsg("could not create temporary file \"%s\": %m",
1861  path)));
1862  else
1863  return file;
1864  }
1865 
1866  /* Mark it for temp_file_limit accounting. */
1868 
1869  /* Register it for automatic close. */
1870  RegisterTemporaryFile(file);
1871 
1872  return file;
1873 }
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1564
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:190
ResourceOwner CurrentResourceOwner
Definition: resowner.c:146
static Vfd * VfdCache
Definition: fd.c:212
#define PG_BINARY
Definition: c.h:1271
#define ERROR
Definition: elog.h:46
int errcode_for_file_access(void)
Definition: elog.c:721
unsigned short fdstate
Definition: fd.c:195
#define ereport(elevel,...)
Definition: elog.h:157
static void RegisterTemporaryFile(File file)
Definition: fd.c:1536
#define Assert(condition)
Definition: c.h:804
int errmsg(const char *fmt,...)
Definition: elog.c:909
void ResourceOwnerEnlargeFiles(ResourceOwner owner)
Definition: resowner.c:1286
int File
Definition: fd.h:54

◆ PathNameDeleteTemporaryDir()

void PathNameDeleteTemporaryDir ( const char *  name)

Definition at line 1672 of file fd.c.

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

Referenced by FileSetDeleteAll().

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

◆ PathNameDeleteTemporaryFile()

bool PathNameDeleteTemporaryFile ( const char *  name,
bool  error_on_failure 
)

Definition at line 1913 of file fd.c.

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

Referenced by FileSetDelete(), and unlink_if_exists_fname().

1914 {
1915  struct stat filestats;
1916  int stat_errno;
1917 
1918  /* Get the final size for pgstat reporting. */
1919  if (stat(path, &filestats) != 0)
1920  stat_errno = errno;
1921  else
1922  stat_errno = 0;
1923 
1924  /*
1925  * Unlike FileClose's automatic file deletion code, we tolerate
1926  * non-existence to support BufFileDeleteFileSet which doesn't know how
1927  * many segments it has to delete until it runs out.
1928  */
1929  if (stat_errno == ENOENT)
1930  return false;
1931 
1932  if (unlink(path) < 0)
1933  {
1934  if (errno != ENOENT)
1935  ereport(error_on_failure ? ERROR : LOG,
1937  errmsg("could not unlink temporary file \"%s\": %m",
1938  path)));
1939  return false;
1940  }
1941 
1942  if (stat_errno == 0)
1943  ReportTemporaryFileUsage(path, filestats.st_size);
1944  else
1945  {
1946  errno = stat_errno;
1947  ereport(LOG,
1949  errmsg("could not stat file \"%s\": %m", path)));
1950  }
1951 
1952  return true;
1953 }
#define LOG
Definition: elog.h:26
#define ERROR
Definition: elog.h:46
int errcode_for_file_access(void)
Definition: elog.c:721
static void ReportTemporaryFileUsage(const char *path, off_t size)
Definition: fd.c:1517
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define stat
Definition: win32_port.h:283

◆ PathNameOpenFile()

File PathNameOpenFile ( const char *  fileName,
int  fileFlags 
)

Definition at line 1564 of file fd.c.

References PathNameOpenFilePerm(), and pg_file_create_mode.

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

1565 {
1566  return PathNameOpenFilePerm(fileName, fileFlags, pg_file_create_mode);
1567 }
File PathNameOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1577
int pg_file_create_mode
Definition: file_perm.c:19

◆ PathNameOpenFilePerm()

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

Definition at line 1577 of file fd.c.

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

Referenced by PathNameOpenFile().

1578 {
1579  char *fnamecopy;
1580  File file;
1581  Vfd *vfdP;
1582 
1583  DO_DB(elog(LOG, "PathNameOpenFilePerm: %s %x %o",
1584  fileName, fileFlags, fileMode));
1585 
1586  /*
1587  * We need a malloc'd copy of the file name; fail cleanly if no room.
1588  */
1589  fnamecopy = strdup(fileName);
1590  if (fnamecopy == NULL)
1591  ereport(ERROR,
1592  (errcode(ERRCODE_OUT_OF_MEMORY),
1593  errmsg("out of memory")));
1594 
1595  file = AllocateVfd();
1596  vfdP = &VfdCache[file];
1597 
1598  /* Close excess kernel FDs. */
1599  ReleaseLruFiles();
1600 
1601  vfdP->fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
1602 
1603  if (vfdP->fd < 0)
1604  {
1605  int save_errno = errno;
1606 
1607  FreeVfd(file);
1608  free(fnamecopy);
1609  errno = save_errno;
1610  return -1;
1611  }
1612  ++nfile;
1613  DO_DB(elog(LOG, "PathNameOpenFile: success %d",
1614  vfdP->fd));
1615 
1616  vfdP->fileName = fnamecopy;
1617  /* Saved flags are adjusted to be OK for re-opening file */
1618  vfdP->fileFlags = fileFlags & ~(O_CREAT | O_TRUNC | O_EXCL);
1619  vfdP->fileMode = fileMode;
1620  vfdP->fileSize = 0;
1621  vfdP->fdstate = 0x0;
1622  vfdP->resowner = NULL;
1623 
1624  Insert(file);
1625 
1626  return file;
1627 }
#define DO_DB(A)
Definition: fd.c:176
static Vfd * VfdCache
Definition: fd.c:212
int errcode(int sqlerrcode)
Definition: elog.c:698
#define LOG
Definition: elog.h:26
mode_t fileMode
Definition: fd.c:204
#define ERROR
Definition: elog.h:46
char * fileName
Definition: fd.c:201
static int nfile
Definition: fd.c:218
static File AllocateVfd(void)
Definition: fd.c:1403
unsigned short fdstate
Definition: fd.c:195
Definition: fd.c:192
off_t fileSize
Definition: fd.c:200
int fd
Definition: fd.c:194
static void Insert(File file)
Definition: fd.c:1302
ResourceOwner resowner
Definition: fd.c:196
static void ReleaseLruFiles(void)
Definition: fd.c:1393
#define ereport(elevel,...)
Definition: elog.h:157
#define free(a)
Definition: header.h:65
int errmsg(const char *fmt,...)
Definition: elog.c:909
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1091
#define elog(elevel,...)
Definition: elog.h:232
static void FreeVfd(File file)
Definition: fd.c:1461
int fileFlags
Definition: fd.c:203
int File
Definition: fd.h:54

◆ PathNameOpenTemporaryFile()

File PathNameOpenTemporaryFile ( const char *  path,
int  mode 
)

Definition at line 1882 of file fd.c.

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

Referenced by FileSetOpen().

1883 {
1884  File file;
1885 
1886  Assert(temporary_files_allowed); /* check temp file access is up */
1887 
1889 
1890  file = PathNameOpenFile(path, mode | PG_BINARY);
1891 
1892  /* If no such file, then we don't raise an error. */
1893  if (file <= 0 && errno != ENOENT)
1894  ereport(ERROR,
1896  errmsg("could not open temporary file \"%s\": %m",
1897  path)));
1898 
1899  if (file > 0)
1900  {
1901  /* Register it for automatic close. */
1902  RegisterTemporaryFile(file);
1903  }
1904 
1905  return file;
1906 }
static PgChecksumMode mode
Definition: pg_checksums.c:65
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1564
ResourceOwner CurrentResourceOwner
Definition: resowner.c:146
#define PG_BINARY
Definition: c.h:1271
#define ERROR
Definition: elog.h:46
int errcode_for_file_access(void)
Definition: elog.c:721
#define ereport(elevel,...)
Definition: elog.h:157
static void RegisterTemporaryFile(File file)
Definition: fd.c:1536
#define Assert(condition)
Definition: c.h:804
int errmsg(const char *fmt,...)
Definition: elog.c:909
void ResourceOwnerEnlargeFiles(ResourceOwner owner)
Definition: resowner.c:1286
int File
Definition: fd.h:54

◆ pg_fdatasync()

int pg_fdatasync ( int  fd)

Definition at line 447 of file fd.c.

References enableFsync, and fsync.

Referenced by issue_xlog_fsync().

448 {
449  if (enableFsync)
450  {
451 #ifdef HAVE_FDATASYNC
452  return fdatasync(fd);
453 #else
454  return fsync(fd);
455 #endif
456  }
457  else
458  return 0;
459 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define fsync(fd)
Definition: win32_port.h:76
bool enableFsync
Definition: globals.c:122

◆ pg_flush_data()

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

Definition at line 467 of file fd.c.

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

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

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

◆ pg_fsync()

int pg_fsync ( int  fd)

Definition at line 357 of file fd.c.

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

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

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

◆ pg_fsync_no_writethrough()

int pg_fsync_no_writethrough ( int  fd)

Definition at line 412 of file fd.c.

References enableFsync, and fsync.

Referenced by issue_xlog_fsync(), and pg_fsync().

413 {
414  if (enableFsync)
415  return fsync(fd);
416  else
417  return 0;
418 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define fsync(fd)
Definition: win32_port.h:76
bool enableFsync
Definition: globals.c:122

◆ pg_fsync_writethrough()

int pg_fsync_writethrough ( int  fd)

Definition at line 424 of file fd.c.

References enableFsync.

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

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

◆ pg_pwritev_with_retry()

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

Definition at line 3815 of file fd.c.

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

Referenced by XLogFileInitInternal().

3816 {
3817  struct iovec iov_copy[PG_IOV_MAX];
3818  ssize_t sum = 0;
3819  ssize_t part;
3820 
3821  /* We'd better have space to make a copy, in case we need to retry. */
3822  if (iovcnt > PG_IOV_MAX)
3823  {
3824  errno = EINVAL;
3825  return -1;
3826  }
3827 
3828  for (;;)
3829  {
3830  /* Write as much as we can. */
3831  part = pg_pwritev(fd, iov, iovcnt, offset);
3832  if (part < 0)
3833  return -1;
3834 
3835 #ifdef SIMULATE_SHORT_WRITE
3836  part = Min(part, 4096);
3837 #endif
3838 
3839  /* Count our progress. */
3840  sum += part;
3841  offset += part;
3842 
3843  /* Step over iovecs that are done. */
3844  while (iovcnt > 0 && iov->iov_len <= part)
3845  {
3846  part -= iov->iov_len;
3847  ++iov;
3848  --iovcnt;
3849  }
3850 
3851  /* Are they all done? */
3852  if (iovcnt == 0)
3853  {
3854  /* We don't expect the kernel to write more than requested. */
3855  Assert(part == 0);
3856  break;
3857  }
3858 
3859  /*
3860  * Move whatever's left to the front of our mutable copy and adjust
3861  * the leading iovec.
3862  */
3863  Assert(iovcnt > 0);
3864  memmove(iov_copy, iov, sizeof(*iov) * iovcnt);
3865  Assert(iov->iov_len > part);
3866  iov_copy[0].iov_base = (char *) iov_copy[0].iov_base + part;
3867  iov_copy[0].iov_len -= part;
3868  iov = iov_copy;
3869  }
3870 
3871  return sum;
3872 }
size_t iov_len
Definition: pg_iovec.h:27
void * iov_base
Definition: pg_iovec.h:26
#define Min(x, y)
Definition: c.h:986
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ssize_t pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
Definition: pwritev.c:29
#define PG_IOV_MAX
Definition: pg_iovec.h:40
Definition: pg_iovec.h:24
#define Assert(condition)
Definition: c.h:804

◆ pg_truncate()

int pg_truncate ( const char *  path,
off_t  length 
)

Definition at line 640 of file fd.c.

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

Referenced by do_truncate().

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

◆ ReadDir()

◆ ReadDirExtended()

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

Definition at line 2801 of file fd.c.

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

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

2802 {
2803  struct dirent *dent;
2804 
2805  /* Give a generic message for AllocateDir failure, if caller didn't */
2806  if (dir == NULL)
2807  {
2808  ereport(elevel,
2810  errmsg("could not open directory \"%s\": %m",
2811  dirname)));
2812  return NULL;
2813  }
2814 
2815  errno = 0;
2816  if ((dent = readdir(dir)) != NULL)
2817  return dent;
2818 
2819  if (errno)
2820  ereport(elevel,
2822  errmsg("could not read directory \"%s\": %m",
2823  dirname)));
2824  return NULL;
2825 }
Definition: dirent.h:9
int errcode_for_file_access(void)
Definition: elog.c:721
static int elevel
Definition: vacuumlazy.c:401
#define ereport(elevel,...)
Definition: elog.h:157
struct dirent * readdir(DIR *)
Definition: dirent.c:78
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ ReleaseExternalFD()

◆ RemovePgTempFiles()

void RemovePgTempFiles ( void  )

Definition at line 3150 of file fd.c.

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

Referenced by PostmasterMain(), and PostmasterStateMachine().

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

◆ RemovePgTempFilesInDir()

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

Definition at line 3209 of file fd.c.

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

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

3210 {
3211  DIR *temp_dir;
3212  struct dirent *temp_de;
3213  char rm_path[MAXPGPATH * 2];
3214 
3215  temp_dir = AllocateDir(tmpdirname);
3216 
3217  if (temp_dir == NULL && errno == ENOENT && missing_ok)
3218  return;
3219 
3220  while ((temp_de = ReadDirExtended(temp_dir, tmpdirname, LOG)) != NULL)
3221  {
3222  if (strcmp(temp_de->d_name, ".") == 0 ||
3223  strcmp(temp_de->d_name, "..") == 0)
3224  continue;
3225 
3226  snprintf(rm_path, sizeof(rm_path), "%s/%s",
3227  tmpdirname, temp_de->d_name);
3228 
3229  if (unlink_all ||
3230  strncmp(temp_de->d_name,
3232  strlen(PG_TEMP_FILE_PREFIX)) == 0)
3233  {
3234  struct stat statbuf;
3235 
3236  if (lstat(rm_path, &statbuf) < 0)
3237  {
3238  ereport(LOG,
3240  errmsg("could not stat file \"%s\": %m", rm_path)));
3241  continue;
3242  }
3243 
3244  if (S_ISDIR(statbuf.st_mode))
3245  {
3246  /* recursively remove contents, then directory itself */
3247  RemovePgTempFilesInDir(rm_path, false, true);
3248 
3249  if (rmdir(rm_path) < 0)
3250  ereport(LOG,
3252  errmsg("could not remove directory \"%s\": %m",
3253  rm_path)));
3254  }
3255  else
3256  {
3257  if (unlink(rm_path) < 0)
3258  ereport(LOG,
3260  errmsg("could not remove file \"%s\": %m",
3261  rm_path)));
3262  }
3263  }
3264  else
3265  ereport(LOG,
3266  (errmsg("unexpected file found in temporary-files directory: \"%s\"",
3267  rm_path)));
3268  }
3269 
3270  FreeDir(temp_dir);
3271 }
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2801
#define LOG
Definition: elog.h:26
Definition: dirent.h:9
Definition: dirent.c:25
#define PG_TEMP_FILE_PREFIX
Definition: pg_checksums.c:63
#define MAXPGPATH
void RemovePgTempFilesInDir(const char *tmpdirname, bool missing_ok, bool unlink_all)
Definition: fd.c:3209
int errcode_for_file_access(void)
Definition: elog.c:721
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2720
#define ereport(elevel,...)
Definition: elog.h:157
#define S_ISDIR(m)
Definition: win32_port.h:324
#define lstat(path, sb)
Definition: win32_port.h:284
int errmsg(const char *fmt,...)
Definition: elog.c:909
char d_name[MAX_PATH]
Definition: dirent.h:15
#define snprintf
Definition: port.h:217
int FreeDir(DIR *dir)
Definition: fd.c:2838

◆ ReserveExternalFD()

void ReserveExternalFD ( void  )

Definition at line 1210 of file fd.c.

References numExternalFDs, and ReleaseLruFiles().

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

1211 {
1212  /*
1213  * Release VFDs if needed to stay safe. Because we do this before
1214  * incrementing numExternalFDs, the final state will be as desired, i.e.,
1215  * nfile + numAllocatedDescs + numExternalFDs <= max_safe_fds.
1216  */
1217  ReleaseLruFiles();
1218 
1219  numExternalFDs++;
1220 }
static int numExternalFDs
Definition: fd.c:270
static void ReleaseLruFiles(void)
Definition: fd.c:1393

◆ set_max_safe_fds()

void set_max_safe_fds ( void  )

Definition at line 1026 of file fd.c.

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

Referenced by PostmasterMain().

1027 {
1028  int usable_fds;
1029  int already_open;
1030 
1031  /*----------
1032  * We want to set max_safe_fds to
1033  * MIN(usable_fds, max_files_per_process - already_open)
1034  * less the slop factor for files that are opened without consulting
1035  * fd.c. This ensures that we won't exceed either max_files_per_process
1036  * or the experimentally-determined EMFILE limit.
1037  *----------
1038  */
1040  &usable_fds, &already_open);
1041 
1042  max_safe_fds = Min(usable_fds, max_files_per_process - already_open);
1043 
1044  /*
1045  * Take off the FDs reserved for system() etc.
1046  */
1048 
1049  /*
1050  * Make sure we still have enough to get by.
1051  */
1052  if (max_safe_fds < FD_MINFREE)
1053  ereport(FATAL,
1054  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
1055  errmsg("insufficient file descriptors available to start server process"),
1056  errdetail("System allows %d, we need at least %d.",
1059 
1060  elog(DEBUG2, "max_safe_fds = %d, usable_fds = %d, already_open = %d",
1061  max_safe_fds, usable_fds, already_open);
1062 }
static void count_usable_fds(int max_to_probe, int *usable_fds, int *already_open)
Definition: fd.c:942
#define NUM_RESERVED_FDS
Definition: fd.c:128
int max_safe_fds
Definition: fd.c:158
#define Min(x, y)
Definition: c.h:986
int errcode(int sqlerrcode)
Definition: elog.c:698
#define FATAL
Definition: elog.h:49
#define DEBUG2
Definition: elog.h:24
int errdetail(const char *fmt,...)
Definition: elog.c:1042
int max_files_per_process
Definition: fd.c:145
#define ereport(elevel,...)
Definition: elog.h:157
#define FD_MINFREE
Definition: fd.c:137
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232

◆ SetTempTablespaces()

void SetTempTablespaces ( Oid tableSpaces,
int  numSpaces 
)

Definition at line 2926 of file fd.c.

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

Referenced by assign_temp_tablespaces(), and PrepareTempTablespaces().

2927 {
2928  Assert(numSpaces >= 0);
2929  tempTableSpaces = tableSpaces;
2930  numTempTableSpaces = numSpaces;
2931 
2932  /*
2933  * Select a random starting point in the list. This is to minimize
2934  * conflicts between backends that are most likely sharing the same list
2935  * of temp tablespaces. Note that if we create multiple temp files in the
2936  * same transaction, we'll advance circularly through the list --- this
2937  * ensures that large temporary sort files are nicely spread across all
2938  * available tablespaces.
2939  */
2940  if (numSpaces > 1)
2941  nextTempTableSpace = random() % numSpaces;
2942  else
2943  nextTempTableSpace = 0;
2944 }
long random(void)
Definition: random.c:22
static int numTempTableSpaces
Definition: fd.c:285
static int nextTempTableSpace
Definition: fd.c:286
#define Assert(condition)
Definition: c.h:804
static Oid * tempTableSpaces
Definition: fd.c:284

◆ SyncDataDirectory()

void SyncDataDirectory ( void  )

Definition at line 3423 of file fd.c.

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

Referenced by StartupXLOG().

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

◆ TempTablespacePath()

void TempTablespacePath ( char *  path,
Oid  tablespace 
)

Definition at line 1760 of file fd.c.

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

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

1761 {
1762  /*
1763  * Identify the tempfile directory for this tablespace.
1764  *
1765  * If someone tries to specify pg_global, use pg_default instead.
1766  */
1767  if (tablespace == InvalidOid ||
1768  tablespace == DEFAULTTABLESPACE_OID ||
1769  tablespace == GLOBALTABLESPACE_OID)
1770  snprintf(path, MAXPGPATH, "base/%s", PG_TEMP_FILES_DIR);
1771  else
1772  {
1773  /* All other tablespaces are accessed via symlinks */
1774  snprintf(path, MAXPGPATH, "pg_tblspc/%u/%s/%s",
1777  }
1778 }
#define PG_TEMP_FILES_DIR
Definition: pg_checksums.c:62
#define MAXPGPATH
#define TABLESPACE_VERSION_DIRECTORY
Definition: relpath.h:26
char * tablespace
Definition: pgbench.c:226
#define InvalidOid
Definition: postgres_ext.h:36
#define snprintf
Definition: port.h:217

◆ TempTablespacesAreSet()

bool TempTablespacesAreSet ( void  )

Definition at line 2954 of file fd.c.

References numTempTableSpaces.

Referenced by GetTempTablespaces(), and PrepareTempTablespaces().

2955 {
2956  return (numTempTableSpaces >= 0);
2957 }
static int numTempTableSpaces
Definition: fd.c:285

Variable Documentation

◆ data_sync_retry

PGDLLIMPORT bool data_sync_retry

Definition at line 161 of file fd.c.

Referenced by data_sync_elevel().

◆ max_files_per_process

PGDLLIMPORT int max_files_per_process

Definition at line 145 of file fd.c.

Referenced by set_max_safe_fds().

◆ max_safe_fds

◆ recovery_init_sync_method

int recovery_init_sync_method

Definition at line 164 of file fd.c.

Referenced by SyncDataDirectory().