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_TEMP_FILES_DIR   "pgsql_tmp"
 
#define PG_TEMP_FILE_PREFIX   "pgsql_tmp"
 

Typedefs

typedef int File
 

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

Macro Definition Documentation

◆ FILE_POSSIBLY_DELETED

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

Definition at line 69 of file fd.h.

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

◆ PG_TEMP_FILE_PREFIX

#define PG_TEMP_FILE_PREFIX   "pgsql_tmp"

Definition at line 166 of file fd.h.

◆ PG_TEMP_FILES_DIR

#define PG_TEMP_FILES_DIR   "pgsql_tmp"

Definition at line 165 of file fd.h.

Typedef Documentation

◆ File

typedef int File

Definition at line 49 of file fd.h.

Function Documentation

◆ AcquireExternalFD()

bool AcquireExternalFD ( void  )

Definition at line 1045 of file fd.c.

References max_safe_fds, numExternalFDs, and ReserveExternalFD().

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

1046 {
1047  /*
1048  * We don't want more than max_safe_fds / 3 FDs to be consumed for
1049  * "external" FDs.
1050  */
1051  if (numExternalFDs < max_safe_fds / 3)
1052  {
1054  return true;
1055  }
1056  errno = EMFILE;
1057  return false;
1058 }
static int numExternalFDs
Definition: fd.c:258
int max_safe_fds
Definition: fd.c:154
void ReserveExternalFD(void)
Definition: fd.c:1080

◆ AllocateDir()

DIR* AllocateDir ( const char *  dirname)

Definition at line 2581 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(), UpdateLogicalMappings(), and walkdir().

2582 {
2583  DIR *dir;
2584 
2585  DO_DB(elog(LOG, "AllocateDir: Allocated %d (%s)",
2586  numAllocatedDescs, dirname));
2587 
2588  /* Can we allocate another non-virtual FD? */
2589  if (!reserveAllocatedDesc())
2590  ereport(ERROR,
2591  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2592  errmsg("exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"",
2593  maxAllocatedDescs, dirname)));
2594 
2595  /* Close excess kernel FDs. */
2596  ReleaseLruFiles();
2597 
2598 TryAgain:
2599  if ((dir = opendir(dirname)) != NULL)
2600  {
2602 
2603  desc->kind = AllocateDescDir;
2604  desc->desc.dir = dir;
2607  return desc->desc.dir;
2608  }
2609 
2610  if (errno == EMFILE || errno == ENFILE)
2611  {
2612  int save_errno = errno;
2613 
2614  ereport(LOG,
2615  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2616  errmsg("out of file descriptors: %m; release and retry")));
2617  errno = 0;
2618  if (ReleaseLruFile())
2619  goto TryAgain;
2620  errno = save_errno;
2621  }
2622 
2623  return NULL;
2624 }
static AllocateDesc * allocatedDescs
Definition: fd.c:253
DIR * dir
Definition: fd.c:246
#define DO_DB(A)
Definition: fd.c:169
int errcode(int sqlerrcode)
Definition: elog.c:610
static bool reserveAllocatedDesc(void)
Definition: fd.c:2245
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:241
static bool ReleaseLruFile(void)
Definition: fd.c:1241
Definition: dirent.c:25
#define ERROR
Definition: elog.h:43
DIR * opendir(const char *)
Definition: dirent.c:33
static void ReleaseLruFiles(void)
Definition: fd.c:1263
#define ereport(elevel,...)
Definition: elog.h:144
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:707
SubTransactionId create_subid
Definition: fd.c:242
union AllocateDesc::@25 desc
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214
static int maxAllocatedDescs
Definition: fd.c:252
static int numAllocatedDescs
Definition: fd.c:251

◆ AllocateFile()

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

Definition at line 2320 of file fd.c.

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

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

2321 {
2322  FILE *file;
2323 
2324  DO_DB(elog(LOG, "AllocateFile: Allocated %d (%s)",
2326 
2327  /* Can we allocate another non-virtual FD? */
2328  if (!reserveAllocatedDesc())
2329  ereport(ERROR,
2330  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2331  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2332  maxAllocatedDescs, name)));
2333 
2334  /* Close excess kernel FDs. */
2335  ReleaseLruFiles();
2336 
2337 TryAgain:
2338  if ((file = fopen(name, mode)) != NULL)
2339  {
2341 
2342  desc->kind = AllocateDescFile;
2343  desc->desc.file = file;
2346  return desc->desc.file;
2347  }
2348 
2349  if (errno == EMFILE || errno == ENFILE)
2350  {
2351  int save_errno = errno;
2352 
2353  ereport(LOG,
2354  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2355  errmsg("out of file descriptors: %m; release and retry")));
2356  errno = 0;
2357  if (ReleaseLruFile())
2358  goto TryAgain;
2359  errno = save_errno;
2360  }
2361 
2362  return NULL;
2363 }
static PgChecksumMode mode
Definition: pg_checksums.c:61
static AllocateDesc * allocatedDescs
Definition: fd.c:253
#define DO_DB(A)
Definition: fd.c:169
int errcode(int sqlerrcode)
Definition: elog.c:610
static bool reserveAllocatedDesc(void)
Definition: fd.c:2245
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:241
static bool ReleaseLruFile(void)
Definition: fd.c:1241
#define ERROR
Definition: elog.h:43
static void ReleaseLruFiles(void)
Definition: fd.c:1263
FILE * file
Definition: fd.c:245
#define ereport(elevel,...)
Definition: elog.h:144
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:707
SubTransactionId create_subid
Definition: fd.c:242
const char * name
Definition: encode.c:555
union AllocateDesc::@25 desc
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214
static int maxAllocatedDescs
Definition: fd.c:252
static int numAllocatedDescs
Definition: fd.c:251

◆ AtEOSubXact_Files()

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

Definition at line 2863 of file fd.c.

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

2865 {
2866  Index i;
2867 
2868  for (i = 0; i < numAllocatedDescs; i++)
2869  {
2870  if (allocatedDescs[i].create_subid == mySubid)
2871  {
2872  if (isCommit)
2873  allocatedDescs[i].create_subid = parentSubid;
2874  else
2875  {
2876  /* have to recheck the item after FreeDesc (ugly) */
2877  FreeDesc(&allocatedDescs[i--]);
2878  }
2879  }
2880  }
2881 }
static AllocateDesc * allocatedDescs
Definition: fd.c:253
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2480
unsigned int Index
Definition: c.h:475
SubTransactionId create_subid
Definition: fd.c:242
int i
static int numAllocatedDescs
Definition: fd.c:251

◆ AtEOXact_Files()

void AtEOXact_Files ( bool  isCommit)

Definition at line 2896 of file fd.c.

References CleanupTempFiles(), numTempTableSpaces, and tempTableSpaces.

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

2897 {
2898  CleanupTempFiles(isCommit, false);
2899  tempTableSpaces = NULL;
2900  numTempTableSpaces = -1;
2901 }
static int numTempTableSpaces
Definition: fd.c:271
static Oid * tempTableSpaces
Definition: fd.c:270
static void CleanupTempFiles(bool isCommit, bool isProcExit)
Definition: fd.c:2928

◆ BasicOpenFile()

int BasicOpenFile ( const char *  fileName,
int  fileFlags 
)

Definition at line 983 of file fd.c.

References BasicOpenFilePerm(), and pg_file_create_mode.

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

984 {
985  return BasicOpenFilePerm(fileName, fileFlags, pg_file_create_mode);
986 }
int pg_file_create_mode
Definition: file_perm.c:19
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1005

◆ BasicOpenFilePerm()

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

Definition at line 1005 of file fd.c.

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

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

1006 {
1007  int fd;
1008 
1009 tryAgain:
1010  fd = open(fileName, fileFlags, fileMode);
1011 
1012  if (fd >= 0)
1013  return fd; /* success! */
1014 
1015  if (errno == EMFILE || errno == ENFILE)
1016  {
1017  int save_errno = errno;
1018 
1019  ereport(LOG,
1020  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
1021  errmsg("out of file descriptors: %m; release and retry")));
1022  errno = 0;
1023  if (ReleaseLruFile())
1024  goto tryAgain;
1025  errno = save_errno;
1026  }
1027 
1028  return -1; /* failure */
1029 }
int errcode(int sqlerrcode)
Definition: elog.c:610
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static bool ReleaseLruFile(void)
Definition: fd.c:1241
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ closeAllVfds()

void closeAllVfds ( void  )

Definition at line 2758 of file fd.c.

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

Referenced by standard_ProcessUtility().

2759 {
2760  Index i;
2761 
2762  if (SizeVfdCache > 0)
2763  {
2764  Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
2765  for (i = 1; i < SizeVfdCache; i++)
2766  {
2767  if (!FileIsNotOpen(i))
2768  LruDelete(i);
2769  }
2770  }
2771 }
static Size SizeVfdCache
Definition: fd.c:206
static void LruDelete(File file)
Definition: fd.c:1146
#define FileIsNotOpen(file)
Definition: fd.c:178
unsigned int Index
Definition: c.h:475
#define Assert(condition)
Definition: c.h:738
int i

◆ ClosePipeStream()

int ClosePipeStream ( FILE *  file)

Definition at line 2729 of file fd.c.

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

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

2730 {
2731  int i;
2732 
2733  DO_DB(elog(LOG, "ClosePipeStream: Allocated %d", numAllocatedDescs));
2734 
2735  /* Remove file from list of allocated files, if it's present */
2736  for (i = numAllocatedDescs; --i >= 0;)
2737  {
2738  AllocateDesc *desc = &allocatedDescs[i];
2739 
2740  if (desc->kind == AllocateDescPipe && desc->desc.file == file)
2741  return FreeDesc(desc);
2742  }
2743 
2744  /* Only get here if someone passes us a file not in allocatedDescs */
2745  elog(WARNING, "file passed to ClosePipeStream was not obtained from OpenPipeStream");
2746 
2747  return pclose(file);
2748 }
static AllocateDesc * allocatedDescs
Definition: fd.c:253
#define DO_DB(A)
Definition: fd.c:169
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:241
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2480
#define WARNING
Definition: elog.h:40
FILE * file
Definition: fd.c:245
union AllocateDesc::@25 desc
#define elog(elevel,...)
Definition: elog.h:214
int i
static int numAllocatedDescs
Definition: fd.c:251

◆ CloseTransientFile()

int CloseTransientFile ( int  fd)

Definition at line 2547 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(), mdunlinkfork(), qtext_load_file(), qtext_store(), ReadTwoPhaseFile(), RecreateTwoPhaseFile(), ReorderBufferSerializeChange(), ReorderBufferSerializeTXN(), RestoreSlotFromDisk(), SaveSlotToPath(), SendTimeLineHistory(), SimpleLruDoesPhysicalPageExist(), SimpleLruFlush(), SlruInternalWritePage(), SlruPhysicalReadPage(), SlruPhysicalWritePage(), SnapBuildRestore(), SnapBuildSerialize(), StartupReplicationOrigin(), walkdir(), write_relmap_file(), writeTimeLineHistory(), writeTimeLineHistoryFile(), and XLogFileCopy().

2548 {
2549  int i;
2550 
2551  DO_DB(elog(LOG, "CloseTransientFile: Allocated %d", numAllocatedDescs));
2552 
2553  /* Remove fd from list of allocated files, if it's present */
2554  for (i = numAllocatedDescs; --i >= 0;)
2555  {
2556  AllocateDesc *desc = &allocatedDescs[i];
2557 
2558  if (desc->kind == AllocateDescRawFD && desc->desc.fd == fd)
2559  return FreeDesc(desc);
2560  }
2561 
2562  /* Only get here if someone passes us a file not in allocatedDescs */
2563  elog(WARNING, "fd passed to CloseTransientFile was not obtained from OpenTransientFile");
2564 
2565  return close(fd);
2566 }
static AllocateDesc * allocatedDescs
Definition: fd.c:253
#define DO_DB(A)
Definition: fd.c:169
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:241
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2480
#define WARNING
Definition: elog.h:40
int fd
Definition: fd.c:247
union AllocateDesc::@25 desc
#define elog(elevel,...)
Definition: elog.h:214
int i
#define close(a)
Definition: win32.h:12
static int numAllocatedDescs
Definition: fd.c:251

◆ data_sync_elevel()

◆ durable_rename()

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

Definition at line 656 of file fd.c.

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

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

657 {
658  int fd;
659 
660  /*
661  * First fsync the old and target path (if it exists), to ensure that they
662  * are properly persistent on disk. Syncing the target file is not
663  * strictly necessary, but it makes it easier to reason about crashes;
664  * because it's then guaranteed that either source or target file exists
665  * after a crash.
666  */
667  if (fsync_fname_ext(oldfile, false, false, elevel) != 0)
668  return -1;
669 
670  fd = OpenTransientFile(newfile, PG_BINARY | O_RDWR);
671  if (fd < 0)
672  {
673  if (errno != ENOENT)
674  {
675  ereport(elevel,
677  errmsg("could not open file \"%s\": %m", newfile)));
678  return -1;
679  }
680  }
681  else
682  {
683  if (pg_fsync(fd) != 0)
684  {
685  int save_errno;
686 
687  /* close file upon error, might not be in transaction context */
688  save_errno = errno;
689  CloseTransientFile(fd);
690  errno = save_errno;
691 
692  ereport(elevel,
694  errmsg("could not fsync file \"%s\": %m", newfile)));
695  return -1;
696  }
697 
698  if (CloseTransientFile(fd) != 0)
699  {
700  ereport(elevel,
702  errmsg("could not close file \"%s\": %m", newfile)));
703  return -1;
704  }
705  }
706 
707  /* Time to do the real deal... */
708  if (rename(oldfile, newfile) < 0)
709  {
710  ereport(elevel,
712  errmsg("could not rename file \"%s\" to \"%s\": %m",
713  oldfile, newfile)));
714  return -1;
715  }
716 
717  /*
718  * To guarantee renaming the file is persistent, fsync the file with its
719  * new name, and its containing directory.
720  */
721  if (fsync_fname_ext(newfile, false, false, elevel) != 0)
722  return -1;
723 
724  if (fsync_parent_path(newfile, elevel) != 0)
725  return -1;
726 
727  return 0;
728 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1234
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2370
int errcode_for_file_access(void)
Definition: elog.c:633
int CloseTransientFile(int fd)
Definition: fd.c:2547
static int elevel
Definition: vacuumlazy.c:323
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824
int pg_fsync(int fd)
Definition: fd.c:343
int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3458
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3534

◆ durable_rename_excl()

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

Definition at line 783 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().

784 {
785  /*
786  * Ensure that, if we crash directly after the rename/link, a file with
787  * valid contents is moved into place.
788  */
789  if (fsync_fname_ext(oldfile, false, false, elevel) != 0)
790  return -1;
791 
792  if (link(oldfile, newfile) < 0)
793  {
794  ereport(elevel,
796  errmsg("could not link file \"%s\" to \"%s\": %m",
797  oldfile, newfile)));
798  return -1;
799  }
800  unlink(oldfile);
801 
802  /*
803  * Make change persistent in case of an OS crash, both the new entry and
804  * its parent directory need to be flushed.
805  */
806  if (fsync_fname_ext(newfile, false, false, elevel) != 0)
807  return -1;
808 
809  /* Same for parent directory */
810  if (fsync_parent_path(newfile, elevel) != 0)
811  return -1;
812 
813  return 0;
814 }
int errcode_for_file_access(void)
Definition: elog.c:633
static int elevel
Definition: vacuumlazy.c:323
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824
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:3458
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3534

◆ durable_unlink()

int durable_unlink ( const char *  fname,
int  loglevel 
)

Definition at line 746 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().

747 {
748  if (unlink(fname) < 0)
749  {
750  ereport(elevel,
752  errmsg("could not remove file \"%s\": %m",
753  fname)));
754  return -1;
755  }
756 
757  /*
758  * To guarantee that the removal of the file is persistent, fsync its
759  * parent directory.
760  */
761  if (fsync_parent_path(fname, elevel) != 0)
762  return -1;
763 
764  return 0;
765 }
int errcode_for_file_access(void)
Definition: elog.c:633
static int elevel
Definition: vacuumlazy.c:323
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3534

◆ FileClose()

void FileClose ( File  file)

Definition at line 1824 of file fd.c.

References Assert, close, data_sync_elevel(), Delete(), DO_DB, elog, 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, temporary_files_size, and VFD_CLOSED.

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

1825 {
1826  Vfd *vfdP;
1827 
1828  Assert(FileIsValid(file));
1829 
1830  DO_DB(elog(LOG, "FileClose: %d (%s)",
1831  file, VfdCache[file].fileName));
1832 
1833  vfdP = &VfdCache[file];
1834 
1835  if (!FileIsNotOpen(file))
1836  {
1837  /* close the file */
1838  if (close(vfdP->fd) != 0)
1839  {
1840  /*
1841  * We may need to panic on failure to close non-temporary files;
1842  * see LruDelete.
1843  */
1845  "could not close file \"%s\": %m", vfdP->fileName);
1846  }
1847 
1848  --nfile;
1849  vfdP->fd = VFD_CLOSED;
1850 
1851  /* remove the file from the lru ring */
1852  Delete(file);
1853  }
1854 
1855  if (vfdP->fdstate & FD_TEMP_FILE_LIMIT)
1856  {
1857  /* Subtract its size from current usage (do first in case of error) */
1858  temporary_files_size -= vfdP->fileSize;
1859  vfdP->fileSize = 0;
1860  }
1861 
1862  /*
1863  * Delete the file if it was temporary, and make a log entry if wanted
1864  */
1865  if (vfdP->fdstate & FD_DELETE_AT_CLOSE)
1866  {
1867  struct stat filestats;
1868  int stat_errno;
1869 
1870  /*
1871  * If we get an error, as could happen within the ereport/elog calls,
1872  * we'll come right back here during transaction abort. Reset the
1873  * flag to ensure that we can't get into an infinite loop. This code
1874  * is arranged to ensure that the worst-case consequence is failing to
1875  * emit log message(s), not failing to attempt the unlink.
1876  */
1877  vfdP->fdstate &= ~FD_DELETE_AT_CLOSE;
1878 
1879 
1880  /* first try the stat() */
1881  if (stat(vfdP->fileName, &filestats))
1882  stat_errno = errno;
1883  else
1884  stat_errno = 0;
1885 
1886  /* in any case do the unlink */
1887  if (unlink(vfdP->fileName))
1888  elog(LOG, "could not unlink file \"%s\": %m", vfdP->fileName);
1889 
1890  /* and last report the stat results */
1891  if (stat_errno == 0)
1892  ReportTemporaryFileUsage(vfdP->fileName, filestats.st_size);
1893  else
1894  {
1895  errno = stat_errno;
1896  elog(LOG, "could not stat file \"%s\": %m", vfdP->fileName);
1897  }
1898  }
1899 
1900  /* Unregister it from the resource owner */
1901  if (vfdP->resowner)
1902  ResourceOwnerForgetFile(vfdP->resowner, file);
1903 
1904  /*
1905  * Return the Vfd slot to the free list
1906  */
1907  FreeVfd(file);
1908 }
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:183
#define DO_DB(A)
Definition: fd.c:169
#define FD_DELETE_AT_CLOSE
Definition: fd.c:181
static Vfd * VfdCache
Definition: fd.c:205
static void Delete(File file)
Definition: fd.c:1127
#define LOG
Definition: elog.h:26
char * fileName
Definition: fd.c:194
static int nfile
Definition: fd.c:211
unsigned short fdstate
Definition: fd.c:188
Definition: fd.c:185
off_t fileSize
Definition: fd.c:193
int fd
Definition: fd.c:187
ResourceOwner resowner
Definition: fd.c:189
static void ReportTemporaryFileUsage(const char *path, off_t size)
Definition: fd.c:1387
#define stat(a, b)
Definition: win32_port.h:255
#define FileIsNotOpen(file)
Definition: fd.c:178
int data_sync_elevel(int elevel)
Definition: fd.c:3597
#define FileIsValid(file)
Definition: fd.c:175
#define VFD_CLOSED
Definition: fd.c:173
static uint64 temporary_files_size
Definition: fd.c:225
#define Assert(condition)
Definition: c.h:738
#define elog(elevel,...)
Definition: elog.h:214
static void FreeVfd(File file)
Definition: fd.c:1331
#define close(a)
Definition: win32.h:12
void ResourceOwnerForgetFile(ResourceOwner owner, File file)
Definition: resowner.c:1277

◆ FileGetRawDesc()

int FileGetRawDesc ( File  file)

Definition at line 2214 of file fd.c.

References Assert, vfd::fd, and FileIsValid.

2215 {
2216  Assert(FileIsValid(file));
2217  return VfdCache[file].fd;
2218 }
static Vfd * VfdCache
Definition: fd.c:205
int fd
Definition: fd.c:187
#define FileIsValid(file)
Definition: fd.c:175
#define Assert(condition)
Definition: c.h:738

◆ FileGetRawFlags()

int FileGetRawFlags ( File  file)

Definition at line 2224 of file fd.c.

References Assert, vfd::fileFlags, and FileIsValid.

2225 {
2226  Assert(FileIsValid(file));
2227  return VfdCache[file].fileFlags;
2228 }
static Vfd * VfdCache
Definition: fd.c:205
#define FileIsValid(file)
Definition: fd.c:175
#define Assert(condition)
Definition: c.h:738
int fileFlags
Definition: fd.c:196

◆ FileGetRawMode()

mode_t FileGetRawMode ( File  file)

Definition at line 2234 of file fd.c.

References Assert, FileIsValid, and vfd::fileMode.

2235 {
2236  Assert(FileIsValid(file));
2237  return VfdCache[file].fileMode;
2238 }
static Vfd * VfdCache
Definition: fd.c:205
mode_t fileMode
Definition: fd.c:197
#define FileIsValid(file)
Definition: fd.c:175
#define Assert(condition)
Definition: c.h:738

◆ FilePathName()

char* FilePathName ( File  file)

Definition at line 2198 of file fd.c.

References Assert, FileIsValid, and vfd::fileName.

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

2199 {
2200  Assert(FileIsValid(file));
2201 
2202  return VfdCache[file].fileName;
2203 }
static Vfd * VfdCache
Definition: fd.c:205
char * fileName
Definition: fd.c:194
#define FileIsValid(file)
Definition: fd.c:175
#define Assert(condition)
Definition: c.h:738

◆ FilePrefetch()

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

Definition at line 1920 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().

1921 {
1922 #if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
1923  int returnCode;
1924 
1925  Assert(FileIsValid(file));
1926 
1927  DO_DB(elog(LOG, "FilePrefetch: %d (%s) " INT64_FORMAT " %d",
1928  file, VfdCache[file].fileName,
1929  (int64) offset, amount));
1930 
1931  returnCode = FileAccess(file);
1932  if (returnCode < 0)
1933  return returnCode;
1934 
1935  pgstat_report_wait_start(wait_event_info);
1936  returnCode = posix_fadvise(VfdCache[file].fd, offset, amount,
1937  POSIX_FADV_WILLNEED);
1939 
1940  return returnCode;
1941 #else
1942  Assert(FileIsValid(file));
1943  return 0;
1944 #endif
1945 }
#define DO_DB(A)
Definition: fd.c:169
static Vfd * VfdCache
Definition: fd.c:205
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1386
#define FileIsValid(file)
Definition: fd.c:175
static int FileAccess(File file)
Definition: fd.c:1351
#define Assert(condition)
Definition: c.h:738
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1362
#define INT64_FORMAT
Definition: c.h:409
#define elog(elevel,...)
Definition: elog.h:214

◆ FileRead()

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

Definition at line 1971 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().

1973 {
1974  int returnCode;
1975  Vfd *vfdP;
1976 
1977  Assert(FileIsValid(file));
1978 
1979  DO_DB(elog(LOG, "FileRead: %d (%s) " INT64_FORMAT " %d %p",
1980  file, VfdCache[file].fileName,
1981  (int64) offset,
1982  amount, buffer));
1983 
1984  returnCode = FileAccess(file);
1985  if (returnCode < 0)
1986  return returnCode;
1987 
1988  vfdP = &VfdCache[file];
1989 
1990 retry:
1991  pgstat_report_wait_start(wait_event_info);
1992  returnCode = pg_pread(vfdP->fd, buffer, amount, offset);
1994 
1995  if (returnCode < 0)
1996  {
1997  /*
1998  * Windows may run out of kernel buffers and return "Insufficient
1999  * system resources" error. Wait a bit and retry to solve it.
2000  *
2001  * It is rumored that EINTR is also possible on some Unix filesystems,
2002  * in which case immediate retry is indicated.
2003  */
2004 #ifdef WIN32
2005  DWORD error = GetLastError();
2006 
2007  switch (error)
2008  {
2009  case ERROR_NO_SYSTEM_RESOURCES:
2010  pg_usleep(1000L);
2011  errno = EINTR;
2012  break;
2013  default:
2014  _dosmaperr(error);
2015  break;
2016  }
2017 #endif
2018  /* OK to retry if interrupted */
2019  if (errno == EINTR)
2020  goto retry;
2021  }
2022 
2023  return returnCode;
2024 }
static void error(void)
Definition: sql-dyntest.c:147
#define DO_DB(A)
Definition: fd.c:169
void _dosmaperr(unsigned long)
Definition: win32error.c:171
static Vfd * VfdCache
Definition: fd.c:205
#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
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1386
Definition: fd.c:185
int fd
Definition: fd.c:187
#define FileIsValid(file)
Definition: fd.c:175
static int FileAccess(File file)
Definition: fd.c:1351
#define Assert(condition)
Definition: c.h:738
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1362
#define INT64_FORMAT
Definition: c.h:409
#define elog(elevel,...)
Definition: elog.h:214
#define EINTR
Definition: win32_port.h:323

◆ FileSize()

off_t FileSize ( File  file)

Definition at line 2146 of file fd.c.

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

Referenced by _mdnblocks(), and BufFileSize().

2147 {
2148  Assert(FileIsValid(file));
2149 
2150  DO_DB(elog(LOG, "FileSize %d (%s)",
2151  file, VfdCache[file].fileName));
2152 
2153  if (FileIsNotOpen(file))
2154  {
2155  if (FileAccess(file) < 0)
2156  return (off_t) -1;
2157  }
2158 
2159  return lseek(VfdCache[file].fd, 0, SEEK_END);
2160 }
#define DO_DB(A)
Definition: fd.c:169
static Vfd * VfdCache
Definition: fd.c:205
#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:178
#define FileIsValid(file)
Definition: fd.c:175
static int FileAccess(File file)
Definition: fd.c:1351
#define Assert(condition)
Definition: c.h:738
#define elog(elevel,...)
Definition: elog.h:214

◆ FileSync()

int FileSync ( File  file,
uint32  wait_event_info 
)

Definition at line 2125 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().

2126 {
2127  int returnCode;
2128 
2129  Assert(FileIsValid(file));
2130 
2131  DO_DB(elog(LOG, "FileSync: %d (%s)",
2132  file, VfdCache[file].fileName));
2133 
2134  returnCode = FileAccess(file);
2135  if (returnCode < 0)
2136  return returnCode;
2137 
2138  pgstat_report_wait_start(wait_event_info);
2139  returnCode = pg_fsync(VfdCache[file].fd);
2141 
2142  return returnCode;
2143 }
#define DO_DB(A)
Definition: fd.c:169
static Vfd * VfdCache
Definition: fd.c:205
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1386
#define FileIsValid(file)
Definition: fd.c:175
static int FileAccess(File file)
Definition: fd.c:1351
#define Assert(condition)
Definition: c.h:738
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1362
#define elog(elevel,...)
Definition: elog.h:214
int pg_fsync(int fd)
Definition: fd.c:343

◆ FileTruncate()

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

Definition at line 2163 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 mdtruncate().

2164 {
2165  int returnCode;
2166 
2167  Assert(FileIsValid(file));
2168 
2169  DO_DB(elog(LOG, "FileTruncate %d (%s)",
2170  file, VfdCache[file].fileName));
2171 
2172  returnCode = FileAccess(file);
2173  if (returnCode < 0)
2174  return returnCode;
2175 
2176  pgstat_report_wait_start(wait_event_info);
2177  returnCode = ftruncate(VfdCache[file].fd, offset);
2179 
2180  if (returnCode == 0 && VfdCache[file].fileSize > offset)
2181  {
2182  /* adjust our state for truncation of a temp file */
2183  Assert(VfdCache[file].fdstate & FD_TEMP_FILE_LIMIT);
2184  temporary_files_size -= VfdCache[file].fileSize - offset;
2185  VfdCache[file].fileSize = offset;
2186  }
2187 
2188  return returnCode;
2189 }
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:183
#define DO_DB(A)
Definition: fd.c:169
static Vfd * VfdCache
Definition: fd.c:205
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1386
off_t fileSize
Definition: fd.c:193
#define FileIsValid(file)
Definition: fd.c:175
static uint64 temporary_files_size
Definition: fd.c:225
static int FileAccess(File file)
Definition: fd.c:1351
#define Assert(condition)
Definition: c.h:738
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1362
#define elog(elevel,...)
Definition: elog.h:214
#define ftruncate(a, b)
Definition: win32_port.h:59

◆ FileWrite()

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

Definition at line 2027 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().

2029 {
2030  int returnCode;
2031  Vfd *vfdP;
2032 
2033  Assert(FileIsValid(file));
2034 
2035  DO_DB(elog(LOG, "FileWrite: %d (%s) " INT64_FORMAT " %d %p",
2036  file, VfdCache[file].fileName,
2037  (int64) offset,
2038  amount, buffer));
2039 
2040  returnCode = FileAccess(file);
2041  if (returnCode < 0)
2042  return returnCode;
2043 
2044  vfdP = &VfdCache[file];
2045 
2046  /*
2047  * If enforcing temp_file_limit and it's a temp file, check to see if the
2048  * write would overrun temp_file_limit, and throw error if so. Note: it's
2049  * really a modularity violation to throw error here; we should set errno
2050  * and return -1. However, there's no way to report a suitable error
2051  * message if we do that. All current callers would just throw error
2052  * immediately anyway, so this is safe at present.
2053  */
2054  if (temp_file_limit >= 0 && (vfdP->fdstate & FD_TEMP_FILE_LIMIT))
2055  {
2056  off_t past_write = offset + amount;
2057 
2058  if (past_write > vfdP->fileSize)
2059  {
2060  uint64 newTotal = temporary_files_size;
2061 
2062  newTotal += past_write - vfdP->fileSize;
2063  if (newTotal > (uint64) temp_file_limit * (uint64) 1024)
2064  ereport(ERROR,
2065  (errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED),
2066  errmsg("temporary file size exceeds temp_file_limit (%dkB)",
2067  temp_file_limit)));
2068  }
2069  }
2070 
2071 retry:
2072  errno = 0;
2073  pgstat_report_wait_start(wait_event_info);
2074  returnCode = pg_pwrite(VfdCache[file].fd, buffer, amount, offset);
2076 
2077  /* if write didn't set errno, assume problem is no disk space */
2078  if (returnCode != amount && errno == 0)
2079  errno = ENOSPC;
2080 
2081  if (returnCode >= 0)
2082  {
2083  /*
2084  * Maintain fileSize and temporary_files_size if it's a temp file.
2085  */
2086  if (vfdP->fdstate & FD_TEMP_FILE_LIMIT)
2087  {
2088  off_t past_write = offset + amount;
2089 
2090  if (past_write > vfdP->fileSize)
2091  {
2092  temporary_files_size += past_write - vfdP->fileSize;
2093  vfdP->fileSize = past_write;
2094  }
2095  }
2096  }
2097  else
2098  {
2099  /*
2100  * See comments in FileRead()
2101  */
2102 #ifdef WIN32
2103  DWORD error = GetLastError();
2104 
2105  switch (error)
2106  {
2107  case ERROR_NO_SYSTEM_RESOURCES:
2108  pg_usleep(1000L);
2109  errno = EINTR;
2110  break;
2111  default:
2112  _dosmaperr(error);
2113  break;
2114  }
2115 #endif
2116  /* OK to retry if interrupted */
2117  if (errno == EINTR)
2118  goto retry;
2119  }
2120 
2121  return returnCode;
2122 }
static void error(void)
Definition: sql-dyntest.c:147
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:183
#define DO_DB(A)
Definition: fd.c:169
void _dosmaperr(unsigned long)
Definition: win32error.c:171
static Vfd * VfdCache
Definition: fd.c:205
int errcode(int sqlerrcode)
Definition: elog.c:610
#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:43
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1386
unsigned short fdstate
Definition: fd.c:188
Definition: fd.c:185
off_t fileSize
Definition: fd.c:193
#define FileIsValid(file)
Definition: fd.c:175
static uint64 temporary_files_size
Definition: fd.c:225
#define ereport(elevel,...)
Definition: elog.h:144
static int FileAccess(File file)
Definition: fd.c:1351
#define Assert(condition)
Definition: c.h:738
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1362
#define INT64_FORMAT
Definition: c.h:409
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214
#define EINTR
Definition: win32_port.h:323
int temp_file_limit
Definition: guc.c:556

◆ FileWriteback()

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

Definition at line 1948 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().

1949 {
1950  int returnCode;
1951 
1952  Assert(FileIsValid(file));
1953 
1954  DO_DB(elog(LOG, "FileWriteback: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
1955  file, VfdCache[file].fileName,
1956  (int64) offset, (int64) nbytes));
1957 
1958  if (nbytes <= 0)
1959  return;
1960 
1961  returnCode = FileAccess(file);
1962  if (returnCode < 0)
1963  return;
1964 
1965  pgstat_report_wait_start(wait_event_info);
1966  pg_flush_data(VfdCache[file].fd, offset, nbytes);
1968 }
#define DO_DB(A)
Definition: fd.c:169
static Vfd * VfdCache
Definition: fd.c:205
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1386
void pg_flush_data(int fd, off_t offset, off_t nbytes)
Definition: fd.c:453
#define FileIsValid(file)
Definition: fd.c:175
static int FileAccess(File file)
Definition: fd.c:1351
#define Assert(condition)
Definition: c.h:738
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1362
#define INT64_FORMAT
Definition: c.h:409
#define elog(elevel,...)
Definition: elog.h:214

◆ FreeDir()

int FreeDir ( DIR dir)

Definition at line 2699 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(), UpdateLogicalMappings(), and walkdir().

2700 {
2701  int i;
2702 
2703  /* Nothing to do if AllocateDir failed */
2704  if (dir == NULL)
2705  return 0;
2706 
2707  DO_DB(elog(LOG, "FreeDir: Allocated %d", numAllocatedDescs));
2708 
2709  /* Remove dir from list of allocated dirs, if it's present */
2710  for (i = numAllocatedDescs; --i >= 0;)
2711  {
2712  AllocateDesc *desc = &allocatedDescs[i];
2713 
2714  if (desc->kind == AllocateDescDir && desc->desc.dir == dir)
2715  return FreeDesc(desc);
2716  }
2717 
2718  /* Only get here if someone passes us a dir not in allocatedDescs */
2719  elog(WARNING, "dir passed to FreeDir was not obtained from AllocateDir");
2720 
2721  return closedir(dir);
2722 }
static AllocateDesc * allocatedDescs
Definition: fd.c:253
DIR * dir
Definition: fd.c:246
#define DO_DB(A)
Definition: fd.c:169
int closedir(DIR *)
Definition: dirent.c:113
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:241
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2480
#define WARNING
Definition: elog.h:40
union AllocateDesc::@25 desc
#define elog(elevel,...)
Definition: elog.h:214
int i
static int numAllocatedDescs
Definition: fd.c:251

◆ FreeFile()

int FreeFile ( FILE *  file)

Definition at line 2519 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(), entry_reset(), existsTimeLineHistory(), ExportSnapshot(), fill_hba_view(), gc_qtexts(), ImportSnapshot(), load_dh_file(), load_hba(), load_ident(), load_relcache_init_file(), parse_extension_control_file(), ParseTzFile(), perform_base_backup(), pg_backup_start_time(), pg_current_logfile(), pg_file_write_internal(), pg_promote(), PGSharedMemoryAttach(), pgss_shmem_shutdown(), pgss_shmem_startup(), pgstat_read_db_statsfile(), pgstat_read_db_statsfile_timestamp(), pgstat_read_statsfiles(), pgstat_write_db_statsfile(), pgstat_write_statsfiles(), PostmasterMarkPIDForWorkerNotify(), read_backup_label(), read_binary_file(), read_tablespace_map(), read_whole_file(), readTimeLineHistory(), sendFile(), tokenize_inc_file(), tsearch_readline_end(), ValidatePgVersion(), write_relcache_init_file(), XLogArchiveForceDone(), and XLogArchiveNotify().

2520 {
2521  int i;
2522 
2523  DO_DB(elog(LOG, "FreeFile: Allocated %d", numAllocatedDescs));
2524 
2525  /* Remove file from list of allocated files, if it's present */
2526  for (i = numAllocatedDescs; --i >= 0;)
2527  {
2528  AllocateDesc *desc = &allocatedDescs[i];
2529 
2530  if (desc->kind == AllocateDescFile && desc->desc.file == file)
2531  return FreeDesc(desc);
2532  }
2533 
2534  /* Only get here if someone passes us a file not in allocatedDescs */
2535  elog(WARNING, "file passed to FreeFile was not obtained from AllocateFile");
2536 
2537  return fclose(file);
2538 }
static AllocateDesc * allocatedDescs
Definition: fd.c:253
#define DO_DB(A)
Definition: fd.c:169
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:241
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2480
#define WARNING
Definition: elog.h:40
FILE * file
Definition: fd.c:245
union AllocateDesc::@25 desc
#define elog(elevel,...)
Definition: elog.h:214
int i
static int numAllocatedDescs
Definition: fd.c:251

◆ fsync_fname()

◆ fsync_fname_ext()

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

Definition at line 3458 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().

3459 {
3460  int fd;
3461  int flags;
3462  int returncode;
3463 
3464  /*
3465  * Some OSs require directories to be opened read-only whereas other
3466  * systems don't allow us to fsync files opened read-only; so we need both
3467  * cases here. Using O_RDWR will cause us to fail to fsync files that are
3468  * not writable by our userid, but we assume that's OK.
3469  */
3470  flags = PG_BINARY;
3471  if (!isdir)
3472  flags |= O_RDWR;
3473  else
3474  flags |= O_RDONLY;
3475 
3476  fd = OpenTransientFile(fname, flags);
3477 
3478  /*
3479  * Some OSs don't allow us to open directories at all (Windows returns
3480  * EACCES), just ignore the error in that case. If desired also silently
3481  * ignoring errors about unreadable files. Log others.
3482  */
3483  if (fd < 0 && isdir && (errno == EISDIR || errno == EACCES))
3484  return 0;
3485  else if (fd < 0 && ignore_perm && errno == EACCES)
3486  return 0;
3487  else if (fd < 0)
3488  {
3489  ereport(elevel,
3491  errmsg("could not open file \"%s\": %m", fname)));
3492  return -1;
3493  }
3494 
3495  returncode = pg_fsync(fd);
3496 
3497  /*
3498  * Some OSes don't allow us to fsync directories at all, so we can ignore
3499  * those errors. Anything else needs to be logged.
3500  */
3501  if (returncode != 0 && !(isdir && (errno == EBADF || errno == EINVAL)))
3502  {
3503  int save_errno;
3504 
3505  /* close file upon error, might not be in transaction context */
3506  save_errno = errno;
3507  (void) CloseTransientFile(fd);
3508  errno = save_errno;
3509 
3510  ereport(elevel,
3512  errmsg("could not fsync file \"%s\": %m", fname)));
3513  return -1;
3514  }
3515 
3516  if (CloseTransientFile(fd) != 0)
3517  {
3518  ereport(elevel,
3520  errmsg("could not close file \"%s\": %m", fname)));
3521  return -1;
3522  }
3523 
3524  return 0;
3525 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1234
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2370
int errcode_for_file_access(void)
Definition: elog.c:633
int CloseTransientFile(int fd)
Definition: fd.c:2547
static int elevel
Definition: vacuumlazy.c:323
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824
int pg_fsync(int fd)
Definition: fd.c:343

◆ GetNextTempTableSpace()

Oid GetNextTempTableSpace ( void  )

Definition at line 2842 of file fd.c.

References InvalidOid, nextTempTableSpace, numTempTableSpaces, and tempTableSpaces.

Referenced by GetDefaultTablespace(), and OpenTemporaryFile().

2843 {
2844  if (numTempTableSpaces > 0)
2845  {
2846  /* Advance nextTempTableSpace counter with wraparound */
2848  nextTempTableSpace = 0;
2850  }
2851  return InvalidOid;
2852 }
static int numTempTableSpaces
Definition: fd.c:271
static int nextTempTableSpace
Definition: fd.c:272
#define InvalidOid
Definition: postgres_ext.h:36
static Oid * tempTableSpaces
Definition: fd.c:270

◆ GetTempTablespaces()

int GetTempTablespaces ( Oid tableSpaces,
int  numSpaces 
)

Definition at line 2824 of file fd.c.

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

Referenced by SharedFileSetInit().

2825 {
2826  int i;
2827 
2829  for (i = 0; i < numTempTableSpaces && i < numSpaces; ++i)
2830  tableSpaces[i] = tempTableSpaces[i];
2831 
2832  return i;
2833 }
static int numTempTableSpaces
Definition: fd.c:271
bool TempTablespacesAreSet(void)
Definition: fd.c:2812
#define Assert(condition)
Definition: c.h:738
static Oid * tempTableSpaces
Definition: fd.c:270
int i

◆ InitFileAccess()

void InitFileAccess ( void  )

Definition at line 823 of file fd.c.

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

Referenced by BaseInit().

824 {
825  Assert(SizeVfdCache == 0); /* call me only once */
826 
827  /* initialize cache header entry */
828  VfdCache = (Vfd *) malloc(sizeof(Vfd));
829  if (VfdCache == NULL)
830  ereport(FATAL,
831  (errcode(ERRCODE_OUT_OF_MEMORY),
832  errmsg("out of memory")));
833 
834  MemSet((char *) &(VfdCache[0]), 0, sizeof(Vfd));
836 
837  SizeVfdCache = 1;
838 
839  /* register proc-exit hook to ensure temp files are dropped at exit */
841 }
static void AtProcExit_Files(int code, Datum arg)
Definition: fd.c:2910
static Size SizeVfdCache
Definition: fd.c:206
void on_proc_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:305
static Vfd * VfdCache
Definition: fd.c:205
int errcode(int sqlerrcode)
Definition: elog.c:610
#define MemSet(start, val, len)
Definition: c.h:971
#define malloc(a)
Definition: header.h:50
#define FATAL
Definition: elog.h:52
Definition: fd.c:185
int fd
Definition: fd.c:187
#define VFD_CLOSED
Definition: fd.c:173
#define ereport(elevel,...)
Definition: elog.h:144
#define Assert(condition)
Definition: c.h:738
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ looks_like_temp_rel_name()

bool looks_like_temp_rel_name ( const char *  name)

Definition at line 3179 of file fd.c.

References forkname_chars().

Referenced by RemovePgTempRelationFilesInDbspace(), and sendDir().

3180 {
3181  int pos;
3182  int savepos;
3183 
3184  /* Must start with "t". */
3185  if (name[0] != 't')
3186  return false;
3187 
3188  /* Followed by a non-empty string of digits and then an underscore. */
3189  for (pos = 1; isdigit((unsigned char) name[pos]); ++pos)
3190  ;
3191  if (pos == 1 || name[pos] != '_')
3192  return false;
3193 
3194  /* Followed by another nonempty string of digits. */
3195  for (savepos = ++pos; isdigit((unsigned char) name[pos]); ++pos)
3196  ;
3197  if (savepos == pos)
3198  return false;
3199 
3200  /* We might have _forkname or .segment or both. */
3201  if (name[pos] == '_')
3202  {
3203  int forkchar = forkname_chars(&name[pos + 1], NULL);
3204 
3205  if (forkchar <= 0)
3206  return false;
3207  pos += forkchar + 1;
3208  }
3209  if (name[pos] == '.')
3210  {
3211  int segchar;
3212 
3213  for (segchar = 1; isdigit((unsigned char) name[pos + segchar]); ++segchar)
3214  ;
3215  if (segchar <= 1)
3216  return false;
3217  pos += segchar;
3218  }
3219 
3220  /* Now we should be at the end. */
3221  if (name[pos] != '\0')
3222  return false;
3223  return true;
3224 }
int forkname_chars(const char *str, ForkNumber *fork)
Definition: relpath.c:81
const char * name
Definition: encode.c:555

◆ MakePGDirectory()

int MakePGDirectory ( const char *  directoryName)

◆ OpenPipeStream()

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

Definition at line 2423 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().

2424 {
2425  FILE *file;
2426  int save_errno;
2427 
2428  DO_DB(elog(LOG, "OpenPipeStream: Allocated %d (%s)",
2429  numAllocatedDescs, command));
2430 
2431  /* Can we allocate another non-virtual FD? */
2432  if (!reserveAllocatedDesc())
2433  ereport(ERROR,
2434  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2435  errmsg("exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"",
2436  maxAllocatedDescs, command)));
2437 
2438  /* Close excess kernel FDs. */
2439  ReleaseLruFiles();
2440 
2441 TryAgain:
2442  fflush(stdout);
2443  fflush(stderr);
2445  errno = 0;
2446  file = popen(command, mode);
2447  save_errno = errno;
2449  errno = save_errno;
2450  if (file != NULL)
2451  {
2453 
2454  desc->kind = AllocateDescPipe;
2455  desc->desc.file = file;
2458  return desc->desc.file;
2459  }
2460 
2461  if (errno == EMFILE || errno == ENFILE)
2462  {
2463  ereport(LOG,
2464  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2465  errmsg("out of file descriptors: %m; release and retry")));
2466  if (ReleaseLruFile())
2467  goto TryAgain;
2468  errno = save_errno;
2469  }
2470 
2471  return NULL;
2472 }
static PgChecksumMode mode
Definition: pg_checksums.c:61
static AllocateDesc * allocatedDescs
Definition: fd.c:253
#define DO_DB(A)
Definition: fd.c:169
int errcode(int sqlerrcode)
Definition: elog.c:610
static bool reserveAllocatedDesc(void)
Definition: fd.c:2245
#define SIGPIPE
Definition: win32_port.h:158
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:241
static bool ReleaseLruFile(void)
Definition: fd.c:1241
#define ERROR
Definition: elog.h:43
#define SIG_IGN
Definition: win32_port.h:150
static void ReleaseLruFiles(void)
Definition: fd.c:1263
FILE * file
Definition: fd.c:245
#define ereport(elevel,...)
Definition: elog.h:144
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:170
#define SIG_DFL
Definition: win32_port.h:148
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:707
SubTransactionId create_subid
Definition: fd.c:242
union AllocateDesc::@25 desc
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214
static int maxAllocatedDescs
Definition: fd.c:252
static int numAllocatedDescs
Definition: fd.c:251

◆ OpenTemporaryFile()

File OpenTemporaryFile ( bool  interXact)

Definition at line 1575 of file fd.c.

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

Referenced by BufFileCreateTemp(), and extendBufFile().

1576 {
1577  File file = 0;
1578 
1579  /*
1580  * Make sure the current resource owner has space for this File before we
1581  * open it, if we'll be registering it below.
1582  */
1583  if (!interXact)
1585 
1586  /*
1587  * If some temp tablespace(s) have been given to us, try to use the next
1588  * one. If a given tablespace can't be found, we silently fall back to
1589  * the database's default tablespace.
1590  *
1591  * BUT: if the temp file is slated to outlive the current transaction,
1592  * force it into the database's default tablespace, so that it will not
1593  * pose a threat to possible tablespace drop attempts.
1594  */
1595  if (numTempTableSpaces > 0 && !interXact)
1596  {
1597  Oid tblspcOid = GetNextTempTableSpace();
1598 
1599  if (OidIsValid(tblspcOid))
1600  file = OpenTemporaryFileInTablespace(tblspcOid, false);
1601  }
1602 
1603  /*
1604  * If not, or if tablespace is bad, create in database's default
1605  * tablespace. MyDatabaseTableSpace should normally be set before we get
1606  * here, but just in case it isn't, fall back to pg_default tablespace.
1607  */
1608  if (file <= 0)
1611  DEFAULTTABLESPACE_OID,
1612  true);
1613 
1614  /* Mark it for deletion at close and temporary file size limit */
1616 
1617  /* Register it with the current resource owner */
1618  if (!interXact)
1619  RegisterTemporaryFile(file);
1620 
1621  return file;
1622 }
static File OpenTemporaryFileInTablespace(Oid tblspcOid, bool rejectError)
Definition: fd.c:1653
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:183
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
#define FD_DELETE_AT_CLOSE
Definition: fd.c:181
static Vfd * VfdCache
Definition: fd.c:205
static int numTempTableSpaces
Definition: fd.c:271
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:644
Oid MyDatabaseTableSpace
Definition: globals.c:87
Oid GetNextTempTableSpace(void)
Definition: fd.c:2842
unsigned short fdstate
Definition: fd.c:188
static void RegisterTemporaryFile(File file)
Definition: fd.c:1406
void ResourceOwnerEnlargeFiles(ResourceOwner owner)
Definition: resowner.c:1257
int File
Definition: fd.h:49

◆ OpenTransientFile()

◆ OpenTransientFilePerm()

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

Definition at line 2379 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().

2380 {
2381  int fd;
2382 
2383  DO_DB(elog(LOG, "OpenTransientFile: Allocated %d (%s)",
2384  numAllocatedDescs, fileName));
2385 
2386  /* Can we allocate another non-virtual FD? */
2387  if (!reserveAllocatedDesc())
2388  ereport(ERROR,
2389  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2390  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2391  maxAllocatedDescs, fileName)));
2392 
2393  /* Close excess kernel FDs. */
2394  ReleaseLruFiles();
2395 
2396  fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
2397 
2398  if (fd >= 0)
2399  {
2401 
2402  desc->kind = AllocateDescRawFD;
2403  desc->desc.fd = fd;
2406 
2407  return fd;
2408  }
2409 
2410  return -1; /* failure */
2411 }
static AllocateDesc * allocatedDescs
Definition: fd.c:253
#define DO_DB(A)
Definition: fd.c:169
int errcode(int sqlerrcode)
Definition: elog.c:610
static bool reserveAllocatedDesc(void)
Definition: fd.c:2245
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:241
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define ERROR
Definition: elog.h:43
static void ReleaseLruFiles(void)
Definition: fd.c:1263
#define ereport(elevel,...)
Definition: elog.h:144
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:707
SubTransactionId create_subid
Definition: fd.c:242
int fd
Definition: fd.c:247
union AllocateDesc::@25 desc
int errmsg(const char *fmt,...)
Definition: elog.c:824
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1005
#define elog(elevel,...)
Definition: elog.h:214
static int maxAllocatedDescs
Definition: fd.c:252
static int numAllocatedDescs
Definition: fd.c:251

◆ PathNameCreateTemporaryDir()

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

Definition at line 1511 of file fd.c.

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

Referenced by SharedFileSetCreate().

1512 {
1513  if (MakePGDirectory(directory) < 0)
1514  {
1515  if (errno == EEXIST)
1516  return;
1517 
1518  /*
1519  * Failed. Try to create basedir first in case it's missing. Tolerate
1520  * EEXIST to close a race against another process following the same
1521  * algorithm.
1522  */
1523  if (MakePGDirectory(basedir) < 0 && errno != EEXIST)
1524  ereport(ERROR,
1526  errmsg("cannot create temporary directory \"%s\": %m",
1527  basedir)));
1528 
1529  /* Try again. */
1530  if (MakePGDirectory(directory) < 0 && errno != EEXIST)
1531  ereport(ERROR,
1533  errmsg("cannot create temporary subdirectory \"%s\": %m",
1534  directory)));
1535  }
1536 }
static char * basedir
#define ERROR
Definition: elog.h:43
int errcode_for_file_access(void)
Definition: elog.c:633
#define ereport(elevel,...)
Definition: elog.h:144
int MakePGDirectory(const char *directoryName)
Definition: fd.c:3574
static const char * directory
Definition: zic.c:622
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ PathNameCreateTemporaryFile()

File PathNameCreateTemporaryFile ( const char *  name,
bool  error_on_failure 
)

Definition at line 1710 of file fd.c.

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

Referenced by SharedFileSetCreate().

1711 {
1712  File file;
1713 
1715 
1716  /*
1717  * Open the file. Note: we don't use O_EXCL, in case there is an orphaned
1718  * temp file that can be reused.
1719  */
1720  file = PathNameOpenFile(path, O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1721  if (file <= 0)
1722  {
1723  if (error_on_failure)
1724  ereport(ERROR,
1726  errmsg("could not create temporary file \"%s\": %m",
1727  path)));
1728  else
1729  return file;
1730  }
1731 
1732  /* Mark it for temp_file_limit accounting. */
1734 
1735  /* Register it for automatic close. */
1736  RegisterTemporaryFile(file);
1737 
1738  return file;
1739 }
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1434
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:183
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
static Vfd * VfdCache
Definition: fd.c:205
#define PG_BINARY
Definition: c.h:1234
#define ERROR
Definition: elog.h:43
int errcode_for_file_access(void)
Definition: elog.c:633
unsigned short fdstate
Definition: fd.c:188
#define ereport(elevel,...)
Definition: elog.h:144
static void RegisterTemporaryFile(File file)
Definition: fd.c:1406
int errmsg(const char *fmt,...)
Definition: elog.c:824
void ResourceOwnerEnlargeFiles(ResourceOwner owner)
Definition: resowner.c:1257
int File
Definition: fd.h:49

◆ PathNameDeleteTemporaryDir()

void PathNameDeleteTemporaryDir ( const char *  name)

Definition at line 1542 of file fd.c.

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

Referenced by SharedFileSetDeleteAll().

1543 {
1544  struct stat statbuf;
1545 
1546  /* Silently ignore missing directory. */
1547  if (stat(dirname, &statbuf) != 0 && errno == ENOENT)
1548  return;
1549 
1550  /*
1551  * Currently, walkdir doesn't offer a way for our passed in function to
1552  * maintain state. Perhaps it should, so that we could tell the caller
1553  * whether this operation succeeded or failed. Since this operation is
1554  * used in a cleanup path, we wouldn't actually behave differently: we'll
1555  * just log failures.
1556  */
1557  walkdir(dirname, unlink_if_exists_fname, false, LOG);
1558 }
static void walkdir(const char *path, void(*action)(const char *fname, bool isdir, int elevel), bool process_symlinks, int elevel)
Definition: fd.c:3323
#define LOG
Definition: elog.h:26
static void unlink_if_exists_fname(const char *fname, bool isdir, int elevel)
Definition: fd.c:3433
#define stat(a, b)
Definition: win32_port.h:255

◆ PathNameDeleteTemporaryFile()

bool PathNameDeleteTemporaryFile ( const char *  name,
bool  error_on_failure 
)

Definition at line 1778 of file fd.c.

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

Referenced by SharedFileSetDelete(), and unlink_if_exists_fname().

1779 {
1780  struct stat filestats;
1781  int stat_errno;
1782 
1783  /* Get the final size for pgstat reporting. */
1784  if (stat(path, &filestats) != 0)
1785  stat_errno = errno;
1786  else
1787  stat_errno = 0;
1788 
1789  /*
1790  * Unlike FileClose's automatic file deletion code, we tolerate
1791  * non-existence to support BufFileDeleteShared which doesn't know how
1792  * many segments it has to delete until it runs out.
1793  */
1794  if (stat_errno == ENOENT)
1795  return false;
1796 
1797  if (unlink(path) < 0)
1798  {
1799  if (errno != ENOENT)
1800  ereport(error_on_failure ? ERROR : LOG,
1802  errmsg("could not unlink temporary file \"%s\": %m",
1803  path)));
1804  return false;
1805  }
1806 
1807  if (stat_errno == 0)
1808  ReportTemporaryFileUsage(path, filestats.st_size);
1809  else
1810  {
1811  errno = stat_errno;
1812  ereport(LOG,
1814  errmsg("could not stat file \"%s\": %m", path)));
1815  }
1816 
1817  return true;
1818 }
#define LOG
Definition: elog.h:26
#define ERROR
Definition: elog.h:43
int errcode_for_file_access(void)
Definition: elog.c:633
static void ReportTemporaryFileUsage(const char *path, off_t size)
Definition: fd.c:1387
#define stat(a, b)
Definition: win32_port.h:255
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ PathNameOpenFile()

File PathNameOpenFile ( const char *  fileName,
int  fileFlags 
)

Definition at line 1434 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().

1435 {
1436  return PathNameOpenFilePerm(fileName, fileFlags, pg_file_create_mode);
1437 }
File PathNameOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1447
int pg_file_create_mode
Definition: file_perm.c:19

◆ PathNameOpenFilePerm()

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

Definition at line 1447 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().

1448 {
1449  char *fnamecopy;
1450  File file;
1451  Vfd *vfdP;
1452 
1453  DO_DB(elog(LOG, "PathNameOpenFilePerm: %s %x %o",
1454  fileName, fileFlags, fileMode));
1455 
1456  /*
1457  * We need a malloc'd copy of the file name; fail cleanly if no room.
1458  */
1459  fnamecopy = strdup(fileName);
1460  if (fnamecopy == NULL)
1461  ereport(ERROR,
1462  (errcode(ERRCODE_OUT_OF_MEMORY),
1463  errmsg("out of memory")));
1464 
1465  file = AllocateVfd();
1466  vfdP = &VfdCache[file];
1467 
1468  /* Close excess kernel FDs. */
1469  ReleaseLruFiles();
1470 
1471  vfdP->fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
1472 
1473  if (vfdP->fd < 0)
1474  {
1475  int save_errno = errno;
1476 
1477  FreeVfd(file);
1478  free(fnamecopy);
1479  errno = save_errno;
1480  return -1;
1481  }
1482  ++nfile;
1483  DO_DB(elog(LOG, "PathNameOpenFile: success %d",
1484  vfdP->fd));
1485 
1486  Insert(file);
1487 
1488  vfdP->fileName = fnamecopy;
1489  /* Saved flags are adjusted to be OK for re-opening file */
1490  vfdP->fileFlags = fileFlags & ~(O_CREAT | O_TRUNC | O_EXCL);
1491  vfdP->fileMode = fileMode;
1492  vfdP->fileSize = 0;
1493  vfdP->fdstate = 0x0;
1494  vfdP->resowner = NULL;
1495 
1496  return file;
1497 }
#define DO_DB(A)
Definition: fd.c:169
static Vfd * VfdCache
Definition: fd.c:205
int errcode(int sqlerrcode)
Definition: elog.c:610
#define LOG
Definition: elog.h:26
mode_t fileMode
Definition: fd.c:197
#define ERROR
Definition: elog.h:43
char * fileName
Definition: fd.c:194
static int nfile
Definition: fd.c:211
static File AllocateVfd(void)
Definition: fd.c:1273
unsigned short fdstate
Definition: fd.c:188
Definition: fd.c:185
off_t fileSize
Definition: fd.c:193
int fd
Definition: fd.c:187
static void Insert(File file)
Definition: fd.c:1172
ResourceOwner resowner
Definition: fd.c:189
static void ReleaseLruFiles(void)
Definition: fd.c:1263
#define ereport(elevel,...)
Definition: elog.h:144
#define free(a)
Definition: header.h:65
int errmsg(const char *fmt,...)
Definition: elog.c:824
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1005
#define elog(elevel,...)
Definition: elog.h:214
static void FreeVfd(File file)
Definition: fd.c:1331
int fileFlags
Definition: fd.c:196
int File
Definition: fd.h:49

◆ PathNameOpenTemporaryFile()

File PathNameOpenTemporaryFile ( const char *  name)

Definition at line 1748 of file fd.c.

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

Referenced by SharedFileSetOpen().

1749 {
1750  File file;
1751 
1753 
1754  /* We open the file read-only. */
1755  file = PathNameOpenFile(path, O_RDONLY | PG_BINARY);
1756 
1757  /* If no such file, then we don't raise an error. */
1758  if (file <= 0 && errno != ENOENT)
1759  ereport(ERROR,
1761  errmsg("could not open temporary file \"%s\": %m",
1762  path)));
1763 
1764  if (file > 0)
1765  {
1766  /* Register it for automatic close. */
1767  RegisterTemporaryFile(file);
1768  }
1769 
1770  return file;
1771 }
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1434
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
#define PG_BINARY
Definition: c.h:1234
#define ERROR
Definition: elog.h:43
int errcode_for_file_access(void)
Definition: elog.c:633
#define ereport(elevel,...)
Definition: elog.h:144
static void RegisterTemporaryFile(File file)
Definition: fd.c:1406
int errmsg(const char *fmt,...)
Definition: elog.c:824
void ResourceOwnerEnlargeFiles(ResourceOwner owner)
Definition: resowner.c:1257
int File
Definition: fd.h:49

◆ pg_fdatasync()

int pg_fdatasync ( int  fd)

Definition at line 433 of file fd.c.

References enableFsync, and fsync.

Referenced by issue_xlog_fsync().

434 {
435  if (enableFsync)
436  {
437 #ifdef HAVE_FDATASYNC
438  return fdatasync(fd);
439 #else
440  return fsync(fd);
441 #endif
442  }
443  else
444  return 0;
445 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define fsync(fd)
Definition: win32_port.h:62
bool enableFsync
Definition: globals.c:119

◆ pg_flush_data()

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

Definition at line 453 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().

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

◆ pg_fsync()

int pg_fsync ( int  fd)

Definition at line 343 of file fd.c.

References Assert, pg_fsync_no_writethrough(), pg_fsync_writethrough(), S_ISDIR, stat, 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(), SimpleLruFlush(), SlruPhysicalWritePage(), SnapBuildSerialize(), update_controlfile(), write_auto_conf_file(), write_relmap_file(), WriteControlFile(), writeTimeLineHistory(), writeTimeLineHistoryFile(), XLogFileCopy(), and XLogFileInit().

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

◆ pg_fsync_no_writethrough()

int pg_fsync_no_writethrough ( int  fd)

Definition at line 398 of file fd.c.

References enableFsync, and fsync.

Referenced by issue_xlog_fsync(), and pg_fsync().

399 {
400  if (enableFsync)
401  return fsync(fd);
402  else
403  return 0;
404 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define fsync(fd)
Definition: win32_port.h:62
bool enableFsync
Definition: globals.c:119

◆ pg_fsync_writethrough()

int pg_fsync_writethrough ( int  fd)

Definition at line 410 of file fd.c.

References enableFsync.

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

411 {
412  if (enableFsync)
413  {
414 #ifdef WIN32
415  return _commit(fd);
416 #elif defined(F_FULLFSYNC)
417  return (fcntl(fd, F_FULLFSYNC, 0) == -1) ? -1 : 0;
418 #else
419  errno = ENOSYS;
420  return -1;
421 #endif
422  }
423  else
424  return 0;
425 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
bool enableFsync
Definition: globals.c:119

◆ ReadDir()

◆ ReadDirExtended()

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

Definition at line 2662 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(), and walkdir().

2663 {
2664  struct dirent *dent;
2665 
2666  /* Give a generic message for AllocateDir failure, if caller didn't */
2667  if (dir == NULL)
2668  {
2669  ereport(elevel,
2671  errmsg("could not open directory \"%s\": %m",
2672  dirname)));
2673  return NULL;
2674  }
2675 
2676  errno = 0;
2677  if ((dent = readdir(dir)) != NULL)
2678  return dent;
2679 
2680  if (errno)
2681  ereport(elevel,
2683  errmsg("could not read directory \"%s\": %m",
2684  dirname)));
2685  return NULL;
2686 }
Definition: dirent.h:9
int errcode_for_file_access(void)
Definition: elog.c:633
static int elevel
Definition: vacuumlazy.c:323
#define ereport(elevel,...)
Definition: elog.h:144
struct dirent * readdir(DIR *)
Definition: dirent.c:77
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ ReleaseExternalFD()

◆ RemovePgTempFiles()

void RemovePgTempFiles ( void  )

Definition at line 2998 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().

2999 {
3000  char temp_path[MAXPGPATH + 10 + sizeof(TABLESPACE_VERSION_DIRECTORY) + sizeof(PG_TEMP_FILES_DIR)];
3001  DIR *spc_dir;
3002  struct dirent *spc_de;
3003 
3004  /*
3005  * First process temp files in pg_default ($PGDATA/base)
3006  */
3007  snprintf(temp_path, sizeof(temp_path), "base/%s", PG_TEMP_FILES_DIR);
3008  RemovePgTempFilesInDir(temp_path, true, false);
3009  RemovePgTempRelationFiles("base");
3010 
3011  /*
3012  * Cycle through temp directories for all non-default tablespaces.
3013  */
3014  spc_dir = AllocateDir("pg_tblspc");
3015 
3016  while ((spc_de = ReadDirExtended(spc_dir, "pg_tblspc", LOG)) != NULL)
3017  {
3018  if (strcmp(spc_de->d_name, ".") == 0 ||
3019  strcmp(spc_de->d_name, "..") == 0)
3020  continue;
3021 
3022  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s/%s",
3024  RemovePgTempFilesInDir(temp_path, true, false);
3025 
3026  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s",
3028  RemovePgTempRelationFiles(temp_path);
3029  }
3030 
3031  FreeDir(spc_dir);
3032 
3033  /*
3034  * In EXEC_BACKEND case there is a pgsql_tmp directory at the top level of
3035  * DataDir as well. However, that is *not* cleaned here because doing so
3036  * would create a race condition. It's done separately, earlier in
3037  * postmaster startup.
3038  */
3039 }
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2662
#define PG_TEMP_FILES_DIR
Definition: pg_checksums.c:58
#define LOG
Definition: elog.h:26
Definition: dirent.h:9
static void RemovePgTempRelationFiles(const char *tsdirname)
Definition: fd.c:3123
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:3057
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2581
char d_name[MAX_PATH]
Definition: dirent.h:14
#define snprintf
Definition: port.h:193
int FreeDir(DIR *dir)
Definition: fd.c:2699

◆ RemovePgTempFilesInDir()

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

Definition at line 3057 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.

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

3058 {
3059  DIR *temp_dir;
3060  struct dirent *temp_de;
3061  char rm_path[MAXPGPATH * 2];
3062 
3063  temp_dir = AllocateDir(tmpdirname);
3064 
3065  if (temp_dir == NULL && errno == ENOENT && missing_ok)
3066  return;
3067 
3068  while ((temp_de = ReadDirExtended(temp_dir, tmpdirname, LOG)) != NULL)
3069  {
3070  if (strcmp(temp_de->d_name, ".") == 0 ||
3071  strcmp(temp_de->d_name, "..") == 0)
3072  continue;
3073 
3074  snprintf(rm_path, sizeof(rm_path), "%s/%s",
3075  tmpdirname, temp_de->d_name);
3076 
3077  if (unlink_all ||
3078  strncmp(temp_de->d_name,
3080  strlen(PG_TEMP_FILE_PREFIX)) == 0)
3081  {
3082  struct stat statbuf;
3083 
3084  if (lstat(rm_path, &statbuf) < 0)
3085  {
3086  ereport(LOG,
3088  errmsg("could not stat file \"%s\": %m", rm_path)));
3089  continue;
3090  }
3091 
3092  if (S_ISDIR(statbuf.st_mode))
3093  {
3094  /* recursively remove contents, then directory itself */
3095  RemovePgTempFilesInDir(rm_path, false, true);
3096 
3097  if (rmdir(rm_path) < 0)
3098  ereport(LOG,
3100  errmsg("could not remove directory \"%s\": %m",
3101  rm_path)));
3102  }
3103  else
3104  {
3105  if (unlink(rm_path) < 0)
3106  ereport(LOG,
3108  errmsg("could not remove file \"%s\": %m",
3109  rm_path)));
3110  }
3111  }
3112  else
3113  ereport(LOG,
3114  (errmsg("unexpected file found in temporary-files directory: \"%s\"",
3115  rm_path)));
3116  }
3117 
3118  FreeDir(temp_dir);
3119 }
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2662
#define LOG
Definition: elog.h:26
Definition: dirent.h:9
Definition: dirent.c:25
#define PG_TEMP_FILE_PREFIX
Definition: pg_checksums.c:59
#define MAXPGPATH
void RemovePgTempFilesInDir(const char *tmpdirname, bool missing_ok, bool unlink_all)
Definition: fd.c:3057
int errcode_for_file_access(void)
Definition: elog.c:633
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2581
#define stat(a, b)
Definition: win32_port.h:255
#define ereport(elevel,...)
Definition: elog.h:144
#define S_ISDIR(m)
Definition: win32_port.h:296
#define lstat(path, sb)
Definition: win32_port.h:244
int errmsg(const char *fmt,...)
Definition: elog.c:824
char d_name[MAX_PATH]
Definition: dirent.h:14
#define snprintf
Definition: port.h:193
int FreeDir(DIR *dir)
Definition: fd.c:2699

◆ ReserveExternalFD()

void ReserveExternalFD ( void  )

Definition at line 1080 of file fd.c.

References numExternalFDs, and ReleaseLruFiles().

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

1081 {
1082  /*
1083  * Release VFDs if needed to stay safe. Because we do this before
1084  * incrementing numExternalFDs, the final state will be as desired, i.e.,
1085  * nfile + numAllocatedDescs + numExternalFDs <= max_safe_fds.
1086  */
1087  ReleaseLruFiles();
1088 
1089  numExternalFDs++;
1090 }
static int numExternalFDs
Definition: fd.c:258
static void ReleaseLruFiles(void)
Definition: fd.c:1263

◆ set_max_safe_fds()

void set_max_safe_fds ( void  )

Definition at line 940 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().

941 {
942  int usable_fds;
943  int already_open;
944 
945  /*----------
946  * We want to set max_safe_fds to
947  * MIN(usable_fds, max_files_per_process - already_open)
948  * less the slop factor for files that are opened without consulting
949  * fd.c. This ensures that we won't exceed either max_files_per_process
950  * or the experimentally-determined EMFILE limit.
951  *----------
952  */
954  &usable_fds, &already_open);
955 
956  max_safe_fds = Min(usable_fds, max_files_per_process - already_open);
957 
958  /*
959  * Take off the FDs reserved for system() etc.
960  */
962 
963  /*
964  * Make sure we still have enough to get by.
965  */
966  if (max_safe_fds < FD_MINFREE)
967  ereport(FATAL,
968  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
969  errmsg("insufficient file descriptors available to start server process"),
970  errdetail("System allows %d, we need at least %d.",
973 
974  elog(DEBUG2, "max_safe_fds = %d, usable_fds = %d, already_open = %d",
975  max_safe_fds, usable_fds, already_open);
976 }
static void count_usable_fds(int max_to_probe, int *usable_fds, int *already_open)
Definition: fd.c:856
#define NUM_RESERVED_FDS
Definition: fd.c:124
int max_safe_fds
Definition: fd.c:154
#define Min(x, y)
Definition: c.h:920
int errcode(int sqlerrcode)
Definition: elog.c:610
#define FATAL
Definition: elog.h:52
#define DEBUG2
Definition: elog.h:24
int errdetail(const char *fmt,...)
Definition: elog.c:957
int max_files_per_process
Definition: fd.c:141
#define ereport(elevel,...)
Definition: elog.h:144
#define FD_MINFREE
Definition: fd.c:133
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214

◆ SetTempTablespaces()

void SetTempTablespaces ( Oid tableSpaces,
int  numSpaces 
)

Definition at line 2784 of file fd.c.

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

Referenced by assign_temp_tablespaces(), and PrepareTempTablespaces().

2785 {
2786  Assert(numSpaces >= 0);
2787  tempTableSpaces = tableSpaces;
2788  numTempTableSpaces = numSpaces;
2789 
2790  /*
2791  * Select a random starting point in the list. This is to minimize
2792  * conflicts between backends that are most likely sharing the same list
2793  * of temp tablespaces. Note that if we create multiple temp files in the
2794  * same transaction, we'll advance circularly through the list --- this
2795  * ensures that large temporary sort files are nicely spread across all
2796  * available tablespaces.
2797  */
2798  if (numSpaces > 1)
2799  nextTempTableSpace = random() % numSpaces;
2800  else
2801  nextTempTableSpace = 0;
2802 }
long random(void)
Definition: random.c:22
static int numTempTableSpaces
Definition: fd.c:271
static int nextTempTableSpace
Definition: fd.c:272
#define Assert(condition)
Definition: c.h:738
static Oid * tempTableSpaces
Definition: fd.c:270

◆ SyncDataDirectory()

void SyncDataDirectory ( void  )

Definition at line 3249 of file fd.c.

References datadir_fsync_fname(), DEBUG1, enableFsync, ereport, errcode_for_file_access(), errmsg(), LOG, lstat, pgwin32_is_junction(), stat, and walkdir().

Referenced by StartupXLOG().

3250 {
3251  bool xlog_is_symlink;
3252 
3253  /* We can skip this whole thing if fsync is disabled. */
3254  if (!enableFsync)
3255  return;
3256 
3257  /*
3258  * If pg_wal is a symlink, we'll need to recurse into it separately,
3259  * because the first walkdir below will ignore it.
3260  */
3261  xlog_is_symlink = false;
3262 
3263 #ifndef WIN32
3264  {
3265  struct stat st;
3266 
3267  if (lstat("pg_wal", &st) < 0)
3268  ereport(LOG,
3270  errmsg("could not stat file \"%s\": %m",
3271  "pg_wal")));
3272  else if (S_ISLNK(st.st_mode))
3273  xlog_is_symlink = true;
3274  }
3275 #else
3276  if (pgwin32_is_junction("pg_wal"))
3277  xlog_is_symlink = true;
3278 #endif
3279 
3280  /*
3281  * If possible, hint to the kernel that we're soon going to fsync the data
3282  * directory and its contents. Errors in this step are even less
3283  * interesting than normal, so log them only at DEBUG1.
3284  */
3285 #ifdef PG_FLUSH_DATA_WORKS
3286  walkdir(".", pre_sync_fname, false, DEBUG1);
3287  if (xlog_is_symlink)
3288  walkdir("pg_wal", pre_sync_fname, false, DEBUG1);
3289  walkdir("pg_tblspc", pre_sync_fname, true, DEBUG1);
3290 #endif
3291 
3292  /*
3293  * Now we do the fsync()s in the same order.
3294  *
3295  * The main call ignores symlinks, so in addition to specially processing
3296  * pg_wal if it's a symlink, pg_tblspc has to be visited separately with
3297  * process_symlinks = true. Note that if there are any plain directories
3298  * in pg_tblspc, they'll get fsync'd twice. That's not an expected case
3299  * so we don't worry about optimizing it.
3300  */
3301  walkdir(".", datadir_fsync_fname, false, LOG);
3302  if (xlog_is_symlink)
3303  walkdir("pg_wal", datadir_fsync_fname, false, LOG);
3304  walkdir("pg_tblspc", datadir_fsync_fname, true, LOG);
3305 }
#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:3323
#define LOG
Definition: elog.h:26
int errcode_for_file_access(void)
Definition: elog.c:633
static void datadir_fsync_fname(const char *fname, bool isdir, int elevel)
Definition: fd.c:3423
#define stat(a, b)
Definition: win32_port.h:255
#define ereport(elevel,...)
Definition: elog.h:144
#define lstat(path, sb)
Definition: win32_port.h:244
bool enableFsync
Definition: globals.c:119
int errmsg(const char *fmt,...)
Definition: elog.c:824
bool pgwin32_is_junction(const char *path)

◆ TempTablespacePath()

void TempTablespacePath ( char *  path,
Oid  tablespace 
)

Definition at line 1628 of file fd.c.

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

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

1629 {
1630  /*
1631  * Identify the tempfile directory for this tablespace.
1632  *
1633  * If someone tries to specify pg_global, use pg_default instead.
1634  */
1635  if (tablespace == InvalidOid ||
1636  tablespace == DEFAULTTABLESPACE_OID ||
1637  tablespace == GLOBALTABLESPACE_OID)
1638  snprintf(path, MAXPGPATH, "base/%s", PG_TEMP_FILES_DIR);
1639  else
1640  {
1641  /* All other tablespaces are accessed via symlinks */
1642  snprintf(path, MAXPGPATH, "pg_tblspc/%u/%s/%s",
1645  }
1646 }
#define PG_TEMP_FILES_DIR
Definition: pg_checksums.c:58
#define MAXPGPATH
#define TABLESPACE_VERSION_DIRECTORY
Definition: relpath.h:26
char * tablespace
Definition: pgbench.c:188
#define InvalidOid
Definition: postgres_ext.h:36
#define snprintf
Definition: port.h:193

◆ TempTablespacesAreSet()

bool TempTablespacesAreSet ( void  )

Definition at line 2812 of file fd.c.

References numTempTableSpaces.

Referenced by GetTempTablespaces(), and PrepareTempTablespaces().

2813 {
2814  return (numTempTableSpaces >= 0);
2815 }
static int numTempTableSpaces
Definition: fd.c:271

Variable Documentation

◆ data_sync_retry

PGDLLIMPORT bool data_sync_retry

Definition at line 157 of file fd.c.

Referenced by data_sync_elevel().

◆ max_files_per_process

PGDLLIMPORT int max_files_per_process

Definition at line 141 of file fd.c.

Referenced by set_max_safe_fds().

◆ max_safe_fds