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)
 
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 durable_rename (const char *oldfile, const char *newfile, int loglevel)
 
int durable_unlink (const char *fname, int loglevel)
 
int durable_link_or_rename (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 65 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 156 of file fd.h.

◆ PG_TEMP_FILES_DIR

#define PG_TEMP_FILES_DIR   "pgsql_tmp"

Definition at line 155 of file fd.h.

Typedef Documentation

◆ File

typedef int File

Definition at line 45 of file fd.h.

Function Documentation

◆ AllocateDir()

DIR* AllocateDir ( const char *  dirname)

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

2467 {
2468  DIR *dir;
2469 
2470  DO_DB(elog(LOG, "AllocateDir: Allocated %d (%s)",
2471  numAllocatedDescs, dirname));
2472 
2473  /* Can we allocate another non-virtual FD? */
2474  if (!reserveAllocatedDesc())
2475  ereport(ERROR,
2476  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2477  errmsg("exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"",
2478  maxAllocatedDescs, dirname)));
2479 
2480  /* Close excess kernel FDs. */
2481  ReleaseLruFiles();
2482 
2483 TryAgain:
2484  if ((dir = opendir(dirname)) != NULL)
2485  {
2487 
2488  desc->kind = AllocateDescDir;
2489  desc->desc.dir = dir;
2492  return desc->desc.dir;
2493  }
2494 
2495  if (errno == EMFILE || errno == ENFILE)
2496  {
2497  int save_errno = errno;
2498 
2499  ereport(LOG,
2500  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2501  errmsg("out of file descriptors: %m; release and retry")));
2502  errno = 0;
2503  if (ReleaseLruFile())
2504  goto TryAgain;
2505  errno = save_errno;
2506  }
2507 
2508  return NULL;
2509 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
union AllocateDesc::@26 desc
DIR * dir
Definition: fd.c:238
#define DO_DB(A)
Definition: fd.c:161
int errcode(int sqlerrcode)
Definition: elog.c:570
static bool reserveAllocatedDesc(void)
Definition: fd.c:2132
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static bool ReleaseLruFile(void)
Definition: fd.c:1128
Definition: dirent.c:25
#define ERROR
Definition: elog.h:43
DIR * opendir(const char *)
Definition: dirent.c:33
#define ereport(elevel, rest)
Definition: elog.h:141
static void ReleaseLruFiles(void)
Definition: fd.c:1150
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:708
SubTransactionId create_subid
Definition: fd.c:234
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
static int maxAllocatedDescs
Definition: fd.c:244
static int numAllocatedDescs
Definition: fd.c:243

◆ AllocateFile()

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

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

2206 {
2207  FILE *file;
2208 
2209  DO_DB(elog(LOG, "AllocateFile: Allocated %d (%s)",
2211 
2212  /* Can we allocate another non-virtual FD? */
2213  if (!reserveAllocatedDesc())
2214  ereport(ERROR,
2215  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2216  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2217  maxAllocatedDescs, name)));
2218 
2219  /* Close excess kernel FDs. */
2220  ReleaseLruFiles();
2221 
2222 TryAgain:
2223  if ((file = fopen(name, mode)) != NULL)
2224  {
2226 
2227  desc->kind = AllocateDescFile;
2228  desc->desc.file = file;
2231  return desc->desc.file;
2232  }
2233 
2234  if (errno == EMFILE || errno == ENFILE)
2235  {
2236  int save_errno = errno;
2237 
2238  ereport(LOG,
2239  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2240  errmsg("out of file descriptors: %m; release and retry")));
2241  errno = 0;
2242  if (ReleaseLruFile())
2243  goto TryAgain;
2244  errno = save_errno;
2245  }
2246 
2247  return NULL;
2248 }
static PgChecksumMode mode
Definition: pg_checksums.c:61
static AllocateDesc * allocatedDescs
Definition: fd.c:245
union AllocateDesc::@26 desc
#define DO_DB(A)
Definition: fd.c:161
int errcode(int sqlerrcode)
Definition: elog.c:570
static bool reserveAllocatedDesc(void)
Definition: fd.c:2132
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static bool ReleaseLruFile(void)
Definition: fd.c:1128
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
static void ReleaseLruFiles(void)
Definition: fd.c:1150
FILE * file
Definition: fd.c:237
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:708
SubTransactionId create_subid
Definition: fd.c:234
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
static int maxAllocatedDescs
Definition: fd.c:244
static int numAllocatedDescs
Definition: fd.c:243

◆ AtEOSubXact_Files()

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

Definition at line 2748 of file fd.c.

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

2750 {
2751  Index i;
2752 
2753  for (i = 0; i < numAllocatedDescs; i++)
2754  {
2755  if (allocatedDescs[i].create_subid == mySubid)
2756  {
2757  if (isCommit)
2758  allocatedDescs[i].create_subid = parentSubid;
2759  else
2760  {
2761  /* have to recheck the item after FreeDesc (ugly) */
2762  FreeDesc(&allocatedDescs[i--]);
2763  }
2764  }
2765  }
2766 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2365
unsigned int Index
Definition: c.h:475
SubTransactionId create_subid
Definition: fd.c:234
int i
static int numAllocatedDescs
Definition: fd.c:243

◆ AtEOXact_Files()

void AtEOXact_Files ( bool  isCommit)

Definition at line 2781 of file fd.c.

References CleanupTempFiles(), numTempTableSpaces, and tempTableSpaces.

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

2782 {
2783  CleanupTempFiles(isCommit, false);
2784  tempTableSpaces = NULL;
2785  numTempTableSpaces = -1;
2786 }
static int numTempTableSpaces
Definition: fd.c:258
static Oid * tempTableSpaces
Definition: fd.c:257
static void CleanupTempFiles(bool isCommit, bool isProcExit)
Definition: fd.c:2813

◆ BasicOpenFile()

int BasicOpenFile ( const char *  fileName,
int  fileFlags 
)

Definition at line 944 of file fd.c.

References BasicOpenFilePerm(), and pg_file_create_mode.

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

945 {
946  return BasicOpenFilePerm(fileName, fileFlags, pg_file_create_mode);
947 }
int pg_file_create_mode
Definition: file_perm.c:19
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:966

◆ BasicOpenFilePerm()

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

Definition at line 966 of file fd.c.

References buf, elog, ereport, errcode(), errmsg(), vfd::fd, LOG, vfd::lruLessRecently, ReleaseLruFile(), and snprintf.

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

967 {
968  int fd;
969 
970 tryAgain:
971  fd = open(fileName, fileFlags, fileMode);
972 
973  if (fd >= 0)
974  return fd; /* success! */
975 
976  if (errno == EMFILE || errno == ENFILE)
977  {
978  int save_errno = errno;
979 
980  ereport(LOG,
981  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
982  errmsg("out of file descriptors: %m; release and retry")));
983  errno = 0;
984  if (ReleaseLruFile())
985  goto tryAgain;
986  errno = save_errno;
987  }
988 
989  return -1; /* failure */
990 }
int errcode(int sqlerrcode)
Definition: elog.c:570
#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:1128
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ closeAllVfds()

void closeAllVfds ( void  )

Definition at line 2643 of file fd.c.

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

Referenced by standard_ProcessUtility().

2644 {
2645  Index i;
2646 
2647  if (SizeVfdCache > 0)
2648  {
2649  Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
2650  for (i = 1; i < SizeVfdCache; i++)
2651  {
2652  if (!FileIsNotOpen(i))
2653  LruDelete(i);
2654  }
2655  }
2656 }
static Size SizeVfdCache
Definition: fd.c:198
static void LruDelete(File file)
Definition: fd.c:1033
#define FileIsNotOpen(file)
Definition: fd.c:170
unsigned int Index
Definition: c.h:475
#define Assert(condition)
Definition: c.h:732
int i

◆ ClosePipeStream()

int ClosePipeStream ( FILE *  file)

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

2615 {
2616  int i;
2617 
2618  DO_DB(elog(LOG, "ClosePipeStream: Allocated %d", numAllocatedDescs));
2619 
2620  /* Remove file from list of allocated files, if it's present */
2621  for (i = numAllocatedDescs; --i >= 0;)
2622  {
2623  AllocateDesc *desc = &allocatedDescs[i];
2624 
2625  if (desc->kind == AllocateDescPipe && desc->desc.file == file)
2626  return FreeDesc(desc);
2627  }
2628 
2629  /* Only get here if someone passes us a file not in allocatedDescs */
2630  elog(WARNING, "file passed to ClosePipeStream was not obtained from OpenPipeStream");
2631 
2632  return pclose(file);
2633 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
union AllocateDesc::@26 desc
#define DO_DB(A)
Definition: fd.c:161
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2365
#define WARNING
Definition: elog.h:40
FILE * file
Definition: fd.c:237
#define elog(elevel,...)
Definition: elog.h:226
int i
static int numAllocatedDescs
Definition: fd.c:243

◆ CloseTransientFile()

int CloseTransientFile ( int  fd)

Definition at line 2432 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(), ReorderBufferIterTXNFinish(), ReorderBufferRestoreChanges(), ReorderBufferSerializeChange(), ReorderBufferSerializeTXN(), RestoreSlotFromDisk(), SaveSlotToPath(), SendTimeLineHistory(), SimpleLruDoesPhysicalPageExist(), SimpleLruFlush(), SlruInternalWritePage(), SlruPhysicalReadPage(), SlruPhysicalWritePage(), SnapBuildRestore(), SnapBuildSerialize(), StartupReplicationOrigin(), walkdir(), write_relmap_file(), writeTimeLineHistory(), writeTimeLineHistoryFile(), and XLogFileCopy().

2433 {
2434  int i;
2435 
2436  DO_DB(elog(LOG, "CloseTransientFile: Allocated %d", numAllocatedDescs));
2437 
2438  /* Remove fd from list of allocated files, if it's present */
2439  for (i = numAllocatedDescs; --i >= 0;)
2440  {
2441  AllocateDesc *desc = &allocatedDescs[i];
2442 
2443  if (desc->kind == AllocateDescRawFD && desc->desc.fd == fd)
2444  return FreeDesc(desc);
2445  }
2446 
2447  /* Only get here if someone passes us a file not in allocatedDescs */
2448  elog(WARNING, "fd passed to CloseTransientFile was not obtained from OpenTransientFile");
2449 
2450  return close(fd);
2451 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
union AllocateDesc::@26 desc
#define DO_DB(A)
Definition: fd.c:161
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2365
#define WARNING
Definition: elog.h:40
int fd
Definition: fd.c:239
#define elog(elevel,...)
Definition: elog.h:226
int i
#define close(a)
Definition: win32.h:12
static int numAllocatedDescs
Definition: fd.c:243

◆ data_sync_elevel()

◆ durable_link_or_rename()

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

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

733 {
734  /*
735  * Ensure that, if we crash directly after the rename/link, a file with
736  * valid contents is moved into place.
737  */
738  if (fsync_fname_ext(oldfile, false, false, elevel) != 0)
739  return -1;
740 
741 #if HAVE_WORKING_LINK
742  if (link(oldfile, newfile) < 0)
743  {
744  ereport(elevel,
746  errmsg("could not link file \"%s\" to \"%s\": %m",
747  oldfile, newfile)));
748  return -1;
749  }
750  unlink(oldfile);
751 #else
752  /* XXX: Add racy file existence check? */
753  if (rename(oldfile, newfile) < 0)
754  {
755  ereport(elevel,
757  errmsg("could not rename file \"%s\" to \"%s\": %m",
758  oldfile, newfile)));
759  return -1;
760  }
761 #endif
762 
763  /*
764  * Make change persistent in case of an OS crash, both the new entry and
765  * its parent directory need to be flushed.
766  */
767  if (fsync_fname_ext(newfile, false, false, elevel) != 0)
768  return -1;
769 
770  /* Same for parent directory */
771  if (fsync_parent_path(newfile, elevel) != 0)
772  return -1;
773 
774  return 0;
775 }
int errcode_for_file_access(void)
Definition: elog.c:593
#define ereport(elevel, rest)
Definition: elog.h:141
int link(const char *fromname, const char *toname)
static int elevel
Definition: vacuumlazy.c:143
int errmsg(const char *fmt,...)
Definition: elog.c:784
static int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3343
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3419

◆ durable_rename()

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

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

607 {
608  int fd;
609 
610  /*
611  * First fsync the old and target path (if it exists), to ensure that they
612  * are properly persistent on disk. Syncing the target file is not
613  * strictly necessary, but it makes it easier to reason about crashes;
614  * because it's then guaranteed that either source or target file exists
615  * after a crash.
616  */
617  if (fsync_fname_ext(oldfile, false, false, elevel) != 0)
618  return -1;
619 
620  fd = OpenTransientFile(newfile, PG_BINARY | O_RDWR);
621  if (fd < 0)
622  {
623  if (errno != ENOENT)
624  {
625  ereport(elevel,
627  errmsg("could not open file \"%s\": %m", newfile)));
628  return -1;
629  }
630  }
631  else
632  {
633  if (pg_fsync(fd) != 0)
634  {
635  int save_errno;
636 
637  /* close file upon error, might not be in transaction context */
638  save_errno = errno;
639  CloseTransientFile(fd);
640  errno = save_errno;
641 
642  ereport(elevel,
644  errmsg("could not fsync file \"%s\": %m", newfile)));
645  return -1;
646  }
647 
648  if (CloseTransientFile(fd) != 0)
649  {
650  ereport(elevel,
652  errmsg("could not close file \"%s\": %m", newfile)));
653  return -1;
654  }
655  }
656 
657  /* Time to do the real deal... */
658  if (rename(oldfile, newfile) < 0)
659  {
660  ereport(elevel,
662  errmsg("could not rename file \"%s\" to \"%s\": %m",
663  oldfile, newfile)));
664  return -1;
665  }
666 
667  /*
668  * To guarantee renaming the file is persistent, fsync the file with its
669  * new name, and its containing directory.
670  */
671  if (fsync_fname_ext(newfile, false, false, elevel) != 0)
672  return -1;
673 
674  if (fsync_parent_path(newfile, elevel) != 0)
675  return -1;
676 
677  return 0;
678 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1191
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2255
int errcode_for_file_access(void)
Definition: elog.c:593
#define ereport(elevel, rest)
Definition: elog.h:141
int CloseTransientFile(int fd)
Definition: fd.c:2432
static int elevel
Definition: vacuumlazy.c:143
int errmsg(const char *fmt,...)
Definition: elog.c:784
static int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3343
int pg_fsync(int fd)
Definition: fd.c:331
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3419

◆ durable_unlink()

int durable_unlink ( const char *  fname,
int  loglevel 
)

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

697 {
698  if (unlink(fname) < 0)
699  {
700  ereport(elevel,
702  errmsg("could not remove file \"%s\": %m",
703  fname)));
704  return -1;
705  }
706 
707  /*
708  * To guarantee that the removal of the file is persistent, fsync its
709  * parent directory.
710  */
711  if (fsync_parent_path(fname, elevel) != 0)
712  return -1;
713 
714  return 0;
715 }
int errcode_for_file_access(void)
Definition: elog.c:593
#define ereport(elevel, rest)
Definition: elog.h:141
static int elevel
Definition: vacuumlazy.c:143
int errmsg(const char *fmt,...)
Definition: elog.c:784
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3419

◆ FileClose()

void FileClose ( File  file)

Definition at line 1711 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(), mdtruncate(), and ResourceOwnerReleaseInternal().

1712 {
1713  Vfd *vfdP;
1714 
1715  Assert(FileIsValid(file));
1716 
1717  DO_DB(elog(LOG, "FileClose: %d (%s)",
1718  file, VfdCache[file].fileName));
1719 
1720  vfdP = &VfdCache[file];
1721 
1722  if (!FileIsNotOpen(file))
1723  {
1724  /* close the file */
1725  if (close(vfdP->fd) != 0)
1726  {
1727  /*
1728  * We may need to panic on failure to close non-temporary files;
1729  * see LruDelete.
1730  */
1732  "could not close file \"%s\": %m", vfdP->fileName);
1733  }
1734 
1735  --nfile;
1736  vfdP->fd = VFD_CLOSED;
1737 
1738  /* remove the file from the lru ring */
1739  Delete(file);
1740  }
1741 
1742  if (vfdP->fdstate & FD_TEMP_FILE_LIMIT)
1743  {
1744  /* Subtract its size from current usage (do first in case of error) */
1745  temporary_files_size -= vfdP->fileSize;
1746  vfdP->fileSize = 0;
1747  }
1748 
1749  /*
1750  * Delete the file if it was temporary, and make a log entry if wanted
1751  */
1752  if (vfdP->fdstate & FD_DELETE_AT_CLOSE)
1753  {
1754  struct stat filestats;
1755  int stat_errno;
1756 
1757  /*
1758  * If we get an error, as could happen within the ereport/elog calls,
1759  * we'll come right back here during transaction abort. Reset the
1760  * flag to ensure that we can't get into an infinite loop. This code
1761  * is arranged to ensure that the worst-case consequence is failing to
1762  * emit log message(s), not failing to attempt the unlink.
1763  */
1764  vfdP->fdstate &= ~FD_DELETE_AT_CLOSE;
1765 
1766 
1767  /* first try the stat() */
1768  if (stat(vfdP->fileName, &filestats))
1769  stat_errno = errno;
1770  else
1771  stat_errno = 0;
1772 
1773  /* in any case do the unlink */
1774  if (unlink(vfdP->fileName))
1775  elog(LOG, "could not unlink file \"%s\": %m", vfdP->fileName);
1776 
1777  /* and last report the stat results */
1778  if (stat_errno == 0)
1779  ReportTemporaryFileUsage(vfdP->fileName, filestats.st_size);
1780  else
1781  {
1782  errno = stat_errno;
1783  elog(LOG, "could not stat file \"%s\": %m", vfdP->fileName);
1784  }
1785  }
1786 
1787  /* Unregister it from the resource owner */
1788  if (vfdP->resowner)
1789  ResourceOwnerForgetFile(vfdP->resowner, file);
1790 
1791  /*
1792  * Return the Vfd slot to the free list
1793  */
1794  FreeVfd(file);
1795 }
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:175
#define DO_DB(A)
Definition: fd.c:161
#define FD_DELETE_AT_CLOSE
Definition: fd.c:173
static Vfd * VfdCache
Definition: fd.c:197
static void Delete(File file)
Definition: fd.c:1014
#define LOG
Definition: elog.h:26
char * fileName
Definition: fd.c:186
static int nfile
Definition: fd.c:203
unsigned short fdstate
Definition: fd.c:180
Definition: fd.c:177
off_t fileSize
Definition: fd.c:185
int fd
Definition: fd.c:179
ResourceOwner resowner
Definition: fd.c:181
static void ReportTemporaryFileUsage(const char *path, off_t size)
Definition: fd.c:1274
#define stat(a, b)
Definition: win32_port.h:264
#define FileIsNotOpen(file)
Definition: fd.c:170
int data_sync_elevel(int elevel)
Definition: fd.c:3482
#define FileIsValid(file)
Definition: fd.c:167
#define VFD_CLOSED
Definition: fd.c:165
static uint64 temporary_files_size
Definition: fd.c:217
#define Assert(condition)
Definition: c.h:732
#define elog(elevel,...)
Definition: elog.h:226
static void FreeVfd(File file)
Definition: fd.c:1218
#define close(a)
Definition: win32.h:12
void ResourceOwnerForgetFile(ResourceOwner owner, File file)
Definition: resowner.c:1253

◆ FileGetRawDesc()

int FileGetRawDesc ( File  file)

Definition at line 2101 of file fd.c.

References Assert, vfd::fd, and FileIsValid.

2102 {
2103  Assert(FileIsValid(file));
2104  return VfdCache[file].fd;
2105 }
static Vfd * VfdCache
Definition: fd.c:197
int fd
Definition: fd.c:179
#define FileIsValid(file)
Definition: fd.c:167
#define Assert(condition)
Definition: c.h:732

◆ FileGetRawFlags()

int FileGetRawFlags ( File  file)

Definition at line 2111 of file fd.c.

References Assert, vfd::fileFlags, and FileIsValid.

2112 {
2113  Assert(FileIsValid(file));
2114  return VfdCache[file].fileFlags;
2115 }
static Vfd * VfdCache
Definition: fd.c:197
#define FileIsValid(file)
Definition: fd.c:167
#define Assert(condition)
Definition: c.h:732
int fileFlags
Definition: fd.c:188

◆ FileGetRawMode()

mode_t FileGetRawMode ( File  file)

Definition at line 2121 of file fd.c.

References Assert, FileIsValid, and vfd::fileMode.

2122 {
2123  Assert(FileIsValid(file));
2124  return VfdCache[file].fileMode;
2125 }
static Vfd * VfdCache
Definition: fd.c:197
mode_t fileMode
Definition: fd.c:189
#define FileIsValid(file)
Definition: fd.c:167
#define Assert(condition)
Definition: c.h:732

◆ FilePathName()

char* FilePathName ( File  file)

Definition at line 2085 of file fd.c.

References Assert, FileIsValid, and vfd::fileName.

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

2086 {
2087  Assert(FileIsValid(file));
2088 
2089  return VfdCache[file].fileName;
2090 }
static Vfd * VfdCache
Definition: fd.c:197
char * fileName
Definition: fd.c:186
#define FileIsValid(file)
Definition: fd.c:167
#define Assert(condition)
Definition: c.h:732

◆ FilePrefetch()

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

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

1808 {
1809 #if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
1810  int returnCode;
1811 
1812  Assert(FileIsValid(file));
1813 
1814  DO_DB(elog(LOG, "FilePrefetch: %d (%s) " INT64_FORMAT " %d",
1815  file, VfdCache[file].fileName,
1816  (int64) offset, amount));
1817 
1818  returnCode = FileAccess(file);
1819  if (returnCode < 0)
1820  return returnCode;
1821 
1822  pgstat_report_wait_start(wait_event_info);
1823  returnCode = posix_fadvise(VfdCache[file].fd, offset, amount,
1824  POSIX_FADV_WILLNEED);
1826 
1827  return returnCode;
1828 #else
1829  Assert(FileIsValid(file));
1830  return 0;
1831 #endif
1832 }
#define DO_DB(A)
Definition: fd.c:161
static Vfd * VfdCache
Definition: fd.c:197
#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:1342
#define FileIsValid(file)
Definition: fd.c:167
static int FileAccess(File file)
Definition: fd.c:1238
#define Assert(condition)
Definition: c.h:732
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1318
#define INT64_FORMAT
Definition: c.h:400
#define elog(elevel,...)
Definition: elog.h:226

◆ FileRead()

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

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

1860 {
1861  int returnCode;
1862  Vfd *vfdP;
1863 
1864  Assert(FileIsValid(file));
1865 
1866  DO_DB(elog(LOG, "FileRead: %d (%s) " INT64_FORMAT " %d %p",
1867  file, VfdCache[file].fileName,
1868  (int64) offset,
1869  amount, buffer));
1870 
1871  returnCode = FileAccess(file);
1872  if (returnCode < 0)
1873  return returnCode;
1874 
1875  vfdP = &VfdCache[file];
1876 
1877 retry:
1878  pgstat_report_wait_start(wait_event_info);
1879  returnCode = pg_pread(vfdP->fd, buffer, amount, offset);
1881 
1882  if (returnCode < 0)
1883  {
1884  /*
1885  * Windows may run out of kernel buffers and return "Insufficient
1886  * system resources" error. Wait a bit and retry to solve it.
1887  *
1888  * It is rumored that EINTR is also possible on some Unix filesystems,
1889  * in which case immediate retry is indicated.
1890  */
1891 #ifdef WIN32
1892  DWORD error = GetLastError();
1893 
1894  switch (error)
1895  {
1896  case ERROR_NO_SYSTEM_RESOURCES:
1897  pg_usleep(1000L);
1898  errno = EINTR;
1899  break;
1900  default:
1901  _dosmaperr(error);
1902  break;
1903  }
1904 #endif
1905  /* OK to retry if interrupted */
1906  if (errno == EINTR)
1907  goto retry;
1908  }
1909 
1910  return returnCode;
1911 }
static void error(void)
Definition: sql-dyntest.c:147
#define DO_DB(A)
Definition: fd.c:161
void _dosmaperr(unsigned long)
Definition: win32error.c:171
static Vfd * VfdCache
Definition: fd.c:197
#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:1342
Definition: fd.c:177
int fd
Definition: fd.c:179
#define FileIsValid(file)
Definition: fd.c:167
static int FileAccess(File file)
Definition: fd.c:1238
#define Assert(condition)
Definition: c.h:732
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1318
#define INT64_FORMAT
Definition: c.h:400
#define elog(elevel,...)
Definition: elog.h:226
#define EINTR
Definition: win32_port.h:332

◆ FileSize()

off_t FileSize ( File  file)

Definition at line 2033 of file fd.c.

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

Referenced by _mdnblocks(), and BufFileSize().

2034 {
2035  Assert(FileIsValid(file));
2036 
2037  DO_DB(elog(LOG, "FileSize %d (%s)",
2038  file, VfdCache[file].fileName));
2039 
2040  if (FileIsNotOpen(file))
2041  {
2042  if (FileAccess(file) < 0)
2043  return (off_t) -1;
2044  }
2045 
2046  return lseek(VfdCache[file].fd, 0, SEEK_END);
2047 }
#define DO_DB(A)
Definition: fd.c:161
static Vfd * VfdCache
Definition: fd.c:197
#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:170
#define FileIsValid(file)
Definition: fd.c:167
static int FileAccess(File file)
Definition: fd.c:1238
#define Assert(condition)
Definition: c.h:732
#define elog(elevel,...)
Definition: elog.h:226

◆ FileSync()

int FileSync ( File  file,
uint32  wait_event_info 
)

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

2013 {
2014  int returnCode;
2015 
2016  Assert(FileIsValid(file));
2017 
2018  DO_DB(elog(LOG, "FileSync: %d (%s)",
2019  file, VfdCache[file].fileName));
2020 
2021  returnCode = FileAccess(file);
2022  if (returnCode < 0)
2023  return returnCode;
2024 
2025  pgstat_report_wait_start(wait_event_info);
2026  returnCode = pg_fsync(VfdCache[file].fd);
2028 
2029  return returnCode;
2030 }
#define DO_DB(A)
Definition: fd.c:161
static Vfd * VfdCache
Definition: fd.c:197
#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:1342
#define FileIsValid(file)
Definition: fd.c:167
static int FileAccess(File file)
Definition: fd.c:1238
#define Assert(condition)
Definition: c.h:732
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1318
#define elog(elevel,...)
Definition: elog.h:226
int pg_fsync(int fd)
Definition: fd.c:331

◆ FileTruncate()

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

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

2051 {
2052  int returnCode;
2053 
2054  Assert(FileIsValid(file));
2055 
2056  DO_DB(elog(LOG, "FileTruncate %d (%s)",
2057  file, VfdCache[file].fileName));
2058 
2059  returnCode = FileAccess(file);
2060  if (returnCode < 0)
2061  return returnCode;
2062 
2063  pgstat_report_wait_start(wait_event_info);
2064  returnCode = ftruncate(VfdCache[file].fd, offset);
2066 
2067  if (returnCode == 0 && VfdCache[file].fileSize > offset)
2068  {
2069  /* adjust our state for truncation of a temp file */
2070  Assert(VfdCache[file].fdstate & FD_TEMP_FILE_LIMIT);
2071  temporary_files_size -= VfdCache[file].fileSize - offset;
2072  VfdCache[file].fileSize = offset;
2073  }
2074 
2075  return returnCode;
2076 }
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:175
#define DO_DB(A)
Definition: fd.c:161
static Vfd * VfdCache
Definition: fd.c:197
#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:1342
off_t fileSize
Definition: fd.c:185
#define FileIsValid(file)
Definition: fd.c:167
static uint64 temporary_files_size
Definition: fd.c:217
static int FileAccess(File file)
Definition: fd.c:1238
#define Assert(condition)
Definition: c.h:732
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1318
#define elog(elevel,...)
Definition: elog.h:226
#define ftruncate(a, b)
Definition: win32_port.h:60

◆ FileWrite()

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

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

1916 {
1917  int returnCode;
1918  Vfd *vfdP;
1919 
1920  Assert(FileIsValid(file));
1921 
1922  DO_DB(elog(LOG, "FileWrite: %d (%s) " INT64_FORMAT " %d %p",
1923  file, VfdCache[file].fileName,
1924  (int64) offset,
1925  amount, buffer));
1926 
1927  returnCode = FileAccess(file);
1928  if (returnCode < 0)
1929  return returnCode;
1930 
1931  vfdP = &VfdCache[file];
1932 
1933  /*
1934  * If enforcing temp_file_limit and it's a temp file, check to see if the
1935  * write would overrun temp_file_limit, and throw error if so. Note: it's
1936  * really a modularity violation to throw error here; we should set errno
1937  * and return -1. However, there's no way to report a suitable error
1938  * message if we do that. All current callers would just throw error
1939  * immediately anyway, so this is safe at present.
1940  */
1941  if (temp_file_limit >= 0 && (vfdP->fdstate & FD_TEMP_FILE_LIMIT))
1942  {
1943  off_t past_write = offset + amount;
1944 
1945  if (past_write > vfdP->fileSize)
1946  {
1947  uint64 newTotal = temporary_files_size;
1948 
1949  newTotal += past_write - vfdP->fileSize;
1950  if (newTotal > (uint64) temp_file_limit * (uint64) 1024)
1951  ereport(ERROR,
1952  (errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED),
1953  errmsg("temporary file size exceeds temp_file_limit (%dkB)",
1954  temp_file_limit)));
1955  }
1956  }
1957 
1958 retry:
1959  errno = 0;
1960  pgstat_report_wait_start(wait_event_info);
1961  returnCode = pg_pwrite(VfdCache[file].fd, buffer, amount, offset);
1963 
1964  /* if write didn't set errno, assume problem is no disk space */
1965  if (returnCode != amount && errno == 0)
1966  errno = ENOSPC;
1967 
1968  if (returnCode >= 0)
1969  {
1970  /*
1971  * Maintain fileSize and temporary_files_size if it's a temp file.
1972  */
1973  if (vfdP->fdstate & FD_TEMP_FILE_LIMIT)
1974  {
1975  off_t past_write = offset + amount;
1976 
1977  if (past_write > vfdP->fileSize)
1978  {
1979  temporary_files_size += past_write - vfdP->fileSize;
1980  vfdP->fileSize = past_write;
1981  }
1982  }
1983  }
1984  else
1985  {
1986  /*
1987  * See comments in FileRead()
1988  */
1989 #ifdef WIN32
1990  DWORD error = GetLastError();
1991 
1992  switch (error)
1993  {
1994  case ERROR_NO_SYSTEM_RESOURCES:
1995  pg_usleep(1000L);
1996  errno = EINTR;
1997  break;
1998  default:
1999  _dosmaperr(error);
2000  break;
2001  }
2002 #endif
2003  /* OK to retry if interrupted */
2004  if (errno == EINTR)
2005  goto retry;
2006  }
2007 
2008  return returnCode;
2009 }
static void error(void)
Definition: sql-dyntest.c:147
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:175
#define DO_DB(A)
Definition: fd.c:161
void _dosmaperr(unsigned long)
Definition: win32error.c:171
static Vfd * VfdCache
Definition: fd.c:197
int errcode(int sqlerrcode)
Definition: elog.c:570
#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:1342
unsigned short fdstate
Definition: fd.c:180
Definition: fd.c:177
off_t fileSize
Definition: fd.c:185
#define ereport(elevel, rest)
Definition: elog.h:141
#define FileIsValid(file)
Definition: fd.c:167
static uint64 temporary_files_size
Definition: fd.c:217
static int FileAccess(File file)
Definition: fd.c:1238
#define Assert(condition)
Definition: c.h:732
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1318
#define INT64_FORMAT
Definition: c.h:400
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
#define EINTR
Definition: win32_port.h:332
int temp_file_limit
Definition: guc.c:517

◆ FileWriteback()

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

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

1836 {
1837  int returnCode;
1838 
1839  Assert(FileIsValid(file));
1840 
1841  DO_DB(elog(LOG, "FileWriteback: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
1842  file, VfdCache[file].fileName,
1843  (int64) offset, (int64) nbytes));
1844 
1845  if (nbytes <= 0)
1846  return;
1847 
1848  returnCode = FileAccess(file);
1849  if (returnCode < 0)
1850  return;
1851 
1852  pgstat_report_wait_start(wait_event_info);
1853  pg_flush_data(VfdCache[file].fd, offset, nbytes);
1855 }
#define DO_DB(A)
Definition: fd.c:161
static Vfd * VfdCache
Definition: fd.c:197
#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:1342
void pg_flush_data(int fd, off_t offset, off_t nbytes)
Definition: fd.c:403
#define FileIsValid(file)
Definition: fd.c:167
static int FileAccess(File file)
Definition: fd.c:1238
#define Assert(condition)
Definition: c.h:732
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1318
#define INT64_FORMAT
Definition: c.h:400
#define elog(elevel,...)
Definition: elog.h:226

◆ FreeDir()

int FreeDir ( DIR dir)

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

2585 {
2586  int i;
2587 
2588  /* Nothing to do if AllocateDir failed */
2589  if (dir == NULL)
2590  return 0;
2591 
2592  DO_DB(elog(LOG, "FreeDir: Allocated %d", numAllocatedDescs));
2593 
2594  /* Remove dir from list of allocated dirs, if it's present */
2595  for (i = numAllocatedDescs; --i >= 0;)
2596  {
2597  AllocateDesc *desc = &allocatedDescs[i];
2598 
2599  if (desc->kind == AllocateDescDir && desc->desc.dir == dir)
2600  return FreeDesc(desc);
2601  }
2602 
2603  /* Only get here if someone passes us a dir not in allocatedDescs */
2604  elog(WARNING, "dir passed to FreeDir was not obtained from AllocateDir");
2605 
2606  return closedir(dir);
2607 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
union AllocateDesc::@26 desc
DIR * dir
Definition: fd.c:238
#define DO_DB(A)
Definition: fd.c:161
int closedir(DIR *)
Definition: dirent.c:113
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2365
#define WARNING
Definition: elog.h:40
#define elog(elevel,...)
Definition: elog.h:226
int i
static int numAllocatedDescs
Definition: fd.c:243

◆ FreeFile()

int FreeFile ( FILE *  file)

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

2405 {
2406  int i;
2407 
2408  DO_DB(elog(LOG, "FreeFile: Allocated %d", numAllocatedDescs));
2409 
2410  /* Remove file from list of allocated files, if it's present */
2411  for (i = numAllocatedDescs; --i >= 0;)
2412  {
2413  AllocateDesc *desc = &allocatedDescs[i];
2414 
2415  if (desc->kind == AllocateDescFile && desc->desc.file == file)
2416  return FreeDesc(desc);
2417  }
2418 
2419  /* Only get here if someone passes us a file not in allocatedDescs */
2420  elog(WARNING, "file passed to FreeFile was not obtained from AllocateFile");
2421 
2422  return fclose(file);
2423 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
union AllocateDesc::@26 desc
#define DO_DB(A)
Definition: fd.c:161
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2365
#define WARNING
Definition: elog.h:40
FILE * file
Definition: fd.c:237
#define elog(elevel,...)
Definition: elog.h:226
int i
static int numAllocatedDescs
Definition: fd.c:243

◆ fsync_fname()

◆ GetNextTempTableSpace()

Oid GetNextTempTableSpace ( void  )

Definition at line 2727 of file fd.c.

References InvalidOid, nextTempTableSpace, numTempTableSpaces, and tempTableSpaces.

Referenced by GetDefaultTablespace(), and OpenTemporaryFile().

2728 {
2729  if (numTempTableSpaces > 0)
2730  {
2731  /* Advance nextTempTableSpace counter with wraparound */
2733  nextTempTableSpace = 0;
2735  }
2736  return InvalidOid;
2737 }
static int numTempTableSpaces
Definition: fd.c:258
static int nextTempTableSpace
Definition: fd.c:259
#define InvalidOid
Definition: postgres_ext.h:36
static Oid * tempTableSpaces
Definition: fd.c:257

◆ GetTempTablespaces()

int GetTempTablespaces ( Oid tableSpaces,
int  numSpaces 
)

Definition at line 2709 of file fd.c.

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

Referenced by SharedFileSetInit().

2710 {
2711  int i;
2712 
2714  for (i = 0; i < numTempTableSpaces && i < numSpaces; ++i)
2715  tableSpaces[i] = tempTableSpaces[i];
2716 
2717  return i;
2718 }
static int numTempTableSpaces
Definition: fd.c:258
bool TempTablespacesAreSet(void)
Definition: fd.c:2697
#define Assert(condition)
Definition: c.h:732
static Oid * tempTableSpaces
Definition: fd.c:257
int i

◆ InitFileAccess()

void InitFileAccess ( void  )

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

785 {
786  Assert(SizeVfdCache == 0); /* call me only once */
787 
788  /* initialize cache header entry */
789  VfdCache = (Vfd *) malloc(sizeof(Vfd));
790  if (VfdCache == NULL)
791  ereport(FATAL,
792  (errcode(ERRCODE_OUT_OF_MEMORY),
793  errmsg("out of memory")));
794 
795  MemSet((char *) &(VfdCache[0]), 0, sizeof(Vfd));
797 
798  SizeVfdCache = 1;
799 
800  /* register proc-exit hook to ensure temp files are dropped at exit */
802 }
static void AtProcExit_Files(int code, Datum arg)
Definition: fd.c:2795
static Size SizeVfdCache
Definition: fd.c:198
void on_proc_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:305
static Vfd * VfdCache
Definition: fd.c:197
int errcode(int sqlerrcode)
Definition: elog.c:570
#define MemSet(start, val, len)
Definition: c.h:955
#define malloc(a)
Definition: header.h:50
#define FATAL
Definition: elog.h:52
Definition: fd.c:177
int fd
Definition: fd.c:179
#define ereport(elevel, rest)
Definition: elog.h:141
#define VFD_CLOSED
Definition: fd.c:165
#define Assert(condition)
Definition: c.h:732
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ looks_like_temp_rel_name()

bool looks_like_temp_rel_name ( const char *  name)

Definition at line 3064 of file fd.c.

References forkname_chars().

Referenced by RemovePgTempRelationFilesInDbspace(), and sendDir().

3065 {
3066  int pos;
3067  int savepos;
3068 
3069  /* Must start with "t". */
3070  if (name[0] != 't')
3071  return false;
3072 
3073  /* Followed by a non-empty string of digits and then an underscore. */
3074  for (pos = 1; isdigit((unsigned char) name[pos]); ++pos)
3075  ;
3076  if (pos == 1 || name[pos] != '_')
3077  return false;
3078 
3079  /* Followed by another nonempty string of digits. */
3080  for (savepos = ++pos; isdigit((unsigned char) name[pos]); ++pos)
3081  ;
3082  if (savepos == pos)
3083  return false;
3084 
3085  /* We might have _forkname or .segment or both. */
3086  if (name[pos] == '_')
3087  {
3088  int forkchar = forkname_chars(&name[pos + 1], NULL);
3089 
3090  if (forkchar <= 0)
3091  return false;
3092  pos += forkchar + 1;
3093  }
3094  if (name[pos] == '.')
3095  {
3096  int segchar;
3097 
3098  for (segchar = 1; isdigit((unsigned char) name[pos + segchar]); ++segchar)
3099  ;
3100  if (segchar <= 1)
3101  return false;
3102  pos += segchar;
3103  }
3104 
3105  /* Now we should be at the end. */
3106  if (name[pos] != '\0')
3107  return false;
3108  return true;
3109 }
int forkname_chars(const char *str, ForkNumber *fork)
Definition: relpath.c:78
const char * name
Definition: encode.c:521

◆ MakePGDirectory()

int MakePGDirectory ( const char *  directoryName)

◆ OpenPipeStream()

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

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

2309 {
2310  FILE *file;
2311  int save_errno;
2312 
2313  DO_DB(elog(LOG, "OpenPipeStream: Allocated %d (%s)",
2314  numAllocatedDescs, command));
2315 
2316  /* Can we allocate another non-virtual FD? */
2317  if (!reserveAllocatedDesc())
2318  ereport(ERROR,
2319  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2320  errmsg("exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"",
2321  maxAllocatedDescs, command)));
2322 
2323  /* Close excess kernel FDs. */
2324  ReleaseLruFiles();
2325 
2326 TryAgain:
2327  fflush(stdout);
2328  fflush(stderr);
2330  errno = 0;
2331  file = popen(command, mode);
2332  save_errno = errno;
2334  errno = save_errno;
2335  if (file != NULL)
2336  {
2338 
2339  desc->kind = AllocateDescPipe;
2340  desc->desc.file = file;
2343  return desc->desc.file;
2344  }
2345 
2346  if (errno == EMFILE || errno == ENFILE)
2347  {
2348  ereport(LOG,
2349  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2350  errmsg("out of file descriptors: %m; release and retry")));
2351  if (ReleaseLruFile())
2352  goto TryAgain;
2353  errno = save_errno;
2354  }
2355 
2356  return NULL;
2357 }
static PgChecksumMode mode
Definition: pg_checksums.c:61
static AllocateDesc * allocatedDescs
Definition: fd.c:245
union AllocateDesc::@26 desc
#define DO_DB(A)
Definition: fd.c:161
int errcode(int sqlerrcode)
Definition: elog.c:570
static bool reserveAllocatedDesc(void)
Definition: fd.c:2132
#define SIGPIPE
Definition: win32_port.h:168
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static bool ReleaseLruFile(void)
Definition: fd.c:1128
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
#define SIG_IGN
Definition: win32_port.h:160
static void ReleaseLruFiles(void)
Definition: fd.c:1150
FILE * file
Definition: fd.c:237
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:170
#define SIG_DFL
Definition: win32_port.h:158
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:708
SubTransactionId create_subid
Definition: fd.c:234
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
static int maxAllocatedDescs
Definition: fd.c:244
static int numAllocatedDescs
Definition: fd.c:243

◆ OpenTemporaryFile()

File OpenTemporaryFile ( bool  interXact)

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

1463 {
1464  File file = 0;
1465 
1466  /*
1467  * Make sure the current resource owner has space for this File before we
1468  * open it, if we'll be registering it below.
1469  */
1470  if (!interXact)
1472 
1473  /*
1474  * If some temp tablespace(s) have been given to us, try to use the next
1475  * one. If a given tablespace can't be found, we silently fall back to
1476  * the database's default tablespace.
1477  *
1478  * BUT: if the temp file is slated to outlive the current transaction,
1479  * force it into the database's default tablespace, so that it will not
1480  * pose a threat to possible tablespace drop attempts.
1481  */
1482  if (numTempTableSpaces > 0 && !interXact)
1483  {
1484  Oid tblspcOid = GetNextTempTableSpace();
1485 
1486  if (OidIsValid(tblspcOid))
1487  file = OpenTemporaryFileInTablespace(tblspcOid, false);
1488  }
1489 
1490  /*
1491  * If not, or if tablespace is bad, create in database's default
1492  * tablespace. MyDatabaseTableSpace should normally be set before we get
1493  * here, but just in case it isn't, fall back to pg_default tablespace.
1494  */
1495  if (file <= 0)
1498  DEFAULTTABLESPACE_OID,
1499  true);
1500 
1501  /* Mark it for deletion at close and temporary file size limit */
1503 
1504  /* Register it with the current resource owner */
1505  if (!interXact)
1506  RegisterTemporaryFile(file);
1507 
1508  return file;
1509 }
static File OpenTemporaryFileInTablespace(Oid tblspcOid, bool rejectError)
Definition: fd.c:1540
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:175
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
#define FD_DELETE_AT_CLOSE
Definition: fd.c:173
static Vfd * VfdCache
Definition: fd.c:197
static int numTempTableSpaces
Definition: fd.c:258
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
Oid MyDatabaseTableSpace
Definition: globals.c:87
Oid GetNextTempTableSpace(void)
Definition: fd.c:2727
unsigned short fdstate
Definition: fd.c:180
static void RegisterTemporaryFile(File file)
Definition: fd.c:1293
void ResourceOwnerEnlargeFiles(ResourceOwner owner)
Definition: resowner.c:1233
int File
Definition: fd.h:45

◆ OpenTransientFile()

◆ OpenTransientFilePerm()

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

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

2265 {
2266  int fd;
2267 
2268  DO_DB(elog(LOG, "OpenTransientFile: Allocated %d (%s)",
2269  numAllocatedDescs, fileName));
2270 
2271  /* Can we allocate another non-virtual FD? */
2272  if (!reserveAllocatedDesc())
2273  ereport(ERROR,
2274  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2275  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2276  maxAllocatedDescs, fileName)));
2277 
2278  /* Close excess kernel FDs. */
2279  ReleaseLruFiles();
2280 
2281  fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
2282 
2283  if (fd >= 0)
2284  {
2286 
2287  desc->kind = AllocateDescRawFD;
2288  desc->desc.fd = fd;
2291 
2292  return fd;
2293  }
2294 
2295  return -1; /* failure */
2296 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
union AllocateDesc::@26 desc
#define DO_DB(A)
Definition: fd.c:161
int errcode(int sqlerrcode)
Definition: elog.c:570
static bool reserveAllocatedDesc(void)
Definition: fd.c:2132
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
static void ReleaseLruFiles(void)
Definition: fd.c:1150
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:708
SubTransactionId create_subid
Definition: fd.c:234
int fd
Definition: fd.c:239
int errmsg(const char *fmt,...)
Definition: elog.c:784
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:966
#define elog(elevel,...)
Definition: elog.h:226
static int maxAllocatedDescs
Definition: fd.c:244
static int numAllocatedDescs
Definition: fd.c:243

◆ PathNameCreateTemporaryDir()

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

Definition at line 1398 of file fd.c.

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

Referenced by SharedFileSetCreate().

1399 {
1400  if (MakePGDirectory(directory) < 0)
1401  {
1402  if (errno == EEXIST)
1403  return;
1404 
1405  /*
1406  * Failed. Try to create basedir first in case it's missing. Tolerate
1407  * EEXIST to close a race against another process following the same
1408  * algorithm.
1409  */
1410  if (MakePGDirectory(basedir) < 0 && errno != EEXIST)
1411  ereport(ERROR,
1413  errmsg("cannot create temporary directory \"%s\": %m",
1414  basedir)));
1415 
1416  /* Try again. */
1417  if (MakePGDirectory(directory) < 0 && errno != EEXIST)
1418  ereport(ERROR,
1420  errmsg("cannot create temporary subdirectory \"%s\": %m",
1421  directory)));
1422  }
1423 }
static char * basedir
Definition: pg_basebackup.c:86
#define ERROR
Definition: elog.h:43
int errcode_for_file_access(void)
Definition: elog.c:593
#define ereport(elevel, rest)
Definition: elog.h:141
int MakePGDirectory(const char *directoryName)
Definition: fd.c:3459
static const char * directory
Definition: zic.c:622
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ PathNameCreateTemporaryFile()

File PathNameCreateTemporaryFile ( const char *  name,
bool  error_on_failure 
)

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

1598 {
1599  File file;
1600 
1602 
1603  /*
1604  * Open the file. Note: we don't use O_EXCL, in case there is an orphaned
1605  * temp file that can be reused.
1606  */
1607  file = PathNameOpenFile(path, O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1608  if (file <= 0)
1609  {
1610  if (error_on_failure)
1611  ereport(ERROR,
1613  errmsg("could not create temporary file \"%s\": %m",
1614  path)));
1615  else
1616  return file;
1617  }
1618 
1619  /* Mark it for temp_file_limit accounting. */
1621 
1622  /* Register it for automatic close. */
1623  RegisterTemporaryFile(file);
1624 
1625  return file;
1626 }
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1321
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:175
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
static Vfd * VfdCache
Definition: fd.c:197
#define PG_BINARY
Definition: c.h:1191
#define ERROR
Definition: elog.h:43
int errcode_for_file_access(void)
Definition: elog.c:593
unsigned short fdstate
Definition: fd.c:180
#define ereport(elevel, rest)
Definition: elog.h:141
static void RegisterTemporaryFile(File file)
Definition: fd.c:1293
int errmsg(const char *fmt,...)
Definition: elog.c:784
void ResourceOwnerEnlargeFiles(ResourceOwner owner)
Definition: resowner.c:1233
int File
Definition: fd.h:45

◆ PathNameDeleteTemporaryDir()

void PathNameDeleteTemporaryDir ( const char *  name)

Definition at line 1429 of file fd.c.

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

Referenced by SharedFileSetDeleteAll().

1430 {
1431  struct stat statbuf;
1432 
1433  /* Silently ignore missing directory. */
1434  if (stat(dirname, &statbuf) != 0 && errno == ENOENT)
1435  return;
1436 
1437  /*
1438  * Currently, walkdir doesn't offer a way for our passed in function to
1439  * maintain state. Perhaps it should, so that we could tell the caller
1440  * whether this operation succeeded or failed. Since this operation is
1441  * used in a cleanup path, we wouldn't actually behave differently: we'll
1442  * just log failures.
1443  */
1444  walkdir(dirname, unlink_if_exists_fname, false, LOG);
1445 }
static void walkdir(const char *path, void(*action)(const char *fname, bool isdir, int elevel), bool process_symlinks, int elevel)
Definition: fd.c:3208
#define LOG
Definition: elog.h:26
static void unlink_if_exists_fname(const char *fname, bool isdir, int elevel)
Definition: fd.c:3318
#define stat(a, b)
Definition: win32_port.h:264

◆ PathNameDeleteTemporaryFile()

bool PathNameDeleteTemporaryFile ( const char *  name,
bool  error_on_failure 
)

Definition at line 1665 of file fd.c.

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

Referenced by SharedFileSetDelete(), and unlink_if_exists_fname().

1666 {
1667  struct stat filestats;
1668  int stat_errno;
1669 
1670  /* Get the final size for pgstat reporting. */
1671  if (stat(path, &filestats) != 0)
1672  stat_errno = errno;
1673  else
1674  stat_errno = 0;
1675 
1676  /*
1677  * Unlike FileClose's automatic file deletion code, we tolerate
1678  * non-existence to support BufFileDeleteShared which doesn't know how
1679  * many segments it has to delete until it runs out.
1680  */
1681  if (stat_errno == ENOENT)
1682  return false;
1683 
1684  if (unlink(path) < 0)
1685  {
1686  if (errno != ENOENT)
1687  ereport(error_on_failure ? ERROR : LOG,
1689  errmsg("cannot unlink temporary file \"%s\": %m",
1690  path)));
1691  return false;
1692  }
1693 
1694  if (stat_errno == 0)
1695  ReportTemporaryFileUsage(path, filestats.st_size);
1696  else
1697  {
1698  errno = stat_errno;
1699  ereport(LOG,
1701  errmsg("could not stat file \"%s\": %m", path)));
1702  }
1703 
1704  return true;
1705 }
#define LOG
Definition: elog.h:26
#define ERROR
Definition: elog.h:43
int errcode_for_file_access(void)
Definition: elog.c:593
#define ereport(elevel, rest)
Definition: elog.h:141
static void ReportTemporaryFileUsage(const char *path, off_t size)
Definition: fd.c:1274
#define stat(a, b)
Definition: win32_port.h:264
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ PathNameOpenFile()

File PathNameOpenFile ( const char *  fileName,
int  fileFlags 
)

Definition at line 1321 of file fd.c.

References PathNameOpenFilePerm(), and pg_file_create_mode.

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

1322 {
1323  return PathNameOpenFilePerm(fileName, fileFlags, pg_file_create_mode);
1324 }
File PathNameOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1334
int pg_file_create_mode
Definition: file_perm.c:19

◆ PathNameOpenFilePerm()

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

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

1335 {
1336  char *fnamecopy;
1337  File file;
1338  Vfd *vfdP;
1339 
1340  DO_DB(elog(LOG, "PathNameOpenFilePerm: %s %x %o",
1341  fileName, fileFlags, fileMode));
1342 
1343  /*
1344  * We need a malloc'd copy of the file name; fail cleanly if no room.
1345  */
1346  fnamecopy = strdup(fileName);
1347  if (fnamecopy == NULL)
1348  ereport(ERROR,
1349  (errcode(ERRCODE_OUT_OF_MEMORY),
1350  errmsg("out of memory")));
1351 
1352  file = AllocateVfd();
1353  vfdP = &VfdCache[file];
1354 
1355  /* Close excess kernel FDs. */
1356  ReleaseLruFiles();
1357 
1358  vfdP->fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
1359 
1360  if (vfdP->fd < 0)
1361  {
1362  int save_errno = errno;
1363 
1364  FreeVfd(file);
1365  free(fnamecopy);
1366  errno = save_errno;
1367  return -1;
1368  }
1369  ++nfile;
1370  DO_DB(elog(LOG, "PathNameOpenFile: success %d",
1371  vfdP->fd));
1372 
1373  Insert(file);
1374 
1375  vfdP->fileName = fnamecopy;
1376  /* Saved flags are adjusted to be OK for re-opening file */
1377  vfdP->fileFlags = fileFlags & ~(O_CREAT | O_TRUNC | O_EXCL);
1378  vfdP->fileMode = fileMode;
1379  vfdP->fileSize = 0;
1380  vfdP->fdstate = 0x0;
1381  vfdP->resowner = NULL;
1382 
1383  return file;
1384 }
#define DO_DB(A)
Definition: fd.c:161
static Vfd * VfdCache
Definition: fd.c:197
int errcode(int sqlerrcode)
Definition: elog.c:570
#define LOG
Definition: elog.h:26
mode_t fileMode
Definition: fd.c:189
#define ERROR
Definition: elog.h:43
char * fileName
Definition: fd.c:186
static int nfile
Definition: fd.c:203
static File AllocateVfd(void)
Definition: fd.c:1160
unsigned short fdstate
Definition: fd.c:180
Definition: fd.c:177
off_t fileSize
Definition: fd.c:185
int fd
Definition: fd.c:179
#define ereport(elevel, rest)
Definition: elog.h:141
static void Insert(File file)
Definition: fd.c:1059
ResourceOwner resowner
Definition: fd.c:181
static void ReleaseLruFiles(void)
Definition: fd.c:1150
#define free(a)
Definition: header.h:65
int errmsg(const char *fmt,...)
Definition: elog.c:784
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:966
#define elog(elevel,...)
Definition: elog.h:226
static void FreeVfd(File file)
Definition: fd.c:1218
int fileFlags
Definition: fd.c:188
int File
Definition: fd.h:45

◆ PathNameOpenTemporaryFile()

File PathNameOpenTemporaryFile ( const char *  name)

Definition at line 1635 of file fd.c.

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

Referenced by SharedFileSetOpen().

1636 {
1637  File file;
1638 
1640 
1641  /* We open the file read-only. */
1642  file = PathNameOpenFile(path, O_RDONLY | PG_BINARY);
1643 
1644  /* If no such file, then we don't raise an error. */
1645  if (file <= 0 && errno != ENOENT)
1646  ereport(ERROR,
1648  errmsg("could not open temporary file \"%s\": %m",
1649  path)));
1650 
1651  if (file > 0)
1652  {
1653  /* Register it for automatic close. */
1654  RegisterTemporaryFile(file);
1655  }
1656 
1657  return file;
1658 }
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1321
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
#define PG_BINARY
Definition: c.h:1191
#define ERROR
Definition: elog.h:43
int errcode_for_file_access(void)
Definition: elog.c:593
#define ereport(elevel, rest)
Definition: elog.h:141
static void RegisterTemporaryFile(File file)
Definition: fd.c:1293
int errmsg(const char *fmt,...)
Definition: elog.c:784
void ResourceOwnerEnlargeFiles(ResourceOwner owner)
Definition: resowner.c:1233
int File
Definition: fd.h:45

◆ pg_fdatasync()

int pg_fdatasync ( int  fd)

Definition at line 383 of file fd.c.

References enableFsync, and fsync.

Referenced by issue_xlog_fsync().

384 {
385  if (enableFsync)
386  {
387 #ifdef HAVE_FDATASYNC
388  return fdatasync(fd);
389 #else
390  return fsync(fd);
391 #endif
392  }
393  else
394  return 0;
395 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define fsync(fd)
Definition: win32_port.h:63
bool enableFsync
Definition: globals.c:119

◆ pg_flush_data()

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

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

404 {
405  /*
406  * Right now file flushing is primarily used to avoid making later
407  * fsync()/fdatasync() calls have less impact. Thus don't trigger flushes
408  * if fsyncs are disabled - that's a decision we might want to make
409  * configurable at some point.
410  */
411  if (!enableFsync)
412  return;
413 
414  /*
415  * We compile all alternatives that are supported on the current platform,
416  * to find portability problems more easily.
417  */
418 #if defined(HAVE_SYNC_FILE_RANGE)
419  {
420  int rc;
421  static bool not_implemented_by_kernel = false;
422 
423  if (not_implemented_by_kernel)
424  return;
425 
426  /*
427  * sync_file_range(SYNC_FILE_RANGE_WRITE), currently linux specific,
428  * tells the OS that writeback for the specified blocks should be
429  * started, but that we don't want to wait for completion. Note that
430  * this call might block if too much dirty data exists in the range.
431  * This is the preferable method on OSs supporting it, as it works
432  * reliably when available (contrast to msync()) and doesn't flush out
433  * clean data (like FADV_DONTNEED).
434  */
435  rc = sync_file_range(fd, offset, nbytes,
436  SYNC_FILE_RANGE_WRITE);
437  if (rc != 0)
438  {
439  int elevel;
440 
441  /*
442  * For systems that don't have an implementation of
443  * sync_file_range() such as Windows WSL, generate only one
444  * warning and then suppress all further attempts by this process.
445  */
446  if (errno == ENOSYS)
447  {
448  elevel = WARNING;
449  not_implemented_by_kernel = true;
450  }
451  else
452  elevel = data_sync_elevel(WARNING);
453 
454  ereport(elevel,
456  errmsg("could not flush dirty data: %m")));
457  }
458 
459  return;
460  }
461 #endif
462 #if !defined(WIN32) && defined(MS_ASYNC)
463  {
464  void *p;
465  static int pagesize = 0;
466 
467  /*
468  * On several OSs msync(MS_ASYNC) on a mmap'ed file triggers
469  * writeback. On linux it only does so if MS_SYNC is specified, but
470  * then it does the writeback synchronously. Luckily all common linux
471  * systems have sync_file_range(). This is preferable over
472  * FADV_DONTNEED because it doesn't flush out clean data.
473  *
474  * We map the file (mmap()), tell the kernel to sync back the contents
475  * (msync()), and then remove the mapping again (munmap()).
476  */
477 
478  /* mmap() needs actual length if we want to map whole file */
479  if (offset == 0 && nbytes == 0)
480  {
481  nbytes = lseek(fd, 0, SEEK_END);
482  if (nbytes < 0)
483  {
486  errmsg("could not determine dirty data size: %m")));
487  return;
488  }
489  }
490 
491  /*
492  * Some platforms reject partial-page mmap() attempts. To deal with
493  * that, just truncate the request to a page boundary. If any extra
494  * bytes don't get flushed, well, it's only a hint anyway.
495  */
496 
497  /* fetch pagesize only once */
498  if (pagesize == 0)
499  pagesize = sysconf(_SC_PAGESIZE);
500 
501  /* align length to pagesize, dropping any fractional page */
502  if (pagesize > 0)
503  nbytes = (nbytes / pagesize) * pagesize;
504 
505  /* fractional-page request is a no-op */
506  if (nbytes <= 0)
507  return;
508 
509  /*
510  * mmap could well fail, particularly on 32-bit platforms where there
511  * may simply not be enough address space. If so, silently fall
512  * through to the next implementation.
513  */
514  if (nbytes <= (off_t) SSIZE_MAX)
515  p = mmap(NULL, nbytes, PROT_READ, MAP_SHARED, fd, offset);
516  else
517  p = MAP_FAILED;
518 
519  if (p != MAP_FAILED)
520  {
521  int rc;
522 
523  rc = msync(p, (size_t) nbytes, MS_ASYNC);
524  if (rc != 0)
525  {
528  errmsg("could not flush dirty data: %m")));
529  /* NB: need to fall through to munmap()! */
530  }
531 
532  rc = munmap(p, (size_t) nbytes);
533  if (rc != 0)
534  {
535  /* FATAL error because mapping would remain */
536  ereport(FATAL,
538  errmsg("could not munmap() while flushing data: %m")));
539  }
540 
541  return;
542  }
543  }
544 #endif
545 #if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED)
546  {
547  int rc;
548 
549  /*
550  * Signal the kernel that the passed in range should not be cached
551  * anymore. This has the, desired, side effect of writing out dirty
552  * data, and the, undesired, side effect of likely discarding useful
553  * clean cached blocks. For the latter reason this is the least
554  * preferable method.
555  */
556 
557  rc = posix_fadvise(fd, offset, nbytes, POSIX_FADV_DONTNEED);
558 
559  if (rc != 0)
560  {
561  /* don't error out, this is just a performance optimization */
564  errmsg("could not flush dirty data: %m")));
565  }
566 
567  return;
568  }
569 #endif
570 }
#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:593
#define ereport(elevel, rest)
Definition: elog.h:141
#define WARNING
Definition: elog.h:40
static int elevel
Definition: vacuumlazy.c:143
int data_sync_elevel(int elevel)
Definition: fd.c:3482
bool enableFsync
Definition: globals.c:119
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ pg_fsync()

int pg_fsync ( int  fd)

Definition at line 331 of file fd.c.

References pg_fsync_no_writethrough(), pg_fsync_writethrough(), 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().

332 {
333  /* #if is to skip the sync_method test if there's no need for it */
334 #if defined(HAVE_FSYNC_WRITETHROUGH) && !defined(FSYNC_WRITETHROUGH_IS_FSYNC)
336  return pg_fsync_writethrough(fd);
337  else
338 #endif
340 }
#define SYNC_METHOD_FSYNC_WRITETHROUGH
Definition: xlog.h:28
int pg_fsync_writethrough(int fd)
Definition: fd.c:360
int pg_fsync_no_writethrough(int fd)
Definition: fd.c:348
static int fd(const char *x, int i)
Definition: preproc-init.c:105
int sync_method
Definition: xlog.c:102

◆ pg_fsync_no_writethrough()

int pg_fsync_no_writethrough ( int  fd)

Definition at line 348 of file fd.c.

References enableFsync, and fsync.

Referenced by issue_xlog_fsync(), and pg_fsync().

349 {
350  if (enableFsync)
351  return fsync(fd);
352  else
353  return 0;
354 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define fsync(fd)
Definition: win32_port.h:63
bool enableFsync
Definition: globals.c:119

◆ pg_fsync_writethrough()

int pg_fsync_writethrough ( int  fd)

Definition at line 360 of file fd.c.

References enableFsync.

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

361 {
362  if (enableFsync)
363  {
364 #ifdef WIN32
365  return _commit(fd);
366 #elif defined(F_FULLFSYNC)
367  return (fcntl(fd, F_FULLFSYNC, 0) == -1) ? -1 : 0;
368 #else
369  errno = ENOSYS;
370  return -1;
371 #endif
372  }
373  else
374  return 0;
375 }
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 2547 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().

2548 {
2549  struct dirent *dent;
2550 
2551  /* Give a generic message for AllocateDir failure, if caller didn't */
2552  if (dir == NULL)
2553  {
2554  ereport(elevel,
2556  errmsg("could not open directory \"%s\": %m",
2557  dirname)));
2558  return NULL;
2559  }
2560 
2561  errno = 0;
2562  if ((dent = readdir(dir)) != NULL)
2563  return dent;
2564 
2565  if (errno)
2566  ereport(elevel,
2568  errmsg("could not read directory \"%s\": %m",
2569  dirname)));
2570  return NULL;
2571 }
Definition: dirent.h:9
int errcode_for_file_access(void)
Definition: elog.c:593
#define ereport(elevel, rest)
Definition: elog.h:141
static int elevel
Definition: vacuumlazy.c:143
struct dirent * readdir(DIR *)
Definition: dirent.c:77
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ RemovePgTempFiles()

void RemovePgTempFiles ( void  )

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

2884 {
2885  char temp_path[MAXPGPATH + 10 + sizeof(TABLESPACE_VERSION_DIRECTORY) + sizeof(PG_TEMP_FILES_DIR)];
2886  DIR *spc_dir;
2887  struct dirent *spc_de;
2888 
2889  /*
2890  * First process temp files in pg_default ($PGDATA/base)
2891  */
2892  snprintf(temp_path, sizeof(temp_path), "base/%s", PG_TEMP_FILES_DIR);
2893  RemovePgTempFilesInDir(temp_path, true, false);
2894  RemovePgTempRelationFiles("base");
2895 
2896  /*
2897  * Cycle through temp directories for all non-default tablespaces.
2898  */
2899  spc_dir = AllocateDir("pg_tblspc");
2900 
2901  while ((spc_de = ReadDirExtended(spc_dir, "pg_tblspc", LOG)) != NULL)
2902  {
2903  if (strcmp(spc_de->d_name, ".") == 0 ||
2904  strcmp(spc_de->d_name, "..") == 0)
2905  continue;
2906 
2907  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s/%s",
2909  RemovePgTempFilesInDir(temp_path, true, false);
2910 
2911  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s",
2913  RemovePgTempRelationFiles(temp_path);
2914  }
2915 
2916  FreeDir(spc_dir);
2917 
2918  /*
2919  * In EXEC_BACKEND case there is a pgsql_tmp directory at the top level of
2920  * DataDir as well. However, that is *not* cleaned here because doing so
2921  * would create a race condition. It's done separately, earlier in
2922  * postmaster startup.
2923  */
2924 }
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2547
#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:3008
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:2942
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2466
char d_name[MAX_PATH]
Definition: dirent.h:14
#define snprintf
Definition: port.h:192
int FreeDir(DIR *dir)
Definition: fd.c:2584

◆ RemovePgTempFilesInDir()

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

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

2943 {
2944  DIR *temp_dir;
2945  struct dirent *temp_de;
2946  char rm_path[MAXPGPATH * 2];
2947 
2948  temp_dir = AllocateDir(tmpdirname);
2949 
2950  if (temp_dir == NULL && errno == ENOENT && missing_ok)
2951  return;
2952 
2953  while ((temp_de = ReadDirExtended(temp_dir, tmpdirname, LOG)) != NULL)
2954  {
2955  if (strcmp(temp_de->d_name, ".") == 0 ||
2956  strcmp(temp_de->d_name, "..") == 0)
2957  continue;
2958 
2959  snprintf(rm_path, sizeof(rm_path), "%s/%s",
2960  tmpdirname, temp_de->d_name);
2961 
2962  if (unlink_all ||
2963  strncmp(temp_de->d_name,
2965  strlen(PG_TEMP_FILE_PREFIX)) == 0)
2966  {
2967  struct stat statbuf;
2968 
2969  if (lstat(rm_path, &statbuf) < 0)
2970  {
2971  ereport(LOG,
2973  errmsg("could not stat file \"%s\": %m", rm_path)));
2974  continue;
2975  }
2976 
2977  if (S_ISDIR(statbuf.st_mode))
2978  {
2979  /* recursively remove contents, then directory itself */
2980  RemovePgTempFilesInDir(rm_path, false, true);
2981 
2982  if (rmdir(rm_path) < 0)
2983  ereport(LOG,
2985  errmsg("could not remove directory \"%s\": %m",
2986  rm_path)));
2987  }
2988  else
2989  {
2990  if (unlink(rm_path) < 0)
2991  ereport(LOG,
2993  errmsg("could not remove file \"%s\": %m",
2994  rm_path)));
2995  }
2996  }
2997  else
2998  ereport(LOG,
2999  (errmsg("unexpected file found in temporary-files directory: \"%s\"",
3000  rm_path)));
3001  }
3002 
3003  FreeDir(temp_dir);
3004 }
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2547
#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:2942
int errcode_for_file_access(void)
Definition: elog.c:593
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2466
#define ereport(elevel, rest)
Definition: elog.h:141
#define stat(a, b)
Definition: win32_port.h:264
#define S_ISDIR(m)
Definition: win32_port.h:305
#define lstat(path, sb)
Definition: win32_port.h:253
int errmsg(const char *fmt,...)
Definition: elog.c:784
char d_name[MAX_PATH]
Definition: dirent.h:14
#define snprintf
Definition: port.h:192
int FreeDir(DIR *dir)
Definition: fd.c:2584

◆ set_max_safe_fds()

void set_max_safe_fds ( void  )

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

902 {
903  int usable_fds;
904  int already_open;
905 
906  /*----------
907  * We want to set max_safe_fds to
908  * MIN(usable_fds, max_files_per_process - already_open)
909  * less the slop factor for files that are opened without consulting
910  * fd.c. This ensures that we won't exceed either max_files_per_process
911  * or the experimentally-determined EMFILE limit.
912  *----------
913  */
915  &usable_fds, &already_open);
916 
917  max_safe_fds = Min(usable_fds, max_files_per_process - already_open);
918 
919  /*
920  * Take off the FDs reserved for system() etc.
921  */
923 
924  /*
925  * Make sure we still have enough to get by.
926  */
927  if (max_safe_fds < FD_MINFREE)
928  ereport(FATAL,
929  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
930  errmsg("insufficient file descriptors available to start server process"),
931  errdetail("System allows %d, we need at least %d.",
934 
935  elog(DEBUG2, "max_safe_fds = %d, usable_fds = %d, already_open = %d",
936  max_safe_fds, usable_fds, already_open);
937 }
static void count_usable_fds(int max_to_probe, int *usable_fds, int *already_open)
Definition: fd.c:817
#define NUM_RESERVED_FDS
Definition: fd.c:119
int max_safe_fds
Definition: fd.c:146
#define Min(x, y)
Definition: c.h:904
int errcode(int sqlerrcode)
Definition: elog.c:570
#define FATAL
Definition: elog.h:52
#define DEBUG2
Definition: elog.h:24
int errdetail(const char *fmt,...)
Definition: elog.c:860
int max_files_per_process
Definition: fd.c:133
#define ereport(elevel, rest)
Definition: elog.h:141
#define FD_MINFREE
Definition: fd.c:125
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226

◆ SetTempTablespaces()

void SetTempTablespaces ( Oid tableSpaces,
int  numSpaces 
)

Definition at line 2669 of file fd.c.

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

Referenced by assign_temp_tablespaces(), and PrepareTempTablespaces().

2670 {
2671  Assert(numSpaces >= 0);
2672  tempTableSpaces = tableSpaces;
2673  numTempTableSpaces = numSpaces;
2674 
2675  /*
2676  * Select a random starting point in the list. This is to minimize
2677  * conflicts between backends that are most likely sharing the same list
2678  * of temp tablespaces. Note that if we create multiple temp files in the
2679  * same transaction, we'll advance circularly through the list --- this
2680  * ensures that large temporary sort files are nicely spread across all
2681  * available tablespaces.
2682  */
2683  if (numSpaces > 1)
2684  nextTempTableSpace = random() % numSpaces;
2685  else
2686  nextTempTableSpace = 0;
2687 }
long random(void)
Definition: random.c:22
static int numTempTableSpaces
Definition: fd.c:258
static int nextTempTableSpace
Definition: fd.c:259
#define Assert(condition)
Definition: c.h:732
static Oid * tempTableSpaces
Definition: fd.c:257

◆ SyncDataDirectory()

void SyncDataDirectory ( void  )

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

3135 {
3136  bool xlog_is_symlink;
3137 
3138  /* We can skip this whole thing if fsync is disabled. */
3139  if (!enableFsync)
3140  return;
3141 
3142  /*
3143  * If pg_wal is a symlink, we'll need to recurse into it separately,
3144  * because the first walkdir below will ignore it.
3145  */
3146  xlog_is_symlink = false;
3147 
3148 #ifndef WIN32
3149  {
3150  struct stat st;
3151 
3152  if (lstat("pg_wal", &st) < 0)
3153  ereport(LOG,
3155  errmsg("could not stat file \"%s\": %m",
3156  "pg_wal")));
3157  else if (S_ISLNK(st.st_mode))
3158  xlog_is_symlink = true;
3159  }
3160 #else
3161  if (pgwin32_is_junction("pg_wal"))
3162  xlog_is_symlink = true;
3163 #endif
3164 
3165  /*
3166  * If possible, hint to the kernel that we're soon going to fsync the data
3167  * directory and its contents. Errors in this step are even less
3168  * interesting than normal, so log them only at DEBUG1.
3169  */
3170 #ifdef PG_FLUSH_DATA_WORKS
3171  walkdir(".", pre_sync_fname, false, DEBUG1);
3172  if (xlog_is_symlink)
3173  walkdir("pg_wal", pre_sync_fname, false, DEBUG1);
3174  walkdir("pg_tblspc", pre_sync_fname, true, DEBUG1);
3175 #endif
3176 
3177  /*
3178  * Now we do the fsync()s in the same order.
3179  *
3180  * The main call ignores symlinks, so in addition to specially processing
3181  * pg_wal if it's a symlink, pg_tblspc has to be visited separately with
3182  * process_symlinks = true. Note that if there are any plain directories
3183  * in pg_tblspc, they'll get fsync'd twice. That's not an expected case
3184  * so we don't worry about optimizing it.
3185  */
3186  walkdir(".", datadir_fsync_fname, false, LOG);
3187  if (xlog_is_symlink)
3188  walkdir("pg_wal", datadir_fsync_fname, false, LOG);
3189  walkdir("pg_tblspc", datadir_fsync_fname, true, LOG);
3190 }
#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:3208
#define LOG
Definition: elog.h:26
int errcode_for_file_access(void)
Definition: elog.c:593
#define ereport(elevel, rest)
Definition: elog.h:141
static void datadir_fsync_fname(const char *fname, bool isdir, int elevel)
Definition: fd.c:3308
#define stat(a, b)
Definition: win32_port.h:264
#define lstat(path, sb)
Definition: win32_port.h:253
bool enableFsync
Definition: globals.c:119
int errmsg(const char *fmt,...)
Definition: elog.c:784
bool pgwin32_is_junction(const char *path)

◆ TempTablespacePath()

void TempTablespacePath ( char *  path,
Oid  tablespace 
)

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

1516 {
1517  /*
1518  * Identify the tempfile directory for this tablespace.
1519  *
1520  * If someone tries to specify pg_global, use pg_default instead.
1521  */
1522  if (tablespace == InvalidOid ||
1523  tablespace == DEFAULTTABLESPACE_OID ||
1524  tablespace == GLOBALTABLESPACE_OID)
1525  snprintf(path, MAXPGPATH, "base/%s", PG_TEMP_FILES_DIR);
1526  else
1527  {
1528  /* All other tablespaces are accessed via symlinks */
1529  snprintf(path, MAXPGPATH, "pg_tblspc/%u/%s/%s",
1532  }
1533 }
#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:186
#define InvalidOid
Definition: postgres_ext.h:36
#define snprintf
Definition: port.h:192

◆ TempTablespacesAreSet()

bool TempTablespacesAreSet ( void  )

Definition at line 2697 of file fd.c.

References numTempTableSpaces.

Referenced by GetTempTablespaces(), and PrepareTempTablespaces().

2698 {
2699  return (numTempTableSpaces >= 0);
2700 }
static int numTempTableSpaces
Definition: fd.c:258

Variable Documentation

◆ data_sync_retry

PGDLLIMPORT bool data_sync_retry

Definition at line 149 of file fd.c.

Referenced by data_sync_elevel().

◆ max_files_per_process

PGDLLIMPORT int max_files_per_process

Definition at line 133 of file fd.c.

Referenced by set_max_safe_fds().

◆ max_safe_fds

int max_safe_fds