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 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, uint32 wait_event_info)
 
int FileWrite (File file, char *buffer, int amount, uint32 wait_event_info)
 
int FileSync (File file, uint32 wait_event_info)
 
off_t FileSeek (File file, off_t offset, int whence)
 
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)
 
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 (void)
 
void AtEOSubXact_Files (bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
 
void RemovePgTempFiles (void)
 
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)
 

Variables

PGDLLIMPORT int max_files_per_process
 
int max_safe_fds
 

Macro Definition Documentation

◆ PG_TEMP_FILE_PREFIX

#define PG_TEMP_FILE_PREFIX   "pgsql_tmp"

◆ PG_TEMP_FILES_DIR

#define PG_TEMP_FILES_DIR   "pgsql_tmp"

Definition at line 139 of file fd.h.

Referenced by BackendRun(), process_source_file(), RemovePgTempFiles(), and TempTablespacePath().

Typedef Documentation

◆ File

Definition at line 49 of file fd.h.

Function Documentation

◆ AllocateDir()

DIR* AllocateDir ( const char *  dirname)

Definition at line 2597 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(), 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(), ResetUnloggedRelations(), ResetUnloggedRelationsInDbspaceDir(), ResetUnloggedRelationsInTablespaceDir(), restoreTwoPhaseData(), scan_directory_ci(), sendDir(), SlruScanDirectory(), StartupReorderBuffer(), StartupReplicationSlots(), UpdateLogicalMappings(), and walkdir().

2598 {
2599  DIR *dir;
2600 
2601  DO_DB(elog(LOG, "AllocateDir: Allocated %d (%s)",
2602  numAllocatedDescs, dirname));
2603 
2604  /* Can we allocate another non-virtual FD? */
2605  if (!reserveAllocatedDesc())
2606  ereport(ERROR,
2607  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2608  errmsg("exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"",
2609  maxAllocatedDescs, dirname)));
2610 
2611  /* Close excess kernel FDs. */
2612  ReleaseLruFiles();
2613 
2614 TryAgain:
2615  if ((dir = opendir(dirname)) != NULL)
2616  {
2618 
2619  desc->kind = AllocateDescDir;
2620  desc->desc.dir = dir;
2623  return desc->desc.dir;
2624  }
2625 
2626  if (errno == EMFILE || errno == ENFILE)
2627  {
2628  int save_errno = errno;
2629 
2630  ereport(LOG,
2631  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2632  errmsg("out of file descriptors: %m; release and retry")));
2633  errno = 0;
2634  if (ReleaseLruFile())
2635  goto TryAgain;
2636  errno = save_errno;
2637  }
2638 
2639  return NULL;
2640 }
static AllocateDesc * allocatedDescs
Definition: fd.c:259
DIR * dir
Definition: fd.c:252
#define DO_DB(A)
Definition: fd.c:165
int errcode(int sqlerrcode)
Definition: elog.c:575
static bool reserveAllocatedDesc(void)
Definition: fd.c:2270
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:247
static bool ReleaseLruFile(void)
Definition: fd.c:1165
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:122
static void ReleaseLruFiles(void)
Definition: fd.c:1187
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:642
SubTransactionId create_subid
Definition: fd.c:248
int errmsg(const char *fmt,...)
Definition: elog.c:797
union AllocateDesc::@27 desc
#define elog
Definition: elog.h:219
static int maxAllocatedDescs
Definition: fd.c:258
static int numAllocatedDescs
Definition: fd.c:257

◆ AllocateFile()

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

Definition at line 2343 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(), checkDataDir(), 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(), PGSharedMemoryIsInUse(), 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(), readRecoveryCommandFile(), readTimeLineHistory(), sendFile(), tokenize_inc_file(), tsearch_readline_begin(), ValidatePgVersion(), write_relcache_init_file(), XLogArchiveForceDone(), and XLogArchiveNotify().

2344 {
2345  FILE *file;
2346 
2347  DO_DB(elog(LOG, "AllocateFile: Allocated %d (%s)",
2349 
2350  /* Can we allocate another non-virtual FD? */
2351  if (!reserveAllocatedDesc())
2352  ereport(ERROR,
2353  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2354  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2355  maxAllocatedDescs, name)));
2356 
2357  /* Close excess kernel FDs. */
2358  ReleaseLruFiles();
2359 
2360 TryAgain:
2361  if ((file = fopen(name, mode)) != NULL)
2362  {
2364 
2365  desc->kind = AllocateDescFile;
2366  desc->desc.file = file;
2369  return desc->desc.file;
2370  }
2371 
2372  if (errno == EMFILE || errno == ENFILE)
2373  {
2374  int save_errno = errno;
2375 
2376  ereport(LOG,
2377  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2378  errmsg("out of file descriptors: %m; release and retry")));
2379  errno = 0;
2380  if (ReleaseLruFile())
2381  goto TryAgain;
2382  errno = save_errno;
2383  }
2384 
2385  return NULL;
2386 }
static AllocateDesc * allocatedDescs
Definition: fd.c:259
#define DO_DB(A)
Definition: fd.c:165
int errcode(int sqlerrcode)
Definition: elog.c:575
static bool reserveAllocatedDesc(void)
Definition: fd.c:2270
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:247
static bool ReleaseLruFile(void)
Definition: fd.c:1165
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
static void ReleaseLruFiles(void)
Definition: fd.c:1187
FILE * file
Definition: fd.c:251
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:642
SubTransactionId create_subid
Definition: fd.c:248
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:797
union AllocateDesc::@27 desc
#define elog
Definition: elog.h:219
static int maxAllocatedDescs
Definition: fd.c:258
static int numAllocatedDescs
Definition: fd.c:257

◆ AtEOSubXact_Files()

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

Definition at line 2879 of file fd.c.

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

2881 {
2882  Index i;
2883 
2884  for (i = 0; i < numAllocatedDescs; i++)
2885  {
2886  if (allocatedDescs[i].create_subid == mySubid)
2887  {
2888  if (isCommit)
2889  allocatedDescs[i].create_subid = parentSubid;
2890  else
2891  {
2892  /* have to recheck the item after FreeDesc (ugly) */
2893  FreeDesc(&allocatedDescs[i--]);
2894  }
2895  }
2896  }
2897 }
static AllocateDesc * allocatedDescs
Definition: fd.c:259
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2496
unsigned int Index
Definition: c.h:423
SubTransactionId create_subid
Definition: fd.c:248
int i
static int numAllocatedDescs
Definition: fd.c:257

◆ AtEOXact_Files()

void AtEOXact_Files ( void  )

Definition at line 2910 of file fd.c.

References CleanupTempFiles(), numTempTableSpaces, and tempTableSpaces.

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

2911 {
2912  CleanupTempFiles(false);
2913  tempTableSpaces = NULL;
2914  numTempTableSpaces = -1;
2915 }
static int numTempTableSpaces
Definition: fd.c:272
static void CleanupTempFiles(bool isProcExit)
Definition: fd.c:2939
static Oid * tempTableSpaces
Definition: fd.c:271

◆ BasicOpenFile()

int BasicOpenFile ( const char *  fileName,
int  fileFlags 
)

Definition at line 939 of file fd.c.

References BasicOpenFilePerm(), and PG_FILE_MODE_DEFAULT.

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

940 {
941  return BasicOpenFilePerm(fileName, fileFlags, PG_FILE_MODE_DEFAULT);
942 }
#define PG_FILE_MODE_DEFAULT
Definition: fd.c:131
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:961

◆ BasicOpenFilePerm()

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

Definition at line 961 of file fd.c.

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

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

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

◆ closeAllVfds()

void closeAllVfds ( void  )

Definition at line 2774 of file fd.c.

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

Referenced by standard_ProcessUtility().

2775 {
2776  Index i;
2777 
2778  if (SizeVfdCache > 0)
2779  {
2780  Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
2781  for (i = 1; i < SizeVfdCache; i++)
2782  {
2783  if (!FileIsNotOpen(i))
2784  LruDelete(i);
2785  }
2786  }
2787 }
static Size SizeVfdCache
Definition: fd.c:212
static void LruDelete(File file)
Definition: fd.c:1028
#define FileIsNotOpen(file)
Definition: fd.c:174
unsigned int Index
Definition: c.h:423
#define Assert(condition)
Definition: c.h:680
int i

◆ ClosePipeStream()

int ClosePipeStream ( FILE *  file)

Definition at line 2745 of file fd.c.

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

Referenced by ClosePipeToProgram(), and pg_import_system_collations().

2746 {
2747  int i;
2748 
2749  DO_DB(elog(LOG, "ClosePipeStream: Allocated %d", numAllocatedDescs));
2750 
2751  /* Remove file from list of allocated files, if it's present */
2752  for (i = numAllocatedDescs; --i >= 0;)
2753  {
2754  AllocateDesc *desc = &allocatedDescs[i];
2755 
2756  if (desc->kind == AllocateDescPipe && desc->desc.file == file)
2757  return FreeDesc(desc);
2758  }
2759 
2760  /* Only get here if someone passes us a file not in allocatedDescs */
2761  elog(WARNING, "file passed to ClosePipeStream was not obtained from OpenPipeStream");
2762 
2763  return pclose(file);
2764 }
static AllocateDesc * allocatedDescs
Definition: fd.c:259
#define DO_DB(A)
Definition: fd.c:165
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:247
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2496
#define WARNING
Definition: elog.h:40
FILE * file
Definition: fd.c:251
union AllocateDesc::@27 desc
int i
#define elog
Definition: elog.h:219
static int numAllocatedDescs
Definition: fd.c:257

◆ CloseTransientFile()

int CloseTransientFile ( int  fd)

Definition at line 2563 of file fd.c.

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

Referenced by be_lo_export(), CheckPointLogicalRewriteHeap(), CheckPointReplicationOrigin(), copy_file(), dsm_impl_mmap(), durable_rename(), fsync_fname_ext(), 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().

2564 {
2565  int i;
2566 
2567  DO_DB(elog(LOG, "CloseTransientFile: Allocated %d", numAllocatedDescs));
2568 
2569  /* Remove fd from list of allocated files, if it's present */
2570  for (i = numAllocatedDescs; --i >= 0;)
2571  {
2572  AllocateDesc *desc = &allocatedDescs[i];
2573 
2574  if (desc->kind == AllocateDescRawFD && desc->desc.fd == fd)
2575  return FreeDesc(desc);
2576  }
2577 
2578  /* Only get here if someone passes us a file not in allocatedDescs */
2579  elog(WARNING, "fd passed to CloseTransientFile was not obtained from OpenTransientFile");
2580 
2581  return close(fd);
2582 }
static AllocateDesc * allocatedDescs
Definition: fd.c:259
#define DO_DB(A)
Definition: fd.c:165
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:247
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2496
#define WARNING
Definition: elog.h:40
int fd
Definition: fd.c:253
union AllocateDesc::@27 desc
int i
#define elog
Definition: elog.h:219
#define close(a)
Definition: win32.h:12
static int numAllocatedDescs
Definition: fd.c:257

◆ durable_link_or_rename()

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

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

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

◆ durable_rename()

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

Definition at line 608 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(), exitArchiveRecovery(), KeepFileRestoredFromArchive(), pgarch_archiveDone(), pgss_shmem_shutdown(), StartupXLOG(), and XLogArchiveForceDone().

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

◆ durable_unlink()

int durable_unlink ( const char *  fname,
int  loglevel 
)

Definition at line 691 of file fd.c.

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

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

692 {
693  if (unlink(fname) < 0)
694  {
695  ereport(elevel,
697  errmsg("could not remove file \"%s\": %m",
698  fname)));
699  return -1;
700  }
701 
702  /*
703  * To guarantee that the removal of the file is persistent, fsync its
704  * parent directory.
705  */
706  if (fsync_parent_path(fname, elevel) != 0)
707  return -1;
708 
709  return 0;
710 }
int errcode_for_file_access(void)
Definition: elog.c:598
#define ereport(elevel, rest)
Definition: elog.h:122
static int elevel
Definition: vacuumlazy.c:136
int errmsg(const char *fmt,...)
Definition: elog.c:797
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3528

◆ FileClose()

void FileClose ( File  file)

Definition at line 1749 of file fd.c.

References Assert, close, 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().

1750 {
1751  Vfd *vfdP;
1752 
1753  Assert(FileIsValid(file));
1754 
1755  DO_DB(elog(LOG, "FileClose: %d (%s)",
1756  file, VfdCache[file].fileName));
1757 
1758  vfdP = &VfdCache[file];
1759 
1760  if (!FileIsNotOpen(file))
1761  {
1762  /* close the file */
1763  if (close(vfdP->fd))
1764  elog(LOG, "could not close file \"%s\": %m", vfdP->fileName);
1765 
1766  --nfile;
1767  vfdP->fd = VFD_CLOSED;
1768 
1769  /* remove the file from the lru ring */
1770  Delete(file);
1771  }
1772 
1773  if (vfdP->fdstate & FD_TEMP_FILE_LIMIT)
1774  {
1775  /* Subtract its size from current usage (do first in case of error) */
1776  temporary_files_size -= vfdP->fileSize;
1777  vfdP->fileSize = 0;
1778  }
1779 
1780  /*
1781  * Delete the file if it was temporary, and make a log entry if wanted
1782  */
1783  if (vfdP->fdstate & FD_DELETE_AT_CLOSE)
1784  {
1785  struct stat filestats;
1786  int stat_errno;
1787 
1788  /*
1789  * If we get an error, as could happen within the ereport/elog calls,
1790  * we'll come right back here during transaction abort. Reset the
1791  * flag to ensure that we can't get into an infinite loop. This code
1792  * is arranged to ensure that the worst-case consequence is failing to
1793  * emit log message(s), not failing to attempt the unlink.
1794  */
1795  vfdP->fdstate &= ~FD_DELETE_AT_CLOSE;
1796 
1797 
1798  /* first try the stat() */
1799  if (stat(vfdP->fileName, &filestats))
1800  stat_errno = errno;
1801  else
1802  stat_errno = 0;
1803 
1804  /* in any case do the unlink */
1805  if (unlink(vfdP->fileName))
1806  elog(LOG, "could not unlink file \"%s\": %m", vfdP->fileName);
1807 
1808  /* and last report the stat results */
1809  if (stat_errno == 0)
1810  ReportTemporaryFileUsage(vfdP->fileName, filestats.st_size);
1811  else
1812  {
1813  errno = stat_errno;
1814  elog(LOG, "could not stat file \"%s\": %m", vfdP->fileName);
1815  }
1816  }
1817 
1818  /* Unregister it from the resource owner */
1819  if (vfdP->resowner)
1820  ResourceOwnerForgetFile(vfdP->resowner, file);
1821 
1822  /*
1823  * Return the Vfd slot to the free list
1824  */
1825  FreeVfd(file);
1826 }
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:188
#define DO_DB(A)
Definition: fd.c:165
#define FD_DELETE_AT_CLOSE
Definition: fd.c:186
static Vfd * VfdCache
Definition: fd.c:211
static void Delete(File file)
Definition: fd.c:1009
#define LOG
Definition: elog.h:26
char * fileName
Definition: fd.c:200
static int nfile
Definition: fd.c:217
unsigned short fdstate
Definition: fd.c:193
Definition: fd.c:190
off_t fileSize
Definition: fd.c:199
int fd
Definition: fd.c:192
ResourceOwner resowner
Definition: fd.c:194
static void ReportTemporaryFileUsage(const char *path, off_t size)
Definition: fd.c:1311
#define stat(a, b)
Definition: win32_port.h:266
#define FileIsNotOpen(file)
Definition: fd.c:174
#define FileIsValid(file)
Definition: fd.c:171
#define VFD_CLOSED
Definition: fd.c:169
static uint64 temporary_files_size
Definition: fd.c:231
#define Assert(condition)
Definition: c.h:680
static void FreeVfd(File file)
Definition: fd.c:1255
#define elog
Definition: elog.h:219
#define close(a)
Definition: win32.h:12
void ResourceOwnerForgetFile(ResourceOwner owner, File file)
Definition: resowner.c:1195

◆ FileGetRawDesc()

int FileGetRawDesc ( File  file)

Definition at line 2239 of file fd.c.

References Assert, vfd::fd, and FileIsValid.

2240 {
2241  Assert(FileIsValid(file));
2242  return VfdCache[file].fd;
2243 }
static Vfd * VfdCache
Definition: fd.c:211
int fd
Definition: fd.c:192
#define FileIsValid(file)
Definition: fd.c:171
#define Assert(condition)
Definition: c.h:680

◆ FileGetRawFlags()

int FileGetRawFlags ( File  file)

Definition at line 2249 of file fd.c.

References Assert, vfd::fileFlags, and FileIsValid.

2250 {
2251  Assert(FileIsValid(file));
2252  return VfdCache[file].fileFlags;
2253 }
static Vfd * VfdCache
Definition: fd.c:211
#define FileIsValid(file)
Definition: fd.c:171
#define Assert(condition)
Definition: c.h:680
int fileFlags
Definition: fd.c:202

◆ FileGetRawMode()

mode_t FileGetRawMode ( File  file)

Definition at line 2259 of file fd.c.

References Assert, FileIsValid, and vfd::fileMode.

2260 {
2261  Assert(FileIsValid(file));
2262  return VfdCache[file].fileMode;
2263 }
static Vfd * VfdCache
Definition: fd.c:211
mode_t fileMode
Definition: fd.c:203
#define FileIsValid(file)
Definition: fd.c:171
#define Assert(condition)
Definition: c.h:680

◆ FilePathName()

char* FilePathName ( File  file)

Definition at line 2223 of file fd.c.

References Assert, FileIsValid, and vfd::fileName.

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

2224 {
2225  Assert(FileIsValid(file));
2226 
2227  return VfdCache[file].fileName;
2228 }
static Vfd * VfdCache
Definition: fd.c:211
char * fileName
Definition: fd.c:200
#define FileIsValid(file)
Definition: fd.c:171
#define Assert(condition)
Definition: c.h:680

◆ FilePrefetch()

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

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

1840 {
1841 #if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
1842  int returnCode;
1843 
1844  Assert(FileIsValid(file));
1845 
1846  DO_DB(elog(LOG, "FilePrefetch: %d (%s) " INT64_FORMAT " %d",
1847  file, VfdCache[file].fileName,
1848  (int64) offset, amount));
1849 
1850  returnCode = FileAccess(file);
1851  if (returnCode < 0)
1852  return returnCode;
1853 
1854  pgstat_report_wait_start(wait_event_info);
1855  returnCode = posix_fadvise(VfdCache[file].fd, offset, amount,
1856  POSIX_FADV_WILLNEED);
1858 
1859  return returnCode;
1860 #else
1861  Assert(FileIsValid(file));
1862  return 0;
1863 #endif
1864 }
#define DO_DB(A)
Definition: fd.c:165
static Vfd * VfdCache
Definition: fd.c:211
#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:1259
#define FileIsValid(file)
Definition: fd.c:171
static int FileAccess(File file)
Definition: fd.c:1275
#define Assert(condition)
Definition: c.h:680
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1235
#define INT64_FORMAT
Definition: c.h:348
#define elog
Definition: elog.h:219

◆ FileRead()

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

Definition at line 1894 of file fd.c.

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

Referenced by BufFileLoadBuffer(), and mdread().

1895 {
1896  int returnCode;
1897  Vfd *vfdP;
1898 
1899  Assert(FileIsValid(file));
1900 
1901  DO_DB(elog(LOG, "FileRead: %d (%s) " INT64_FORMAT " %d %p",
1902  file, VfdCache[file].fileName,
1903  (int64) VfdCache[file].seekPos,
1904  amount, buffer));
1905 
1906  returnCode = FileAccess(file);
1907  if (returnCode < 0)
1908  return returnCode;
1909 
1910  vfdP = &VfdCache[file];
1911 
1912 retry:
1913  pgstat_report_wait_start(wait_event_info);
1914  returnCode = read(vfdP->fd, buffer, amount);
1916 
1917  if (returnCode >= 0)
1918  {
1919  /* if seekPos is unknown, leave it that way */
1920  if (!FilePosIsUnknown(vfdP->seekPos))
1921  vfdP->seekPos += returnCode;
1922  }
1923  else
1924  {
1925  /*
1926  * Windows may run out of kernel buffers and return "Insufficient
1927  * system resources" error. Wait a bit and retry to solve it.
1928  *
1929  * It is rumored that EINTR is also possible on some Unix filesystems,
1930  * in which case immediate retry is indicated.
1931  */
1932 #ifdef WIN32
1933  DWORD error = GetLastError();
1934 
1935  switch (error)
1936  {
1937  case ERROR_NO_SYSTEM_RESOURCES:
1938  pg_usleep(1000L);
1939  errno = EINTR;
1940  break;
1941  default:
1942  _dosmaperr(error);
1943  break;
1944  }
1945 #endif
1946  /* OK to retry if interrupted */
1947  if (errno == EINTR)
1948  goto retry;
1949 
1950  /* Trouble, so assume we don't know the file position anymore */
1951  vfdP->seekPos = FileUnknownPos;
1952  }
1953 
1954  return returnCode;
1955 }
static void error(void)
Definition: sql-dyntest.c:147
#define DO_DB(A)
Definition: fd.c:165
void _dosmaperr(unsigned long)
Definition: win32error.c:171
static Vfd * VfdCache
Definition: fd.c:211
#define LOG
Definition: elog.h:26
#define FilePosIsUnknown(pos)
Definition: fd.c:183
void pg_usleep(long microsec)
Definition: signal.c:53
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1259
off_t seekPos
Definition: fd.c:198
Definition: fd.c:190
int fd
Definition: fd.c:192
#define FileIsValid(file)
Definition: fd.c:171
static int FileAccess(File file)
Definition: fd.c:1275
#define Assert(condition)
Definition: c.h:680
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:215
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1235
#define INT64_FORMAT
Definition: c.h:348
#define elog
Definition: elog.h:219
#define EINTR
Definition: win32_port.h:334
#define FileUnknownPos
Definition: fd.c:182
#define read(a, b, c)
Definition: win32.h:13

◆ FileSeek()

off_t FileSeek ( File  file,
off_t  offset,
int  whence 
)

Definition at line 2100 of file fd.c.

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

Referenced by _mdnblocks(), BufFileDumpBuffer(), BufFileLoadBuffer(), mdextend(), mdread(), and mdwrite().

2101 {
2102  Vfd *vfdP;
2103 
2104  Assert(FileIsValid(file));
2105 
2106  DO_DB(elog(LOG, "FileSeek: %d (%s) " INT64_FORMAT " " INT64_FORMAT " %d",
2107  file, VfdCache[file].fileName,
2108  (int64) VfdCache[file].seekPos,
2109  (int64) offset, whence));
2110 
2111  vfdP = &VfdCache[file];
2112 
2113  if (FileIsNotOpen(file))
2114  {
2115  switch (whence)
2116  {
2117  case SEEK_SET:
2118  if (offset < 0)
2119  {
2120  errno = EINVAL;
2121  return (off_t) -1;
2122  }
2123  vfdP->seekPos = offset;
2124  break;
2125  case SEEK_CUR:
2126  if (FilePosIsUnknown(vfdP->seekPos) ||
2127  vfdP->seekPos + offset < 0)
2128  {
2129  errno = EINVAL;
2130  return (off_t) -1;
2131  }
2132  vfdP->seekPos += offset;
2133  break;
2134  case SEEK_END:
2135  if (FileAccess(file) < 0)
2136  return (off_t) -1;
2137  vfdP->seekPos = lseek(vfdP->fd, offset, whence);
2138  break;
2139  default:
2140  elog(ERROR, "invalid whence: %d", whence);
2141  break;
2142  }
2143  }
2144  else
2145  {
2146  switch (whence)
2147  {
2148  case SEEK_SET:
2149  if (offset < 0)
2150  {
2151  errno = EINVAL;
2152  return (off_t) -1;
2153  }
2154  if (vfdP->seekPos != offset)
2155  vfdP->seekPos = lseek(vfdP->fd, offset, whence);
2156  break;
2157  case SEEK_CUR:
2158  if (offset != 0 || FilePosIsUnknown(vfdP->seekPos))
2159  vfdP->seekPos = lseek(vfdP->fd, offset, whence);
2160  break;
2161  case SEEK_END:
2162  vfdP->seekPos = lseek(vfdP->fd, offset, whence);
2163  break;
2164  default:
2165  elog(ERROR, "invalid whence: %d", whence);
2166  break;
2167  }
2168  }
2169 
2170  return vfdP->seekPos;
2171 }
#define DO_DB(A)
Definition: fd.c:165
static Vfd * VfdCache
Definition: fd.c:211
#define LOG
Definition: elog.h:26
#define FilePosIsUnknown(pos)
Definition: fd.c:183
#define ERROR
Definition: elog.h:43
off_t seekPos
Definition: fd.c:198
Definition: fd.c:190
int fd
Definition: fd.c:192
#define FileIsNotOpen(file)
Definition: fd.c:174
#define FileIsValid(file)
Definition: fd.c:171
static int FileAccess(File file)
Definition: fd.c:1275
#define Assert(condition)
Definition: c.h:680
#define INT64_FORMAT
Definition: c.h:348
#define elog
Definition: elog.h:219

◆ FileSync()

int FileSync ( File  file,
uint32  wait_event_info 
)

Definition at line 2079 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(), mdsync(), and register_dirty_segment().

2080 {
2081  int returnCode;
2082 
2083  Assert(FileIsValid(file));
2084 
2085  DO_DB(elog(LOG, "FileSync: %d (%s)",
2086  file, VfdCache[file].fileName));
2087 
2088  returnCode = FileAccess(file);
2089  if (returnCode < 0)
2090  return returnCode;
2091 
2092  pgstat_report_wait_start(wait_event_info);
2093  returnCode = pg_fsync(VfdCache[file].fd);
2095 
2096  return returnCode;
2097 }
#define DO_DB(A)
Definition: fd.c:165
static Vfd * VfdCache
Definition: fd.c:211
#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:1259
#define FileIsValid(file)
Definition: fd.c:171
static int FileAccess(File file)
Definition: fd.c:1275
#define Assert(condition)
Definition: c.h:680
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1235
int pg_fsync(int fd)
Definition: fd.c:348
#define elog
Definition: elog.h:219

◆ FileTruncate()

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

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

2189 {
2190  int returnCode;
2191 
2192  Assert(FileIsValid(file));
2193 
2194  DO_DB(elog(LOG, "FileTruncate %d (%s)",
2195  file, VfdCache[file].fileName));
2196 
2197  returnCode = FileAccess(file);
2198  if (returnCode < 0)
2199  return returnCode;
2200 
2201  pgstat_report_wait_start(wait_event_info);
2202  returnCode = ftruncate(VfdCache[file].fd, offset);
2204 
2205  if (returnCode == 0 && VfdCache[file].fileSize > offset)
2206  {
2207  /* adjust our state for truncation of a temp file */
2208  Assert(VfdCache[file].fdstate & FD_TEMP_FILE_LIMIT);
2209  temporary_files_size -= VfdCache[file].fileSize - offset;
2210  VfdCache[file].fileSize = offset;
2211  }
2212 
2213  return returnCode;
2214 }
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:188
#define DO_DB(A)
Definition: fd.c:165
static Vfd * VfdCache
Definition: fd.c:211
#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:1259
off_t fileSize
Definition: fd.c:199
#define FileIsValid(file)
Definition: fd.c:171
static uint64 temporary_files_size
Definition: fd.c:231
static int FileAccess(File file)
Definition: fd.c:1275
#define Assert(condition)
Definition: c.h:680
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1235
#define elog
Definition: elog.h:219
#define ftruncate(a, b)
Definition: win32_port.h:60

◆ FileWrite()

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

Definition at line 1958 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, FilePosIsUnknown, vfd::fileSize, FileUnknownPos, INT64_FORMAT, LOG, pg_usleep(), pgstat_report_wait_end(), pgstat_report_wait_start(), vfd::seekPos, temp_file_limit, temporary_files_size, and write.

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

1959 {
1960  int returnCode;
1961  Vfd *vfdP;
1962 
1963  Assert(FileIsValid(file));
1964 
1965  DO_DB(elog(LOG, "FileWrite: %d (%s) " INT64_FORMAT " %d %p",
1966  file, VfdCache[file].fileName,
1967  (int64) VfdCache[file].seekPos,
1968  amount, buffer));
1969 
1970  returnCode = FileAccess(file);
1971  if (returnCode < 0)
1972  return returnCode;
1973 
1974  vfdP = &VfdCache[file];
1975 
1976  /*
1977  * If enforcing temp_file_limit and it's a temp file, check to see if the
1978  * write would overrun temp_file_limit, and throw error if so. Note: it's
1979  * really a modularity violation to throw error here; we should set errno
1980  * and return -1. However, there's no way to report a suitable error
1981  * message if we do that. All current callers would just throw error
1982  * immediately anyway, so this is safe at present.
1983  */
1984  if (temp_file_limit >= 0 && (vfdP->fdstate & FD_TEMP_FILE_LIMIT))
1985  {
1986  off_t newPos;
1987 
1988  /*
1989  * Normally we should know the seek position, but if for some reason
1990  * we have lost track of it, try again to get it. Here, it's fine to
1991  * throw an error if we still can't get it.
1992  */
1993  if (FilePosIsUnknown(vfdP->seekPos))
1994  {
1995  vfdP->seekPos = lseek(vfdP->fd, (off_t) 0, SEEK_CUR);
1996  if (FilePosIsUnknown(vfdP->seekPos))
1997  elog(ERROR, "could not seek file \"%s\": %m", vfdP->fileName);
1998  }
1999 
2000  newPos = vfdP->seekPos + amount;
2001  if (newPos > vfdP->fileSize)
2002  {
2003  uint64 newTotal = temporary_files_size;
2004 
2005  newTotal += newPos - vfdP->fileSize;
2006  if (newTotal > (uint64) temp_file_limit * (uint64) 1024)
2007  ereport(ERROR,
2008  (errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED),
2009  errmsg("temporary file size exceeds temp_file_limit (%dkB)",
2010  temp_file_limit)));
2011  }
2012  }
2013 
2014 retry:
2015  errno = 0;
2016  pgstat_report_wait_start(wait_event_info);
2017  returnCode = write(vfdP->fd, buffer, amount);
2019 
2020  /* if write didn't set errno, assume problem is no disk space */
2021  if (returnCode != amount && errno == 0)
2022  errno = ENOSPC;
2023 
2024  if (returnCode >= 0)
2025  {
2026  /* if seekPos is unknown, leave it that way */
2027  if (!FilePosIsUnknown(vfdP->seekPos))
2028  vfdP->seekPos += returnCode;
2029 
2030  /*
2031  * Maintain fileSize and temporary_files_size if it's a temp file.
2032  *
2033  * If seekPos is -1 (unknown), this will do nothing; but we could only
2034  * get here in that state if we're not enforcing temporary_files_size,
2035  * so we don't care.
2036  */
2037  if (vfdP->fdstate & FD_TEMP_FILE_LIMIT)
2038  {
2039  off_t newPos = vfdP->seekPos;
2040 
2041  if (newPos > vfdP->fileSize)
2042  {
2043  temporary_files_size += newPos - vfdP->fileSize;
2044  vfdP->fileSize = newPos;
2045  }
2046  }
2047  }
2048  else
2049  {
2050  /*
2051  * See comments in FileRead()
2052  */
2053 #ifdef WIN32
2054  DWORD error = GetLastError();
2055 
2056  switch (error)
2057  {
2058  case ERROR_NO_SYSTEM_RESOURCES:
2059  pg_usleep(1000L);
2060  errno = EINTR;
2061  break;
2062  default:
2063  _dosmaperr(error);
2064  break;
2065  }
2066 #endif
2067  /* OK to retry if interrupted */
2068  if (errno == EINTR)
2069  goto retry;
2070 
2071  /* Trouble, so assume we don't know the file position anymore */
2072  vfdP->seekPos = FileUnknownPos;
2073  }
2074 
2075  return returnCode;
2076 }
static void error(void)
Definition: sql-dyntest.c:147
#define write(a, b, c)
Definition: win32.h:14
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:188
#define DO_DB(A)
Definition: fd.c:165
void _dosmaperr(unsigned long)
Definition: win32error.c:171
static Vfd * VfdCache
Definition: fd.c:211
int errcode(int sqlerrcode)
Definition: elog.c:575
#define LOG
Definition: elog.h:26
#define FilePosIsUnknown(pos)
Definition: fd.c:183
void pg_usleep(long microsec)
Definition: signal.c:53
#define ERROR
Definition: elog.h:43
char * fileName
Definition: fd.c:200
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1259
off_t seekPos
Definition: fd.c:198
unsigned short fdstate
Definition: fd.c:193
Definition: fd.c:190
off_t fileSize
Definition: fd.c:199
int fd
Definition: fd.c:192
#define ereport(elevel, rest)
Definition: elog.h:122
#define FileIsValid(file)
Definition: fd.c:171
static uint64 temporary_files_size
Definition: fd.c:231
static int FileAccess(File file)
Definition: fd.c:1275
#define Assert(condition)
Definition: c.h:680
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:215
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1235
#define INT64_FORMAT
Definition: c.h:348
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219
#define EINTR
Definition: win32_port.h:334
#define FileUnknownPos
Definition: fd.c:182
int temp_file_limit
Definition: guc.c:458

◆ FileWriteback()

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

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

1868 {
1869  int returnCode;
1870 
1871  Assert(FileIsValid(file));
1872 
1873  DO_DB(elog(LOG, "FileWriteback: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
1874  file, VfdCache[file].fileName,
1875  (int64) offset, (int64) nbytes));
1876 
1877  /*
1878  * Caution: do not call pg_flush_data with nbytes = 0, it could trash the
1879  * file's seek position. We prefer to define that as a no-op here.
1880  */
1881  if (nbytes <= 0)
1882  return;
1883 
1884  returnCode = FileAccess(file);
1885  if (returnCode < 0)
1886  return;
1887 
1888  pgstat_report_wait_start(wait_event_info);
1889  pg_flush_data(VfdCache[file].fd, offset, nbytes);
1891 }
#define DO_DB(A)
Definition: fd.c:165
static Vfd * VfdCache
Definition: fd.c:211
#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:1259
void pg_flush_data(int fd, off_t offset, off_t nbytes)
Definition: fd.c:422
#define FileIsValid(file)
Definition: fd.c:171
static int FileAccess(File file)
Definition: fd.c:1275
#define Assert(condition)
Definition: c.h:680
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1235
#define INT64_FORMAT
Definition: c.h:348
#define elog
Definition: elog.h:219

◆ FreeDir()

int FreeDir ( DIR dir)

Definition at line 2715 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(), 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(), ResetUnloggedRelations(), ResetUnloggedRelationsInDbspaceDir(), ResetUnloggedRelationsInTablespaceDir(), restoreTwoPhaseData(), scan_directory_ci(), sendDir(), SlruScanDirectory(), StartupReorderBuffer(), StartupReplicationSlots(), UpdateLogicalMappings(), and walkdir().

2716 {
2717  int i;
2718 
2719  /* Nothing to do if AllocateDir failed */
2720  if (dir == NULL)
2721  return 0;
2722 
2723  DO_DB(elog(LOG, "FreeDir: Allocated %d", numAllocatedDescs));
2724 
2725  /* Remove dir from list of allocated dirs, if it's present */
2726  for (i = numAllocatedDescs; --i >= 0;)
2727  {
2728  AllocateDesc *desc = &allocatedDescs[i];
2729 
2730  if (desc->kind == AllocateDescDir && desc->desc.dir == dir)
2731  return FreeDesc(desc);
2732  }
2733 
2734  /* Only get here if someone passes us a dir not in allocatedDescs */
2735  elog(WARNING, "dir passed to FreeDir was not obtained from AllocateDir");
2736 
2737  return closedir(dir);
2738 }
static AllocateDesc * allocatedDescs
Definition: fd.c:259
DIR * dir
Definition: fd.c:252
#define DO_DB(A)
Definition: fd.c:165
int closedir(DIR *)
Definition: dirent.c:111
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:247
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2496
#define WARNING
Definition: elog.h:40
union AllocateDesc::@27 desc
int i
#define elog
Definition: elog.h:219
static int numAllocatedDescs
Definition: fd.c:257

◆ FreeFile()

int FreeFile ( FILE *  file)

Definition at line 2535 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(), checkDataDir(), 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(), PGSharedMemoryIsInUse(), 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(), readRecoveryCommandFile(), readTimeLineHistory(), sendFile(), tokenize_inc_file(), tsearch_readline_end(), ValidatePgVersion(), write_relcache_init_file(), XLogArchiveForceDone(), and XLogArchiveNotify().

2536 {
2537  int i;
2538 
2539  DO_DB(elog(LOG, "FreeFile: Allocated %d", numAllocatedDescs));
2540 
2541  /* Remove file from list of allocated files, if it's present */
2542  for (i = numAllocatedDescs; --i >= 0;)
2543  {
2544  AllocateDesc *desc = &allocatedDescs[i];
2545 
2546  if (desc->kind == AllocateDescFile && desc->desc.file == file)
2547  return FreeDesc(desc);
2548  }
2549 
2550  /* Only get here if someone passes us a file not in allocatedDescs */
2551  elog(WARNING, "file passed to FreeFile was not obtained from AllocateFile");
2552 
2553  return fclose(file);
2554 }
static AllocateDesc * allocatedDescs
Definition: fd.c:259
#define DO_DB(A)
Definition: fd.c:165
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:247
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2496
#define WARNING
Definition: elog.h:40
FILE * file
Definition: fd.c:251
union AllocateDesc::@27 desc
int i
#define elog
Definition: elog.h:219
static int numAllocatedDescs
Definition: fd.c:257

◆ fsync_fname()

void fsync_fname ( const char *  fname,
bool  isdir 
)

◆ GetNextTempTableSpace()

Oid GetNextTempTableSpace ( void  )

Definition at line 2858 of file fd.c.

References InvalidOid, nextTempTableSpace, numTempTableSpaces, and tempTableSpaces.

Referenced by GetDefaultTablespace(), and OpenTemporaryFile().

2859 {
2860  if (numTempTableSpaces > 0)
2861  {
2862  /* Advance nextTempTableSpace counter with wraparound */
2864  nextTempTableSpace = 0;
2866  }
2867  return InvalidOid;
2868 }
static int numTempTableSpaces
Definition: fd.c:272
static int nextTempTableSpace
Definition: fd.c:273
#define InvalidOid
Definition: postgres_ext.h:36
static Oid * tempTableSpaces
Definition: fd.c:271

◆ GetTempTablespaces()

int GetTempTablespaces ( Oid tableSpaces,
int  numSpaces 
)

Definition at line 2840 of file fd.c.

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

Referenced by SharedFileSetInit().

2841 {
2842  int i;
2843 
2845  for (i = 0; i < numTempTableSpaces && i < numSpaces; ++i)
2846  tableSpaces[i] = tempTableSpaces[i];
2847 
2848  return i;
2849 }
static int numTempTableSpaces
Definition: fd.c:272
bool TempTablespacesAreSet(void)
Definition: fd.c:2828
#define Assert(condition)
Definition: c.h:680
static Oid * tempTableSpaces
Definition: fd.c:271
int i

◆ InitFileAccess()

void InitFileAccess ( void  )

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

780 {
781  Assert(SizeVfdCache == 0); /* call me only once */
782 
783  /* initialize cache header entry */
784  VfdCache = (Vfd *) malloc(sizeof(Vfd));
785  if (VfdCache == NULL)
786  ereport(FATAL,
787  (errcode(ERRCODE_OUT_OF_MEMORY),
788  errmsg("out of memory")));
789 
790  MemSet((char *) &(VfdCache[0]), 0, sizeof(Vfd));
792 
793  SizeVfdCache = 1;
794 
795  /* register proc-exit hook to ensure temp files are dropped at exit */
797 }
static void AtProcExit_Files(int code, Datum arg)
Definition: fd.c:2924
static Size SizeVfdCache
Definition: fd.c:212
void on_proc_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:292
static Vfd * VfdCache
Definition: fd.c:211
int errcode(int sqlerrcode)
Definition: elog.c:575
#define MemSet(start, val, len)
Definition: c.h:877
#define malloc(a)
Definition: header.h:50
#define FATAL
Definition: elog.h:52
Definition: fd.c:190
int fd
Definition: fd.c:192
#define ereport(elevel, rest)
Definition: elog.h:122
#define VFD_CLOSED
Definition: fd.c:169
#define Assert(condition)
Definition: c.h:680
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ OpenPipeStream()

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

Definition at line 2442 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, ReleaseLruFile(), ReleaseLruFiles(), and reserveAllocatedDesc().

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

2443 {
2444  FILE *file;
2445 
2446  DO_DB(elog(LOG, "OpenPipeStream: Allocated %d (%s)",
2447  numAllocatedDescs, command));
2448 
2449  /* Can we allocate another non-virtual FD? */
2450  if (!reserveAllocatedDesc())
2451  ereport(ERROR,
2452  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2453  errmsg("exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"",
2454  maxAllocatedDescs, command)));
2455 
2456  /* Close excess kernel FDs. */
2457  ReleaseLruFiles();
2458 
2459 TryAgain:
2460  fflush(stdout);
2461  fflush(stderr);
2462  errno = 0;
2463  if ((file = popen(command, mode)) != NULL)
2464  {
2466 
2467  desc->kind = AllocateDescPipe;
2468  desc->desc.file = file;
2471  return desc->desc.file;
2472  }
2473 
2474  if (errno == EMFILE || errno == ENFILE)
2475  {
2476  int save_errno = errno;
2477 
2478  ereport(LOG,
2479  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2480  errmsg("out of file descriptors: %m; release and retry")));
2481  errno = 0;
2482  if (ReleaseLruFile())
2483  goto TryAgain;
2484  errno = save_errno;
2485  }
2486 
2487  return NULL;
2488 }
static AllocateDesc * allocatedDescs
Definition: fd.c:259
#define DO_DB(A)
Definition: fd.c:165
int errcode(int sqlerrcode)
Definition: elog.c:575
static bool reserveAllocatedDesc(void)
Definition: fd.c:2270
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:247
static bool ReleaseLruFile(void)
Definition: fd.c:1165
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
static void ReleaseLruFiles(void)
Definition: fd.c:1187
FILE * file
Definition: fd.c:251
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:642
SubTransactionId create_subid
Definition: fd.c:248
int errmsg(const char *fmt,...)
Definition: elog.c:797
union AllocateDesc::@27 desc
#define elog
Definition: elog.h:219
static int maxAllocatedDescs
Definition: fd.c:258
static int numAllocatedDescs
Definition: fd.c:257

◆ OpenTemporaryFile()

File OpenTemporaryFile ( bool  interXact)

Definition at line 1500 of file fd.c.

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

Referenced by BufFileCreateTemp(), and extendBufFile().

1501 {
1502  File file = 0;
1503 
1504  /*
1505  * Make sure the current resource owner has space for this File before we
1506  * open it, if we'll be registering it below.
1507  */
1508  if (!interXact)
1510 
1511  /*
1512  * If some temp tablespace(s) have been given to us, try to use the next
1513  * one. If a given tablespace can't be found, we silently fall back to
1514  * the database's default tablespace.
1515  *
1516  * BUT: if the temp file is slated to outlive the current transaction,
1517  * force it into the database's default tablespace, so that it will not
1518  * pose a threat to possible tablespace drop attempts.
1519  */
1520  if (numTempTableSpaces > 0 && !interXact)
1521  {
1522  Oid tblspcOid = GetNextTempTableSpace();
1523 
1524  if (OidIsValid(tblspcOid))
1525  file = OpenTemporaryFileInTablespace(tblspcOid, false);
1526  }
1527 
1528  /*
1529  * If not, or if tablespace is bad, create in database's default
1530  * tablespace. MyDatabaseTableSpace should normally be set before we get
1531  * here, but just in case it isn't, fall back to pg_default tablespace.
1532  */
1533  if (file <= 0)
1537  true);
1538 
1539  /* Mark it for deletion at close and temporary file size limit */
1541 
1542  /* Register it with the current resource owner */
1543  if (!interXact)
1544  RegisterTemporaryFile(file);
1545 
1546  return file;
1547 }
static File OpenTemporaryFileInTablespace(Oid tblspcOid, bool rejectError)
Definition: fd.c:1578
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:188
ResourceOwner CurrentResourceOwner
Definition: resowner.c:138
#define FD_DELETE_AT_CLOSE
Definition: fd.c:186
static Vfd * VfdCache
Definition: fd.c:211
static int numTempTableSpaces
Definition: fd.c:272
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:586
Oid MyDatabaseTableSpace
Definition: globals.c:79
Oid GetNextTempTableSpace(void)
Definition: fd.c:2858
#define DEFAULTTABLESPACE_OID
Definition: pg_tablespace.h:63
unsigned short fdstate
Definition: fd.c:193
static void RegisterTemporaryFile(File file)
Definition: fd.c:1330
void ResourceOwnerEnlargeFiles(ResourceOwner owner)
Definition: resowner.c:1175
int File
Definition: fd.h:49

◆ OpenTransientFile()

◆ OpenTransientFilePerm()

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

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

2403 {
2404  int fd;
2405 
2406  DO_DB(elog(LOG, "OpenTransientFile: Allocated %d (%s)",
2407  numAllocatedDescs, fileName));
2408 
2409  /* Can we allocate another non-virtual FD? */
2410  if (!reserveAllocatedDesc())
2411  ereport(ERROR,
2412  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2413  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2414  maxAllocatedDescs, fileName)));
2415 
2416  /* Close excess kernel FDs. */
2417  ReleaseLruFiles();
2418 
2419  fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
2420 
2421  if (fd >= 0)
2422  {
2424 
2425  desc->kind = AllocateDescRawFD;
2426  desc->desc.fd = fd;
2429 
2430  return fd;
2431  }
2432 
2433  return -1; /* failure */
2434 }
static AllocateDesc * allocatedDescs
Definition: fd.c:259
#define DO_DB(A)
Definition: fd.c:165
int errcode(int sqlerrcode)
Definition: elog.c:575
static bool reserveAllocatedDesc(void)
Definition: fd.c:2270
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:247
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:122
static void ReleaseLruFiles(void)
Definition: fd.c:1187
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:642
SubTransactionId create_subid
Definition: fd.c:248
int fd
Definition: fd.c:253
int errmsg(const char *fmt,...)
Definition: elog.c:797
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:961
union AllocateDesc::@27 desc
#define elog
Definition: elog.h:219
static int maxAllocatedDescs
Definition: fd.c:258
static int numAllocatedDescs
Definition: fd.c:257

◆ PathNameCreateTemporaryDir()

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

Definition at line 1436 of file fd.c.

References ereport, errcode_for_file_access(), errmsg(), ERROR, mkdir, and S_IRWXU.

Referenced by SharedFileSetCreate().

1437 {
1438  if (mkdir(directory, S_IRWXU) < 0)
1439  {
1440  if (errno == EEXIST)
1441  return;
1442 
1443  /*
1444  * Failed. Try to create basedir first in case it's missing. Tolerate
1445  * EEXIST to close a race against another process following the same
1446  * algorithm.
1447  */
1448  if (mkdir(basedir, S_IRWXU) < 0 && errno != EEXIST)
1449  ereport(ERROR,
1451  errmsg("cannot create temporary directory \"%s\": %m",
1452  basedir)));
1453 
1454  /* Try again. */
1455  if (mkdir(directory, S_IRWXU) < 0 && errno != EEXIST)
1456  ereport(ERROR,
1458  errmsg("cannot create temporary subdirectory \"%s\": %m",
1459  directory)));
1460  }
1461 }
static char * basedir
Definition: pg_basebackup.c:78
#define ERROR
Definition: elog.h:43
int errcode_for_file_access(void)
Definition: elog.c:598
#define ereport(elevel, rest)
Definition: elog.h:122
static const char * directory
Definition: zic.c:567
#define S_IRWXU
Definition: win32_port.h:280
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define mkdir(a, b)
Definition: win32_port.h:58

◆ PathNameCreateTemporaryFile()

File PathNameCreateTemporaryFile ( const char *  name,
bool  error_on_failure 
)

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

1636 {
1637  File file;
1638 
1640 
1641  /*
1642  * Open the file. Note: we don't use O_EXCL, in case there is an orphaned
1643  * temp file that can be reused.
1644  */
1645  file = PathNameOpenFile(path, O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1646  if (file <= 0)
1647  {
1648  if (error_on_failure)
1649  ereport(ERROR,
1651  errmsg("could not create temporary file \"%s\": %m",
1652  path)));
1653  else
1654  return file;
1655  }
1656 
1657  /* Mark it for temp_file_limit accounting. */
1659 
1660  /* Register it for automatic close. */
1661  RegisterTemporaryFile(file);
1662 
1663  return file;
1664 }
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1358
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:188
ResourceOwner CurrentResourceOwner
Definition: resowner.c:138
static Vfd * VfdCache
Definition: fd.c:211
#define PG_BINARY
Definition: c.h:1049
#define ERROR
Definition: elog.h:43
int errcode_for_file_access(void)
Definition: elog.c:598
unsigned short fdstate
Definition: fd.c:193
#define ereport(elevel, rest)
Definition: elog.h:122
static void RegisterTemporaryFile(File file)
Definition: fd.c:1330
int errmsg(const char *fmt,...)
Definition: elog.c:797
void ResourceOwnerEnlargeFiles(ResourceOwner owner)
Definition: resowner.c:1175
int File
Definition: fd.h:49

◆ PathNameDeleteTemporaryDir()

void PathNameDeleteTemporaryDir ( const char *  name)

Definition at line 1467 of file fd.c.

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

Referenced by SharedFileSetDeleteAll().

1468 {
1469  struct stat statbuf;
1470 
1471  /* Silently ignore missing directory. */
1472  if (stat(dirname, &statbuf) != 0 && errno == ENOENT)
1473  return;
1474 
1475  /*
1476  * Currently, walkdir doesn't offer a way for our passed in function to
1477  * maintain state. Perhaps it should, so that we could tell the caller
1478  * whether this operation succeeded or failed. Since this operation is
1479  * used in a cleanup path, we wouldn't actually behave differently: we'll
1480  * just log failures.
1481  */
1482  walkdir(dirname, unlink_if_exists_fname, false, LOG);
1483 }
static void walkdir(const char *path, void(*action)(const char *fname, bool isdir, int elevel), bool process_symlinks, int elevel)
Definition: fd.c:3326
#define LOG
Definition: elog.h:26
static void unlink_if_exists_fname(const char *fname, bool isdir, int elevel)
Definition: fd.c:3433
#define stat(a, b)
Definition: win32_port.h:266

◆ PathNameDeleteTemporaryFile()

bool PathNameDeleteTemporaryFile ( const char *  name,
bool  error_on_failure 
)

Definition at line 1703 of file fd.c.

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

Referenced by SharedFileSetDelete(), and unlink_if_exists_fname().

1704 {
1705  struct stat filestats;
1706  int stat_errno;
1707 
1708  /* Get the final size for pgstat reporting. */
1709  if (stat(path, &filestats) != 0)
1710  stat_errno = errno;
1711  else
1712  stat_errno = 0;
1713 
1714  /*
1715  * Unlike FileClose's automatic file deletion code, we tolerate
1716  * non-existence to support BufFileDeleteShared which doesn't know how
1717  * many segments it has to delete until it runs out.
1718  */
1719  if (stat_errno == ENOENT)
1720  return false;
1721 
1722  if (unlink(path) < 0)
1723  {
1724  if (errno != ENOENT)
1725  ereport(error_on_failure ? ERROR : LOG,
1727  errmsg("cannot unlink temporary file \"%s\": %m",
1728  path)));
1729  return false;
1730  }
1731 
1732  if (stat_errno == 0)
1733  ReportTemporaryFileUsage(path, filestats.st_size);
1734  else
1735  {
1736  errno = stat_errno;
1737  ereport(LOG,
1739  errmsg("could not stat file \"%s\": %m", path)));
1740  }
1741 
1742  return true;
1743 }
#define LOG
Definition: elog.h:26
#define ERROR
Definition: elog.h:43
int errcode_for_file_access(void)
Definition: elog.c:598
#define ereport(elevel, rest)
Definition: elog.h:122
static void ReportTemporaryFileUsage(const char *path, off_t size)
Definition: fd.c:1311
#define stat(a, b)
Definition: win32_port.h:266
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ PathNameOpenFile()

File PathNameOpenFile ( const char *  fileName,
int  fileFlags 
)

Definition at line 1358 of file fd.c.

References PathNameOpenFilePerm(), and PG_FILE_MODE_DEFAULT.

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

1359 {
1360  return PathNameOpenFilePerm(fileName, fileFlags, PG_FILE_MODE_DEFAULT);
1361 }
File PathNameOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1371
#define PG_FILE_MODE_DEFAULT
Definition: fd.c:131

◆ PathNameOpenFilePerm()

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

Definition at line 1371 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(), vfd::resowner, and vfd::seekPos.

Referenced by PathNameOpenFile().

1372 {
1373  char *fnamecopy;
1374  File file;
1375  Vfd *vfdP;
1376 
1377  DO_DB(elog(LOG, "PathNameOpenFilePerm: %s %x %o",
1378  fileName, fileFlags, fileMode));
1379 
1380  /*
1381  * We need a malloc'd copy of the file name; fail cleanly if no room.
1382  */
1383  fnamecopy = strdup(fileName);
1384  if (fnamecopy == NULL)
1385  ereport(ERROR,
1386  (errcode(ERRCODE_OUT_OF_MEMORY),
1387  errmsg("out of memory")));
1388 
1389  file = AllocateVfd();
1390  vfdP = &VfdCache[file];
1391 
1392  /* Close excess kernel FDs. */
1393  ReleaseLruFiles();
1394 
1395  vfdP->fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
1396 
1397  if (vfdP->fd < 0)
1398  {
1399  int save_errno = errno;
1400 
1401  FreeVfd(file);
1402  free(fnamecopy);
1403  errno = save_errno;
1404  return -1;
1405  }
1406  ++nfile;
1407  DO_DB(elog(LOG, "PathNameOpenFile: success %d",
1408  vfdP->fd));
1409 
1410  Insert(file);
1411 
1412  vfdP->fileName = fnamecopy;
1413  /* Saved flags are adjusted to be OK for re-opening file */
1414  vfdP->fileFlags = fileFlags & ~(O_CREAT | O_TRUNC | O_EXCL);
1415  vfdP->fileMode = fileMode;
1416  vfdP->seekPos = 0;
1417  vfdP->fileSize = 0;
1418  vfdP->fdstate = 0x0;
1419  vfdP->resowner = NULL;
1420 
1421  return file;
1422 }
#define DO_DB(A)
Definition: fd.c:165
static Vfd * VfdCache
Definition: fd.c:211
int errcode(int sqlerrcode)
Definition: elog.c:575
#define LOG
Definition: elog.h:26
mode_t fileMode
Definition: fd.c:203
#define ERROR
Definition: elog.h:43
char * fileName
Definition: fd.c:200
static int nfile
Definition: fd.c:217
static File AllocateVfd(void)
Definition: fd.c:1197
off_t seekPos
Definition: fd.c:198
unsigned short fdstate
Definition: fd.c:193
Definition: fd.c:190
off_t fileSize
Definition: fd.c:199
int fd
Definition: fd.c:192
#define ereport(elevel, rest)
Definition: elog.h:122
static void Insert(File file)
Definition: fd.c:1069
ResourceOwner resowner
Definition: fd.c:194
static void ReleaseLruFiles(void)
Definition: fd.c:1187
#define free(a)
Definition: header.h:65
int errmsg(const char *fmt,...)
Definition: elog.c:797
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:961
static void FreeVfd(File file)
Definition: fd.c:1255
#define elog
Definition: elog.h:219
int fileFlags
Definition: fd.c:202
int File
Definition: fd.h:49

◆ PathNameOpenTemporaryFile()

File PathNameOpenTemporaryFile ( const char *  name)

Definition at line 1673 of file fd.c.

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

Referenced by SharedFileSetOpen().

1674 {
1675  File file;
1676 
1678 
1679  /* We open the file read-only. */
1680  file = PathNameOpenFile(path, O_RDONLY | PG_BINARY);
1681 
1682  /* If no such file, then we don't raise an error. */
1683  if (file <= 0 && errno != ENOENT)
1684  ereport(ERROR,
1686  errmsg("could not open temporary file \"%s\": %m",
1687  path)));
1688 
1689  if (file > 0)
1690  {
1691  /* Register it for automatic close. */
1692  RegisterTemporaryFile(file);
1693  }
1694 
1695  return file;
1696 }
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1358
ResourceOwner CurrentResourceOwner
Definition: resowner.c:138
#define PG_BINARY
Definition: c.h:1049
#define ERROR
Definition: elog.h:43
int errcode_for_file_access(void)
Definition: elog.c:598
#define ereport(elevel, rest)
Definition: elog.h:122
static void RegisterTemporaryFile(File file)
Definition: fd.c:1330
int errmsg(const char *fmt,...)
Definition: elog.c:797
void ResourceOwnerEnlargeFiles(ResourceOwner owner)
Definition: resowner.c:1175
int File
Definition: fd.h:49

◆ pg_fdatasync()

int pg_fdatasync ( int  fd)

Definition at line 400 of file fd.c.

References enableFsync, and fsync.

Referenced by issue_xlog_fsync().

401 {
402  if (enableFsync)
403  {
404 #ifdef HAVE_FDATASYNC
405  return fdatasync(fd);
406 #else
407  return fsync(fd);
408 #endif
409  }
410  else
411  return 0;
412 }
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:111

◆ pg_flush_data()

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

Definition at line 422 of file fd.c.

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

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

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

◆ pg_fsync()

int pg_fsync ( int  fd)

Definition at line 348 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(), RecreateTwoPhaseFile(), RestoreSlotFromDisk(), SaveSlotToPath(), SimpleLruFlush(), SlruPhysicalWritePage(), SnapBuildSerialize(), UpdateControlFile(), write_auto_conf_file(), write_relmap_file(), WriteControlFile(), writeTimeLineHistory(), writeTimeLineHistoryFile(), XLogFileCopy(), and XLogFileInit().

349 {
350  /* #if is to skip the sync_method test if there's no need for it */
351 #if defined(HAVE_FSYNC_WRITETHROUGH) && !defined(FSYNC_WRITETHROUGH_IS_FSYNC)
353  return pg_fsync_writethrough(fd);
354  else
355 #endif
357 }
#define SYNC_METHOD_FSYNC_WRITETHROUGH
Definition: xlog.h:28
int pg_fsync_writethrough(int fd)
Definition: fd.c:377
int pg_fsync_no_writethrough(int fd)
Definition: fd.c:365
static int fd(const char *x, int i)
Definition: preproc-init.c:105
int sync_method
Definition: xlog.c:103

◆ pg_fsync_no_writethrough()

int pg_fsync_no_writethrough ( int  fd)

Definition at line 365 of file fd.c.

References enableFsync, and fsync.

Referenced by issue_xlog_fsync(), and pg_fsync().

366 {
367  if (enableFsync)
368  return fsync(fd);
369  else
370  return 0;
371 }
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:111

◆ pg_fsync_writethrough()

int pg_fsync_writethrough ( int  fd)

Definition at line 377 of file fd.c.

References enableFsync.

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

378 {
379  if (enableFsync)
380  {
381 #ifdef WIN32
382  return _commit(fd);
383 #elif defined(F_FULLFSYNC)
384  return (fcntl(fd, F_FULLFSYNC, 0) == -1) ? -1 : 0;
385 #else
386  errno = ENOSYS;
387  return -1;
388 #endif
389  }
390  else
391  return 0;
392 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
bool enableFsync
Definition: globals.c:111

◆ ReadDir()

◆ ReadDirExtended()

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

Definition at line 2678 of file fd.c.

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

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

2679 {
2680  struct dirent *dent;
2681 
2682  /* Give a generic message for AllocateDir failure, if caller didn't */
2683  if (dir == NULL)
2684  {
2685  ereport(elevel,
2687  errmsg("could not open directory \"%s\": %m",
2688  dirname)));
2689  return NULL;
2690  }
2691 
2692  errno = 0;
2693  if ((dent = readdir(dir)) != NULL)
2694  return dent;
2695 
2696  if (errno)
2697  ereport(elevel,
2699  errmsg("could not read directory \"%s\": %m",
2700  dirname)));
2701  return NULL;
2702 }
Definition: dirent.h:9
int errcode_for_file_access(void)
Definition: elog.c:598
#define ereport(elevel, rest)
Definition: elog.h:122
static int elevel
Definition: vacuumlazy.c:136
struct dirent * readdir(DIR *)
Definition: dirent.c:77
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ RemovePgTempFiles()

void RemovePgTempFiles ( void  )

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

3005 {
3006  char temp_path[MAXPGPATH + 10 + sizeof(TABLESPACE_VERSION_DIRECTORY) + sizeof(PG_TEMP_FILES_DIR)];
3007  DIR *spc_dir;
3008  struct dirent *spc_de;
3009 
3010  /*
3011  * First process temp files in pg_default ($PGDATA/base)
3012  */
3013  snprintf(temp_path, sizeof(temp_path), "base/%s", PG_TEMP_FILES_DIR);
3014  RemovePgTempFilesInDir(temp_path, true, false);
3015  RemovePgTempRelationFiles("base");
3016 
3017  /*
3018  * Cycle through temp directories for all non-default tablespaces.
3019  */
3020  spc_dir = AllocateDir("pg_tblspc");
3021 
3022  while ((spc_de = ReadDirExtended(spc_dir, "pg_tblspc", LOG)) != NULL)
3023  {
3024  if (strcmp(spc_de->d_name, ".") == 0 ||
3025  strcmp(spc_de->d_name, "..") == 0)
3026  continue;
3027 
3028  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s/%s",
3030  RemovePgTempFilesInDir(temp_path, true, false);
3031 
3032  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s",
3034  RemovePgTempRelationFiles(temp_path);
3035  }
3036 
3037  FreeDir(spc_dir);
3038 
3039  /*
3040  * In EXEC_BACKEND case there is a pgsql_tmp directory at the top level of
3041  * DataDir as well.
3042  */
3043 #ifdef EXEC_BACKEND
3045 #endif
3046 }
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2678
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#define LOG
Definition: elog.h:26
Definition: dirent.h:9
static void RemovePgTempRelationFiles(const char *tsdirname)
Definition: fd.c:3130
Definition: dirent.c:25
#define MAXPGPATH
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2597
static void RemovePgTempFilesInDir(const char *tmpdirname, bool missing_ok, bool unlink_all)
Definition: fd.c:3064
#define PG_TEMP_FILES_DIR
Definition: fd.h:139
#define TABLESPACE_VERSION_DIRECTORY
Definition: catalog.h:26
char d_name[MAX_PATH]
Definition: dirent.h:14
int FreeDir(DIR *dir)
Definition: fd.c:2715

◆ set_max_safe_fds()

void set_max_safe_fds ( void  )

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

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

◆ SetTempTablespaces()

void SetTempTablespaces ( Oid tableSpaces,
int  numSpaces 
)

Definition at line 2800 of file fd.c.

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

Referenced by assign_temp_tablespaces(), and PrepareTempTablespaces().

2801 {
2802  Assert(numSpaces >= 0);
2803  tempTableSpaces = tableSpaces;
2804  numTempTableSpaces = numSpaces;
2805 
2806  /*
2807  * Select a random starting point in the list. This is to minimize
2808  * conflicts between backends that are most likely sharing the same list
2809  * of temp tablespaces. Note that if we create multiple temp files in the
2810  * same transaction, we'll advance circularly through the list --- this
2811  * ensures that large temporary sort files are nicely spread across all
2812  * available tablespaces.
2813  */
2814  if (numSpaces > 1)
2815  nextTempTableSpace = random() % numSpaces;
2816  else
2817  nextTempTableSpace = 0;
2818 }
long random(void)
Definition: random.c:22
static int numTempTableSpaces
Definition: fd.c:272
static int nextTempTableSpace
Definition: fd.c:273
#define Assert(condition)
Definition: c.h:680
static Oid * tempTableSpaces
Definition: fd.c:271

◆ SyncDataDirectory()

void SyncDataDirectory ( void  )

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

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

◆ TempTablespacePath()

void TempTablespacePath ( char *  path,
Oid  tablespace 
)

Definition at line 1553 of file fd.c.

References DEFAULTTABLESPACE_OID, GLOBALTABLESPACE_OID, InvalidOid, MAXPGPATH, PG_TEMP_FILES_DIR, snprintf(), and TABLESPACE_VERSION_DIRECTORY.

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

1554 {
1555  /*
1556  * Identify the tempfile directory for this tablespace.
1557  *
1558  * If someone tries to specify pg_global, use pg_default instead.
1559  */
1560  if (tablespace == InvalidOid ||
1563  snprintf(path, MAXPGPATH, "base/%s", PG_TEMP_FILES_DIR);
1564  else
1565  {
1566  /* All other tablespaces are accessed via symlinks */
1567  snprintf(path, MAXPGPATH, "pg_tblspc/%u/%s/%s",
1570  }
1571 }
#define GLOBALTABLESPACE_OID
Definition: pg_tablespace.h:64
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#define MAXPGPATH
#define DEFAULTTABLESPACE_OID
Definition: pg_tablespace.h:63
char * tablespace
Definition: pgbench.c:146
#define InvalidOid
Definition: postgres_ext.h:36
#define PG_TEMP_FILES_DIR
Definition: fd.h:139
#define TABLESPACE_VERSION_DIRECTORY
Definition: catalog.h:26

◆ TempTablespacesAreSet()

bool TempTablespacesAreSet ( void  )

Definition at line 2828 of file fd.c.

References numTempTableSpaces.

Referenced by GetTempTablespaces(), and PrepareTempTablespaces().

2829 {
2830  return (numTempTableSpaces >= 0);
2831 }
static int numTempTableSpaces
Definition: fd.c:272

Variable Documentation

◆ max_files_per_process

PGDLLIMPORT int max_files_per_process

Definition at line 139 of file fd.c.

Referenced by set_max_safe_fds().

◆ max_safe_fds

int max_safe_fds