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 "access/xact.h"
#include "access/xlog.h"
#include "catalog/pg_tablespace.h"
#include "common/file_perm.h"
#include "common/file_utils.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "port/pg_iovec.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   48
 
#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_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)
 
int pg_truncate (const char *path, off_t length)
 
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_rename_excl (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)
 
bool AcquireExternalFD (void)
 
void ReserveExternalFD (void)
 
void ReleaseExternalFD (void)
 
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, int mode)
 
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 fsync_fname_ext (const char *fname, bool isdir, bool ignore_perm, int elevel)
 
int MakePGDirectory (const char *directoryName)
 
int data_sync_elevel (int elevel)
 
ssize_t pg_pwritev_with_retry (int fd, const struct iovec *iov, int iovcnt, off_t offset)
 

Variables

int max_files_per_process = 1000
 
int max_safe_fds = FD_MINFREE
 
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 int numExternalFDs = 0
 
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 184 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 183 of file fd.c.

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

◆ FD_MINFREE

#define FD_MINFREE   48

Definition at line 135 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 126 of file fd.c.

Referenced by set_max_safe_fds().

◆ VFD_CLOSED

#define VFD_CLOSED   (-1)

Definition at line 175 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 233 of file fd.c.

Function Documentation

◆ AcquireExternalFD()

bool AcquireExternalFD ( void  )

Definition at line 1076 of file fd.c.

References max_safe_fds, numExternalFDs, and ReserveExternalFD().

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

1077 {
1078  /*
1079  * We don't want more than max_safe_fds / 3 FDs to be consumed for
1080  * "external" FDs.
1081  */
1082  if (numExternalFDs < max_safe_fds / 3)
1083  {
1085  return true;
1086  }
1087  errno = EMFILE;
1088  return false;
1089 }
static int numExternalFDs
Definition: fd.c:260
int max_safe_fds
Definition: fd.c:156
void ReserveExternalFD(void)
Definition: fd.c:1111

◆ AllocateDir()

DIR* AllocateDir ( const char *  dirname)

Definition at line 2615 of file fd.c.

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

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

2616 {
2617  DIR *dir;
2618 
2619  DO_DB(elog(LOG, "AllocateDir: Allocated %d (%s)",
2620  numAllocatedDescs, dirname));
2621 
2622  /* Can we allocate another non-virtual FD? */
2623  if (!reserveAllocatedDesc())
2624  ereport(ERROR,
2625  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2626  errmsg("exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"",
2627  maxAllocatedDescs, dirname)));
2628 
2629  /* Close excess kernel FDs. */
2630  ReleaseLruFiles();
2631 
2632 TryAgain:
2633  if ((dir = opendir(dirname)) != NULL)
2634  {
2636 
2637  desc->kind = AllocateDescDir;
2638  desc->desc.dir = dir;
2641  return desc->desc.dir;
2642  }
2643 
2644  if (errno == EMFILE || errno == ENFILE)
2645  {
2646  int save_errno = errno;
2647 
2648  ereport(LOG,
2649  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2650  errmsg("out of file descriptors: %m; release and retry")));
2651  errno = 0;
2652  if (ReleaseLruFile())
2653  goto TryAgain;
2654  errno = save_errno;
2655  }
2656 
2657  return NULL;
2658 }
static AllocateDesc * allocatedDescs
Definition: fd.c:255
DIR * dir
Definition: fd.c:248
#define DO_DB(A)
Definition: fd.c:171
int errcode(int sqlerrcode)
Definition: elog.c:704
static bool reserveAllocatedDesc(void)
Definition: fd.c:2279
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:243
static bool ReleaseLruFile(void)
Definition: fd.c:1272
Definition: dirent.c:25
#define ERROR
Definition: elog.h:45
DIR * opendir(const char *)
Definition: dirent.c:33
static void ReleaseLruFiles(void)
Definition: fd.c:1294
#define ereport(elevel,...)
Definition: elog.h:155
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:723
SubTransactionId create_subid
Definition: fd.c:244
int errmsg(const char *fmt,...)
Definition: elog.c:915
#define elog(elevel,...)
Definition: elog.h:228
union AllocateDesc::@23 desc
static int maxAllocatedDescs
Definition: fd.c:254
static int numAllocatedDescs
Definition: fd.c:253

◆ AllocateFile()

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

Definition at line 2354 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(), 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(), tokenize_inc_file(), tsearch_readline_begin(), ValidatePgVersion(), write_relcache_init_file(), XLogArchiveForceDone(), and XLogArchiveNotify().

2355 {
2356  FILE *file;
2357 
2358  DO_DB(elog(LOG, "AllocateFile: Allocated %d (%s)",
2360 
2361  /* Can we allocate another non-virtual FD? */
2362  if (!reserveAllocatedDesc())
2363  ereport(ERROR,
2364  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2365  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2366  maxAllocatedDescs, name)));
2367 
2368  /* Close excess kernel FDs. */
2369  ReleaseLruFiles();
2370 
2371 TryAgain:
2372  if ((file = fopen(name, mode)) != NULL)
2373  {
2375 
2376  desc->kind = AllocateDescFile;
2377  desc->desc.file = file;
2380  return desc->desc.file;
2381  }
2382 
2383  if (errno == EMFILE || errno == ENFILE)
2384  {
2385  int save_errno = errno;
2386 
2387  ereport(LOG,
2388  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2389  errmsg("out of file descriptors: %m; release and retry")));
2390  errno = 0;
2391  if (ReleaseLruFile())
2392  goto TryAgain;
2393  errno = save_errno;
2394  }
2395 
2396  return NULL;
2397 }
static PgChecksumMode mode
Definition: pg_checksums.c:61
static AllocateDesc * allocatedDescs
Definition: fd.c:255
#define DO_DB(A)
Definition: fd.c:171
int errcode(int sqlerrcode)
Definition: elog.c:704
static bool reserveAllocatedDesc(void)
Definition: fd.c:2279
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:243
static bool ReleaseLruFile(void)
Definition: fd.c:1272
#define ERROR
Definition: elog.h:45
static void ReleaseLruFiles(void)
Definition: fd.c:1294
FILE * file
Definition: fd.c:247
#define ereport(elevel,...)
Definition: elog.h:155
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:723
SubTransactionId create_subid
Definition: fd.c:244
const char * name
Definition: encode.c:515
int errmsg(const char *fmt,...)
Definition: elog.c:915
#define elog(elevel,...)
Definition: elog.h:228
union AllocateDesc::@23 desc
static int maxAllocatedDescs
Definition: fd.c:254
static int numAllocatedDescs
Definition: fd.c:253

◆ AllocateVfd()

static File AllocateVfd ( void  )
static

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

1305 {
1306  Index i;
1307  File file;
1308 
1309  DO_DB(elog(LOG, "AllocateVfd. Size %zu", SizeVfdCache));
1310 
1311  Assert(SizeVfdCache > 0); /* InitFileAccess not called? */
1312 
1313  if (VfdCache[0].nextFree == 0)
1314  {
1315  /*
1316  * The free list is empty so it is time to increase the size of the
1317  * array. We choose to double it each time this happens. However,
1318  * there's not much point in starting *real* small.
1319  */
1320  Size newCacheSize = SizeVfdCache * 2;
1321  Vfd *newVfdCache;
1322 
1323  if (newCacheSize < 32)
1324  newCacheSize = 32;
1325 
1326  /*
1327  * Be careful not to clobber VfdCache ptr if realloc fails.
1328  */
1329  newVfdCache = (Vfd *) realloc(VfdCache, sizeof(Vfd) * newCacheSize);
1330  if (newVfdCache == NULL)
1331  ereport(ERROR,
1332  (errcode(ERRCODE_OUT_OF_MEMORY),
1333  errmsg("out of memory")));
1334  VfdCache = newVfdCache;
1335 
1336  /*
1337  * Initialize the new entries and link them into the free list.
1338  */
1339  for (i = SizeVfdCache; i < newCacheSize; i++)
1340  {
1341  MemSet((char *) &(VfdCache[i]), 0, sizeof(Vfd));
1342  VfdCache[i].nextFree = i + 1;
1343  VfdCache[i].fd = VFD_CLOSED;
1344  }
1345  VfdCache[newCacheSize - 1].nextFree = 0;
1347 
1348  /*
1349  * Record the new size
1350  */
1351  SizeVfdCache = newCacheSize;
1352  }
1353 
1354  file = VfdCache[0].nextFree;
1355 
1356  VfdCache[0].nextFree = VfdCache[file].nextFree;
1357 
1358  return file;
1359 }
File nextFree
Definition: fd.c:192
static Size SizeVfdCache
Definition: fd.c:208
#define DO_DB(A)
Definition: fd.c:171
static Vfd * VfdCache
Definition: fd.c:207
int errcode(int sqlerrcode)
Definition: elog.c:704
#define MemSet(start, val, len)
Definition: c.h:996
#define LOG
Definition: elog.h:26
#define ERROR
Definition: elog.h:45
Definition: fd.c:187
int fd
Definition: fd.c:189
unsigned int Index
Definition: c.h:537
#define VFD_CLOSED
Definition: fd.c:175
#define ereport(elevel,...)
Definition: elog.h:155
#define Assert(condition)
Definition: c.h:792
size_t Size
Definition: c.h:528
#define realloc(a, b)
Definition: header.h:60
int errmsg(const char *fmt,...)
Definition: elog.c:915
#define elog(elevel,...)
Definition: elog.h:228
int i
int File
Definition: fd.h:48

◆ AtEOSubXact_Files()

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

Definition at line 2903 of file fd.c.

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

2905 {
2906  Index i;
2907 
2908  for (i = 0; i < numAllocatedDescs; i++)
2909  {
2910  if (allocatedDescs[i].create_subid == mySubid)
2911  {
2912  if (isCommit)
2913  allocatedDescs[i].create_subid = parentSubid;
2914  else
2915  {
2916  /* have to recheck the item after FreeDesc (ugly) */
2917  FreeDesc(&allocatedDescs[i--]);
2918  }
2919  }
2920  }
2921 }
static AllocateDesc * allocatedDescs
Definition: fd.c:255
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2514
unsigned int Index
Definition: c.h:537
SubTransactionId create_subid
Definition: fd.c:244
int i
static int numAllocatedDescs
Definition: fd.c:253

◆ AtEOXact_Files()

void AtEOXact_Files ( bool  isCommit)

Definition at line 2936 of file fd.c.

References CleanupTempFiles(), numTempTableSpaces, and tempTableSpaces.

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

2937 {
2938  CleanupTempFiles(isCommit, false);
2939  tempTableSpaces = NULL;
2940  numTempTableSpaces = -1;
2941 }
static int numTempTableSpaces
Definition: fd.c:275
static Oid * tempTableSpaces
Definition: fd.c:274
static void CleanupTempFiles(bool isCommit, bool isProcExit)
Definition: fd.c:2968

◆ AtProcExit_Files()

static void AtProcExit_Files ( int  code,
Datum  arg 
)
static

Definition at line 2950 of file fd.c.

References CleanupTempFiles().

Referenced by InitFileAccess().

2951 {
2952  CleanupTempFiles(false, true);
2953 }
static void CleanupTempFiles(bool isCommit, bool isProcExit)
Definition: fd.c:2968

◆ BasicOpenFile()

int BasicOpenFile ( const char *  fileName,
int  fileFlags 
)

Definition at line 1014 of file fd.c.

References BasicOpenFilePerm(), and pg_file_create_mode.

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

1015 {
1016  return BasicOpenFilePerm(fileName, fileFlags, pg_file_create_mode);
1017 }
int pg_file_create_mode
Definition: file_perm.c:19
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1036

◆ BasicOpenFilePerm()

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

Definition at line 1036 of file fd.c.

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

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

1037 {
1038  int fd;
1039 
1040 tryAgain:
1041  fd = open(fileName, fileFlags, fileMode);
1042 
1043  if (fd >= 0)
1044  return fd; /* success! */
1045 
1046  if (errno == EMFILE || errno == ENFILE)
1047  {
1048  int save_errno = errno;
1049 
1050  ereport(LOG,
1051  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
1052  errmsg("out of file descriptors: %m; release and retry")));
1053  errno = 0;
1054  if (ReleaseLruFile())
1055  goto tryAgain;
1056  errno = save_errno;
1057  }
1058 
1059  return -1; /* failure */
1060 }
int errcode(int sqlerrcode)
Definition: elog.c:704
#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:1272
#define ereport(elevel,...)
Definition: elog.h:155
int errmsg(const char *fmt,...)
Definition: elog.c:915

◆ CleanupTempFiles()

static void CleanupTempFiles ( bool  isCommit,
bool  isProcExit 
)
static

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

2969 {
2970  Index i;
2971 
2972  /*
2973  * Careful here: at proc_exit we need extra cleanup, not just
2974  * xact_temporary files.
2975  */
2976  if (isProcExit || have_xact_temporary_files)
2977  {
2978  Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
2979  for (i = 1; i < SizeVfdCache; i++)
2980  {
2981  unsigned short fdstate = VfdCache[i].fdstate;
2982 
2983  if (((fdstate & FD_DELETE_AT_CLOSE) || (fdstate & FD_CLOSE_AT_EOXACT)) &&
2984  VfdCache[i].fileName != NULL)
2985  {
2986  /*
2987  * If we're in the process of exiting a backend process, close
2988  * all temporary files. Otherwise, only close temporary files
2989  * local to the current transaction. They should be closed by
2990  * the ResourceOwner mechanism already, so this is just a
2991  * debugging cross-check.
2992  */
2993  if (isProcExit)
2994  FileClose(i);
2995  else if (fdstate & FD_CLOSE_AT_EOXACT)
2996  {
2997  elog(WARNING,
2998  "temporary file %s not closed at end-of-transaction",
2999  VfdCache[i].fileName);
3000  FileClose(i);
3001  }
3002  }
3003  }
3004 
3005  have_xact_temporary_files = false;
3006  }
3007 
3008  /* Complain if any allocated files remain open at commit. */
3009  if (isCommit && numAllocatedDescs > 0)
3010  elog(WARNING, "%d temporary files and directories not closed at end-of-transaction",
3012 
3013  /* Clean up "allocated" stdio files, dirs and fds. */
3014  while (numAllocatedDescs > 0)
3015  FreeDesc(&allocatedDescs[0]);
3016 }
static AllocateDesc * allocatedDescs
Definition: fd.c:255
static Size SizeVfdCache
Definition: fd.c:208
#define FD_DELETE_AT_CLOSE
Definition: fd.c:183
static Vfd * VfdCache
Definition: fd.c:207
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2514
static bool have_xact_temporary_files
Definition: fd.c:219
unsigned short fdstate
Definition: fd.c:190
#define WARNING
Definition: elog.h:40
#define FileIsNotOpen(file)
Definition: fd.c:180
unsigned int Index
Definition: c.h:537
void FileClose(File file)
Definition: fd.c:1854
#define Assert(condition)
Definition: c.h:792
#define elog(elevel,...)
Definition: elog.h:228
int i
#define FD_CLOSE_AT_EOXACT
Definition: fd.c:184
static int numAllocatedDescs
Definition: fd.c:253

◆ closeAllVfds()

void closeAllVfds ( void  )

Definition at line 2792 of file fd.c.

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

Referenced by standard_ProcessUtility().

2793 {
2794  Index i;
2795 
2796  if (SizeVfdCache > 0)
2797  {
2798  Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
2799  for (i = 1; i < SizeVfdCache; i++)
2800  {
2801  if (!FileIsNotOpen(i))
2802  LruDelete(i);
2803  }
2804  }
2805 }
static Size SizeVfdCache
Definition: fd.c:208
static void LruDelete(File file)
Definition: fd.c:1177
#define FileIsNotOpen(file)
Definition: fd.c:180
unsigned int Index
Definition: c.h:537
#define Assert(condition)
Definition: c.h:792
int i

◆ ClosePipeStream()

int ClosePipeStream ( FILE *  file)

Definition at line 2763 of file fd.c.

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

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

2764 {
2765  int i;
2766 
2767  DO_DB(elog(LOG, "ClosePipeStream: Allocated %d", numAllocatedDescs));
2768 
2769  /* Remove file from list of allocated files, if it's present */
2770  for (i = numAllocatedDescs; --i >= 0;)
2771  {
2772  AllocateDesc *desc = &allocatedDescs[i];
2773 
2774  if (desc->kind == AllocateDescPipe && desc->desc.file == file)
2775  return FreeDesc(desc);
2776  }
2777 
2778  /* Only get here if someone passes us a file not in allocatedDescs */
2779  elog(WARNING, "file passed to ClosePipeStream was not obtained from OpenPipeStream");
2780 
2781  return pclose(file);
2782 }
static AllocateDesc * allocatedDescs
Definition: fd.c:255
#define DO_DB(A)
Definition: fd.c:171
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:243
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2514
#define WARNING
Definition: elog.h:40
FILE * file
Definition: fd.c:247
#define elog(elevel,...)
Definition: elog.h:228
int i
union AllocateDesc::@23 desc
static int numAllocatedDescs
Definition: fd.c:253

◆ CloseTransientFile()

int CloseTransientFile ( int  fd)

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

2582 {
2583  int i;
2584 
2585  DO_DB(elog(LOG, "CloseTransientFile: Allocated %d", numAllocatedDescs));
2586 
2587  /* Remove fd from list of allocated files, if it's present */
2588  for (i = numAllocatedDescs; --i >= 0;)
2589  {
2590  AllocateDesc *desc = &allocatedDescs[i];
2591 
2592  if (desc->kind == AllocateDescRawFD && desc->desc.fd == fd)
2593  return FreeDesc(desc);
2594  }
2595 
2596  /* Only get here if someone passes us a file not in allocatedDescs */
2597  elog(WARNING, "fd passed to CloseTransientFile was not obtained from OpenTransientFile");
2598 
2599  return close(fd);
2600 }
static AllocateDesc * allocatedDescs
Definition: fd.c:255
#define DO_DB(A)
Definition: fd.c:171
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:243
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2514
#define WARNING
Definition: elog.h:40
int fd
Definition: fd.c:249
#define elog(elevel,...)
Definition: elog.h:228
int i
#define close(a)
Definition: win32.h:12
union AllocateDesc::@23 desc
static int numAllocatedDescs
Definition: fd.c:253

◆ count_usable_fds()

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

Definition at line 887 of file fd.c.

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

Referenced by set_max_safe_fds().

888 {
889  int *fd;
890  int size;
891  int used = 0;
892  int highestfd = 0;
893  int j;
894 
895 #ifdef HAVE_GETRLIMIT
896  struct rlimit rlim;
897  int getrlimit_status;
898 #endif
899 
900  size = 1024;
901  fd = (int *) palloc(size * sizeof(int));
902 
903 #ifdef HAVE_GETRLIMIT
904 #ifdef RLIMIT_NOFILE /* most platforms use RLIMIT_NOFILE */
905  getrlimit_status = getrlimit(RLIMIT_NOFILE, &rlim);
906 #else /* but BSD doesn't ... */
907  getrlimit_status = getrlimit(RLIMIT_OFILE, &rlim);
908 #endif /* RLIMIT_NOFILE */
909  if (getrlimit_status != 0)
910  ereport(WARNING, (errmsg("getrlimit failed: %m")));
911 #endif /* HAVE_GETRLIMIT */
912 
913  /* dup until failure or probe limit reached */
914  for (;;)
915  {
916  int thisfd;
917 
918 #ifdef HAVE_GETRLIMIT
919 
920  /*
921  * don't go beyond RLIMIT_NOFILE; causes irritating kernel logs on
922  * some platforms
923  */
924  if (getrlimit_status == 0 && highestfd >= rlim.rlim_cur - 1)
925  break;
926 #endif
927 
928  thisfd = dup(0);
929  if (thisfd < 0)
930  {
931  /* Expect EMFILE or ENFILE, else it's fishy */
932  if (errno != EMFILE && errno != ENFILE)
933  elog(WARNING, "dup(0) failed after %d successes: %m", used);
934  break;
935  }
936 
937  if (used >= size)
938  {
939  size *= 2;
940  fd = (int *) repalloc(fd, size * sizeof(int));
941  }
942  fd[used++] = thisfd;
943 
944  if (highestfd < thisfd)
945  highestfd = thisfd;
946 
947  if (used >= max_to_probe)
948  break;
949  }
950 
951  /* release the files we opened */
952  for (j = 0; j < used; j++)
953  close(fd[j]);
954 
955  pfree(fd);
956 
957  /*
958  * Return results. usable_fds is just the number of successful dups. We
959  * assume that the system limit is highestfd+1 (remember 0 is a legal FD
960  * number) and so already_open is highestfd+1 - usable_fds.
961  */
962  *usable_fds = used;
963  *already_open = highestfd + 1 - used;
964 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
void pfree(void *pointer)
Definition: mcxt.c:1057
#define WARNING
Definition: elog.h:40
#define ereport(elevel,...)
Definition: elog.h:155
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1070
void * palloc(Size size)
Definition: mcxt.c:950
int errmsg(const char *fmt,...)
Definition: elog.c:915
#define elog(elevel,...)
Definition: elog.h:228
#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 3461 of file fd.c.

References fsync_fname_ext().

Referenced by SyncDataDirectory().

3462 {
3463  /*
3464  * We want to silently ignoring errors about unreadable files. Pass that
3465  * desire on to fsync_fname_ext().
3466  */
3467  fsync_fname_ext(fname, isdir, true, elevel);
3468 }
static int elevel
Definition: vacuumlazy.c:333
int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3496

◆ Delete()

static void Delete ( File  file)
static

Definition at line 1158 of file fd.c.

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

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

1159 {
1160  Vfd *vfdP;
1161 
1162  Assert(file != 0);
1163 
1164  DO_DB(elog(LOG, "Delete %d (%s)",
1165  file, VfdCache[file].fileName));
1166  DO_DB(_dump_lru());
1167 
1168  vfdP = &VfdCache[file];
1169 
1172 
1173  DO_DB(_dump_lru());
1174 }
File lruLessRecently
Definition: fd.c:194
#define DO_DB(A)
Definition: fd.c:171
static Vfd * VfdCache
Definition: fd.c:207
#define LOG
Definition: elog.h:26
Definition: fd.c:187
#define Assert(condition)
Definition: c.h:792
File lruMoreRecently
Definition: fd.c:193
#define elog(elevel,...)
Definition: elog.h:228

◆ durable_rename()

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

Definition at line 687 of file fd.c.

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

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

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

◆ durable_rename_excl()

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

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

815 {
816  /*
817  * Ensure that, if we crash directly after the rename/link, a file with
818  * valid contents is moved into place.
819  */
820  if (fsync_fname_ext(oldfile, false, false, elevel) != 0)
821  return -1;
822 
823  if (link(oldfile, newfile) < 0)
824  {
825  ereport(elevel,
827  errmsg("could not link file \"%s\" to \"%s\": %m",
828  oldfile, newfile)));
829  return -1;
830  }
831  unlink(oldfile);
832 
833  /*
834  * Make change persistent in case of an OS crash, both the new entry and
835  * its parent directory need to be flushed.
836  */
837  if (fsync_fname_ext(newfile, false, false, elevel) != 0)
838  return -1;
839 
840  /* Same for parent directory */
841  if (fsync_parent_path(newfile, elevel) != 0)
842  return -1;
843 
844  return 0;
845 }
int errcode_for_file_access(void)
Definition: elog.c:727
static int elevel
Definition: vacuumlazy.c:333
#define ereport(elevel,...)
Definition: elog.h:155
int errmsg(const char *fmt,...)
Definition: elog.c:915
int link(const char *src, const char *dst)
int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3496
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3572

◆ durable_unlink()

int durable_unlink ( const char *  fname,
int  elevel 
)

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

778 {
779  if (unlink(fname) < 0)
780  {
781  ereport(elevel,
783  errmsg("could not remove file \"%s\": %m",
784  fname)));
785  return -1;
786  }
787 
788  /*
789  * To guarantee that the removal of the file is persistent, fsync its
790  * parent directory.
791  */
792  if (fsync_parent_path(fname, elevel) != 0)
793  return -1;
794 
795  return 0;
796 }
int errcode_for_file_access(void)
Definition: elog.c:727
static int elevel
Definition: vacuumlazy.c:333
#define ereport(elevel,...)
Definition: elog.h:155
int errmsg(const char *fmt,...)
Definition: elog.c:915
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3572

◆ FileAccess()

static int FileAccess ( File  file)
static

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

1383 {
1384  int returnValue;
1385 
1386  DO_DB(elog(LOG, "FileAccess %d (%s)",
1387  file, VfdCache[file].fileName));
1388 
1389  /*
1390  * Is the file open? If not, open it and put it at the head of the LRU
1391  * ring (possibly closing the least recently used file to get an FD).
1392  */
1393 
1394  if (FileIsNotOpen(file))
1395  {
1396  returnValue = LruInsert(file);
1397  if (returnValue != 0)
1398  return returnValue;
1399  }
1400  else if (VfdCache[0].lruLessRecently != file)
1401  {
1402  /*
1403  * We now know that the file is open and that it is not the last one
1404  * accessed, so we need to move it to the head of the Lru ring.
1405  */
1406 
1407  Delete(file);
1408  Insert(file);
1409  }
1410 
1411  return 0;
1412 }
#define DO_DB(A)
Definition: fd.c:171
static Vfd * VfdCache
Definition: fd.c:207
static void Delete(File file)
Definition: fd.c:1158
#define LOG
Definition: elog.h:26
static int LruInsert(File file)
Definition: fd.c:1225
static void Insert(File file)
Definition: fd.c:1203
#define FileIsNotOpen(file)
Definition: fd.c:180
#define elog(elevel,...)
Definition: elog.h:228

◆ FileClose()

void FileClose ( File  file)

Definition at line 1854 of file fd.c.

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

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

1855 {
1856  Vfd *vfdP;
1857 
1858  Assert(FileIsValid(file));
1859 
1860  DO_DB(elog(LOG, "FileClose: %d (%s)",
1861  file, VfdCache[file].fileName));
1862 
1863  vfdP = &VfdCache[file];
1864 
1865  if (!FileIsNotOpen(file))
1866  {
1867  /* close the file */
1868  if (close(vfdP->fd) != 0)
1869  {
1870  /*
1871  * We may need to panic on failure to close non-temporary files;
1872  * see LruDelete.
1873  */
1875  "could not close file \"%s\": %m", vfdP->fileName);
1876  }
1877 
1878  --nfile;
1879  vfdP->fd = VFD_CLOSED;
1880 
1881  /* remove the file from the lru ring */
1882  Delete(file);
1883  }
1884 
1885  if (vfdP->fdstate & FD_TEMP_FILE_LIMIT)
1886  {
1887  /* Subtract its size from current usage (do first in case of error) */
1888  temporary_files_size -= vfdP->fileSize;
1889  vfdP->fileSize = 0;
1890  }
1891 
1892  /*
1893  * Delete the file if it was temporary, and make a log entry if wanted
1894  */
1895  if (vfdP->fdstate & FD_DELETE_AT_CLOSE)
1896  {
1897  struct stat filestats;
1898  int stat_errno;
1899 
1900  /*
1901  * If we get an error, as could happen within the ereport/elog calls,
1902  * we'll come right back here during transaction abort. Reset the
1903  * flag to ensure that we can't get into an infinite loop. This code
1904  * is arranged to ensure that the worst-case consequence is failing to
1905  * emit log message(s), not failing to attempt the unlink.
1906  */
1907  vfdP->fdstate &= ~FD_DELETE_AT_CLOSE;
1908 
1909 
1910  /* first try the stat() */
1911  if (stat(vfdP->fileName, &filestats))
1912  stat_errno = errno;
1913  else
1914  stat_errno = 0;
1915 
1916  /* in any case do the unlink */
1917  if (unlink(vfdP->fileName))
1918  ereport(LOG,
1920  errmsg("could not delete file \"%s\": %m", vfdP->fileName)));
1921 
1922  /* and last report the stat results */
1923  if (stat_errno == 0)
1924  ReportTemporaryFileUsage(vfdP->fileName, filestats.st_size);
1925  else
1926  {
1927  errno = stat_errno;
1928  ereport(LOG,
1930  errmsg("could not stat file \"%s\": %m", vfdP->fileName)));
1931  }
1932  }
1933 
1934  /* Unregister it from the resource owner */
1935  if (vfdP->resowner)
1936  ResourceOwnerForgetFile(vfdP->resowner, file);
1937 
1938  /*
1939  * Return the Vfd slot to the free list
1940  */
1941  FreeVfd(file);
1942 }
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:185
#define DO_DB(A)
Definition: fd.c:171
#define FD_DELETE_AT_CLOSE
Definition: fd.c:183
static Vfd * VfdCache
Definition: fd.c:207
static void Delete(File file)
Definition: fd.c:1158
#define LOG
Definition: elog.h:26
char * fileName
Definition: fd.c:196
int errcode_for_file_access(void)
Definition: elog.c:727
static int nfile
Definition: fd.c:213
unsigned short fdstate
Definition: fd.c:190
Definition: fd.c:187
off_t fileSize
Definition: fd.c:195
int fd
Definition: fd.c:189
ResourceOwner resowner
Definition: fd.c:191
static void ReportTemporaryFileUsage(const char *path, off_t size)
Definition: fd.c:1418
#define FileIsNotOpen(file)
Definition: fd.c:180
int data_sync_elevel(int elevel)
Definition: fd.c:3635
#define FileIsValid(file)
Definition: fd.c:177
#define VFD_CLOSED
Definition: fd.c:175
static uint64 temporary_files_size
Definition: fd.c:227
#define ereport(elevel,...)
Definition: elog.h:155
#define Assert(condition)
Definition: c.h:792
int errmsg(const char *fmt,...)
Definition: elog.c:915
#define elog(elevel,...)
Definition: elog.h:228
static void FreeVfd(File file)
Definition: fd.c:1362
#define close(a)
Definition: win32.h:12
void ResourceOwnerForgetFile(ResourceOwner owner, File file)
Definition: resowner.c:1294
#define stat
Definition: win32_port.h:275

◆ FileGetRawDesc()

int FileGetRawDesc ( File  file)

Definition at line 2248 of file fd.c.

References Assert, vfd::fd, and FileIsValid.

2249 {
2250  Assert(FileIsValid(file));
2251  return VfdCache[file].fd;
2252 }
static Vfd * VfdCache
Definition: fd.c:207
int fd
Definition: fd.c:189
#define FileIsValid(file)
Definition: fd.c:177
#define Assert(condition)
Definition: c.h:792

◆ FileGetRawFlags()

int FileGetRawFlags ( File  file)

Definition at line 2258 of file fd.c.

References Assert, vfd::fileFlags, and FileIsValid.

2259 {
2260  Assert(FileIsValid(file));
2261  return VfdCache[file].fileFlags;
2262 }
static Vfd * VfdCache
Definition: fd.c:207
#define FileIsValid(file)
Definition: fd.c:177
#define Assert(condition)
Definition: c.h:792
int fileFlags
Definition: fd.c:198

◆ FileGetRawMode()

mode_t FileGetRawMode ( File  file)

Definition at line 2268 of file fd.c.

References Assert, FileIsValid, and vfd::fileMode.

2269 {
2270  Assert(FileIsValid(file));
2271  return VfdCache[file].fileMode;
2272 }
static Vfd * VfdCache
Definition: fd.c:207
mode_t fileMode
Definition: fd.c:199
#define FileIsValid(file)
Definition: fd.c:177
#define Assert(condition)
Definition: c.h:792

◆ FilePathName()

char* FilePathName ( File  file)

Definition at line 2232 of file fd.c.

References Assert, FileIsValid, and vfd::fileName.

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

2233 {
2234  Assert(FileIsValid(file));
2235 
2236  return VfdCache[file].fileName;
2237 }
static Vfd * VfdCache
Definition: fd.c:207
char * fileName
Definition: fd.c:196
#define FileIsValid(file)
Definition: fd.c:177
#define Assert(condition)
Definition: c.h:792

◆ FilePrefetch()

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

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

1955 {
1956 #if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
1957  int returnCode;
1958 
1959  Assert(FileIsValid(file));
1960 
1961  DO_DB(elog(LOG, "FilePrefetch: %d (%s) " INT64_FORMAT " %d",
1962  file, VfdCache[file].fileName,
1963  (int64) offset, amount));
1964 
1965  returnCode = FileAccess(file);
1966  if (returnCode < 0)
1967  return returnCode;
1968 
1969  pgstat_report_wait_start(wait_event_info);
1970  returnCode = posix_fadvise(VfdCache[file].fd, offset, amount,
1971  POSIX_FADV_WILLNEED);
1973 
1974  return returnCode;
1975 #else
1976  Assert(FileIsValid(file));
1977  return 0;
1978 #endif
1979 }
#define DO_DB(A)
Definition: fd.c:171
static Vfd * VfdCache
Definition: fd.c:207
#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:1512
#define FileIsValid(file)
Definition: fd.c:177
static int FileAccess(File file)
Definition: fd.c:1382
#define Assert(condition)
Definition: c.h:792
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1488
#define INT64_FORMAT
Definition: c.h:471
#define elog(elevel,...)
Definition: elog.h:228

◆ FileRead()

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

Definition at line 2005 of file fd.c.

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

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

2007 {
2008  int returnCode;
2009  Vfd *vfdP;
2010 
2011  Assert(FileIsValid(file));
2012 
2013  DO_DB(elog(LOG, "FileRead: %d (%s) " INT64_FORMAT " %d %p",
2014  file, VfdCache[file].fileName,
2015  (int64) offset,
2016  amount, buffer));
2017 
2018  returnCode = FileAccess(file);
2019  if (returnCode < 0)
2020  return returnCode;
2021 
2022  vfdP = &VfdCache[file];
2023 
2024 retry:
2025  pgstat_report_wait_start(wait_event_info);
2026  returnCode = pg_pread(vfdP->fd, buffer, amount, offset);
2028 
2029  if (returnCode < 0)
2030  {
2031  /*
2032  * Windows may run out of kernel buffers and return "Insufficient
2033  * system resources" error. Wait a bit and retry to solve it.
2034  *
2035  * It is rumored that EINTR is also possible on some Unix filesystems,
2036  * in which case immediate retry is indicated.
2037  */
2038 #ifdef WIN32
2039  DWORD error = GetLastError();
2040 
2041  switch (error)
2042  {
2043  case ERROR_NO_SYSTEM_RESOURCES:
2044  pg_usleep(1000L);
2045  errno = EINTR;
2046  break;
2047  default:
2048  _dosmaperr(error);
2049  break;
2050  }
2051 #endif
2052  /* OK to retry if interrupted */
2053  if (errno == EINTR)
2054  goto retry;
2055  }
2056 
2057  return returnCode;
2058 }
static void error(void)
Definition: sql-dyntest.c:147
#define DO_DB(A)
Definition: fd.c:171
void _dosmaperr(unsigned long)
Definition: win32error.c:171
static Vfd * VfdCache
Definition: fd.c:207
#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:1512
Definition: fd.c:187
int fd
Definition: fd.c:189
#define FileIsValid(file)
Definition: fd.c:177
static int FileAccess(File file)
Definition: fd.c:1382
#define Assert(condition)
Definition: c.h:792
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1488
#define INT64_FORMAT
Definition: c.h:471
#define elog(elevel,...)
Definition: elog.h:228
#define EINTR
Definition: win32_port.h:343

◆ FileSize()

off_t FileSize ( File  file)

Definition at line 2180 of file fd.c.

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

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

2181 {
2182  Assert(FileIsValid(file));
2183 
2184  DO_DB(elog(LOG, "FileSize %d (%s)",
2185  file, VfdCache[file].fileName));
2186 
2187  if (FileIsNotOpen(file))
2188  {
2189  if (FileAccess(file) < 0)
2190  return (off_t) -1;
2191  }
2192 
2193  return lseek(VfdCache[file].fd, 0, SEEK_END);
2194 }
#define DO_DB(A)
Definition: fd.c:171
static Vfd * VfdCache
Definition: fd.c:207
#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:180
#define FileIsValid(file)
Definition: fd.c:177
static int FileAccess(File file)
Definition: fd.c:1382
#define Assert(condition)
Definition: c.h:792
#define elog(elevel,...)
Definition: elog.h:228

◆ FileSync()

int FileSync ( File  file,
uint32  wait_event_info 
)

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

2160 {
2161  int returnCode;
2162 
2163  Assert(FileIsValid(file));
2164 
2165  DO_DB(elog(LOG, "FileSync: %d (%s)",
2166  file, VfdCache[file].fileName));
2167 
2168  returnCode = FileAccess(file);
2169  if (returnCode < 0)
2170  return returnCode;
2171 
2172  pgstat_report_wait_start(wait_event_info);
2173  returnCode = pg_fsync(VfdCache[file].fd);
2175 
2176  return returnCode;
2177 }
#define DO_DB(A)
Definition: fd.c:171
static Vfd * VfdCache
Definition: fd.c:207
#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:1512
#define FileIsValid(file)
Definition: fd.c:177
static int FileAccess(File file)
Definition: fd.c:1382
#define Assert(condition)
Definition: c.h:792
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1488
#define elog(elevel,...)
Definition: elog.h:228
int pg_fsync(int fd)
Definition: fd.c:347

◆ FileTruncate()

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

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

2198 {
2199  int returnCode;
2200 
2201  Assert(FileIsValid(file));
2202 
2203  DO_DB(elog(LOG, "FileTruncate %d (%s)",
2204  file, VfdCache[file].fileName));
2205 
2206  returnCode = FileAccess(file);
2207  if (returnCode < 0)
2208  return returnCode;
2209 
2210  pgstat_report_wait_start(wait_event_info);
2211  returnCode = ftruncate(VfdCache[file].fd, offset);
2213 
2214  if (returnCode == 0 && VfdCache[file].fileSize > offset)
2215  {
2216  /* adjust our state for truncation of a temp file */
2217  Assert(VfdCache[file].fdstate & FD_TEMP_FILE_LIMIT);
2218  temporary_files_size -= VfdCache[file].fileSize - offset;
2219  VfdCache[file].fileSize = offset;
2220  }
2221 
2222  return returnCode;
2223 }
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:185
#define DO_DB(A)
Definition: fd.c:171
static Vfd * VfdCache
Definition: fd.c:207
#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:1512
off_t fileSize
Definition: fd.c:195
#define FileIsValid(file)
Definition: fd.c:177
static uint64 temporary_files_size
Definition: fd.c:227
static int FileAccess(File file)
Definition: fd.c:1382
#define Assert(condition)
Definition: c.h:792
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1488
#define elog(elevel,...)
Definition: elog.h:228
#define ftruncate(a, b)
Definition: win32_port.h:65

◆ FileWrite()

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

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

2063 {
2064  int returnCode;
2065  Vfd *vfdP;
2066 
2067  Assert(FileIsValid(file));
2068 
2069  DO_DB(elog(LOG, "FileWrite: %d (%s) " INT64_FORMAT " %d %p",
2070  file, VfdCache[file].fileName,
2071  (int64) offset,
2072  amount, buffer));
2073 
2074  returnCode = FileAccess(file);
2075  if (returnCode < 0)
2076  return returnCode;
2077 
2078  vfdP = &VfdCache[file];
2079 
2080  /*
2081  * If enforcing temp_file_limit and it's a temp file, check to see if the
2082  * write would overrun temp_file_limit, and throw error if so. Note: it's
2083  * really a modularity violation to throw error here; we should set errno
2084  * and return -1. However, there's no way to report a suitable error
2085  * message if we do that. All current callers would just throw error
2086  * immediately anyway, so this is safe at present.
2087  */
2088  if (temp_file_limit >= 0 && (vfdP->fdstate & FD_TEMP_FILE_LIMIT))
2089  {
2090  off_t past_write = offset + amount;
2091 
2092  if (past_write > vfdP->fileSize)
2093  {
2094  uint64 newTotal = temporary_files_size;
2095 
2096  newTotal += past_write - vfdP->fileSize;
2097  if (newTotal > (uint64) temp_file_limit * (uint64) 1024)
2098  ereport(ERROR,
2099  (errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED),
2100  errmsg("temporary file size exceeds temp_file_limit (%dkB)",
2101  temp_file_limit)));
2102  }
2103  }
2104 
2105 retry:
2106  errno = 0;
2107  pgstat_report_wait_start(wait_event_info);
2108  returnCode = pg_pwrite(VfdCache[file].fd, buffer, amount, offset);
2110 
2111  /* if write didn't set errno, assume problem is no disk space */
2112  if (returnCode != amount && errno == 0)
2113  errno = ENOSPC;
2114 
2115  if (returnCode >= 0)
2116  {
2117  /*
2118  * Maintain fileSize and temporary_files_size if it's a temp file.
2119  */
2120  if (vfdP->fdstate & FD_TEMP_FILE_LIMIT)
2121  {
2122  off_t past_write = offset + amount;
2123 
2124  if (past_write > vfdP->fileSize)
2125  {
2126  temporary_files_size += past_write - vfdP->fileSize;
2127  vfdP->fileSize = past_write;
2128  }
2129  }
2130  }
2131  else
2132  {
2133  /*
2134  * See comments in FileRead()
2135  */
2136 #ifdef WIN32
2137  DWORD error = GetLastError();
2138 
2139  switch (error)
2140  {
2141  case ERROR_NO_SYSTEM_RESOURCES:
2142  pg_usleep(1000L);
2143  errno = EINTR;
2144  break;
2145  default:
2146  _dosmaperr(error);
2147  break;
2148  }
2149 #endif
2150  /* OK to retry if interrupted */
2151  if (errno == EINTR)
2152  goto retry;
2153  }
2154 
2155  return returnCode;
2156 }
static void error(void)
Definition: sql-dyntest.c:147
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:185
#define DO_DB(A)
Definition: fd.c:171
void _dosmaperr(unsigned long)
Definition: win32error.c:171
static Vfd * VfdCache
Definition: fd.c:207
int errcode(int sqlerrcode)
Definition: elog.c:704
#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:45
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1512
unsigned short fdstate
Definition: fd.c:190
Definition: fd.c:187
off_t fileSize
Definition: fd.c:195
#define FileIsValid(file)
Definition: fd.c:177
static uint64 temporary_files_size
Definition: fd.c:227
#define ereport(elevel,...)
Definition: elog.h:155
static int FileAccess(File file)
Definition: fd.c:1382
#define Assert(condition)
Definition: c.h:792
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1488
#define INT64_FORMAT
Definition: c.h:471
int errmsg(const char *fmt,...)
Definition: elog.c:915
#define elog(elevel,...)
Definition: elog.h:228
#define EINTR
Definition: win32_port.h:343
int temp_file_limit
Definition: guc.c:553

◆ FileWriteback()

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

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

1983 {
1984  int returnCode;
1985 
1986  Assert(FileIsValid(file));
1987 
1988  DO_DB(elog(LOG, "FileWriteback: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
1989  file, VfdCache[file].fileName,
1990  (int64) offset, (int64) nbytes));
1991 
1992  if (nbytes <= 0)
1993  return;
1994 
1995  returnCode = FileAccess(file);
1996  if (returnCode < 0)
1997  return;
1998 
1999  pgstat_report_wait_start(wait_event_info);
2000  pg_flush_data(VfdCache[file].fd, offset, nbytes);
2002 }
#define DO_DB(A)
Definition: fd.c:171
static Vfd * VfdCache
Definition: fd.c:207
#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:1512
void pg_flush_data(int fd, off_t offset, off_t nbytes)
Definition: fd.c:457
#define FileIsValid(file)
Definition: fd.c:177
static int FileAccess(File file)
Definition: fd.c:1382
#define Assert(condition)
Definition: c.h:792
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1488
#define INT64_FORMAT
Definition: c.h:471
#define elog(elevel,...)
Definition: elog.h:228

◆ FreeDesc()

static int FreeDesc ( AllocateDesc desc)
static

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

2515 {
2516  int result;
2517 
2518  /* Close the underlying object */
2519  switch (desc->kind)
2520  {
2521  case AllocateDescFile:
2522  result = fclose(desc->desc.file);
2523  break;
2524  case AllocateDescPipe:
2525  result = pclose(desc->desc.file);
2526  break;
2527  case AllocateDescDir:
2528  result = closedir(desc->desc.dir);
2529  break;
2530  case AllocateDescRawFD:
2531  result = close(desc->desc.fd);
2532  break;
2533  default:
2534  elog(ERROR, "AllocateDesc kind not recognized");
2535  result = 0; /* keep compiler quiet */
2536  break;
2537  }
2538 
2539  /* Compact storage in the allocatedDescs array */
2542 
2543  return result;
2544 }
static AllocateDesc * allocatedDescs
Definition: fd.c:255
DIR * dir
Definition: fd.c:248
int closedir(DIR *)
Definition: dirent.c:123
AllocateDescKind kind
Definition: fd.c:243
#define ERROR
Definition: elog.h:45
FILE * file
Definition: fd.c:247
int fd
Definition: fd.c:249
#define elog(elevel,...)
Definition: elog.h:228
#define close(a)
Definition: win32.h:12
union AllocateDesc::@23 desc
static int numAllocatedDescs
Definition: fd.c:253

◆ FreeDir()

int FreeDir ( DIR dir)

Definition at line 2733 of file fd.c.

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

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

2734 {
2735  int i;
2736 
2737  /* Nothing to do if AllocateDir failed */
2738  if (dir == NULL)
2739  return 0;
2740 
2741  DO_DB(elog(LOG, "FreeDir: Allocated %d", numAllocatedDescs));
2742 
2743  /* Remove dir from list of allocated dirs, if it's present */
2744  for (i = numAllocatedDescs; --i >= 0;)
2745  {
2746  AllocateDesc *desc = &allocatedDescs[i];
2747 
2748  if (desc->kind == AllocateDescDir && desc->desc.dir == dir)
2749  return FreeDesc(desc);
2750  }
2751 
2752  /* Only get here if someone passes us a dir not in allocatedDescs */
2753  elog(WARNING, "dir passed to FreeDir was not obtained from AllocateDir");
2754 
2755  return closedir(dir);
2756 }
static AllocateDesc * allocatedDescs
Definition: fd.c:255
DIR * dir
Definition: fd.c:248
#define DO_DB(A)
Definition: fd.c:171
int closedir(DIR *)
Definition: dirent.c:123
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:243
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2514
#define WARNING
Definition: elog.h:40
#define elog(elevel,...)
Definition: elog.h:228
int i
union AllocateDesc::@23 desc
static int numAllocatedDescs
Definition: fd.c:253

◆ FreeFile()

int FreeFile ( FILE *  file)

Definition at line 2553 of file fd.c.

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

Referenced by _ShowOption(), AlterSystemSetConfigFile(), apw_dump_now(), apw_load_buffers(), BackendRun(), checkControlFile(), do_pg_start_backup(), do_pg_stop_backup(), EndCopy(), EndCopyFrom(), entry_reset(), existsTimeLineHistory(), ExportSnapshot(), fill_hba_view(), gc_qtexts(), ImportSnapshot(), load_dh_file(), load_hba(), load_ident(), load_relcache_init_file(), parse_extension_control_file(), ParseTzFile(), pg_backup_start_time(), pg_current_logfile(), pg_file_write_internal(), pg_promote(), 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(), tokenize_inc_file(), tsearch_readline_end(), ValidatePgVersion(), write_relcache_init_file(), XLogArchiveForceDone(), and XLogArchiveNotify().

2554 {
2555  int i;
2556 
2557  DO_DB(elog(LOG, "FreeFile: Allocated %d", numAllocatedDescs));
2558 
2559  /* Remove file from list of allocated files, if it's present */
2560  for (i = numAllocatedDescs; --i >= 0;)
2561  {
2562  AllocateDesc *desc = &allocatedDescs[i];
2563 
2564  if (desc->kind == AllocateDescFile && desc->desc.file == file)
2565  return FreeDesc(desc);
2566  }
2567 
2568  /* Only get here if someone passes us a file not in allocatedDescs */
2569  elog(WARNING, "file passed to FreeFile was not obtained from AllocateFile");
2570 
2571  return fclose(file);
2572 }
static AllocateDesc * allocatedDescs
Definition: fd.c:255
#define DO_DB(A)
Definition: fd.c:171
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:243
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2514
#define WARNING
Definition: elog.h:40
FILE * file
Definition: fd.c:247
#define elog(elevel,...)
Definition: elog.h:228
int i
union AllocateDesc::@23 desc
static int numAllocatedDescs
Definition: fd.c:253

◆ FreeVfd()

static void FreeVfd ( File  file)
static

Definition at line 1362 of file fd.c.

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

Referenced by FileClose(), and PathNameOpenFilePerm().

1363 {
1364  Vfd *vfdP = &VfdCache[file];
1365 
1366  DO_DB(elog(LOG, "FreeVfd: %d (%s)",
1367  file, vfdP->fileName ? vfdP->fileName : ""));
1368 
1369  if (vfdP->fileName != NULL)
1370  {
1371  free(vfdP->fileName);
1372  vfdP->fileName = NULL;
1373  }
1374  vfdP->fdstate = 0x0;
1375 
1376  vfdP->nextFree = VfdCache[0].nextFree;
1377  VfdCache[0].nextFree = file;
1378 }
File nextFree
Definition: fd.c:192
#define DO_DB(A)
Definition: fd.c:171
static Vfd * VfdCache
Definition: fd.c:207
#define LOG
Definition: elog.h:26
char * fileName
Definition: fd.c:196
unsigned short fdstate
Definition: fd.c:190
Definition: fd.c:187
#define free(a)
Definition: header.h:65
#define elog(elevel,...)
Definition: elog.h:228

◆ fsync_fname()

void fsync_fname ( const char *  fname,
bool  isdir 
)

Definition at line 661 of file fd.c.

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

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

662 {
663  fsync_fname_ext(fname, isdir, false, data_sync_elevel(ERROR));
664 }
#define ERROR
Definition: elog.h:45
int data_sync_elevel(int elevel)
Definition: fd.c:3635
int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3496

◆ fsync_fname_ext()

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

Definition at line 3496 of file fd.c.

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

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

3497 {
3498  int fd;
3499  int flags;
3500  int returncode;
3501 
3502  /*
3503  * Some OSs require directories to be opened read-only whereas other
3504  * systems don't allow us to fsync files opened read-only; so we need both
3505  * cases here. Using O_RDWR will cause us to fail to fsync files that are
3506  * not writable by our userid, but we assume that's OK.
3507  */
3508  flags = PG_BINARY;
3509  if (!isdir)
3510  flags |= O_RDWR;
3511  else
3512  flags |= O_RDONLY;
3513 
3514  fd = OpenTransientFile(fname, flags);
3515 
3516  /*
3517  * Some OSs don't allow us to open directories at all (Windows returns
3518  * EACCES), just ignore the error in that case. If desired also silently
3519  * ignoring errors about unreadable files. Log others.
3520  */
3521  if (fd < 0 && isdir && (errno == EISDIR || errno == EACCES))
3522  return 0;
3523  else if (fd < 0 && ignore_perm && errno == EACCES)
3524  return 0;
3525  else if (fd < 0)
3526  {
3527  ereport(elevel,
3529  errmsg("could not open file \"%s\": %m", fname)));
3530  return -1;
3531  }
3532 
3533  returncode = pg_fsync(fd);
3534 
3535  /*
3536  * Some OSes don't allow us to fsync directories at all, so we can ignore
3537  * those errors. Anything else needs to be logged.
3538  */
3539  if (returncode != 0 && !(isdir && (errno == EBADF || errno == EINVAL)))
3540  {
3541  int save_errno;
3542 
3543  /* close file upon error, might not be in transaction context */
3544  save_errno = errno;
3545  (void) CloseTransientFile(fd);
3546  errno = save_errno;
3547 
3548  ereport(elevel,
3550  errmsg("could not fsync file \"%s\": %m", fname)));
3551  return -1;
3552  }
3553 
3554  if (CloseTransientFile(fd) != 0)
3555  {
3556  ereport(elevel,
3558  errmsg("could not close file \"%s\": %m", fname)));
3559  return -1;
3560  }
3561 
3562  return 0;
3563 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1259
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2404
int errcode_for_file_access(void)
Definition: elog.c:727
int CloseTransientFile(int fd)
Definition: fd.c:2581
static int elevel
Definition: vacuumlazy.c:333
#define ereport(elevel,...)
Definition: elog.h:155
int errmsg(const char *fmt,...)
Definition: elog.c:915
int pg_fsync(int fd)
Definition: fd.c:347

◆ fsync_parent_path()

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

Definition at line 3572 of file fd.c.

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

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

3573 {
3574  char parentpath[MAXPGPATH];
3575 
3576  strlcpy(parentpath, fname, MAXPGPATH);
3577  get_parent_directory(parentpath);
3578 
3579  /*
3580  * get_parent_directory() returns an empty string if the input argument is
3581  * just a file name (see comments in path.c), so handle that as being the
3582  * current directory.
3583  */
3584  if (strlen(parentpath) == 0)
3585  strlcpy(parentpath, ".", MAXPGPATH);
3586 
3587  if (fsync_fname_ext(parentpath, true, false, elevel) != 0)
3588  return -1;
3589 
3590  return 0;
3591 }
#define MAXPGPATH
void get_parent_directory(char *path)
Definition: path.c:854
static int elevel
Definition: vacuumlazy.c:333
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3496

◆ GetNextTempTableSpace()

Oid GetNextTempTableSpace ( void  )

Definition at line 2882 of file fd.c.

References InvalidOid, nextTempTableSpace, numTempTableSpaces, and tempTableSpaces.

Referenced by GetDefaultTablespace(), and OpenTemporaryFile().

2883 {
2884  if (numTempTableSpaces > 0)
2885  {
2886  /* Advance nextTempTableSpace counter with wraparound */
2888  nextTempTableSpace = 0;
2890  }
2891  return InvalidOid;
2892 }
static int numTempTableSpaces
Definition: fd.c:275
static int nextTempTableSpace
Definition: fd.c:276
#define InvalidOid
Definition: postgres_ext.h:36
static Oid * tempTableSpaces
Definition: fd.c:274

◆ GetTempTablespaces()

int GetTempTablespaces ( Oid tableSpaces,
int  numSpaces 
)

Definition at line 2864 of file fd.c.

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

Referenced by SharedFileSetInit().

2865 {
2866  int i;
2867 
2869  for (i = 0; i < numTempTableSpaces && i < numSpaces; ++i)
2870  tableSpaces[i] = tempTableSpaces[i];
2871 
2872  return i;
2873 }
static int numTempTableSpaces
Definition: fd.c:275
bool TempTablespacesAreSet(void)
Definition: fd.c:2849
#define Assert(condition)
Definition: c.h:792
static Oid * tempTableSpaces
Definition: fd.c:274
int i

◆ InitFileAccess()

void InitFileAccess ( void  )

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

855 {
856  Assert(SizeVfdCache == 0); /* call me only once */
857 
858  /* initialize cache header entry */
859  VfdCache = (Vfd *) malloc(sizeof(Vfd));
860  if (VfdCache == NULL)
861  ereport(FATAL,
862  (errcode(ERRCODE_OUT_OF_MEMORY),
863  errmsg("out of memory")));
864 
865  MemSet((char *) &(VfdCache[0]), 0, sizeof(Vfd));
867 
868  SizeVfdCache = 1;
869 
870  /* register proc-exit hook to ensure temp files are dropped at exit */
872 }
static void AtProcExit_Files(int code, Datum arg)
Definition: fd.c:2950
static Size SizeVfdCache
Definition: fd.c:208
void on_proc_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:305
static Vfd * VfdCache
Definition: fd.c:207
int errcode(int sqlerrcode)
Definition: elog.c:704
#define MemSet(start, val, len)
Definition: c.h:996
#define malloc(a)
Definition: header.h:50
#define FATAL
Definition: elog.h:54
Definition: fd.c:187
int fd
Definition: fd.c:189
#define VFD_CLOSED
Definition: fd.c:175
#define ereport(elevel,...)
Definition: elog.h:155
#define Assert(condition)
Definition: c.h:792
int errmsg(const char *fmt,...)
Definition: elog.c:915

◆ Insert()

static void Insert ( File  file)
static

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

1204 {
1205  Vfd *vfdP;
1206 
1207  Assert(file != 0);
1208 
1209  DO_DB(elog(LOG, "Insert %d (%s)",
1210  file, VfdCache[file].fileName));
1211  DO_DB(_dump_lru());
1212 
1213  vfdP = &VfdCache[file];
1214 
1215  vfdP->lruMoreRecently = 0;
1217  VfdCache[0].lruLessRecently = file;
1219 
1220  DO_DB(_dump_lru());
1221 }
File lruLessRecently
Definition: fd.c:194
#define DO_DB(A)
Definition: fd.c:171
static Vfd * VfdCache
Definition: fd.c:207
#define LOG
Definition: elog.h:26
Definition: fd.c:187
#define Assert(condition)
Definition: c.h:792
File lruMoreRecently
Definition: fd.c:193
#define elog(elevel,...)
Definition: elog.h:228

◆ looks_like_temp_rel_name()

bool looks_like_temp_rel_name ( const char *  name)

Definition at line 3219 of file fd.c.

References forkname_chars().

Referenced by RemovePgTempRelationFilesInDbspace(), and sendDir().

3220 {
3221  int pos;
3222  int savepos;
3223 
3224  /* Must start with "t". */
3225  if (name[0] != 't')
3226  return false;
3227 
3228  /* Followed by a non-empty string of digits and then an underscore. */
3229  for (pos = 1; isdigit((unsigned char) name[pos]); ++pos)
3230  ;
3231  if (pos == 1 || name[pos] != '_')
3232  return false;
3233 
3234  /* Followed by another nonempty string of digits. */
3235  for (savepos = ++pos; isdigit((unsigned char) name[pos]); ++pos)
3236  ;
3237  if (savepos == pos)
3238  return false;
3239 
3240  /* We might have _forkname or .segment or both. */
3241  if (name[pos] == '_')
3242  {
3243  int forkchar = forkname_chars(&name[pos + 1], NULL);
3244 
3245  if (forkchar <= 0)
3246  return false;
3247  pos += forkchar + 1;
3248  }
3249  if (name[pos] == '.')
3250  {
3251  int segchar;
3252 
3253  for (segchar = 1; isdigit((unsigned char) name[pos + segchar]); ++segchar)
3254  ;
3255  if (segchar <= 1)
3256  return false;
3257  pos += segchar;
3258  }
3259 
3260  /* Now we should be at the end. */
3261  if (name[pos] != '\0')
3262  return false;
3263  return true;
3264 }
int forkname_chars(const char *str, ForkNumber *fork)
Definition: relpath.c:81
const char * name
Definition: encode.c:515

◆ LruDelete()

static void LruDelete ( File  file)
static

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

1178 {
1179  Vfd *vfdP;
1180 
1181  Assert(file != 0);
1182 
1183  DO_DB(elog(LOG, "LruDelete %d (%s)",
1184  file, VfdCache[file].fileName));
1185 
1186  vfdP = &VfdCache[file];
1187 
1188  /*
1189  * Close the file. We aren't expecting this to fail; if it does, better
1190  * to leak the FD than to mess up our internal state.
1191  */
1192  if (close(vfdP->fd) != 0)
1194  "could not close file \"%s\": %m", vfdP->fileName);
1195  vfdP->fd = VFD_CLOSED;
1196  --nfile;
1197 
1198  /* delete the vfd record from the LRU ring */
1199  Delete(file);
1200 }
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:185
#define DO_DB(A)
Definition: fd.c:171
static Vfd * VfdCache
Definition: fd.c:207
static void Delete(File file)
Definition: fd.c:1158
#define LOG
Definition: elog.h:26
char * fileName
Definition: fd.c:196
static int nfile
Definition: fd.c:213
unsigned short fdstate
Definition: fd.c:190
Definition: fd.c:187
int fd
Definition: fd.c:189
int data_sync_elevel(int elevel)
Definition: fd.c:3635
#define VFD_CLOSED
Definition: fd.c:175
#define Assert(condition)
Definition: c.h:792
#define elog(elevel,...)
Definition: elog.h:228
#define close(a)
Definition: win32.h:12

◆ LruInsert()

static int LruInsert ( File  file)
static

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

1226 {
1227  Vfd *vfdP;
1228 
1229  Assert(file != 0);
1230 
1231  DO_DB(elog(LOG, "LruInsert %d (%s)",
1232  file, VfdCache[file].fileName));
1233 
1234  vfdP = &VfdCache[file];
1235 
1236  if (FileIsNotOpen(file))
1237  {
1238  /* Close excess kernel FDs. */
1239  ReleaseLruFiles();
1240 
1241  /*
1242  * The open could still fail for lack of file descriptors, eg due to
1243  * overall system file table being full. So, be prepared to release
1244  * another FD if necessary...
1245  */
1246  vfdP->fd = BasicOpenFilePerm(vfdP->fileName, vfdP->fileFlags,
1247  vfdP->fileMode);
1248  if (vfdP->fd < 0)
1249  {
1250  DO_DB(elog(LOG, "re-open failed: %m"));
1251  return -1;
1252  }
1253  else
1254  {
1255  ++nfile;
1256  }
1257  }
1258 
1259  /*
1260  * put it at the head of the Lru ring
1261  */
1262 
1263  Insert(file);
1264 
1265  return 0;
1266 }
#define DO_DB(A)
Definition: fd.c:171
static Vfd * VfdCache
Definition: fd.c:207
#define LOG
Definition: elog.h:26
mode_t fileMode
Definition: fd.c:199
char * fileName
Definition: fd.c:196
static int nfile
Definition: fd.c:213
Definition: fd.c:187
int fd
Definition: fd.c:189
static void Insert(File file)
Definition: fd.c:1203
static void ReleaseLruFiles(void)
Definition: fd.c:1294
#define FileIsNotOpen(file)
Definition: fd.c:180
#define Assert(condition)
Definition: c.h:792
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1036
#define elog(elevel,...)
Definition: elog.h:228
int fileFlags
Definition: fd.c:198

◆ MakePGDirectory()

int MakePGDirectory ( const char *  directoryName)

◆ OpenPipeStream()

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

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

2458 {
2459  FILE *file;
2460  int save_errno;
2461 
2462  DO_DB(elog(LOG, "OpenPipeStream: Allocated %d (%s)",
2463  numAllocatedDescs, command));
2464 
2465  /* Can we allocate another non-virtual FD? */
2466  if (!reserveAllocatedDesc())
2467  ereport(ERROR,
2468  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2469  errmsg("exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"",
2470  maxAllocatedDescs, command)));
2471 
2472  /* Close excess kernel FDs. */
2473  ReleaseLruFiles();
2474 
2475 TryAgain:
2476  fflush(stdout);
2477  fflush(stderr);
2479  errno = 0;
2480  file = popen(command, mode);
2481  save_errno = errno;
2483  errno = save_errno;
2484  if (file != NULL)
2485  {
2487 
2488  desc->kind = AllocateDescPipe;
2489  desc->desc.file = file;
2492  return desc->desc.file;
2493  }
2494 
2495  if (errno == EMFILE || errno == ENFILE)
2496  {
2497  ereport(LOG,
2498  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2499  errmsg("out of file descriptors: %m; release and retry")));
2500  if (ReleaseLruFile())
2501  goto TryAgain;
2502  errno = save_errno;
2503  }
2504 
2505  return NULL;
2506 }
static PgChecksumMode mode
Definition: pg_checksums.c:61
static AllocateDesc * allocatedDescs
Definition: fd.c:255
#define DO_DB(A)
Definition: fd.c:171
int errcode(int sqlerrcode)
Definition: elog.c:704
static bool reserveAllocatedDesc(void)
Definition: fd.c:2279
#define SIGPIPE
Definition: win32_port.h:164
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:243
static bool ReleaseLruFile(void)
Definition: fd.c:1272
#define ERROR
Definition: elog.h:45
#define SIG_IGN
Definition: win32_port.h:156
static void ReleaseLruFiles(void)
Definition: fd.c:1294
FILE * file
Definition: fd.c:247
#define ereport(elevel,...)
Definition: elog.h:155
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:170
#define SIG_DFL
Definition: win32_port.h:154
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:723
SubTransactionId create_subid
Definition: fd.c:244
int errmsg(const char *fmt,...)
Definition: elog.c:915
#define elog(elevel,...)
Definition: elog.h:228
union AllocateDesc::@23 desc
static int maxAllocatedDescs
Definition: fd.c:254
static int numAllocatedDescs
Definition: fd.c:253

◆ OpenTemporaryFile()

File OpenTemporaryFile ( bool  interXact)

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

1607 {
1608  File file = 0;
1609 
1610  /*
1611  * Make sure the current resource owner has space for this File before we
1612  * open it, if we'll be registering it below.
1613  */
1614  if (!interXact)
1616 
1617  /*
1618  * If some temp tablespace(s) have been given to us, try to use the next
1619  * one. If a given tablespace can't be found, we silently fall back to
1620  * the database's default tablespace.
1621  *
1622  * BUT: if the temp file is slated to outlive the current transaction,
1623  * force it into the database's default tablespace, so that it will not
1624  * pose a threat to possible tablespace drop attempts.
1625  */
1626  if (numTempTableSpaces > 0 && !interXact)
1627  {
1628  Oid tblspcOid = GetNextTempTableSpace();
1629 
1630  if (OidIsValid(tblspcOid))
1631  file = OpenTemporaryFileInTablespace(tblspcOid, false);
1632  }
1633 
1634  /*
1635  * If not, or if tablespace is bad, create in database's default
1636  * tablespace. MyDatabaseTableSpace should normally be set before we get
1637  * here, but just in case it isn't, fall back to pg_default tablespace.
1638  */
1639  if (file <= 0)
1642  DEFAULTTABLESPACE_OID,
1643  true);
1644 
1645  /* Mark it for deletion at close and temporary file size limit */
1647 
1648  /* Register it with the current resource owner */
1649  if (!interXact)
1650  RegisterTemporaryFile(file);
1651 
1652  return file;
1653 }
static File OpenTemporaryFileInTablespace(Oid tblspcOid, bool rejectError)
Definition: fd.c:1684
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:185
ResourceOwner CurrentResourceOwner
Definition: resowner.c:144
#define FD_DELETE_AT_CLOSE
Definition: fd.c:183
static Vfd * VfdCache
Definition: fd.c:207
static int numTempTableSpaces
Definition: fd.c:275
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:698
Oid MyDatabaseTableSpace
Definition: globals.c:88
Oid GetNextTempTableSpace(void)
Definition: fd.c:2882
unsigned short fdstate
Definition: fd.c:190
static void RegisterTemporaryFile(File file)
Definition: fd.c:1437
void ResourceOwnerEnlargeFiles(ResourceOwner owner)
Definition: resowner.c:1274
int File
Definition: fd.h:48

◆ OpenTemporaryFileInTablespace()

static File OpenTemporaryFileInTablespace ( Oid  tblspcOid,
bool  rejectError 
)
static

Definition at line 1684 of file fd.c.

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

Referenced by OpenTemporaryFile().

1685 {
1686  char tempdirpath[MAXPGPATH];
1687  char tempfilepath[MAXPGPATH];
1688  File file;
1689 
1690  TempTablespacePath(tempdirpath, tblspcOid);
1691 
1692  /*
1693  * Generate a tempfile name that should be unique within the current
1694  * database instance.
1695  */
1696  snprintf(tempfilepath, sizeof(tempfilepath), "%s/%s%d.%ld",
1697  tempdirpath, PG_TEMP_FILE_PREFIX, MyProcPid, tempFileCounter++);
1698 
1699  /*
1700  * Open the file. Note: we don't use O_EXCL, in case there is an orphaned
1701  * temp file that can be reused.
1702  */
1703  file = PathNameOpenFile(tempfilepath,
1704  O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1705  if (file <= 0)
1706  {
1707  /*
1708  * We might need to create the tablespace's tempfile directory, if no
1709  * one has yet done so.
1710  *
1711  * Don't check for an error from MakePGDirectory; it could fail if
1712  * someone else just did the same thing. If it doesn't work then
1713  * we'll bomb out on the second create attempt, instead.
1714  */
1715  (void) MakePGDirectory(tempdirpath);
1716 
1717  file = PathNameOpenFile(tempfilepath,
1718  O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1719  if (file <= 0 && rejectError)
1720  elog(ERROR, "could not create temporary file \"%s\": %m",
1721  tempfilepath);
1722  }
1723 
1724  return file;
1725 }
int MyProcPid
Definition: globals.c:41
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1465
void TempTablespacePath(char *path, Oid tablespace)
Definition: fd.c:1659
#define PG_BINARY
Definition: c.h:1259
#define ERROR
Definition: elog.h:45
#define PG_TEMP_FILE_PREFIX
Definition: pg_checksums.c:59
#define MAXPGPATH
int MakePGDirectory(const char *directoryName)
Definition: fd.c:3612
static long tempFileCounter
Definition: fd.c:266
#define elog(elevel,...)
Definition: elog.h:228
#define snprintf
Definition: port.h:215
int File
Definition: fd.h:48

◆ OpenTransientFile()

◆ OpenTransientFilePerm()

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

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

2414 {
2415  int fd;
2416 
2417  DO_DB(elog(LOG, "OpenTransientFile: Allocated %d (%s)",
2418  numAllocatedDescs, fileName));
2419 
2420  /* Can we allocate another non-virtual FD? */
2421  if (!reserveAllocatedDesc())
2422  ereport(ERROR,
2423  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2424  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2425  maxAllocatedDescs, fileName)));
2426 
2427  /* Close excess kernel FDs. */
2428  ReleaseLruFiles();
2429 
2430  fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
2431 
2432  if (fd >= 0)
2433  {
2435 
2436  desc->kind = AllocateDescRawFD;
2437  desc->desc.fd = fd;
2440 
2441  return fd;
2442  }
2443 
2444  return -1; /* failure */
2445 }
static AllocateDesc * allocatedDescs
Definition: fd.c:255
#define DO_DB(A)
Definition: fd.c:171
int errcode(int sqlerrcode)
Definition: elog.c:704
static bool reserveAllocatedDesc(void)
Definition: fd.c:2279
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:243
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define ERROR
Definition: elog.h:45
static void ReleaseLruFiles(void)
Definition: fd.c:1294
#define ereport(elevel,...)
Definition: elog.h:155
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:723
SubTransactionId create_subid
Definition: fd.c:244
int fd
Definition: fd.c:249
int errmsg(const char *fmt,...)
Definition: elog.c:915
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1036
#define elog(elevel,...)
Definition: elog.h:228
union AllocateDesc::@23 desc
static int maxAllocatedDescs
Definition: fd.c:254
static int numAllocatedDescs
Definition: fd.c:253

◆ PathNameCreateTemporaryDir()

void PathNameCreateTemporaryDir ( const char *  basedir,
const char *  directory 
)

Definition at line 1542 of file fd.c.

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

Referenced by SharedFileSetCreate().

1543 {
1544  if (MakePGDirectory(directory) < 0)
1545  {
1546  if (errno == EEXIST)
1547  return;
1548 
1549  /*
1550  * Failed. Try to create basedir first in case it's missing. Tolerate
1551  * EEXIST to close a race against another process following the same
1552  * algorithm.
1553  */
1554  if (MakePGDirectory(basedir) < 0 && errno != EEXIST)
1555  ereport(ERROR,
1557  errmsg("cannot create temporary directory \"%s\": %m",
1558  basedir)));
1559 
1560  /* Try again. */
1561  if (MakePGDirectory(directory) < 0 && errno != EEXIST)
1562  ereport(ERROR,
1564  errmsg("cannot create temporary subdirectory \"%s\": %m",
1565  directory)));
1566  }
1567 }
static char * basedir
#define ERROR
Definition: elog.h:45
int errcode_for_file_access(void)
Definition: elog.c:727
#define ereport(elevel,...)
Definition: elog.h:155
int MakePGDirectory(const char *directoryName)
Definition: fd.c:3612
static const char * directory
Definition: zic.c:632
int errmsg(const char *fmt,...)
Definition: elog.c:915

◆ PathNameCreateTemporaryFile()

File PathNameCreateTemporaryFile ( const char *  path,
bool  error_on_failure 
)

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

1742 {
1743  File file;
1744 
1746 
1747  /*
1748  * Open the file. Note: we don't use O_EXCL, in case there is an orphaned
1749  * temp file that can be reused.
1750  */
1751  file = PathNameOpenFile(path, O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1752  if (file <= 0)
1753  {
1754  if (error_on_failure)
1755  ereport(ERROR,
1757  errmsg("could not create temporary file \"%s\": %m",
1758  path)));
1759  else
1760  return file;
1761  }
1762 
1763  /* Mark it for temp_file_limit accounting. */
1765 
1766  /* Register it for automatic close. */
1767  RegisterTemporaryFile(file);
1768 
1769  return file;
1770 }
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1465
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:185
ResourceOwner CurrentResourceOwner
Definition: resowner.c:144
static Vfd * VfdCache
Definition: fd.c:207
#define PG_BINARY
Definition: c.h:1259
#define ERROR
Definition: elog.h:45
int errcode_for_file_access(void)
Definition: elog.c:727
unsigned short fdstate
Definition: fd.c:190
#define ereport(elevel,...)
Definition: elog.h:155
static void RegisterTemporaryFile(File file)
Definition: fd.c:1437
int errmsg(const char *fmt,...)
Definition: elog.c:915
void ResourceOwnerEnlargeFiles(ResourceOwner owner)
Definition: resowner.c:1274
int File
Definition: fd.h:48

◆ PathNameDeleteTemporaryDir()

void PathNameDeleteTemporaryDir ( const char *  dirname)

Definition at line 1573 of file fd.c.

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

Referenced by SharedFileSetDeleteAll().

1574 {
1575  struct stat statbuf;
1576 
1577  /* Silently ignore missing directory. */
1578  if (stat(dirname, &statbuf) != 0 && errno == ENOENT)
1579  return;
1580 
1581  /*
1582  * Currently, walkdir doesn't offer a way for our passed in function to
1583  * maintain state. Perhaps it should, so that we could tell the caller
1584  * whether this operation succeeded or failed. Since this operation is
1585  * used in a cleanup path, we wouldn't actually behave differently: we'll
1586  * just log failures.
1587  */
1588  walkdir(dirname, unlink_if_exists_fname, false, LOG);
1589 }
static void walkdir(const char *path, void(*action)(const char *fname, bool isdir, int elevel), bool process_symlinks, int elevel)
Definition: fd.c:3363
#define LOG
Definition: elog.h:26
static void unlink_if_exists_fname(const char *fname, bool isdir, int elevel)
Definition: fd.c:3471
#define stat
Definition: win32_port.h:275

◆ PathNameDeleteTemporaryFile()

bool PathNameDeleteTemporaryFile ( const char *  path,
bool  error_on_failure 
)

Definition at line 1808 of file fd.c.

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

Referenced by SharedFileSetDelete(), and unlink_if_exists_fname().

1809 {
1810  struct stat filestats;
1811  int stat_errno;
1812 
1813  /* Get the final size for pgstat reporting. */
1814  if (stat(path, &filestats) != 0)
1815  stat_errno = errno;
1816  else
1817  stat_errno = 0;
1818 
1819  /*
1820  * Unlike FileClose's automatic file deletion code, we tolerate
1821  * non-existence to support BufFileDeleteShared which doesn't know how
1822  * many segments it has to delete until it runs out.
1823  */
1824  if (stat_errno == ENOENT)
1825  return false;
1826 
1827  if (unlink(path) < 0)
1828  {
1829  if (errno != ENOENT)
1830  ereport(error_on_failure ? ERROR : LOG,
1832  errmsg("could not unlink temporary file \"%s\": %m",
1833  path)));
1834  return false;
1835  }
1836 
1837  if (stat_errno == 0)
1838  ReportTemporaryFileUsage(path, filestats.st_size);
1839  else
1840  {
1841  errno = stat_errno;
1842  ereport(LOG,
1844  errmsg("could not stat file \"%s\": %m", path)));
1845  }
1846 
1847  return true;
1848 }
#define LOG
Definition: elog.h:26
#define ERROR
Definition: elog.h:45
int errcode_for_file_access(void)
Definition: elog.c:727
static void ReportTemporaryFileUsage(const char *path, off_t size)
Definition: fd.c:1418
#define ereport(elevel,...)
Definition: elog.h:155
int errmsg(const char *fmt,...)
Definition: elog.c:915
#define stat
Definition: win32_port.h:275

◆ PathNameOpenFile()

File PathNameOpenFile ( const char *  fileName,
int  fileFlags 
)

Definition at line 1465 of file fd.c.

References PathNameOpenFilePerm(), and pg_file_create_mode.

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

1466 {
1467  return PathNameOpenFilePerm(fileName, fileFlags, pg_file_create_mode);
1468 }
File PathNameOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1478
int pg_file_create_mode
Definition: file_perm.c:19

◆ PathNameOpenFilePerm()

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

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

1479 {
1480  char *fnamecopy;
1481  File file;
1482  Vfd *vfdP;
1483 
1484  DO_DB(elog(LOG, "PathNameOpenFilePerm: %s %x %o",
1485  fileName, fileFlags, fileMode));
1486 
1487  /*
1488  * We need a malloc'd copy of the file name; fail cleanly if no room.
1489  */
1490  fnamecopy = strdup(fileName);
1491  if (fnamecopy == NULL)
1492  ereport(ERROR,
1493  (errcode(ERRCODE_OUT_OF_MEMORY),
1494  errmsg("out of memory")));
1495 
1496  file = AllocateVfd();
1497  vfdP = &VfdCache[file];
1498 
1499  /* Close excess kernel FDs. */
1500  ReleaseLruFiles();
1501 
1502  vfdP->fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
1503 
1504  if (vfdP->fd < 0)
1505  {
1506  int save_errno = errno;
1507 
1508  FreeVfd(file);
1509  free(fnamecopy);
1510  errno = save_errno;
1511  return -1;
1512  }
1513  ++nfile;
1514  DO_DB(elog(LOG, "PathNameOpenFile: success %d",
1515  vfdP->fd));
1516 
1517  vfdP->fileName = fnamecopy;
1518  /* Saved flags are adjusted to be OK for re-opening file */
1519  vfdP->fileFlags = fileFlags & ~(O_CREAT | O_TRUNC | O_EXCL);
1520  vfdP->fileMode = fileMode;
1521  vfdP->fileSize = 0;
1522  vfdP->fdstate = 0x0;
1523  vfdP->resowner = NULL;
1524 
1525  Insert(file);
1526 
1527  return file;
1528 }
#define DO_DB(A)
Definition: fd.c:171
static Vfd * VfdCache
Definition: fd.c:207
int errcode(int sqlerrcode)
Definition: elog.c:704
#define LOG
Definition: elog.h:26
mode_t fileMode
Definition: fd.c:199
#define ERROR
Definition: elog.h:45
char * fileName
Definition: fd.c:196
static int nfile
Definition: fd.c:213
static File AllocateVfd(void)
Definition: fd.c:1304
unsigned short fdstate
Definition: fd.c:190
Definition: fd.c:187
off_t fileSize
Definition: fd.c:195
int fd
Definition: fd.c:189
static void Insert(File file)
Definition: fd.c:1203
ResourceOwner resowner
Definition: fd.c:191
static void ReleaseLruFiles(void)
Definition: fd.c:1294
#define ereport(elevel,...)
Definition: elog.h:155
#define free(a)
Definition: header.h:65
int errmsg(const char *fmt,...)
Definition: elog.c:915
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1036
#define elog(elevel,...)
Definition: elog.h:228
static void FreeVfd(File file)
Definition: fd.c:1362
int fileFlags
Definition: fd.c:198
int File
Definition: fd.h:48

◆ PathNameOpenTemporaryFile()

File PathNameOpenTemporaryFile ( const char *  path,
int  mode 
)

Definition at line 1779 of file fd.c.

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

Referenced by SharedFileSetOpen().

1780 {
1781  File file;
1782 
1784 
1785  file = PathNameOpenFile(path, mode | PG_BINARY);
1786 
1787  /* If no such file, then we don't raise an error. */
1788  if (file <= 0 && errno != ENOENT)
1789  ereport(ERROR,
1791  errmsg("could not open temporary file \"%s\": %m",
1792  path)));
1793 
1794  if (file > 0)
1795  {
1796  /* Register it for automatic close. */
1797  RegisterTemporaryFile(file);
1798  }
1799 
1800  return file;
1801 }
static PgChecksumMode mode
Definition: pg_checksums.c:61
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1465
ResourceOwner CurrentResourceOwner
Definition: resowner.c:144
#define PG_BINARY
Definition: c.h:1259
#define ERROR
Definition: elog.h:45
int errcode_for_file_access(void)
Definition: elog.c:727
#define ereport(elevel,...)
Definition: elog.h:155
static void RegisterTemporaryFile(File file)
Definition: fd.c:1437
int errmsg(const char *fmt,...)
Definition: elog.c:915
void ResourceOwnerEnlargeFiles(ResourceOwner owner)
Definition: resowner.c:1274
int File
Definition: fd.h:48

◆ pg_fdatasync()

int pg_fdatasync ( int  fd)

Definition at line 437 of file fd.c.

References enableFsync, and fsync.

Referenced by issue_xlog_fsync().

438 {
439  if (enableFsync)
440  {
441 #ifdef HAVE_FDATASYNC
442  return fdatasync(fd);
443 #else
444  return fsync(fd);
445 #endif
446  }
447  else
448  return 0;
449 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define fsync(fd)
Definition: win32_port.h:68
bool enableFsync
Definition: globals.c:120

◆ pg_flush_data()

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

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

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

◆ pg_fsync()

int pg_fsync ( int  fd)

Definition at line 347 of file fd.c.

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

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

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

◆ pg_fsync_no_writethrough()

int pg_fsync_no_writethrough ( int  fd)

Definition at line 402 of file fd.c.

References enableFsync, and fsync.

Referenced by issue_xlog_fsync(), and pg_fsync().

403 {
404  if (enableFsync)
405  return fsync(fd);
406  else
407  return 0;
408 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define fsync(fd)
Definition: win32_port.h:68
bool enableFsync
Definition: globals.c:120

◆ pg_fsync_writethrough()

int pg_fsync_writethrough ( int  fd)

Definition at line 414 of file fd.c.

References enableFsync.

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

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

◆ pg_pwritev_with_retry()

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

Definition at line 3645 of file fd.c.

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

Referenced by XLogFileInit().

3646 {
3647  struct iovec iov_copy[PG_IOV_MAX];
3648  ssize_t sum = 0;
3649  ssize_t part;
3650 
3651  /* We'd better have space to make a copy, in case we need to retry. */
3652  if (iovcnt > PG_IOV_MAX)
3653  {
3654  errno = EINVAL;
3655  return -1;
3656  }
3657 
3658  for (;;)
3659  {
3660  /* Write as much as we can. */
3661  part = pg_pwritev(fd, iov, iovcnt, offset);
3662  if (part < 0)
3663  return -1;
3664 
3665 #ifdef SIMULATE_SHORT_WRITE
3666  part = Min(part, 4096);
3667 #endif
3668 
3669  /* Count our progress. */
3670  sum += part;
3671  offset += part;
3672 
3673  /* Step over iovecs that are done. */
3674  while (iovcnt > 0 && iov->iov_len <= part)
3675  {
3676  part -= iov->iov_len;
3677  ++iov;
3678  --iovcnt;
3679  }
3680 
3681  /* Are they all done? */
3682  if (iovcnt == 0)
3683  {
3684  /* We don't expect the kernel to write more than requested. */
3685  Assert(part == 0);
3686  break;
3687  }
3688 
3689  /*
3690  * Move whatever's left to the front of our mutable copy and adjust
3691  * the leading iovec.
3692  */
3693  Assert(iovcnt > 0);
3694  memmove(iov_copy, iov, sizeof(*iov) * iovcnt);
3695  Assert(iov->iov_len > part);
3696  iov_copy[0].iov_base = (char *) iov_copy[0].iov_base + part;
3697  iov_copy[0].iov_len -= part;
3698  iov = iov_copy;
3699  }
3700 
3701  return sum;
3702 }
size_t iov_len
Definition: pg_iovec.h:27
void * iov_base
Definition: pg_iovec.h:26
#define Min(x, y)
Definition: c.h:974
static int fd(const char *x, int i)
Definition: preproc-init.c:105
ssize_t pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
Definition: pwritev.c:29
#define PG_IOV_MAX
Definition: pg_iovec.h:40
Definition: pg_iovec.h:24
#define Assert(condition)
Definition: c.h:792

◆ pg_truncate()

int pg_truncate ( const char *  path,
off_t  length 
)

Definition at line 630 of file fd.c.

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

Referenced by do_truncate().

631 {
632 #ifdef WIN32
633  int save_errno;
634  int ret;
635  int fd;
636 
637  fd = OpenTransientFile(path, O_RDWR | PG_BINARY);
638  if (fd >= 0)
639  {
640  ret = ftruncate(fd, 0);
641  save_errno = errno;
642  CloseTransientFile(fd);
643  errno = save_errno;
644  }
645  else
646  ret = -1;
647 
648  return ret;
649 #else
650  return truncate(path, length);
651 #endif
652 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1259
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2404
int CloseTransientFile(int fd)
Definition: fd.c:2581
#define ftruncate(a, b)
Definition: win32_port.h:65

◆ ReadDir()

◆ ReadDirExtended()

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

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

2697 {
2698  struct dirent *dent;
2699 
2700  /* Give a generic message for AllocateDir failure, if caller didn't */
2701  if (dir == NULL)
2702  {
2703  ereport(elevel,
2705  errmsg("could not open directory \"%s\": %m",
2706  dirname)));
2707  return NULL;
2708  }
2709 
2710  errno = 0;
2711  if ((dent = readdir(dir)) != NULL)
2712  return dent;
2713 
2714  if (errno)
2715  ereport(elevel,
2717  errmsg("could not read directory \"%s\": %m",
2718  dirname)));
2719  return NULL;
2720 }
Definition: dirent.h:9
int errcode_for_file_access(void)
Definition: elog.c:727
static int elevel
Definition: vacuumlazy.c:333
#define ereport(elevel,...)
Definition: elog.h:155
struct dirent * readdir(DIR *)
Definition: dirent.c:78
int errmsg(const char *fmt,...)
Definition: elog.c:915

◆ RegisterTemporaryFile()

static void RegisterTemporaryFile ( File  file)
static

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

1438 {
1441 
1442  /* Backup mechanism for closing at end of xact. */
1445 }
ResourceOwner CurrentResourceOwner
Definition: resowner.c:144
static Vfd * VfdCache
Definition: fd.c:207
static bool have_xact_temporary_files
Definition: fd.c:219
void ResourceOwnerRememberFile(ResourceOwner owner, File file)
Definition: resowner.c:1285
unsigned short fdstate
Definition: fd.c:190
ResourceOwner resowner
Definition: fd.c:191
#define FD_CLOSE_AT_EOXACT
Definition: fd.c:184

◆ ReleaseExternalFD()

◆ ReleaseLruFile()

static bool ReleaseLruFile ( void  )
static

Definition at line 1272 of file fd.c.

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

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

1273 {
1274  DO_DB(elog(LOG, "ReleaseLruFile. Opened %d", nfile));
1275 
1276  if (nfile > 0)
1277  {
1278  /*
1279  * There are opened files and so there should be at least one used vfd
1280  * in the ring.
1281  */
1282  Assert(VfdCache[0].lruMoreRecently != 0);
1283  LruDelete(VfdCache[0].lruMoreRecently);
1284  return true; /* freed a file */
1285  }
1286  return false; /* no files available to free */
1287 }
#define DO_DB(A)
Definition: fd.c:171
static Vfd * VfdCache
Definition: fd.c:207
#define LOG
Definition: elog.h:26
static void LruDelete(File file)
Definition: fd.c:1177
static int nfile
Definition: fd.c:213
#define Assert(condition)
Definition: c.h:792
#define elog(elevel,...)
Definition: elog.h:228

◆ ReleaseLruFiles()

static void ReleaseLruFiles ( void  )
static

Definition at line 1294 of file fd.c.

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

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

1295 {
1297  {
1298  if (!ReleaseLruFile())
1299  break;
1300  }
1301 }
static int numExternalFDs
Definition: fd.c:260
int max_safe_fds
Definition: fd.c:156
static bool ReleaseLruFile(void)
Definition: fd.c:1272
static int nfile
Definition: fd.c:213
static int numAllocatedDescs
Definition: fd.c:253

◆ RemovePgTempFiles()

void RemovePgTempFiles ( void  )

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

3039 {
3040  char temp_path[MAXPGPATH + 10 + sizeof(TABLESPACE_VERSION_DIRECTORY) + sizeof(PG_TEMP_FILES_DIR)];
3041  DIR *spc_dir;
3042  struct dirent *spc_de;
3043 
3044  /*
3045  * First process temp files in pg_default ($PGDATA/base)
3046  */
3047  snprintf(temp_path, sizeof(temp_path), "base/%s", PG_TEMP_FILES_DIR);
3048  RemovePgTempFilesInDir(temp_path, true, false);
3049  RemovePgTempRelationFiles("base");
3050 
3051  /*
3052  * Cycle through temp directories for all non-default tablespaces.
3053  */
3054  spc_dir = AllocateDir("pg_tblspc");
3055 
3056  while ((spc_de = ReadDirExtended(spc_dir, "pg_tblspc", LOG)) != NULL)
3057  {
3058  if (strcmp(spc_de->d_name, ".") == 0 ||
3059  strcmp(spc_de->d_name, "..") == 0)
3060  continue;
3061 
3062  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s/%s",
3064  RemovePgTempFilesInDir(temp_path, true, false);
3065 
3066  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s",
3068  RemovePgTempRelationFiles(temp_path);
3069  }
3070 
3071  FreeDir(spc_dir);
3072 
3073  /*
3074  * In EXEC_BACKEND case there is a pgsql_tmp directory at the top level of
3075  * DataDir as well. However, that is *not* cleaned here because doing so
3076  * would create a race condition. It's done separately, earlier in
3077  * postmaster startup.
3078  */
3079 }
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2696
#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:3163
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:3097
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2615
char d_name[MAX_PATH]
Definition: dirent.h:15
#define snprintf
Definition: port.h:215
int FreeDir(DIR *dir)
Definition: fd.c:2733

◆ RemovePgTempFilesInDir()

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

Definition at line 3097 of file fd.c.

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

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

3098 {
3099  DIR *temp_dir;
3100  struct dirent *temp_de;
3101  char rm_path[MAXPGPATH * 2];
3102 
3103  temp_dir = AllocateDir(tmpdirname);
3104 
3105  if (temp_dir == NULL && errno == ENOENT && missing_ok)
3106  return;
3107 
3108  while ((temp_de = ReadDirExtended(temp_dir, tmpdirname, LOG)) != NULL)
3109  {
3110  if (strcmp(temp_de->d_name, ".") == 0 ||
3111  strcmp(temp_de->d_name, "..") == 0)
3112  continue;
3113 
3114  snprintf(rm_path, sizeof(rm_path), "%s/%s",
3115  tmpdirname, temp_de->d_name);
3116 
3117  if (unlink_all ||
3118  strncmp(temp_de->d_name,
3120  strlen(PG_TEMP_FILE_PREFIX)) == 0)
3121  {
3122  struct stat statbuf;
3123 
3124  if (lstat(rm_path, &statbuf) < 0)
3125  {
3126  ereport(LOG,
3128  errmsg("could not stat file \"%s\": %m", rm_path)));
3129  continue;
3130  }
3131 
3132  if (S_ISDIR(statbuf.st_mode))
3133  {
3134  /* recursively remove contents, then directory itself */
3135  RemovePgTempFilesInDir(rm_path, false, true);
3136 
3137  if (rmdir(rm_path) < 0)
3138  ereport(LOG,
3140  errmsg("could not remove directory \"%s\": %m",
3141  rm_path)));
3142  }
3143  else
3144  {
3145  if (unlink(rm_path) < 0)
3146  ereport(LOG,
3148  errmsg("could not remove file \"%s\": %m",
3149  rm_path)));
3150  }
3151  }
3152  else
3153  ereport(LOG,
3154  (errmsg("unexpected file found in temporary-files directory: \"%s\"",
3155  rm_path)));
3156  }
3157 
3158  FreeDir(temp_dir);
3159 }
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2696
#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:3097
int errcode_for_file_access(void)
Definition: elog.c:727
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2615
#define ereport(elevel,...)
Definition: elog.h:155
#define S_ISDIR(m)
Definition: win32_port.h:316
#define lstat(path, sb)
Definition: win32_port.h:276
int errmsg(const char *fmt,...)
Definition: elog.c:915
char d_name[MAX_PATH]
Definition: dirent.h:15
#define snprintf
Definition: port.h:215
int FreeDir(DIR *dir)
Definition: fd.c:2733

◆ RemovePgTempRelationFiles()

static void RemovePgTempRelationFiles ( const char *  tsdirname)
static

Definition at line 3163 of file fd.c.

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

Referenced by RemovePgTempFiles().

3164 {
3165  DIR *ts_dir;
3166  struct dirent *de;
3167  char dbspace_path[MAXPGPATH * 2];
3168 
3169  ts_dir = AllocateDir(tsdirname);
3170 
3171  while ((de = ReadDirExtended(ts_dir, tsdirname, LOG)) != NULL)
3172  {
3173  /*
3174  * We're only interested in the per-database directories, which have
3175  * numeric names. Note that this code will also (properly) ignore "."
3176  * and "..".
3177  */
3178  if (strspn(de->d_name, "0123456789") != strlen(de->d_name))
3179  continue;
3180 
3181  snprintf(dbspace_path, sizeof(dbspace_path), "%s/%s",
3182  tsdirname, de->d_name);
3183  RemovePgTempRelationFilesInDbspace(dbspace_path);
3184  }
3185 
3186  FreeDir(ts_dir);
3187 }
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2696
static void RemovePgTempRelationFilesInDbspace(const char *dbspacedirname)
Definition: fd.c:3191
#define LOG
Definition: elog.h:26
Definition: dirent.h:9
Definition: dirent.c:25
#define MAXPGPATH
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2615
char d_name[MAX_PATH]
Definition: dirent.h:15
#define snprintf
Definition: port.h:215
int FreeDir(DIR *dir)
Definition: fd.c:2733

◆ RemovePgTempRelationFilesInDbspace()

static void RemovePgTempRelationFilesInDbspace ( const char *  dbspacedirname)
static

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

3192 {
3193  DIR *dbspace_dir;
3194  struct dirent *de;
3195  char rm_path[MAXPGPATH * 2];
3196 
3197  dbspace_dir = AllocateDir(dbspacedirname);
3198 
3199  while ((de = ReadDirExtended(dbspace_dir, dbspacedirname, LOG)) != NULL)
3200  {
3201  if (!looks_like_temp_rel_name(de->d_name))
3202  continue;
3203 
3204  snprintf(rm_path, sizeof(rm_path), "%s/%s",
3205  dbspacedirname, de->d_name);
3206 
3207  if (unlink(rm_path) < 0)
3208  ereport(LOG,
3210  errmsg("could not remove file \"%s\": %m",
3211  rm_path)));
3212  }
3213 
3214  FreeDir(dbspace_dir);
3215 }
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2696
#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:727
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2615
#define ereport(elevel,...)
Definition: elog.h:155
bool looks_like_temp_rel_name(const char *name)
Definition: fd.c:3219
int errmsg(const char *fmt,...)
Definition: elog.c:915
char d_name[MAX_PATH]
Definition: dirent.h:15
#define snprintf
Definition: port.h:215
int FreeDir(DIR *dir)
Definition: fd.c:2733

◆ ReportTemporaryFileUsage()

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

Definition at line 1418 of file fd.c.

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

Referenced by FileClose(), and PathNameDeleteTemporaryFile().

1419 {
1420  pgstat_report_tempfile(size);
1421 
1422  if (log_temp_files >= 0)
1423  {
1424  if ((size / 1024) >= log_temp_files)
1425  ereport(LOG,
1426  (errmsg("temporary file: path \"%s\", size %lu",
1427  path, (unsigned long) size)));
1428  }
1429 }
int log_temp_files
Definition: guc.c:546
void pgstat_report_tempfile(size_t filesize)
Definition: pgstat.c:1756
#define LOG
Definition: elog.h:26
#define ereport(elevel,...)
Definition: elog.h:155
int errmsg(const char *fmt,...)
Definition: elog.c:915

◆ reserveAllocatedDesc()

static bool reserveAllocatedDesc ( void  )
static

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

2280 {
2281  AllocateDesc *newDescs;
2282  int newMax;
2283 
2284  /* Quick out if array already has a free slot. */
2286  return true;
2287 
2288  /*
2289  * If the array hasn't yet been created in the current process, initialize
2290  * it with FD_MINFREE / 3 elements. In many scenarios this is as many as
2291  * we will ever need, anyway. We don't want to look at max_safe_fds
2292  * immediately because set_max_safe_fds() may not have run yet.
2293  */
2294  if (allocatedDescs == NULL)
2295  {
2296  newMax = FD_MINFREE / 3;
2297  newDescs = (AllocateDesc *) malloc(newMax * sizeof(AllocateDesc));
2298  /* Out of memory already? Treat as fatal error. */
2299  if (newDescs == NULL)
2300  ereport(ERROR,
2301  (errcode(ERRCODE_OUT_OF_MEMORY),
2302  errmsg("out of memory")));
2303  allocatedDescs = newDescs;
2304  maxAllocatedDescs = newMax;
2305  return true;
2306  }
2307 
2308  /*
2309  * Consider enlarging the array beyond the initial allocation used above.
2310  * By the time this happens, max_safe_fds should be known accurately.
2311  *
2312  * We mustn't let allocated descriptors hog all the available FDs, and in
2313  * practice we'd better leave a reasonable number of FDs for VFD use. So
2314  * set the maximum to max_safe_fds / 3. (This should certainly be at
2315  * least as large as the initial size, FD_MINFREE / 3, so we aren't
2316  * tightening the restriction here.) Recall that "external" FDs are
2317  * allowed to consume another third of max_safe_fds.
2318  */
2319  newMax = max_safe_fds / 3;
2320  if (newMax > maxAllocatedDescs)
2321  {
2322  newDescs = (AllocateDesc *) realloc(allocatedDescs,
2323  newMax * sizeof(AllocateDesc));
2324  /* Treat out-of-memory as a non-fatal error. */
2325  if (newDescs == NULL)
2326  return false;
2327  allocatedDescs = newDescs;
2328  maxAllocatedDescs = newMax;
2329  return true;
2330  }
2331 
2332  /* Can't enlarge allocatedDescs[] any more. */
2333  return false;
2334 }
static AllocateDesc * allocatedDescs
Definition: fd.c:255
int max_safe_fds
Definition: fd.c:156
int errcode(int sqlerrcode)
Definition: elog.c:704
#define malloc(a)
Definition: header.h:50
#define ERROR
Definition: elog.h:45
#define ereport(elevel,...)
Definition: elog.h:155
#define FD_MINFREE
Definition: fd.c:135
#define realloc(a, b)
Definition: header.h:60
int errmsg(const char *fmt,...)
Definition: elog.c:915
static int maxAllocatedDescs
Definition: fd.c:254
static int numAllocatedDescs
Definition: fd.c:253

◆ ReserveExternalFD()

void ReserveExternalFD ( void  )

Definition at line 1111 of file fd.c.

References numExternalFDs, and ReleaseLruFiles().

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

1112 {
1113  /*
1114  * Release VFDs if needed to stay safe. Because we do this before
1115  * incrementing numExternalFDs, the final state will be as desired, i.e.,
1116  * nfile + numAllocatedDescs + numExternalFDs <= max_safe_fds.
1117  */
1118  ReleaseLruFiles();
1119 
1120  numExternalFDs++;
1121 }
static int numExternalFDs
Definition: fd.c:260
static void ReleaseLruFiles(void)
Definition: fd.c:1294

◆ set_max_safe_fds()

void set_max_safe_fds ( void  )

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

972 {
973  int usable_fds;
974  int already_open;
975 
976  /*----------
977  * We want to set max_safe_fds to
978  * MIN(usable_fds, max_files_per_process - already_open)
979  * less the slop factor for files that are opened without consulting
980  * fd.c. This ensures that we won't exceed either max_files_per_process
981  * or the experimentally-determined EMFILE limit.
982  *----------
983  */
985  &usable_fds, &already_open);
986 
987  max_safe_fds = Min(usable_fds, max_files_per_process - already_open);
988 
989  /*
990  * Take off the FDs reserved for system() etc.
991  */
993 
994  /*
995  * Make sure we still have enough to get by.
996  */
997  if (max_safe_fds < FD_MINFREE)
998  ereport(FATAL,
999  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
1000  errmsg("insufficient file descriptors available to start server process"),
1001  errdetail("System allows %d, we need at least %d.",
1004 
1005  elog(DEBUG2, "max_safe_fds = %d, usable_fds = %d, already_open = %d",
1006  max_safe_fds, usable_fds, already_open);
1007 }
static void count_usable_fds(int max_to_probe, int *usable_fds, int *already_open)
Definition: fd.c:887
#define NUM_RESERVED_FDS
Definition: fd.c:126
int max_safe_fds
Definition: fd.c:156
#define Min(x, y)
Definition: c.h:974
int errcode(int sqlerrcode)
Definition: elog.c:704
#define FATAL
Definition: elog.h:54
#define DEBUG2
Definition: elog.h:24
int errdetail(const char *fmt,...)
Definition: elog.c:1048
int max_files_per_process
Definition: fd.c:143
#define ereport(elevel,...)
Definition: elog.h:155
#define FD_MINFREE
Definition: fd.c:135
int errmsg(const char *fmt,...)
Definition: elog.c:915
#define elog(elevel,...)
Definition: elog.h:228

◆ SetTempTablespaces()

void SetTempTablespaces ( Oid tableSpaces,
int  numSpaces 
)

Definition at line 2821 of file fd.c.

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

Referenced by assign_temp_tablespaces(), and PrepareTempTablespaces().

2822 {
2823  Assert(numSpaces >= 0);
2824  tempTableSpaces = tableSpaces;
2825  numTempTableSpaces = numSpaces;
2826 
2827  /*
2828  * Select a random starting point in the list. This is to minimize
2829  * conflicts between backends that are most likely sharing the same list
2830  * of temp tablespaces. Note that if we create multiple temp files in the
2831  * same transaction, we'll advance circularly through the list --- this
2832  * ensures that large temporary sort files are nicely spread across all
2833  * available tablespaces.
2834  */
2835  if (numSpaces > 1)
2836  nextTempTableSpace = random() % numSpaces;
2837  else
2838  nextTempTableSpace = 0;
2839 }
long random(void)
Definition: random.c:22
static int numTempTableSpaces
Definition: fd.c:275
static int nextTempTableSpace
Definition: fd.c:276
#define Assert(condition)
Definition: c.h:792
static Oid * tempTableSpaces
Definition: fd.c:274

◆ SyncDataDirectory()

void SyncDataDirectory ( void  )

Definition at line 3289 of file fd.c.

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

Referenced by StartupXLOG().

3290 {
3291  bool xlog_is_symlink;
3292 
3293  /* We can skip this whole thing if fsync is disabled. */
3294  if (!enableFsync)
3295  return;
3296 
3297  /*
3298  * If pg_wal is a symlink, we'll need to recurse into it separately,
3299  * because the first walkdir below will ignore it.
3300  */
3301  xlog_is_symlink = false;
3302 
3303 #ifndef WIN32
3304  {
3305  struct stat st;
3306 
3307  if (lstat("pg_wal", &st) < 0)
3308  ereport(LOG,
3310  errmsg("could not stat file \"%s\": %m",
3311  "pg_wal")));
3312  else if (S_ISLNK(st.st_mode))
3313  xlog_is_symlink = true;
3314  }
3315 #else
3316  if (pgwin32_is_junction("pg_wal"))
3317  xlog_is_symlink = true;
3318 #endif
3319 
3320  /*
3321  * If possible, hint to the kernel that we're soon going to fsync the data
3322  * directory and its contents. Errors in this step are even less
3323  * interesting than normal, so log them only at DEBUG1.
3324  */
3325 #ifdef PG_FLUSH_DATA_WORKS
3326  walkdir(".", pre_sync_fname, false, DEBUG1);
3327  if (xlog_is_symlink)
3328  walkdir("pg_wal", pre_sync_fname, false, DEBUG1);
3329  walkdir("pg_tblspc", pre_sync_fname, true, DEBUG1);
3330 #endif
3331 
3332  /*
3333  * Now we do the fsync()s in the same order.
3334  *
3335  * The main call ignores symlinks, so in addition to specially processing
3336  * pg_wal if it's a symlink, pg_tblspc has to be visited separately with
3337  * process_symlinks = true. Note that if there are any plain directories
3338  * in pg_tblspc, they'll get fsync'd twice. That's not an expected case
3339  * so we don't worry about optimizing it.
3340  */
3341  walkdir(".", datadir_fsync_fname, false, LOG);
3342  if (xlog_is_symlink)
3343  walkdir("pg_wal", datadir_fsync_fname, false, LOG);
3344  walkdir("pg_tblspc", datadir_fsync_fname, true, LOG);
3345 }
#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:3363
#define LOG
Definition: elog.h:26
int errcode_for_file_access(void)
Definition: elog.c:727
static void datadir_fsync_fname(const char *fname, bool isdir, int elevel)
Definition: fd.c:3461
#define ereport(elevel,...)
Definition: elog.h:155
#define lstat(path, sb)
Definition: win32_port.h:276
bool enableFsync
Definition: globals.c:120
int errmsg(const char *fmt,...)
Definition: elog.c:915
bool pgwin32_is_junction(const char *path)

◆ TempTablespacePath()

void TempTablespacePath ( char *  path,
Oid  tablespace 
)

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

1660 {
1661  /*
1662  * Identify the tempfile directory for this tablespace.
1663  *
1664  * If someone tries to specify pg_global, use pg_default instead.
1665  */
1666  if (tablespace == InvalidOid ||
1667  tablespace == DEFAULTTABLESPACE_OID ||
1668  tablespace == GLOBALTABLESPACE_OID)
1669  snprintf(path, MAXPGPATH, "base/%s", PG_TEMP_FILES_DIR);
1670  else
1671  {
1672  /* All other tablespaces are accessed via symlinks */
1673  snprintf(path, MAXPGPATH, "pg_tblspc/%u/%s/%s",
1676  }
1677 }
#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:189
#define InvalidOid
Definition: postgres_ext.h:36
#define snprintf
Definition: port.h:215

◆ TempTablespacesAreSet()

bool TempTablespacesAreSet ( void  )

Definition at line 2849 of file fd.c.

References numTempTableSpaces.

Referenced by GetTempTablespaces(), and PrepareTempTablespaces().

2850 {
2851  return (numTempTableSpaces >= 0);
2852 }
static int numTempTableSpaces
Definition: fd.c:275

◆ unlink_if_exists_fname()

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

Definition at line 3471 of file fd.c.

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

Referenced by PathNameDeleteTemporaryDir().

3472 {
3473  if (isdir)
3474  {
3475  if (rmdir(fname) != 0 && errno != ENOENT)
3476  ereport(elevel,
3478  errmsg("could not remove directory \"%s\": %m", fname)));
3479  }
3480  else
3481  {
3482  /* Use PathNameDeleteTemporaryFile to report filesize */
3483  PathNameDeleteTemporaryFile(fname, false);
3484  }
3485 }
bool PathNameDeleteTemporaryFile(const char *path, bool error_on_failure)
Definition: fd.c:1808
int errcode_for_file_access(void)
Definition: elog.c:727
static int elevel
Definition: vacuumlazy.c:333
#define ereport(elevel,...)
Definition: elog.h:155
int errmsg(const char *fmt,...)
Definition: elog.c:915

◆ 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 3363 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(), get_dirent_type(), MAXPGPATH, OpenTransientFile(), PG_BINARY, pg_flush_data(), PGFILETYPE_DIR, PGFILETYPE_REG, ReadDirExtended(), snprintf, and subpath().

Referenced by PathNameDeleteTemporaryDir(), and SyncDataDirectory().

3367 {
3368  DIR *dir;
3369  struct dirent *de;
3370 
3371  dir = AllocateDir(path);
3372 
3373  while ((de = ReadDirExtended(dir, path, elevel)) != NULL)
3374  {
3375  char subpath[MAXPGPATH * 2];
3376 
3378 
3379  if (strcmp(de->d_name, ".") == 0 ||
3380  strcmp(de->d_name, "..") == 0)
3381  continue;
3382 
3383  snprintf(subpath, sizeof(subpath), "%s/%s", path, de->d_name);
3384 
3385  switch (get_dirent_type(subpath, de, process_symlinks, elevel))
3386  {
3387  case PGFILETYPE_REG:
3388  (*action) (subpath, false, elevel);
3389  break;
3390  case PGFILETYPE_DIR:
3391  walkdir(subpath, action, false, elevel);
3392  break;
3393  default:
3394 
3395  /*
3396  * Errors are already reported directly by get_dirent_type(),
3397  * and any remaining symlinks and unknown file types are
3398  * ignored.
3399  */
3400  break;
3401  }
3402  }
3403 
3404  FreeDir(dir); /* we ignore any error here */
3405 
3406  /*
3407  * It's important to fsync the destination directory itself as individual
3408  * file fsyncs don't guarantee that the directory entry for the file is
3409  * synced. However, skip this if AllocateDir failed; the action function
3410  * might not be robust against that.
3411  */
3412  if (dir)
3413  (*action) (path, true, elevel);
3414 }
static void walkdir(const char *path, void(*action)(const char *fname, bool isdir, int elevel), bool process_symlinks, int elevel)
Definition: fd.c:3363
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2696
Definition: dirent.h:9
Definition: dirent.c:25
#define MAXPGPATH
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2615
PGFileType get_dirent_type(const char *path, const struct dirent *de, bool look_through_symlinks, int elevel)
Definition: file_utils.c:410
static int elevel
Definition: vacuumlazy.c:333
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:100
char d_name[MAX_PATH]
Definition: dirent.h:15
#define snprintf
Definition: port.h:215
int FreeDir(DIR *dir)
Definition: fd.c:2733
Datum subpath(PG_FUNCTION_ARGS)
Definition: ltree_op.c:241

Variable Documentation

◆ allocatedDescs

AllocateDesc* allocatedDescs = NULL
static

Definition at line 255 of file fd.c.

◆ data_sync_retry

bool data_sync_retry = false

Definition at line 159 of file fd.c.

Referenced by data_sync_elevel().

◆ have_xact_temporary_files

bool have_xact_temporary_files = false
static

Definition at line 219 of file fd.c.

Referenced by CleanupTempFiles(), and RegisterTemporaryFile().

◆ max_files_per_process

int max_files_per_process = 1000

Definition at line 143 of file fd.c.

Referenced by set_max_safe_fds().

◆ max_safe_fds

◆ maxAllocatedDescs

int maxAllocatedDescs = 0
static

◆ nextTempTableSpace

int nextTempTableSpace = 0
static

Definition at line 276 of file fd.c.

Referenced by GetNextTempTableSpace(), and SetTempTablespaces().

◆ nfile

int nfile = 0
static

◆ numAllocatedDescs

◆ numExternalFDs

int numExternalFDs = 0
static

Definition at line 260 of file fd.c.

Referenced by AcquireExternalFD(), ReleaseExternalFD(), ReleaseLruFiles(), and ReserveExternalFD().

◆ numTempTableSpaces

int numTempTableSpaces = -1
static

◆ SizeVfdCache

Size SizeVfdCache = 0
static

Definition at line 208 of file fd.c.

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

◆ tempFileCounter

long tempFileCounter = 0
static

Definition at line 266 of file fd.c.

Referenced by OpenTemporaryFileInTablespace().

◆ temporary_files_size

uint64 temporary_files_size = 0
static

Definition at line 227 of file fd.c.

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

◆ tempTableSpaces

Oid* tempTableSpaces = NULL
static

◆ VfdCache

Vfd* VfdCache
static

Definition at line 207 of file fd.c.