PostgreSQL Source Code  git master
fd.c File Reference
#include "postgres.h"
#include <sys/file.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <limits.h>
#include <unistd.h>
#include <fcntl.h>
#include "miscadmin.h"
#include "access/xact.h"
#include "access/xlog.h"
#include "catalog/pg_tablespace.h"
#include "common/file_perm.h"
#include "pgstat.h"
#include "portability/mem.h"
#include "storage/fd.h"
#include "storage/ipc.h"
#include "utils/guc.h"
#include "utils/resowner_private.h"
Include dependency graph for fd.c:

Go to the source code of this file.

Data Structures

struct  vfd
 
struct  AllocateDesc
 

Macros

#define NUM_RESERVED_FDS   10
 
#define FD_MINFREE   10
 
#define DO_DB(A)   ((void) 0)
 
#define VFD_CLOSED   (-1)
 
#define FileIsValid(file)   ((file) > 0 && (file) < (int) SizeVfdCache && VfdCache[file].fileName != NULL)
 
#define FileIsNotOpen(file)   (VfdCache[file].fd == VFD_CLOSED)
 
#define FD_DELETE_AT_CLOSE   (1 << 0) /* T = delete when closed */
 
#define FD_CLOSE_AT_EOXACT   (1 << 1) /* T = close at eoXact */
 
#define FD_TEMP_FILE_LIMIT   (1 << 2) /* T = respect temp_file_limit */
 

Typedefs

typedef struct vfd Vfd
 

Enumerations

enum  AllocateDescKind { AllocateDescFile, AllocateDescPipe, AllocateDescDir, AllocateDescRawFD }
 

Functions

static void Delete (File file)
 
static void LruDelete (File file)
 
static void Insert (File file)
 
static int LruInsert (File file)
 
static bool ReleaseLruFile (void)
 
static void ReleaseLruFiles (void)
 
static File AllocateVfd (void)
 
static void FreeVfd (File file)
 
static int FileAccess (File file)
 
static File OpenTemporaryFileInTablespace (Oid tblspcOid, bool rejectError)
 
static bool reserveAllocatedDesc (void)
 
static int FreeDesc (AllocateDesc *desc)
 
static void AtProcExit_Files (int code, Datum arg)
 
static void CleanupTempFiles (bool isCommit, bool isProcExit)
 
static void RemovePgTempRelationFiles (const char *tsdirname)
 
static void RemovePgTempRelationFilesInDbspace (const char *dbspacedirname)
 
static void walkdir (const char *path, void(*action)(const char *fname, bool isdir, int elevel), bool process_symlinks, int elevel)
 
static void datadir_fsync_fname (const char *fname, bool isdir, int elevel)
 
static void unlink_if_exists_fname (const char *fname, bool isdir, int elevel)
 
static int fsync_fname_ext (const char *fname, bool isdir, bool ignore_perm, int elevel)
 
static int fsync_parent_path (const char *fname, int elevel)
 
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 nbytes)
 
void fsync_fname (const char *fname, bool isdir)
 
int durable_rename (const char *oldfile, const char *newfile, int elevel)
 
int durable_unlink (const char *fname, int elevel)
 
int durable_link_or_rename (const char *oldfile, const char *newfile, int elevel)
 
void InitFileAccess (void)
 
static void count_usable_fds (int max_to_probe, int *usable_fds, int *already_open)
 
void set_max_safe_fds (void)
 
int BasicOpenFile (const char *fileName, int fileFlags)
 
int BasicOpenFilePerm (const char *fileName, int fileFlags, mode_t fileMode)
 
static void ReportTemporaryFileUsage (const char *path, off_t size)
 
static void RegisterTemporaryFile (File file)
 
File PathNameOpenFile (const char *fileName, int fileFlags)
 
File PathNameOpenFilePerm (const char *fileName, int fileFlags, mode_t fileMode)
 
void PathNameCreateTemporaryDir (const char *basedir, const char *directory)
 
void PathNameDeleteTemporaryDir (const char *dirname)
 
File OpenTemporaryFile (bool interXact)
 
void TempTablespacePath (char *path, Oid tablespace)
 
File PathNameCreateTemporaryFile (const char *path, bool error_on_failure)
 
File PathNameOpenTemporaryFile (const char *path)
 
bool PathNameDeleteTemporaryFile (const char *path, bool error_on_failure)
 
void FileClose (File file)
 
int FilePrefetch (File file, off_t offset, int amount, uint32 wait_event_info)
 
void FileWriteback (File file, off_t offset, off_t nbytes, 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)
 
char * FilePathName (File file)
 
int FileGetRawDesc (File file)
 
int FileGetRawFlags (File file)
 
mode_t FileGetRawMode (File file)
 
FILE * AllocateFile (const char *name, const char *mode)
 
int OpenTransientFile (const char *fileName, int fileFlags)
 
int OpenTransientFilePerm (const char *fileName, int fileFlags, mode_t fileMode)
 
FILE * OpenPipeStream (const char *command, const char *mode)
 
int FreeFile (FILE *file)
 
int CloseTransientFile (int fd)
 
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 ClosePipeStream (FILE *file)
 
void closeAllVfds (void)
 
void SetTempTablespaces (Oid *tableSpaces, int numSpaces)
 
bool TempTablespacesAreSet (void)
 
int GetTempTablespaces (Oid *tableSpaces, int numSpaces)
 
Oid GetNextTempTableSpace (void)
 
void AtEOSubXact_Files (bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
 
void AtEOXact_Files (bool isCommit)
 
void RemovePgTempFiles (void)
 
void RemovePgTempFilesInDir (const char *tmpdirname, bool missing_ok, bool unlink_all)
 
bool looks_like_temp_rel_name (const char *name)
 
void SyncDataDirectory (void)
 
int MakePGDirectory (const char *directoryName)
 
int data_sync_elevel (int elevel)
 

Variables

int max_files_per_process = 1000
 
int max_safe_fds = 32
 
bool data_sync_retry = false
 
static VfdVfdCache
 
static Size SizeVfdCache = 0
 
static int nfile = 0
 
static bool have_xact_temporary_files = false
 
static uint64 temporary_files_size = 0
 
static int numAllocatedDescs = 0
 
static int maxAllocatedDescs = 0
 
static AllocateDescallocatedDescs = NULL
 
static long tempFileCounter = 0
 
static OidtempTableSpaces = NULL
 
static int numTempTableSpaces = -1
 
static int nextTempTableSpace = 0
 

Macro Definition Documentation

◆ DO_DB

◆ FD_CLOSE_AT_EOXACT

#define FD_CLOSE_AT_EOXACT   (1 << 1) /* T = close at eoXact */

Definition at line 174 of file fd.c.

Referenced by CleanupTempFiles(), and RegisterTemporaryFile().

◆ FD_DELETE_AT_CLOSE

#define FD_DELETE_AT_CLOSE   (1 << 0) /* T = delete when closed */

Definition at line 173 of file fd.c.

Referenced by CleanupTempFiles(), FileClose(), and OpenTemporaryFile().

◆ FD_MINFREE

#define FD_MINFREE   10

Definition at line 125 of file fd.c.

Referenced by reserveAllocatedDesc(), and set_max_safe_fds().

◆ FD_TEMP_FILE_LIMIT

#define FD_TEMP_FILE_LIMIT   (1 << 2) /* T = respect temp_file_limit */

◆ FileIsNotOpen

#define FileIsNotOpen (   file)    (VfdCache[file].fd == VFD_CLOSED)

◆ FileIsValid

#define FileIsValid (   file)    ((file) > 0 && (file) < (int) SizeVfdCache && VfdCache[file].fileName != NULL)

◆ NUM_RESERVED_FDS

#define NUM_RESERVED_FDS   10

Definition at line 119 of file fd.c.

Referenced by set_max_safe_fds().

◆ VFD_CLOSED

#define VFD_CLOSED   (-1)

Definition at line 165 of file fd.c.

Referenced by AllocateVfd(), FileClose(), InitFileAccess(), and LruDelete().

Typedef Documentation

◆ Vfd

typedef struct vfd Vfd

Enumeration Type Documentation

◆ AllocateDescKind

Enumerator
AllocateDescFile 
AllocateDescPipe 
AllocateDescDir 
AllocateDescRawFD 

Definition at line 223 of file fd.c.

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

◆ AllocateVfd()

static File AllocateVfd ( void  )
static

Definition at line 1160 of file fd.c.

References Assert, DO_DB, elog, ereport, errcode(), errmsg(), ERROR, vfd::fd, i, LOG, MemSet, vfd::nextFree, realloc, SizeVfdCache, and VFD_CLOSED.

Referenced by PathNameOpenFilePerm().

1161 {
1162  Index i;
1163  File file;
1164 
1165  DO_DB(elog(LOG, "AllocateVfd. Size %zu", SizeVfdCache));
1166 
1167  Assert(SizeVfdCache > 0); /* InitFileAccess not called? */
1168 
1169  if (VfdCache[0].nextFree == 0)
1170  {
1171  /*
1172  * The free list is empty so it is time to increase the size of the
1173  * array. We choose to double it each time this happens. However,
1174  * there's not much point in starting *real* small.
1175  */
1176  Size newCacheSize = SizeVfdCache * 2;
1177  Vfd *newVfdCache;
1178 
1179  if (newCacheSize < 32)
1180  newCacheSize = 32;
1181 
1182  /*
1183  * Be careful not to clobber VfdCache ptr if realloc fails.
1184  */
1185  newVfdCache = (Vfd *) realloc(VfdCache, sizeof(Vfd) * newCacheSize);
1186  if (newVfdCache == NULL)
1187  ereport(ERROR,
1188  (errcode(ERRCODE_OUT_OF_MEMORY),
1189  errmsg("out of memory")));
1190  VfdCache = newVfdCache;
1191 
1192  /*
1193  * Initialize the new entries and link them into the free list.
1194  */
1195  for (i = SizeVfdCache; i < newCacheSize; i++)
1196  {
1197  MemSet((char *) &(VfdCache[i]), 0, sizeof(Vfd));
1198  VfdCache[i].nextFree = i + 1;
1199  VfdCache[i].fd = VFD_CLOSED;
1200  }
1201  VfdCache[newCacheSize - 1].nextFree = 0;
1203 
1204  /*
1205  * Record the new size
1206  */
1207  SizeVfdCache = newCacheSize;
1208  }
1209 
1210  file = VfdCache[0].nextFree;
1211 
1212  VfdCache[0].nextFree = VfdCache[file].nextFree;
1213 
1214  return file;
1215 }
File nextFree
Definition: fd.c:182
static Size SizeVfdCache
Definition: fd.c:198
#define DO_DB(A)
Definition: fd.c:161
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 LOG
Definition: elog.h:26
#define ERROR
Definition: elog.h:43
Definition: fd.c:177
int fd
Definition: fd.c:179
#define ereport(elevel, rest)
Definition: elog.h:141
unsigned int Index
Definition: c.h:475
#define VFD_CLOSED
Definition: fd.c:165
#define Assert(condition)
Definition: c.h:732
size_t Size
Definition: c.h:466
#define realloc(a, b)
Definition: header.h:60
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
int i
int File
Definition: fd.h:45

◆ 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

◆ AtProcExit_Files()

static void AtProcExit_Files ( int  code,
Datum  arg 
)
static

Definition at line 2795 of file fd.c.

References CleanupTempFiles().

Referenced by InitFileAccess().

2796 {
2797  CleanupTempFiles(false, true);
2798 }
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

◆ CleanupTempFiles()

static void CleanupTempFiles ( bool  isCommit,
bool  isProcExit 
)
static

Definition at line 2813 of file fd.c.

References Assert, elog, FD_CLOSE_AT_EOXACT, FD_DELETE_AT_CLOSE, vfd::fdstate, FileClose(), FileIsNotOpen, vfd::fileName, FreeDesc(), have_xact_temporary_files, i, numAllocatedDescs, SizeVfdCache, and WARNING.

Referenced by AtEOXact_Files(), and AtProcExit_Files().

2814 {
2815  Index i;
2816 
2817  /*
2818  * Careful here: at proc_exit we need extra cleanup, not just
2819  * xact_temporary files.
2820  */
2821  if (isProcExit || have_xact_temporary_files)
2822  {
2823  Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
2824  for (i = 1; i < SizeVfdCache; i++)
2825  {
2826  unsigned short fdstate = VfdCache[i].fdstate;
2827 
2828  if (((fdstate & FD_DELETE_AT_CLOSE) || (fdstate & FD_CLOSE_AT_EOXACT)) &&
2829  VfdCache[i].fileName != NULL)
2830  {
2831  /*
2832  * If we're in the process of exiting a backend process, close
2833  * all temporary files. Otherwise, only close temporary files
2834  * local to the current transaction. They should be closed by
2835  * the ResourceOwner mechanism already, so this is just a
2836  * debugging cross-check.
2837  */
2838  if (isProcExit)
2839  FileClose(i);
2840  else if (fdstate & FD_CLOSE_AT_EOXACT)
2841  {
2842  elog(WARNING,
2843  "temporary file %s not closed at end-of-transaction",
2844  VfdCache[i].fileName);
2845  FileClose(i);
2846  }
2847  }
2848  }
2849 
2850  have_xact_temporary_files = false;
2851  }
2852 
2853  /* Complain if any allocated files remain open at commit. */
2854  if (isCommit && numAllocatedDescs > 0)
2855  elog(WARNING, "%d temporary files and directories not closed at end-of-transaction",
2857 
2858  /* Clean up "allocated" stdio files, dirs and fds. */
2859  while (numAllocatedDescs > 0)
2860  FreeDesc(&allocatedDescs[0]);
2861 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
static Size SizeVfdCache
Definition: fd.c:198
#define FD_DELETE_AT_CLOSE
Definition: fd.c:173
static Vfd * VfdCache
Definition: fd.c:197
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2365
static bool have_xact_temporary_files
Definition: fd.c:209
unsigned short fdstate
Definition: fd.c:180
#define WARNING
Definition: elog.h:40
#define FileIsNotOpen(file)
Definition: fd.c:170
unsigned int Index
Definition: c.h:475
void FileClose(File file)
Definition: fd.c:1711
#define Assert(condition)
Definition: c.h:732
#define elog(elevel,...)
Definition: elog.h:226
int i
#define FD_CLOSE_AT_EOXACT
Definition: fd.c:174
static int numAllocatedDescs
Definition: fd.c:243

◆ 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

◆ count_usable_fds()

static void count_usable_fds ( int  max_to_probe,
int *  usable_fds,
int *  already_open 
)
static

Definition at line 817 of file fd.c.

References close, elog, ereport, errmsg(), vfd::fd, palloc(), pfree(), repalloc(), and WARNING.

Referenced by set_max_safe_fds().

818 {
819  int *fd;
820  int size;
821  int used = 0;
822  int highestfd = 0;
823  int j;
824 
825 #ifdef HAVE_GETRLIMIT
826  struct rlimit rlim;
827  int getrlimit_status;
828 #endif
829 
830  size = 1024;
831  fd = (int *) palloc(size * sizeof(int));
832 
833 #ifdef HAVE_GETRLIMIT
834 #ifdef RLIMIT_NOFILE /* most platforms use RLIMIT_NOFILE */
835  getrlimit_status = getrlimit(RLIMIT_NOFILE, &rlim);
836 #else /* but BSD doesn't ... */
837  getrlimit_status = getrlimit(RLIMIT_OFILE, &rlim);
838 #endif /* RLIMIT_NOFILE */
839  if (getrlimit_status != 0)
840  ereport(WARNING, (errmsg("getrlimit failed: %m")));
841 #endif /* HAVE_GETRLIMIT */
842 
843  /* dup until failure or probe limit reached */
844  for (;;)
845  {
846  int thisfd;
847 
848 #ifdef HAVE_GETRLIMIT
849 
850  /*
851  * don't go beyond RLIMIT_NOFILE; causes irritating kernel logs on
852  * some platforms
853  */
854  if (getrlimit_status == 0 && highestfd >= rlim.rlim_cur - 1)
855  break;
856 #endif
857 
858  thisfd = dup(0);
859  if (thisfd < 0)
860  {
861  /* Expect EMFILE or ENFILE, else it's fishy */
862  if (errno != EMFILE && errno != ENFILE)
863  elog(WARNING, "dup(0) failed after %d successes: %m", used);
864  break;
865  }
866 
867  if (used >= size)
868  {
869  size *= 2;
870  fd = (int *) repalloc(fd, size * sizeof(int));
871  }
872  fd[used++] = thisfd;
873 
874  if (highestfd < thisfd)
875  highestfd = thisfd;
876 
877  if (used >= max_to_probe)
878  break;
879  }
880 
881  /* release the files we opened */
882  for (j = 0; j < used; j++)
883  close(fd[j]);
884 
885  pfree(fd);
886 
887  /*
888  * Return results. usable_fds is just the number of successful dups. We
889  * assume that the system limit is highestfd+1 (remember 0 is a legal FD
890  * number) and so already_open is highestfd+1 - usable_fds.
891  */
892  *usable_fds = used;
893  *already_open = highestfd + 1 - used;
894 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
void pfree(void *pointer)
Definition: mcxt.c:1056
#define ereport(elevel, rest)
Definition: elog.h:141
#define WARNING
Definition: elog.h:40
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1069
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
#define close(a)
Definition: win32.h:12

◆ data_sync_elevel()

◆ datadir_fsync_fname()

static void datadir_fsync_fname ( const char *  fname,
bool  isdir,
int  elevel 
)
static

Definition at line 3308 of file fd.c.

References fsync_fname_ext().

Referenced by SyncDataDirectory().

3309 {
3310  /*
3311  * We want to silently ignoring errors about unreadable files. Pass that
3312  * desire on to fsync_fname_ext().
3313  */
3314  fsync_fname_ext(fname, isdir, true, elevel);
3315 }
static int elevel
Definition: vacuumlazy.c:143
static int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3343

◆ Delete()

static void Delete ( File  file)
static

Definition at line 1014 of file fd.c.

References Assert, DO_DB, elog, vfd::fileName, LOG, vfd::lruLessRecently, and vfd::lruMoreRecently.

Referenced by FileAccess(), FileClose(), and LruDelete().

1015 {
1016  Vfd *vfdP;
1017 
1018  Assert(file != 0);
1019 
1020  DO_DB(elog(LOG, "Delete %d (%s)",
1021  file, VfdCache[file].fileName));
1022  DO_DB(_dump_lru());
1023 
1024  vfdP = &VfdCache[file];
1025 
1028 
1029  DO_DB(_dump_lru());
1030 }
File lruLessRecently
Definition: fd.c:184
#define DO_DB(A)
Definition: fd.c:161
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
Definition: fd.c:177
#define Assert(condition)
Definition: c.h:732
File lruMoreRecently
Definition: fd.c:183
#define elog(elevel,...)
Definition: elog.h:226

◆ durable_link_or_rename()

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

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 #ifdef 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  elevel 
)

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  elevel 
)

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

◆ FileAccess()

static int FileAccess ( File  file)
static

Definition at line 1238 of file fd.c.

References Delete(), DO_DB, elog, FileIsNotOpen, vfd::fileName, Insert(), LOG, LruInsert(), and vfd::lruLessRecently.

Referenced by FilePrefetch(), FileRead(), FileSize(), FileSync(), FileTruncate(), FileWrite(), and FileWriteback().

1239 {
1240  int returnValue;
1241 
1242  DO_DB(elog(LOG, "FileAccess %d (%s)",
1243  file, VfdCache[file].fileName));
1244 
1245  /*
1246  * Is the file open? If not, open it and put it at the head of the LRU
1247  * ring (possibly closing the least recently used file to get an FD).
1248  */
1249 
1250  if (FileIsNotOpen(file))
1251  {
1252  returnValue = LruInsert(file);
1253  if (returnValue != 0)
1254  return returnValue;
1255  }
1256  else if (VfdCache[0].lruLessRecently != file)
1257  {
1258  /*
1259  * We now know that the file is open and that it is not the last one
1260  * accessed, so we need to move it to the head of the Lru ring.
1261  */
1262 
1263  Delete(file);
1264  Insert(file);
1265  }
1266 
1267  return 0;
1268 }
#define DO_DB(A)
Definition: fd.c:161
static Vfd * VfdCache
Definition: fd.c:197
static void Delete(File file)
Definition: fd.c:1014
#define LOG
Definition: elog.h:26
static int LruInsert(File file)
Definition: fd.c:1081
static void Insert(File file)
Definition: fd.c:1059
#define FileIsNotOpen(file)
Definition: fd.c:170
#define elog(elevel,...)
Definition: elog.h:226

◆ 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:255
#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:323

◆ 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:323
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

◆ FreeDesc()

static int FreeDesc ( AllocateDesc desc)
static

Definition at line 2365 of file fd.c.

References AllocateDescDir, AllocateDescFile, AllocateDescPipe, AllocateDescRawFD, close, closedir(), AllocateDesc::desc, AllocateDesc::dir, elog, ERROR, AllocateDesc::fd, AllocateDesc::file, AllocateDesc::kind, and numAllocatedDescs.

Referenced by AtEOSubXact_Files(), CleanupTempFiles(), ClosePipeStream(), CloseTransientFile(), FreeDir(), and FreeFile().

2366 {
2367  int result;
2368 
2369  /* Close the underlying object */
2370  switch (desc->kind)
2371  {
2372  case AllocateDescFile:
2373  result = fclose(desc->desc.file);
2374  break;
2375  case AllocateDescPipe:
2376  result = pclose(desc->desc.file);
2377  break;
2378  case AllocateDescDir:
2379  result = closedir(desc->desc.dir);
2380  break;
2381  case AllocateDescRawFD:
2382  result = close(desc->desc.fd);
2383  break;
2384  default:
2385  elog(ERROR, "AllocateDesc kind not recognized");
2386  result = 0; /* keep compiler quiet */
2387  break;
2388  }
2389 
2390  /* Compact storage in the allocatedDescs array */
2393 
2394  return result;
2395 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
union AllocateDesc::@26 desc
DIR * dir
Definition: fd.c:238
int closedir(DIR *)
Definition: dirent.c:113
AllocateDescKind kind
Definition: fd.c:233
#define ERROR
Definition: elog.h:43
FILE * file
Definition: fd.c:237
int fd
Definition: fd.c:239
#define elog(elevel,...)
Definition: elog.h:226
#define close(a)
Definition: win32.h:12
static int numAllocatedDescs
Definition: fd.c:243

◆ 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

◆ FreeVfd()

static void FreeVfd ( File  file)
static

Definition at line 1218 of file fd.c.

References DO_DB, elog, vfd::fdstate, vfd::fileName, free, LOG, and vfd::nextFree.

Referenced by FileClose(), and PathNameOpenFilePerm().

1219 {
1220  Vfd *vfdP = &VfdCache[file];
1221 
1222  DO_DB(elog(LOG, "FreeVfd: %d (%s)",
1223  file, vfdP->fileName ? vfdP->fileName : ""));
1224 
1225  if (vfdP->fileName != NULL)
1226  {
1227  free(vfdP->fileName);
1228  vfdP->fileName = NULL;
1229  }
1230  vfdP->fdstate = 0x0;
1231 
1232  vfdP->nextFree = VfdCache[0].nextFree;
1233  VfdCache[0].nextFree = file;
1234 }
File nextFree
Definition: fd.c:182
#define DO_DB(A)
Definition: fd.c:161
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
char * fileName
Definition: fd.c:186
unsigned short fdstate
Definition: fd.c:180
Definition: fd.c:177
#define free(a)
Definition: header.h:65
#define elog(elevel,...)
Definition: elog.h:226

◆ fsync_fname()

void fsync_fname ( const char *  fname,
bool  isdir 
)

Definition at line 580 of file fd.c.

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

581 {
582  fsync_fname_ext(fname, isdir, false, data_sync_elevel(ERROR));
583 }
#define ERROR
Definition: elog.h:43
int data_sync_elevel(int elevel)
Definition: fd.c:3482
static int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3343

◆ fsync_fname_ext()

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

Definition at line 3343 of file fd.c.

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

Referenced by datadir_fsync_fname(), durable_link_or_rename(), durable_rename(), fsync_fname(), and fsync_parent_path().

3344 {
3345  int fd;
3346  int flags;
3347  int returncode;
3348 
3349  /*
3350  * Some OSs require directories to be opened read-only whereas other
3351  * systems don't allow us to fsync files opened read-only; so we need both
3352  * cases here. Using O_RDWR will cause us to fail to fsync files that are
3353  * not writable by our userid, but we assume that's OK.
3354  */
3355  flags = PG_BINARY;
3356  if (!isdir)
3357  flags |= O_RDWR;
3358  else
3359  flags |= O_RDONLY;
3360 
3361  fd = OpenTransientFile(fname, flags);
3362 
3363  /*
3364  * Some OSs don't allow us to open directories at all (Windows returns
3365  * EACCES), just ignore the error in that case. If desired also silently
3366  * ignoring errors about unreadable files. Log others.
3367  */
3368  if (fd < 0 && isdir && (errno == EISDIR || errno == EACCES))
3369  return 0;
3370  else if (fd < 0 && ignore_perm && errno == EACCES)
3371  return 0;
3372  else if (fd < 0)
3373  {
3374  ereport(elevel,
3376  errmsg("could not open file \"%s\": %m", fname)));
3377  return -1;
3378  }
3379 
3380  returncode = pg_fsync(fd);
3381 
3382  /*
3383  * Some OSes don't allow us to fsync directories at all, so we can ignore
3384  * those errors. Anything else needs to be logged.
3385  */
3386  if (returncode != 0 && !(isdir && (errno == EBADF || errno == EINVAL)))
3387  {
3388  int save_errno;
3389 
3390  /* close file upon error, might not be in transaction context */
3391  save_errno = errno;
3392  (void) CloseTransientFile(fd);
3393  errno = save_errno;
3394 
3395  ereport(elevel,
3397  errmsg("could not fsync file \"%s\": %m", fname)));
3398  return -1;
3399  }
3400 
3401  if (CloseTransientFile(fd) != 0)
3402  {
3403  ereport(elevel,
3405  errmsg("could not close file \"%s\": %m", fname)));
3406  return -1;
3407  }
3408 
3409  return 0;
3410 }
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
int pg_fsync(int fd)
Definition: fd.c:331

◆ fsync_parent_path()

static int fsync_parent_path ( const char *  fname,
int  elevel 
)
static

Definition at line 3419 of file fd.c.

References fsync_fname_ext(), get_parent_directory(), MAXPGPATH, and strlcpy().

Referenced by dir_close(), dir_open_for_write(), durable_link_or_rename(), durable_rename(), durable_unlink(), and tar_finish().

3420 {
3421  char parentpath[MAXPGPATH];
3422 
3423  strlcpy(parentpath, fname, MAXPGPATH);
3424  get_parent_directory(parentpath);
3425 
3426  /*
3427  * get_parent_directory() returns an empty string if the input argument is
3428  * just a file name (see comments in path.c), so handle that as being the
3429  * current directory.
3430  */
3431  if (strlen(parentpath) == 0)
3432  strlcpy(parentpath, ".", MAXPGPATH);
3433 
3434  if (fsync_fname_ext(parentpath, true, false, elevel) != 0)
3435  return -1;
3436 
3437  return 0;
3438 }
#define MAXPGPATH
void get_parent_directory(char *path)
Definition: path.c:854
static int elevel
Definition: vacuumlazy.c:143
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
static int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3343

◆ 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

◆ Insert()

static void Insert ( File  file)
static

Definition at line 1059 of file fd.c.

References Assert, DO_DB, elog, vfd::fileName, LOG, vfd::lruLessRecently, and vfd::lruMoreRecently.

Referenced by AdvanceXLInsertBuffer(), CreateCheckPoint(), FileAccess(), GetXLogInsertRecPtr(), InitXLOGAccess(), LruInsert(), PathNameOpenFilePerm(), ReserveXLogInsertLocation(), ReserveXLogSwitch(), StartupXLOG(), UpdateFullPageWrites(), WaitXLogInsertionsToFinish(), and XLogInsertRecord().

1060 {
1061  Vfd *vfdP;
1062 
1063  Assert(file != 0);
1064 
1065  DO_DB(elog(LOG, "Insert %d (%s)",
1066  file, VfdCache[file].fileName));
1067  DO_DB(_dump_lru());
1068 
1069  vfdP = &VfdCache[file];
1070 
1071  vfdP->lruMoreRecently = 0;
1073  VfdCache[0].lruLessRecently = file;
1075 
1076  DO_DB(_dump_lru());
1077 }
File lruLessRecently
Definition: fd.c:184
#define DO_DB(A)
Definition: fd.c:161
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
Definition: fd.c:177
#define Assert(condition)
Definition: c.h:732
File lruMoreRecently
Definition: fd.c:183
#define elog(elevel,...)
Definition: elog.h:226

◆ 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

◆ LruDelete()

static void LruDelete ( File  file)
static

Definition at line 1033 of file fd.c.

References Assert, close, data_sync_elevel(), Delete(), DO_DB, elog, vfd::fd, FD_TEMP_FILE_LIMIT, vfd::fdstate, vfd::fileName, LOG, nfile, and VFD_CLOSED.

Referenced by closeAllVfds(), RegisterTemporaryFile(), and ReleaseLruFile().

1034 {
1035  Vfd *vfdP;
1036 
1037  Assert(file != 0);
1038 
1039  DO_DB(elog(LOG, "LruDelete %d (%s)",
1040  file, VfdCache[file].fileName));
1041 
1042  vfdP = &VfdCache[file];
1043 
1044  /*
1045  * Close the file. We aren't expecting this to fail; if it does, better
1046  * to leak the FD than to mess up our internal state.
1047  */
1048  if (close(vfdP->fd) != 0)
1050  "could not close file \"%s\": %m", vfdP->fileName);
1051  vfdP->fd = VFD_CLOSED;
1052  --nfile;
1053 
1054  /* delete the vfd record from the LRU ring */
1055  Delete(file);
1056 }
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:175
#define DO_DB(A)
Definition: fd.c:161
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
int fd
Definition: fd.c:179
int data_sync_elevel(int elevel)
Definition: fd.c:3482
#define VFD_CLOSED
Definition: fd.c:165
#define Assert(condition)
Definition: c.h:732
#define elog(elevel,...)
Definition: elog.h:226
#define close(a)
Definition: win32.h:12

◆ LruInsert()

static int LruInsert ( File  file)
static

Definition at line 1081 of file fd.c.

References Assert, BasicOpenFilePerm(), DO_DB, elog, vfd::fd, vfd::fileFlags, FileIsNotOpen, vfd::fileMode, vfd::fileName, Insert(), LOG, nfile, and ReleaseLruFiles().

Referenced by FileAccess().

1082 {
1083  Vfd *vfdP;
1084 
1085  Assert(file != 0);
1086 
1087  DO_DB(elog(LOG, "LruInsert %d (%s)",
1088  file, VfdCache[file].fileName));
1089 
1090  vfdP = &VfdCache[file];
1091 
1092  if (FileIsNotOpen(file))
1093  {
1094  /* Close excess kernel FDs. */
1095  ReleaseLruFiles();
1096 
1097  /*
1098  * The open could still fail for lack of file descriptors, eg due to
1099  * overall system file table being full. So, be prepared to release
1100  * another FD if necessary...
1101  */
1102  vfdP->fd = BasicOpenFilePerm(vfdP->fileName, vfdP->fileFlags,
1103  vfdP->fileMode);
1104  if (vfdP->fd < 0)
1105  {
1106  DO_DB(elog(LOG, "re-open failed: %m"));
1107  return -1;
1108  }
1109  else
1110  {
1111  ++nfile;
1112  }
1113  }
1114 
1115  /*
1116  * put it at the head of the Lru ring
1117  */
1118 
1119  Insert(file);
1120 
1121  return 0;
1122 }
#define DO_DB(A)
Definition: fd.c:161
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
mode_t fileMode
Definition: fd.c:189
char * fileName
Definition: fd.c:186
static int nfile
Definition: fd.c:203
Definition: fd.c:177
int fd
Definition: fd.c:179
static void Insert(File file)
Definition: fd.c:1059
static void ReleaseLruFiles(void)
Definition: fd.c:1150
#define FileIsNotOpen(file)
Definition: fd.c:170
#define Assert(condition)
Definition: c.h:732
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:966
#define elog(elevel,...)
Definition: elog.h:226
int fileFlags
Definition: fd.c:188

◆ 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:159
#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:151
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:149
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

◆ OpenTemporaryFileInTablespace()

static File OpenTemporaryFileInTablespace ( Oid  tblspcOid,
bool  rejectError 
)
static

Definition at line 1540 of file fd.c.

References elog, ERROR, MakePGDirectory(), MAXPGPATH, MyProcPid, PathNameOpenFile(), PG_BINARY, PG_TEMP_FILE_PREFIX, snprintf, tempFileCounter, and TempTablespacePath().

Referenced by OpenTemporaryFile().

1541 {
1542  char tempdirpath[MAXPGPATH];
1543  char tempfilepath[MAXPGPATH];
1544  File file;
1545 
1546  TempTablespacePath(tempdirpath, tblspcOid);
1547 
1548  /*
1549  * Generate a tempfile name that should be unique within the current
1550  * database instance.
1551  */
1552  snprintf(tempfilepath, sizeof(tempfilepath), "%s/%s%d.%ld",
1553  tempdirpath, PG_TEMP_FILE_PREFIX, MyProcPid, tempFileCounter++);
1554 
1555  /*
1556  * Open the file. Note: we don't use O_EXCL, in case there is an orphaned
1557  * temp file that can be reused.
1558  */
1559  file = PathNameOpenFile(tempfilepath,
1560  O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1561  if (file <= 0)
1562  {
1563  /*
1564  * We might need to create the tablespace's tempfile directory, if no
1565  * one has yet done so.
1566  *
1567  * Don't check for an error from MakePGDirectory; it could fail if
1568  * someone else just did the same thing. If it doesn't work then
1569  * we'll bomb out on the second create attempt, instead.
1570  */
1571  (void) MakePGDirectory(tempdirpath);
1572 
1573  file = PathNameOpenFile(tempfilepath,
1574  O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1575  if (file <= 0 && rejectError)
1576  elog(ERROR, "could not create temporary file \"%s\": %m",
1577  tempfilepath);
1578  }
1579 
1580  return file;
1581 }
int MyProcPid
Definition: globals.c:40
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1321
void TempTablespacePath(char *path, Oid tablespace)
Definition: fd.c:1515
#define PG_BINARY
Definition: c.h:1191
#define ERROR
Definition: elog.h:43
#define PG_TEMP_FILE_PREFIX
Definition: pg_checksums.c:59
#define MAXPGPATH
int MakePGDirectory(const char *directoryName)
Definition: fd.c:3459
static long tempFileCounter
Definition: fd.c:251
#define elog(elevel,...)
Definition: elog.h:226
#define snprintf
Definition: port.h:192
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 *  basedir,
const char *  directory 
)

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:82
#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 *  path,
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 *  dirname)

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:255

◆ PathNameDeleteTemporaryFile()

bool PathNameDeleteTemporaryFile ( const char *  path,
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("could not 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:255
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 *  path)

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  nbytes 
)

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

◆ RegisterTemporaryFile()

static void RegisterTemporaryFile ( File  file)
static

Definition at line 1293 of file fd.c.

References Assert, CurrentResourceOwner, FD_CLOSE_AT_EOXACT, vfd::fdstate, FileIsNotOpen, FileIsValid, have_xact_temporary_files, LruDelete(), ResourceOwnerRememberFile(), and vfd::resowner.

Referenced by OpenTemporaryFile(), PathNameCreateTemporaryFile(), and PathNameOpenTemporaryFile().

1294 {
1297 
1298  /* Backup mechanism for closing at end of xact. */
1301 }
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
static Vfd * VfdCache
Definition: fd.c:197
static bool have_xact_temporary_files
Definition: fd.c:209
void ResourceOwnerRememberFile(ResourceOwner owner, File file)
Definition: resowner.c:1244
unsigned short fdstate
Definition: fd.c:180
ResourceOwner resowner
Definition: fd.c:181
#define FD_CLOSE_AT_EOXACT
Definition: fd.c:174

◆ ReleaseLruFile()

static bool ReleaseLruFile ( void  )
static

Definition at line 1128 of file fd.c.

References Assert, DO_DB, elog, LOG, LruDelete(), vfd::lruMoreRecently, and nfile.

Referenced by AllocateDir(), AllocateFile(), BasicOpenFilePerm(), OpenPipeStream(), and ReleaseLruFiles().

1129 {
1130  DO_DB(elog(LOG, "ReleaseLruFile. Opened %d", nfile));
1131 
1132  if (nfile > 0)
1133  {
1134  /*
1135  * There are opened files and so there should be at least one used vfd
1136  * in the ring.
1137  */
1138  Assert(VfdCache[0].lruMoreRecently != 0);
1139  LruDelete(VfdCache[0].lruMoreRecently);
1140  return true; /* freed a file */
1141  }
1142  return false; /* no files available to free */
1143 }
#define DO_DB(A)
Definition: fd.c:161
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
static void LruDelete(File file)
Definition: fd.c:1033
static int nfile
Definition: fd.c:203
#define Assert(condition)
Definition: c.h:732
#define elog(elevel,...)
Definition: elog.h:226

◆ ReleaseLruFiles()

static void ReleaseLruFiles ( void  )
static

Definition at line 1150 of file fd.c.

References max_safe_fds, nfile, numAllocatedDescs, and ReleaseLruFile().

Referenced by AllocateDir(), AllocateFile(), LruInsert(), OpenPipeStream(), OpenTransientFilePerm(), and PathNameOpenFilePerm().

1151 {
1152  while (nfile + numAllocatedDescs >= max_safe_fds)
1153  {
1154  if (!ReleaseLruFile())
1155  break;
1156  }
1157 }
int max_safe_fds
Definition: fd.c:146
static bool ReleaseLruFile(void)
Definition: fd.c:1128
static int nfile
Definition: fd.c:203
static int numAllocatedDescs
Definition: fd.c:243

◆ 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:255
#define S_ISDIR(m)
Definition: win32_port.h:296
#define lstat(path, sb)
Definition: win32_port.h:244
int errmsg(const char *fmt,...)
Definition: elog.c:784
char d_name[MAX_PATH]
Definition: dirent.h:14
#define snprintf
Definition: port.h:192
int FreeDir(DIR *dir)
Definition: fd.c:2584

◆ RemovePgTempRelationFiles()

static void RemovePgTempRelationFiles ( const char *  tsdirname)
static

Definition at line 3008 of file fd.c.

References AllocateDir(), dirent::d_name, FreeDir(), LOG, MAXPGPATH, ReadDirExtended(), RemovePgTempRelationFilesInDbspace(), and snprintf.

Referenced by RemovePgTempFiles().

3009 {
3010  DIR *ts_dir;
3011  struct dirent *de;
3012  char dbspace_path[MAXPGPATH * 2];
3013 
3014  ts_dir = AllocateDir(tsdirname);
3015 
3016  while ((de = ReadDirExtended(ts_dir, tsdirname, LOG)) != NULL)
3017  {
3018  /*
3019  * We're only interested in the per-database directories, which have
3020  * numeric names. Note that this code will also (properly) ignore "."
3021  * and "..".
3022  */
3023  if (strspn(de->d_name, "0123456789") != strlen(de->d_name))
3024  continue;
3025 
3026  snprintf(dbspace_path, sizeof(dbspace_path), "%s/%s",
3027  tsdirname, de->d_name);
3028  RemovePgTempRelationFilesInDbspace(dbspace_path);
3029  }
3030 
3031  FreeDir(ts_dir);
3032 }
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2547
static void RemovePgTempRelationFilesInDbspace(const char *dbspacedirname)
Definition: fd.c:3036
#define LOG
Definition: elog.h:26
Definition: dirent.h:9
Definition: dirent.c:25
#define MAXPGPATH
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

◆ RemovePgTempRelationFilesInDbspace()

static void RemovePgTempRelationFilesInDbspace ( const char *  dbspacedirname)
static

Definition at line 3036 of file fd.c.

References AllocateDir(), dirent::d_name, ereport, errcode_for_file_access(), errmsg(), FreeDir(), LOG, looks_like_temp_rel_name(), MAXPGPATH, ReadDirExtended(), and snprintf.

Referenced by RemovePgTempRelationFiles().

3037 {
3038  DIR *dbspace_dir;
3039  struct dirent *de;
3040  char rm_path[MAXPGPATH * 2];
3041 
3042  dbspace_dir = AllocateDir(dbspacedirname);
3043 
3044  while ((de = ReadDirExtended(dbspace_dir, dbspacedirname, LOG)) != NULL)
3045  {
3046  if (!looks_like_temp_rel_name(de->d_name))
3047  continue;
3048 
3049  snprintf(rm_path, sizeof(rm_path), "%s/%s",
3050  dbspacedirname, de->d_name);
3051 
3052  if (unlink(rm_path) < 0)
3053  ereport(LOG,
3055  errmsg("could not remove file \"%s\": %m",
3056  rm_path)));
3057  }
3058 
3059  FreeDir(dbspace_dir);
3060 }
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 MAXPGPATH
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
bool looks_like_temp_rel_name(const char *name)
Definition: fd.c:3064
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

◆ ReportTemporaryFileUsage()

static void ReportTemporaryFileUsage ( const char *  path,
off_t  size 
)
static

Definition at line 1274 of file fd.c.

References ereport, errmsg(), LOG, log_temp_files, and pgstat_report_tempfile().

Referenced by FileClose(), and PathNameDeleteTemporaryFile().

1275 {
1276  pgstat_report_tempfile(size);
1277 
1278  if (log_temp_files >= 0)
1279  {
1280  if ((size / 1024) >= log_temp_files)
1281  ereport(LOG,
1282  (errmsg("temporary file: path \"%s\", size %lu",
1283  path, (unsigned long) size)));
1284  }
1285 }
int log_temp_files
Definition: guc.c:513
void pgstat_report_tempfile(size_t filesize)
Definition: pgstat.c:1566
#define LOG
Definition: elog.h:26
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ reserveAllocatedDesc()

static bool reserveAllocatedDesc ( void  )
static

Definition at line 2132 of file fd.c.

References ereport, errcode(), errmsg(), ERROR, FD_MINFREE, malloc, max_safe_fds, maxAllocatedDescs, numAllocatedDescs, and realloc.

Referenced by AllocateDir(), AllocateFile(), OpenPipeStream(), and OpenTransientFilePerm().

2133 {
2134  AllocateDesc *newDescs;
2135  int newMax;
2136 
2137  /* Quick out if array already has a free slot. */
2139  return true;
2140 
2141  /*
2142  * If the array hasn't yet been created in the current process, initialize
2143  * it with FD_MINFREE / 2 elements. In many scenarios this is as many as
2144  * we will ever need, anyway. We don't want to look at max_safe_fds
2145  * immediately because set_max_safe_fds() may not have run yet.
2146  */
2147  if (allocatedDescs == NULL)
2148  {
2149  newMax = FD_MINFREE / 2;
2150  newDescs = (AllocateDesc *) malloc(newMax * sizeof(AllocateDesc));
2151  /* Out of memory already? Treat as fatal error. */
2152  if (newDescs == NULL)
2153  ereport(ERROR,
2154  (errcode(ERRCODE_OUT_OF_MEMORY),
2155  errmsg("out of memory")));
2156  allocatedDescs = newDescs;
2157  maxAllocatedDescs = newMax;
2158  return true;
2159  }
2160 
2161  /*
2162  * Consider enlarging the array beyond the initial allocation used above.
2163  * By the time this happens, max_safe_fds should be known accurately.
2164  *
2165  * We mustn't let allocated descriptors hog all the available FDs, and in
2166  * practice we'd better leave a reasonable number of FDs for VFD use. So
2167  * set the maximum to max_safe_fds / 2. (This should certainly be at
2168  * least as large as the initial size, FD_MINFREE / 2.)
2169  */
2170  newMax = max_safe_fds / 2;
2171  if (newMax > maxAllocatedDescs)
2172  {
2173  newDescs = (AllocateDesc *) realloc(allocatedDescs,
2174  newMax * sizeof(AllocateDesc));
2175  /* Treat out-of-memory as a non-fatal error. */
2176  if (newDescs == NULL)
2177  return false;
2178  allocatedDescs = newDescs;
2179  maxAllocatedDescs = newMax;
2180  return true;
2181  }
2182 
2183  /* Can't enlarge allocatedDescs[] any more. */
2184  return false;
2185 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
int max_safe_fds
Definition: fd.c:146
int errcode(int sqlerrcode)
Definition: elog.c:570
#define malloc(a)
Definition: header.h:50
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
#define FD_MINFREE
Definition: fd.c:125
#define realloc(a, b)
Definition: header.h:60
int errmsg(const char *fmt,...)
Definition: elog.c:784
static int maxAllocatedDescs
Definition: fd.c:244
static int numAllocatedDescs
Definition: fd.c:243

◆ 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:255
#define lstat(path, sb)
Definition: win32_port.h:244
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

◆ unlink_if_exists_fname()

static void unlink_if_exists_fname ( const char *  fname,
bool  isdir,
int  elevel 
)
static

Definition at line 3318 of file fd.c.

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

Referenced by PathNameDeleteTemporaryDir().

3319 {
3320  if (isdir)
3321  {
3322  if (rmdir(fname) != 0 && errno != ENOENT)
3323  ereport(elevel,
3325  errmsg("could not remove directory \"%s\": %m", fname)));
3326  }
3327  else
3328  {
3329  /* Use PathNameDeleteTemporaryFile to report filesize */
3330  PathNameDeleteTemporaryFile(fname, false);
3331  }
3332 }
bool PathNameDeleteTemporaryFile(const char *path, bool error_on_failure)
Definition: fd.c:1665
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

◆ walkdir()

static void walkdir ( const char *  path,
void(*)(const char *fname, bool isdir, int elevel action,
bool  process_symlinks,
int  elevel 
)
static

Definition at line 3208 of file fd.c.

References generate_unaccent_rules::action, AllocateDir(), CHECK_FOR_INTERRUPTS, CloseTransientFile(), dirent::d_name, elevel, ereport, errcode_for_file_access(), errmsg(), vfd::fd, FreeDir(), lstat, MAXPGPATH, OpenTransientFile(), PG_BINARY, pg_flush_data(), ReadDirExtended(), S_ISDIR, S_ISREG, snprintf, stat, and subpath().

Referenced by PathNameDeleteTemporaryDir(), and SyncDataDirectory().

3212 {
3213  DIR *dir;
3214  struct dirent *de;
3215 
3216  dir = AllocateDir(path);
3217 
3218  while ((de = ReadDirExtended(dir, path, elevel)) != NULL)
3219  {
3220  char subpath[MAXPGPATH * 2];
3221  struct stat fst;
3222  int sret;
3223 
3225 
3226  if (strcmp(de->d_name, ".") == 0 ||
3227  strcmp(de->d_name, "..") == 0)
3228  continue;
3229 
3230  snprintf(subpath, sizeof(subpath), "%s/%s", path, de->d_name);
3231 
3232  if (process_symlinks)
3233  sret = stat(subpath, &fst);
3234  else
3235  sret = lstat(subpath, &fst);
3236 
3237  if (sret < 0)
3238  {
3239  ereport(elevel,
3241  errmsg("could not stat file \"%s\": %m", subpath)));
3242  continue;
3243  }
3244 
3245  if (S_ISREG(fst.st_mode))
3246  (*action) (subpath, false, elevel);
3247  else if (S_ISDIR(fst.st_mode))
3248  walkdir(subpath, action, false, elevel);
3249  }
3250 
3251  FreeDir(dir); /* we ignore any error here */
3252 
3253  /*
3254  * It's important to fsync the destination directory itself as individual
3255  * file fsyncs don't guarantee that the directory entry for the file is
3256  * synced. However, skip this if AllocateDir failed; the action function
3257  * might not be robust against that.
3258  */
3259  if (dir)
3260  (*action) (path, true, elevel);
3261 }
static void walkdir(const char *path, void(*action)(const char *fname, bool isdir, int elevel), bool process_symlinks, int elevel)
Definition: fd.c:3208
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2547
Definition: dirent.h:9
Definition: dirent.c:25
#define MAXPGPATH
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 S_ISREG(m)
Definition: win32_port.h:299
#define stat(a, b)
Definition: win32_port.h:255
static int elevel
Definition: vacuumlazy.c:143
#define S_ISDIR(m)
Definition: win32_port.h:296
#define lstat(path, sb)
Definition: win32_port.h:244
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:99
char d_name[MAX_PATH]
Definition: dirent.h:14
#define snprintf
Definition: port.h:192
int FreeDir(DIR *dir)
Definition: fd.c:2584
Datum subpath(PG_FUNCTION_ARGS)
Definition: ltree_op.c:241

Variable Documentation

◆ allocatedDescs

AllocateDesc* allocatedDescs = NULL
static

Definition at line 245 of file fd.c.

◆ data_sync_retry

bool data_sync_retry = false

Definition at line 149 of file fd.c.

Referenced by data_sync_elevel().

◆ have_xact_temporary_files

bool have_xact_temporary_files = false
static

Definition at line 209 of file fd.c.

Referenced by CleanupTempFiles(), and RegisterTemporaryFile().

◆ max_files_per_process

int max_files_per_process = 1000

Definition at line 133 of file fd.c.

Referenced by set_max_safe_fds().

◆ max_safe_fds

int max_safe_fds = 32

◆ maxAllocatedDescs

int maxAllocatedDescs = 0
static

◆ nextTempTableSpace

int nextTempTableSpace = 0
static

Definition at line 259 of file fd.c.

Referenced by GetNextTempTableSpace(), and SetTempTablespaces().

◆ nfile

int nfile = 0
static

◆ numAllocatedDescs

◆ numTempTableSpaces

int numTempTableSpaces = -1
static

◆ SizeVfdCache

Size SizeVfdCache = 0
static

Definition at line 198 of file fd.c.

Referenced by AllocateVfd(), CleanupTempFiles(), closeAllVfds(), and InitFileAccess().

◆ tempFileCounter

long tempFileCounter = 0
static

Definition at line 251 of file fd.c.

Referenced by OpenTemporaryFileInTablespace().

◆ temporary_files_size

uint64 temporary_files_size = 0
static

Definition at line 217 of file fd.c.

Referenced by FileClose(), FileTruncate(), and FileWrite().

◆ tempTableSpaces

Oid* tempTableSpaces = NULL
static

◆ VfdCache

Vfd* VfdCache
static

Definition at line 197 of file fd.c.