PostgreSQL Source Code  git master
fd.c File Reference
#include "postgres.h"
#include <dirent.h>
#include <sys/file.h>
#include <sys/param.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/types.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 "common/pg_prng.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "portability/mem.h"
#include "postmaster/startup.h"
#include "storage/fd.h"
#include "storage/ipc.h"
#include "utils/guc.h"
#include "utils/guc_hooks.h"
#include "utils/resowner.h"
#include "utils/varlena.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 BeforeShmemExit_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)
 
static void ResOwnerReleaseFile (Datum res)
 
static char * ResOwnerPrintFile (Datum res)
 
static void ResourceOwnerRememberFile (ResourceOwner owner, File file)
 
static void ResourceOwnerForgetFile (ResourceOwner owner, File file)
 
int pg_fsync (int fd)
 
int pg_fsync_no_writethrough (int fd)
 
int pg_fsync_writethrough (int fd)
 
int pg_fdatasync (int fd)
 
bool pg_file_exists (const char *name)
 
void pg_flush_data (int fd, off_t offset, off_t nbytes)
 
static int pg_ftruncate (int fd, off_t length)
 
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)
 
void InitFileAccess (void)
 
void InitTemporaryFileAccess (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, off_t amount, uint32 wait_event_info)
 
void FileWriteback (File file, off_t offset, off_t nbytes, uint32 wait_event_info)
 
ssize_t FileReadV (File file, const struct iovec *iov, int iovcnt, off_t offset, uint32 wait_event_info)
 
ssize_t FileWriteV (File file, const struct iovec *iov, int iovcnt, off_t offset, uint32 wait_event_info)
 
int FileSync (File file, uint32 wait_event_info)
 
int FileZero (File file, off_t offset, off_t amount, uint32 wait_event_info)
 
int FileFallocate (File file, off_t offset, off_t amount, 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)
 
bool check_debug_io_direct (char **newval, void **extra, GucSource source)
 
void assign_debug_io_direct (const char *newval, void *extra)
 

Variables

int max_files_per_process = 1000
 
int max_safe_fds = FD_MINFREE
 
bool data_sync_retry = false
 
int recovery_init_sync_method = DATA_DIR_SYNC_METHOD_FSYNC
 
int io_direct_flags
 
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
 
static const ResourceOwnerDesc file_resowner_desc
 

Macro Definition Documentation

◆ DO_DB

#define DO_DB (   A)     ((void) 0)

Definition at line 180 of file fd.c.

◆ FD_CLOSE_AT_EOXACT

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

Definition at line 193 of file fd.c.

◆ FD_DELETE_AT_CLOSE

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

Definition at line 192 of file fd.c.

◆ FD_MINFREE

#define FD_MINFREE   48

Definition at line 138 of file fd.c.

◆ FD_TEMP_FILE_LIMIT

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

Definition at line 194 of file fd.c.

◆ FileIsNotOpen

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

Definition at line 189 of file fd.c.

◆ FileIsValid

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

Definition at line 186 of file fd.c.

◆ NUM_RESERVED_FDS

#define NUM_RESERVED_FDS   10

Definition at line 129 of file fd.c.

◆ VFD_CLOSED

#define VFD_CLOSED   (-1)

Definition at line 184 of file fd.c.

Typedef Documentation

◆ Vfd

typedef struct vfd Vfd

Enumeration Type Documentation

◆ AllocateDescKind

Enumerator
AllocateDescFile 
AllocateDescPipe 
AllocateDescDir 
AllocateDescRawFD 

Definition at line 247 of file fd.c.

248 {
AllocateDescKind
Definition: fd.c:248
@ AllocateDescDir
Definition: fd.c:251
@ AllocateDescPipe
Definition: fd.c:250
@ AllocateDescFile
Definition: fd.c:249
@ AllocateDescRawFD
Definition: fd.c:252

Function Documentation

◆ AcquireExternalFD()

bool AcquireExternalFD ( void  )

Definition at line 1186 of file fd.c.

1187 {
1188  /*
1189  * We don't want more than max_safe_fds / 3 FDs to be consumed for
1190  * "external" FDs.
1191  */
1192  if (numExternalFDs < max_safe_fds / 3)
1193  {
1195  return true;
1196  }
1197  errno = EMFILE;
1198  return false;
1199 }
int max_safe_fds
Definition: fd.c:159
void ReserveExternalFD(void)
Definition: fd.c:1221
static int numExternalFDs
Definition: fd.c:274

References max_safe_fds, numExternalFDs, and ReserveExternalFD().

Referenced by CreateWaitEventSet(), and libpqsrv_connect_prepare().

◆ AllocateDir()

DIR* AllocateDir ( const char *  dirname)

Definition at line 2843 of file fd.c.

2844 {
2845  DIR *dir;
2846 
2847  DO_DB(elog(LOG, "AllocateDir: Allocated %d (%s)",
2848  numAllocatedDescs, dirname));
2849 
2850  /* Can we allocate another non-virtual FD? */
2851  if (!reserveAllocatedDesc())
2852  ereport(ERROR,
2853  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2854  errmsg("exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"",
2855  maxAllocatedDescs, dirname)));
2856 
2857  /* Close excess kernel FDs. */
2858  ReleaseLruFiles();
2859 
2860 TryAgain:
2861  if ((dir = opendir(dirname)) != NULL)
2862  {
2864 
2865  desc->kind = AllocateDescDir;
2866  desc->desc.dir = dir;
2869  return desc->desc.dir;
2870  }
2871 
2872  if (errno == EMFILE || errno == ENFILE)
2873  {
2874  int save_errno = errno;
2875 
2876  ereport(LOG,
2877  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2878  errmsg("out of file descriptors: %m; release and retry")));
2879  errno = 0;
2880  if (ReleaseLruFile())
2881  goto TryAgain;
2882  errno = save_errno;
2883  }
2884 
2885  return NULL;
2886 }
DIR * opendir(const char *)
Definition: dirent.c:33
int errcode(int sqlerrcode)
Definition: elog.c:859
int errmsg(const char *fmt,...)
Definition: elog.c:1072
#define LOG
Definition: elog.h:31
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
#define ereport(elevel,...)
Definition: elog.h:149
static bool ReleaseLruFile(void)
Definition: fd.c:1382
static int maxAllocatedDescs
Definition: fd.c:268
static int numAllocatedDescs
Definition: fd.c:267
#define DO_DB(A)
Definition: fd.c:180
static AllocateDesc * allocatedDescs
Definition: fd.c:269
static bool reserveAllocatedDesc(void)
Definition: fd.c:2508
static void ReleaseLruFiles(void)
Definition: fd.c:1404
SubTransactionId create_subid
Definition: fd.c:258
DIR * dir
Definition: fd.c:262
union AllocateDesc::@22 desc
AllocateDescKind kind
Definition: fd.c:257
Definition: dirent.c:26
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:788

References allocatedDescs, 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(), CheckTablespaceDirectory(), CleanupBackupHistory(), copydir(), db_dir_size(), DeleteAllExportedSnapshotFiles(), destroy_tablespace_directories(), directory_is_empty(), do_pg_backup_start(), dsm_cleanup_for_mmap(), extension_file_exists(), get_ext_ver_list(), GetConfFilesInDir(), getInstallationPaths(), GetWalSummaries(), movedb(), ParseTzFile(), perform_base_backup(), pg_available_extension_versions(), pg_available_extensions(), pg_ls_dir(), pg_ls_dir_files(), pg_tablespace_databases(), pg_tzenumerate_next(), pg_tzenumerate_start(), pgarch_readyXlog(), RelationCacheInitFileRemove(), RelationCacheInitFileRemoveInDir(), RemoveNonParentXlogFiles(), RemoveOldXlogFiles(), RemovePgTempFiles(), RemovePgTempFilesInDir(), RemovePgTempRelationFiles(), RemovePgTempRelationFilesInDbspace(), RemoveTempXlogFiles(), ReorderBufferCleanupSerializedTXNs(), ResetUnloggedRelations(), ResetUnloggedRelationsInDbspaceDir(), ResetUnloggedRelationsInTablespaceDir(), restoreTwoPhaseData(), scan_directory_ci(), sendDir(), SlruScanDirectory(), StartupReorderBuffer(), StartupReplicationSlots(), SyncDataDirectory(), UpdateLogicalMappings(), walkdir(), and XLogGetOldestSegno().

◆ AllocateFile()

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

Definition at line 2583 of file fd.c.

2584 {
2585  FILE *file;
2586 
2587  DO_DB(elog(LOG, "AllocateFile: Allocated %d (%s)",
2589 
2590  /* Can we allocate another non-virtual FD? */
2591  if (!reserveAllocatedDesc())
2592  ereport(ERROR,
2593  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2594  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2595  maxAllocatedDescs, name)));
2596 
2597  /* Close excess kernel FDs. */
2598  ReleaseLruFiles();
2599 
2600 TryAgain:
2601  if ((file = fopen(name, mode)) != NULL)
2602  {
2604 
2605  desc->kind = AllocateDescFile;
2606  desc->desc.file = file;
2609  return desc->desc.file;
2610  }
2611 
2612  if (errno == EMFILE || errno == ENFILE)
2613  {
2614  int save_errno = errno;
2615 
2616  ereport(LOG,
2617  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2618  errmsg("out of file descriptors: %m; release and retry")));
2619  errno = 0;
2620  if (ReleaseLruFile())
2621  goto TryAgain;
2622  errno = save_errno;
2623  }
2624 
2625  return NULL;
2626 }
static PgChecksumMode mode
Definition: pg_checksums.c:56
FILE * file
Definition: fd.c:261
const char * name

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

Referenced by AlterSystemSetConfigFile(), apw_dump_now(), apw_load_buffers(), BeginCopyFrom(), BeginCopyTo(), checkControlFile(), do_pg_backup_stop(), entry_reset(), existsTimeLineHistory(), ExportSnapshot(), gc_qtexts(), GetHugePageSize(), ImportSnapshot(), load_dh_file(), load_relcache_init_file(), open_auth_file(), parse_extension_control_file(), ParseTzFile(), pg_current_logfile(), pg_promote(), pgss_shmem_shutdown(), pgss_shmem_startup(), pgstat_read_statsfile(), pgstat_write_statsfile(), read_backup_label(), read_binary_file(), read_tablespace_map(), read_whole_file(), readTimeLineHistory(), tsearch_readline_begin(), ValidatePgVersion(), write_relcache_init_file(), XLogArchiveForceDone(), and XLogArchiveNotify().

◆ AllocateVfd()

static File AllocateVfd ( void  )
static

Definition at line 1414 of file fd.c.

1415 {
1416  Index i;
1417  File file;
1418 
1419  DO_DB(elog(LOG, "AllocateVfd. Size %zu", SizeVfdCache));
1420 
1421  Assert(SizeVfdCache > 0); /* InitFileAccess not called? */
1422 
1423  if (VfdCache[0].nextFree == 0)
1424  {
1425  /*
1426  * The free list is empty so it is time to increase the size of the
1427  * array. We choose to double it each time this happens. However,
1428  * there's not much point in starting *real* small.
1429  */
1430  Size newCacheSize = SizeVfdCache * 2;
1431  Vfd *newVfdCache;
1432 
1433  if (newCacheSize < 32)
1434  newCacheSize = 32;
1435 
1436  /*
1437  * Be careful not to clobber VfdCache ptr if realloc fails.
1438  */
1439  newVfdCache = (Vfd *) realloc(VfdCache, sizeof(Vfd) * newCacheSize);
1440  if (newVfdCache == NULL)
1441  ereport(ERROR,
1442  (errcode(ERRCODE_OUT_OF_MEMORY),
1443  errmsg("out of memory")));
1444  VfdCache = newVfdCache;
1445 
1446  /*
1447  * Initialize the new entries and link them into the free list.
1448  */
1449  for (i = SizeVfdCache; i < newCacheSize; i++)
1450  {
1451  MemSet((char *) &(VfdCache[i]), 0, sizeof(Vfd));
1452  VfdCache[i].nextFree = i + 1;
1453  VfdCache[i].fd = VFD_CLOSED;
1454  }
1455  VfdCache[newCacheSize - 1].nextFree = 0;
1457 
1458  /*
1459  * Record the new size
1460  */
1461  SizeVfdCache = newCacheSize;
1462  }
1463 
1464  file = VfdCache[0].nextFree;
1465 
1466  VfdCache[0].nextFree = VfdCache[file].nextFree;
1467 
1468  return file;
1469 }
#define Assert(condition)
Definition: c.h:858
unsigned int Index
Definition: c.h:614
#define MemSet(start, val, len)
Definition: c.h:1020
size_t Size
Definition: c.h:605
static Size SizeVfdCache
Definition: fd.c:217
#define VFD_CLOSED
Definition: fd.c:184
static Vfd * VfdCache
Definition: fd.c:216
int File
Definition: fd.h:51
#define realloc(a, b)
Definition: header.h:60
int i
Definition: isn.c:73
Definition: fd.c:197
int fd
Definition: fd.c:198
File nextFree
Definition: fd.c:201

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

Referenced by PathNameOpenFilePerm().

◆ assign_debug_io_direct()

void assign_debug_io_direct ( const char *  newval,
void *  extra 
)

Definition at line 4024 of file fd.c.

4025 {
4026  int *flags = (int *) extra;
4027 
4028  io_direct_flags = *flags;
4029 }
int io_direct_flags
Definition: fd.c:168

References io_direct_flags.

◆ AtEOSubXact_Files()

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

Definition at line 3132 of file fd.c.

3134 {
3135  Index i;
3136 
3137  for (i = 0; i < numAllocatedDescs; i++)
3138  {
3139  if (allocatedDescs[i].create_subid == mySubid)
3140  {
3141  if (isCommit)
3142  allocatedDescs[i].create_subid = parentSubid;
3143  else
3144  {
3145  /* have to recheck the item after FreeDesc (ugly) */
3146  FreeDesc(&allocatedDescs[i--]);
3147  }
3148  }
3149  }
3150 }
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2742

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

◆ AtEOXact_Files()

void AtEOXact_Files ( bool  isCommit)

Definition at line 3165 of file fd.c.

3166 {
3167  CleanupTempFiles(isCommit, false);
3168  tempTableSpaces = NULL;
3169  numTempTableSpaces = -1;
3170 }
static int numTempTableSpaces
Definition: fd.c:289
static Oid * tempTableSpaces
Definition: fd.c:288
static void CleanupTempFiles(bool isCommit, bool isProcExit)
Definition: fd.c:3202

References CleanupTempFiles(), numTempTableSpaces, and tempTableSpaces.

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

◆ BasicOpenFile()

int BasicOpenFile ( const char *  fileName,
int  fileFlags 
)

Definition at line 1087 of file fd.c.

1088 {
1089  return BasicOpenFilePerm(fileName, fileFlags, pg_file_create_mode);
1090 }
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1109
int pg_file_create_mode
Definition: file_perm.c:19

References BasicOpenFilePerm(), and pg_file_create_mode.

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

◆ BasicOpenFilePerm()

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

Definition at line 1109 of file fd.c.

1110 {
1111  int fd;
1112 
1113 tryAgain:
1114 #ifdef PG_O_DIRECT_USE_F_NOCACHE
1115 
1116  /*
1117  * The value we defined to stand in for O_DIRECT when simulating it with
1118  * F_NOCACHE had better not collide with any of the standard flags.
1119  */
1121  (O_APPEND |
1122  O_CLOEXEC |
1123  O_CREAT |
1124  O_DSYNC |
1125  O_EXCL |
1126  O_RDWR |
1127  O_RDONLY |
1128  O_SYNC |
1129  O_TRUNC |
1130  O_WRONLY)) == 0,
1131  "PG_O_DIRECT value collides with standard flag");
1132  fd = open(fileName, fileFlags & ~PG_O_DIRECT, fileMode);
1133 #else
1134  fd = open(fileName, fileFlags, fileMode);
1135 #endif
1136 
1137  if (fd >= 0)
1138  {
1139 #ifdef PG_O_DIRECT_USE_F_NOCACHE
1140  if (fileFlags & PG_O_DIRECT)
1141  {
1142  if (fcntl(fd, F_NOCACHE, 1) < 0)
1143  {
1144  int save_errno = errno;
1145 
1146  close(fd);
1147  errno = save_errno;
1148  return -1;
1149  }
1150  }
1151 #endif
1152 
1153  return fd; /* success! */
1154  }
1155 
1156  if (errno == EMFILE || errno == ENFILE)
1157  {
1158  int save_errno = errno;
1159 
1160  ereport(LOG,
1161  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
1162  errmsg("out of file descriptors: %m; release and retry")));
1163  errno = 0;
1164  if (ReleaseLruFile())
1165  goto tryAgain;
1166  errno = save_errno;
1167  }
1168 
1169  return -1; /* failure */
1170 }
#define StaticAssertStmt(condition, errmessage)
Definition: c.h:938
#define PG_O_DIRECT
Definition: fd.h:97
#define close(a)
Definition: win32.h:12
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define O_CLOEXEC
Definition: win32_port.h:359
#define O_DSYNC
Definition: win32_port.h:352

References close, ereport, errcode(), errmsg(), fd(), LOG, O_CLOEXEC, O_DSYNC, PG_O_DIRECT, ReleaseLruFile(), and StaticAssertStmt.

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

◆ BeforeShmemExit_Files()

static void BeforeShmemExit_Files ( int  code,
Datum  arg 
)
static

Definition at line 3179 of file fd.c.

3180 {
3181  CleanupTempFiles(false, true);
3182 
3183  /* prevent further temp files from being created */
3184 #ifdef USE_ASSERT_CHECKING
3185  temporary_files_allowed = false;
3186 #endif
3187 }

References CleanupTempFiles().

Referenced by InitTemporaryFileAccess().

◆ check_debug_io_direct()

bool check_debug_io_direct ( char **  newval,
void **  extra,
GucSource  source 
)

Definition at line 3942 of file fd.c.

3943 {
3944  bool result = true;
3945  int flags;
3946 
3947 #if PG_O_DIRECT == 0
3948  if (strcmp(*newval, "") != 0)
3949  {
3950  GUC_check_errdetail("debug_io_direct is not supported on this platform.");
3951  result = false;
3952  }
3953  flags = 0;
3954 #else
3955  List *elemlist;
3956  ListCell *l;
3957  char *rawstring;
3958 
3959  /* Need a modifiable copy of string */
3960  rawstring = pstrdup(*newval);
3961 
3962  if (!SplitGUCList(rawstring, ',', &elemlist))
3963  {
3964  GUC_check_errdetail("Invalid list syntax in parameter %s",
3965  "debug_io_direct");
3966  pfree(rawstring);
3967  list_free(elemlist);
3968  return false;
3969  }
3970 
3971  flags = 0;
3972  foreach(l, elemlist)
3973  {
3974  char *item = (char *) lfirst(l);
3975 
3976  if (pg_strcasecmp(item, "data") == 0)
3977  flags |= IO_DIRECT_DATA;
3978  else if (pg_strcasecmp(item, "wal") == 0)
3979  flags |= IO_DIRECT_WAL;
3980  else if (pg_strcasecmp(item, "wal_init") == 0)
3981  flags |= IO_DIRECT_WAL_INIT;
3982  else
3983  {
3984  GUC_check_errdetail("Invalid option \"%s\"", item);
3985  result = false;
3986  break;
3987  }
3988  }
3989 
3990  /*
3991  * It's possible to configure block sizes smaller than our assumed I/O
3992  * alignment size, which could result in invalid I/O requests.
3993  */
3994 #if XLOG_BLCKSZ < PG_IO_ALIGN_SIZE
3995  if (result && (flags & (IO_DIRECT_WAL | IO_DIRECT_WAL_INIT)))
3996  {
3997  GUC_check_errdetail("debug_io_direct is not supported for WAL because XLOG_BLCKSZ is too small");
3998  result = false;
3999  }
4000 #endif
4001 #if BLCKSZ < PG_IO_ALIGN_SIZE
4002  if (result && (flags & IO_DIRECT_DATA))
4003  {
4004  GUC_check_errdetail("debug_io_direct is not supported for data because BLCKSZ is too small");
4005  result = false;
4006  }
4007 #endif
4008 
4009  pfree(rawstring);
4010  list_free(elemlist);
4011 #endif
4012 
4013  if (!result)
4014  return result;
4015 
4016  /* Save the flags in *extra, for use by assign_debug_io_direct */
4017  *extra = guc_malloc(ERROR, sizeof(int));
4018  *((int *) *extra) = flags;
4019 
4020  return result;
4021 }
#define IO_DIRECT_WAL
Definition: fd.h:55
#define IO_DIRECT_DATA
Definition: fd.h:54
#define IO_DIRECT_WAL_INIT
Definition: fd.h:56
void * guc_malloc(int elevel, size_t size)
Definition: guc.c:640
#define newval
#define GUC_check_errdetail
Definition: guc.h:448
void list_free(List *list)
Definition: list.c:1546
char * pstrdup(const char *in)
Definition: mcxt.c:1695
void pfree(void *pointer)
Definition: mcxt.c:1520
#define lfirst(lc)
Definition: pg_list.h:172
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
Definition: pg_list.h:54
bool SplitGUCList(char *rawstring, char separator, List **namelist)
Definition: varlena.c:3705

References ERROR, GUC_check_errdetail, guc_malloc(), IO_DIRECT_DATA, IO_DIRECT_WAL, IO_DIRECT_WAL_INIT, lfirst, list_free(), newval, pfree(), pg_strcasecmp(), pstrdup(), and SplitGUCList().

◆ CleanupTempFiles()

static void CleanupTempFiles ( bool  isCommit,
bool  isProcExit 
)
static

Definition at line 3202 of file fd.c.

3203 {
3204  Index i;
3205 
3206  /*
3207  * Careful here: at proc_exit we need extra cleanup, not just
3208  * xact_temporary files.
3209  */
3210  if (isProcExit || have_xact_temporary_files)
3211  {
3212  Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
3213  for (i = 1; i < SizeVfdCache; i++)
3214  {
3215  unsigned short fdstate = VfdCache[i].fdstate;
3216 
3217  if (((fdstate & FD_DELETE_AT_CLOSE) || (fdstate & FD_CLOSE_AT_EOXACT)) &&
3218  VfdCache[i].fileName != NULL)
3219  {
3220  /*
3221  * If we're in the process of exiting a backend process, close
3222  * all temporary files. Otherwise, only close temporary files
3223  * local to the current transaction. They should be closed by
3224  * the ResourceOwner mechanism already, so this is just a
3225  * debugging cross-check.
3226  */
3227  if (isProcExit)
3228  FileClose(i);
3229  else if (fdstate & FD_CLOSE_AT_EOXACT)
3230  {
3231  elog(WARNING,
3232  "temporary file %s not closed at end-of-transaction",
3233  VfdCache[i].fileName);
3234  FileClose(i);
3235  }
3236  }
3237  }
3238 
3239  have_xact_temporary_files = false;
3240  }
3241 
3242  /* Complain if any allocated files remain open at commit. */
3243  if (isCommit && numAllocatedDescs > 0)
3244  elog(WARNING, "%d temporary files and directories not closed at end-of-transaction",
3246 
3247  /* Clean up "allocated" stdio files, dirs and fds. */
3248  while (numAllocatedDescs > 0)
3249  FreeDesc(&allocatedDescs[0]);
3250 }
#define WARNING
Definition: elog.h:36
#define FD_DELETE_AT_CLOSE
Definition: fd.c:192
#define FD_CLOSE_AT_EOXACT
Definition: fd.c:193
void FileClose(File file)
Definition: fd.c:1978
#define FileIsNotOpen(file)
Definition: fd.c:189
static bool have_xact_temporary_files
Definition: fd.c:228
unsigned short fdstate
Definition: fd.c:199

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

Referenced by AtEOXact_Files(), and BeforeShmemExit_Files().

◆ closeAllVfds()

void closeAllVfds ( void  )

Definition at line 3020 of file fd.c.

3021 {
3022  Index i;
3023 
3024  if (SizeVfdCache > 0)
3025  {
3026  Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
3027  for (i = 1; i < SizeVfdCache; i++)
3028  {
3029  if (!FileIsNotOpen(i))
3030  LruDelete(i);
3031  }
3032  }
3033 }
static void LruDelete(File file)
Definition: fd.c:1287

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

Referenced by standard_ProcessUtility().

◆ ClosePipeStream()

int ClosePipeStream ( FILE *  file)

Definition at line 2991 of file fd.c.

2992 {
2993  int i;
2994 
2995  DO_DB(elog(LOG, "ClosePipeStream: Allocated %d", numAllocatedDescs));
2996 
2997  /* Remove file from list of allocated files, if it's present */
2998  for (i = numAllocatedDescs; --i >= 0;)
2999  {
3000  AllocateDesc *desc = &allocatedDescs[i];
3001 
3002  if (desc->kind == AllocateDescPipe && desc->desc.file == file)
3003  return FreeDesc(desc);
3004  }
3005 
3006  /* Only get here if someone passes us a file not in allocatedDescs */
3007  elog(WARNING, "file passed to ClosePipeStream was not obtained from OpenPipeStream");
3008 
3009  return pclose(file);
3010 }

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

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

◆ CloseTransientFile()

int CloseTransientFile ( int  fd)

Definition at line 2809 of file fd.c.

2810 {
2811  int i;
2812 
2813  DO_DB(elog(LOG, "CloseTransientFile: Allocated %d", numAllocatedDescs));
2814 
2815  /* Remove fd from list of allocated files, if it's present */
2816  for (i = numAllocatedDescs; --i >= 0;)
2817  {
2818  AllocateDesc *desc = &allocatedDescs[i];
2819 
2820  if (desc->kind == AllocateDescRawFD && desc->desc.fd == fd)
2821  return FreeDesc(desc);
2822  }
2823 
2824  /* Only get here if someone passes us a file not in allocatedDescs */
2825  elog(WARNING, "fd passed to CloseTransientFile was not obtained from OpenTransientFile");
2826 
2827  return close(fd);
2828 }
int fd
Definition: fd.c:263

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

Referenced by ApplyLogicalMappingFile(), be_lo_export(), CheckPointLogicalRewriteHeap(), CheckPointReplicationOrigin(), compare_files(), copy_file(), CreateDirAndVersionFile(), dsm_impl_mmap(), durable_rename(), fsync_fname_ext(), get_controlfile_by_exact_path(), heap_xlog_logical_rewrite(), lo_import_internal(), perform_base_backup(), pg_truncate(), qtext_load_file(), qtext_store(), read_relmap_file(), ReadTwoPhaseFile(), RecreateTwoPhaseFile(), ReorderBufferSerializeChange(), ReorderBufferSerializeTXN(), RestoreSlotFromDisk(), SaveSlotToPath(), sendFile(), SendTimeLineHistory(), SimpleLruDoesPhysicalPageExist(), SimpleLruWriteAll(), SlruInternalWritePage(), SlruPhysicalReadPage(), SlruPhysicalWritePage(), SlruSyncFileTag(), SnapBuildRestore(), SnapBuildRestoreContents(), SnapBuildSerialize(), StartupReplicationOrigin(), write_relmap_file(), writeTimeLineHistory(), writeTimeLineHistoryFile(), and XLogFileCopy().

◆ count_usable_fds()

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

Definition at line 964 of file fd.c.

965 {
966  int *fd;
967  int size;
968  int used = 0;
969  int highestfd = 0;
970  int j;
971 
972 #ifdef HAVE_GETRLIMIT
973  struct rlimit rlim;
974  int getrlimit_status;
975 #endif
976 
977  size = 1024;
978  fd = (int *) palloc(size * sizeof(int));
979 
980 #ifdef HAVE_GETRLIMIT
981  getrlimit_status = getrlimit(RLIMIT_NOFILE, &rlim);
982  if (getrlimit_status != 0)
983  ereport(WARNING, (errmsg("getrlimit failed: %m")));
984 #endif /* HAVE_GETRLIMIT */
985 
986  /* dup until failure or probe limit reached */
987  for (;;)
988  {
989  int thisfd;
990 
991 #ifdef HAVE_GETRLIMIT
992 
993  /*
994  * don't go beyond RLIMIT_NOFILE; causes irritating kernel logs on
995  * some platforms
996  */
997  if (getrlimit_status == 0 && highestfd >= rlim.rlim_cur - 1)
998  break;
999 #endif
1000 
1001  thisfd = dup(2);
1002  if (thisfd < 0)
1003  {
1004  /* Expect EMFILE or ENFILE, else it's fishy */
1005  if (errno != EMFILE && errno != ENFILE)
1006  elog(WARNING, "duplicating stderr file descriptor failed after %d successes: %m", used);
1007  break;
1008  }
1009 
1010  if (used >= size)
1011  {
1012  size *= 2;
1013  fd = (int *) repalloc(fd, size * sizeof(int));
1014  }
1015  fd[used++] = thisfd;
1016 
1017  if (highestfd < thisfd)
1018  highestfd = thisfd;
1019 
1020  if (used >= max_to_probe)
1021  break;
1022  }
1023 
1024  /* release the files we opened */
1025  for (j = 0; j < used; j++)
1026  close(fd[j]);
1027 
1028  pfree(fd);
1029 
1030  /*
1031  * Return results. usable_fds is just the number of successful dups. We
1032  * assume that the system limit is highestfd+1 (remember 0 is a legal FD
1033  * number) and so already_open is highestfd+1 - usable_fds.
1034  */
1035  *usable_fds = used;
1036  *already_open = highestfd + 1 - used;
1037 }
int j
Definition: isn.c:74
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1540
void * palloc(Size size)
Definition: mcxt.c:1316
static pg_noinline void Size size
Definition: slab.c:607

References close, elog, ereport, errmsg(), fd(), j, palloc(), pfree(), repalloc(), size, and WARNING.

Referenced by set_max_safe_fds().

◆ data_sync_elevel()

◆ datadir_fsync_fname()

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

Definition at line 3759 of file fd.c.

3760 {
3761  ereport_startup_progress("syncing data directory (fsync), elapsed time: %ld.%02d s, current path: %s",
3762  fname);
3763 
3764  /*
3765  * We want to silently ignoring errors about unreadable files. Pass that
3766  * desire on to fsync_fname_ext().
3767  */
3768  fsync_fname_ext(fname, isdir, true, elevel);
3769 }
int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3797
#define ereport_startup_progress(msg,...)
Definition: startup.h:18

References ereport_startup_progress, and fsync_fname_ext().

Referenced by SyncDataDirectory().

◆ Delete()

static void Delete ( File  file)
static

Definition at line 1268 of file fd.c.

1269 {
1270  Vfd *vfdP;
1271 
1272  Assert(file != 0);
1273 
1274  DO_DB(elog(LOG, "Delete %d (%s)",
1275  file, VfdCache[file].fileName));
1276  DO_DB(_dump_lru());
1277 
1278  vfdP = &VfdCache[file];
1279 
1282 
1283  DO_DB(_dump_lru());
1284 }
File lruLessRecently
Definition: fd.c:203
File lruMoreRecently
Definition: fd.c:202

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

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

◆ durable_rename()

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

Definition at line 782 of file fd.c.

783 {
784  int fd;
785 
786  /*
787  * First fsync the old and target path (if it exists), to ensure that they
788  * are properly persistent on disk. Syncing the target file is not
789  * strictly necessary, but it makes it easier to reason about crashes;
790  * because it's then guaranteed that either source or target file exists
791  * after a crash.
792  */
793  if (fsync_fname_ext(oldfile, false, false, elevel) != 0)
794  return -1;
795 
796  fd = OpenTransientFile(newfile, PG_BINARY | O_RDWR);
797  if (fd < 0)
798  {
799  if (errno != ENOENT)
800  {
801  ereport(elevel,
803  errmsg("could not open file \"%s\": %m", newfile)));
804  return -1;
805  }
806  }
807  else
808  {
809  if (pg_fsync(fd) != 0)
810  {
811  int save_errno;
812 
813  /* close file upon error, might not be in transaction context */
814  save_errno = errno;
816  errno = save_errno;
817 
818  ereport(elevel,
820  errmsg("could not fsync file \"%s\": %m", newfile)));
821  return -1;
822  }
823 
824  if (CloseTransientFile(fd) != 0)
825  {
826  ereport(elevel,
828  errmsg("could not close file \"%s\": %m", newfile)));
829  return -1;
830  }
831  }
832 
833  /* Time to do the real deal... */
834  if (rename(oldfile, newfile) < 0)
835  {
836  ereport(elevel,
838  errmsg("could not rename file \"%s\" to \"%s\": %m",
839  oldfile, newfile)));
840  return -1;
841  }
842 
843  /*
844  * To guarantee renaming the file is persistent, fsync the file with its
845  * new name, and its containing directory.
846  */
847  if (fsync_fname_ext(newfile, false, false, elevel) != 0)
848  return -1;
849 
850  if (fsync_parent_path(newfile, elevel) != 0)
851  return -1;
852 
853  return 0;
854 }
#define PG_BINARY
Definition: c.h:1273
int errcode_for_file_access(void)
Definition: elog.c:882
int CloseTransientFile(int fd)
Definition: fd.c:2809
int pg_fsync(int fd)
Definition: fd.c:386
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3873
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2633

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

Referenced by AlterSystemSetConfigFile(), apw_dump_now(), BaseBackup(), basic_archive_file(), bbsink_server_end_manifest(), CheckPointReplicationOrigin(), CleanupAfterArchiveRecovery(), dir_close(), InitWalRecovery(), InstallXLogFileSegment(), KeepFileRestoredFromArchive(), pgss_shmem_shutdown(), StartupXLOG(), SummarizeWAL(), write_relmap_file(), writeTimeLineHistory(), writeTimeLineHistoryFile(), and XLogArchiveForceDone().

◆ durable_unlink()

int durable_unlink ( const char *  fname,
int  elevel 
)

Definition at line 872 of file fd.c.

873 {
874  if (unlink(fname) < 0)
875  {
876  ereport(elevel,
878  errmsg("could not remove file \"%s\": %m",
879  fname)));
880  return -1;
881  }
882 
883  /*
884  * To guarantee that the removal of the file is persistent, fsync its
885  * parent directory.
886  */
887  if (fsync_parent_path(fname, elevel) != 0)
888  return -1;
889 
890  return 0;
891 }

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

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

◆ FileAccess()

static int FileAccess ( File  file)
static

Definition at line 1492 of file fd.c.

1493 {
1494  int returnValue;
1495 
1496  DO_DB(elog(LOG, "FileAccess %d (%s)",
1497  file, VfdCache[file].fileName));
1498 
1499  /*
1500  * Is the file open? If not, open it and put it at the head of the LRU
1501  * ring (possibly closing the least recently used file to get an FD).
1502  */
1503 
1504  if (FileIsNotOpen(file))
1505  {
1506  returnValue = LruInsert(file);
1507  if (returnValue != 0)
1508  return returnValue;
1509  }
1510  else if (VfdCache[0].lruLessRecently != file)
1511  {
1512  /*
1513  * We now know that the file is open and that it is not the last one
1514  * accessed, so we need to move it to the head of the Lru ring.
1515  */
1516 
1517  Delete(file);
1518  Insert(file);
1519  }
1520 
1521  return 0;
1522 }
static void Delete(File file)
Definition: fd.c:1268
static void Insert(File file)
Definition: fd.c:1313
static int LruInsert(File file)
Definition: fd.c:1335

References Delete(), DO_DB, elog, FileIsNotOpen, Insert(), LOG, LruInsert(), and VfdCache.

Referenced by FileFallocate(), FilePrefetch(), FileReadV(), FileSize(), FileSync(), FileTruncate(), FileWriteback(), FileWriteV(), and FileZero().

◆ FileClose()

void FileClose ( File  file)

Definition at line 1978 of file fd.c.

1979 {
1980  Vfd *vfdP;
1981 
1982  Assert(FileIsValid(file));
1983 
1984  DO_DB(elog(LOG, "FileClose: %d (%s)",
1985  file, VfdCache[file].fileName));
1986 
1987  vfdP = &VfdCache[file];
1988 
1989  if (!FileIsNotOpen(file))
1990  {
1991  /* close the file */
1992  if (close(vfdP->fd) != 0)
1993  {
1994  /*
1995  * We may need to panic on failure to close non-temporary files;
1996  * see LruDelete.
1997  */
1999  "could not close file \"%s\": %m", vfdP->fileName);
2000  }
2001 
2002  --nfile;
2003  vfdP->fd = VFD_CLOSED;
2004 
2005  /* remove the file from the lru ring */
2006  Delete(file);
2007  }
2008 
2009  if (vfdP->fdstate & FD_TEMP_FILE_LIMIT)
2010  {
2011  /* Subtract its size from current usage (do first in case of error) */
2012  temporary_files_size -= vfdP->fileSize;
2013  vfdP->fileSize = 0;
2014  }
2015 
2016  /*
2017  * Delete the file if it was temporary, and make a log entry if wanted
2018  */
2019  if (vfdP->fdstate & FD_DELETE_AT_CLOSE)
2020  {
2021  struct stat filestats;
2022  int stat_errno;
2023 
2024  /*
2025  * If we get an error, as could happen within the ereport/elog calls,
2026  * we'll come right back here during transaction abort. Reset the
2027  * flag to ensure that we can't get into an infinite loop. This code
2028  * is arranged to ensure that the worst-case consequence is failing to
2029  * emit log message(s), not failing to attempt the unlink.
2030  */
2031  vfdP->fdstate &= ~FD_DELETE_AT_CLOSE;
2032 
2033 
2034  /* first try the stat() */
2035  if (stat(vfdP->fileName, &filestats))
2036  stat_errno = errno;
2037  else
2038  stat_errno = 0;
2039 
2040  /* in any case do the unlink */
2041  if (unlink(vfdP->fileName))
2042  ereport(LOG,
2044  errmsg("could not delete file \"%s\": %m", vfdP->fileName)));
2045 
2046  /* and last report the stat results */
2047  if (stat_errno == 0)
2048  ReportTemporaryFileUsage(vfdP->fileName, filestats.st_size);
2049  else
2050  {
2051  errno = stat_errno;
2052  ereport(LOG,
2054  errmsg("could not stat file \"%s\": %m", vfdP->fileName)));
2055  }
2056  }
2057 
2058  /* Unregister it from the resource owner */
2059  if (vfdP->resowner)
2060  ResourceOwnerForgetFile(vfdP->resowner, file);
2061 
2062  /*
2063  * Return the Vfd slot to the free list
2064  */
2065  FreeVfd(file);
2066 }
static void ResourceOwnerForgetFile(ResourceOwner owner, File file)
Definition: fd.c:377
#define FileIsValid(file)
Definition: fd.c:186
static int nfile
Definition: fd.c:222
static void FreeVfd(File file)
Definition: fd.c:1472
#define FD_TEMP_FILE_LIMIT
Definition: fd.c:194
int data_sync_elevel(int elevel)
Definition: fd.c:3936
static void ReportTemporaryFileUsage(const char *path, off_t size)
Definition: fd.c:1528
static uint64 temporary_files_size
Definition: fd.c:236
char * fileName
Definition: fd.c:205
ResourceOwner resowner
Definition: fd.c:200
off_t fileSize
Definition: fd.c:204
#define stat
Definition: win32_port.h:284

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, VFD_CLOSED, and VfdCache.

Referenced by bbsink_server_end_archive(), bbsink_server_end_manifest(), BufFileClose(), BufFileTruncateFileSet(), CleanupTempFiles(), logical_end_heap_rewrite(), mdclose(), mdimmedsync(), mdregistersync(), mdsyncfiletag(), mdtruncate(), pg_wal_summary_contents(), PrepareForIncrementalBackup(), ReorderBufferIterTXNFinish(), ReorderBufferRestoreChanges(), ResOwnerReleaseFile(), and SummarizeWAL().

◆ FileFallocate()

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

Definition at line 2369 of file fd.c.

2370 {
2371 #ifdef HAVE_POSIX_FALLOCATE
2372  int returnCode;
2373 
2374  Assert(FileIsValid(file));
2375 
2376  DO_DB(elog(LOG, "FileFallocate: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
2377  file, VfdCache[file].fileName,
2378  (int64) offset, (int64) amount));
2379 
2380  returnCode = FileAccess(file);
2381  if (returnCode < 0)
2382  return -1;
2383 
2384 retry:
2385  pgstat_report_wait_start(wait_event_info);
2386  returnCode = posix_fallocate(VfdCache[file].fd, offset, amount);
2388 
2389  if (returnCode == 0)
2390  return 0;
2391  else if (returnCode == EINTR)
2392  goto retry;
2393 
2394  /* for compatibility with %m printing etc */
2395  errno = returnCode;
2396 
2397  /*
2398  * Return in cases of a "real" failure, if fallocate is not supported,
2399  * fall through to the FileZero() backed implementation.
2400  */
2401  if (returnCode != EINVAL && returnCode != EOPNOTSUPP)
2402  return -1;
2403 #endif
2404 
2405  return FileZero(file, offset, amount, wait_event_info);
2406 }
#define INT64_FORMAT
Definition: c.h:548
static int FileAccess(File file)
Definition: fd.c:1492
int FileZero(File file, off_t offset, off_t amount, uint32 wait_event_info)
Definition: fd.c:2324
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:88
static void pgstat_report_wait_end(void)
Definition: wait_event.h:104
#define EINTR
Definition: win32_port.h:374
#define EOPNOTSUPP
Definition: win32_port.h:398

References Assert, DO_DB, EINTR, elog, EOPNOTSUPP, fd(), FileAccess(), FileIsValid, FileZero(), INT64_FORMAT, LOG, pgstat_report_wait_end(), pgstat_report_wait_start(), and VfdCache.

Referenced by mdzeroextend().

◆ FileGetRawDesc()

int FileGetRawDesc ( File  file)

Definition at line 2477 of file fd.c.

2478 {
2479  Assert(FileIsValid(file));
2480  return VfdCache[file].fd;
2481 }

References Assert, vfd::fd, FileIsValid, and VfdCache.

◆ FileGetRawFlags()

int FileGetRawFlags ( File  file)

Definition at line 2487 of file fd.c.

2488 {
2489  Assert(FileIsValid(file));
2490  return VfdCache[file].fileFlags;
2491 }
int fileFlags
Definition: fd.c:207

References Assert, vfd::fileFlags, FileIsValid, and VfdCache.

◆ FileGetRawMode()

mode_t FileGetRawMode ( File  file)

Definition at line 2497 of file fd.c.

2498 {
2499  Assert(FileIsValid(file));
2500  return VfdCache[file].fileMode;
2501 }
mode_t fileMode
Definition: fd.c:208

References Assert, FileIsValid, vfd::fileMode, and VfdCache.

◆ FilePathName()

◆ FilePrefetch()

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

Definition at line 2078 of file fd.c.

2079 {
2080 #if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
2081  int returnCode;
2082 
2083  Assert(FileIsValid(file));
2084 
2085  DO_DB(elog(LOG, "FilePrefetch: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
2086  file, VfdCache[file].fileName,
2087  (int64) offset, (int64) amount));
2088 
2089  returnCode = FileAccess(file);
2090  if (returnCode < 0)
2091  return returnCode;
2092 
2093 retry:
2094  pgstat_report_wait_start(wait_event_info);
2095  returnCode = posix_fadvise(VfdCache[file].fd, offset, amount,
2096  POSIX_FADV_WILLNEED);
2098 
2099  if (returnCode == EINTR)
2100  goto retry;
2101 
2102  return returnCode;
2103 #else
2104  Assert(FileIsValid(file));
2105  return 0;
2106 #endif
2107 }

References Assert, DO_DB, EINTR, elog, fd(), FileAccess(), FileIsValid, INT64_FORMAT, LOG, pgstat_report_wait_end(), pgstat_report_wait_start(), and VfdCache.

Referenced by mdprefetch().

◆ FileReadV()

ssize_t FileReadV ( File  file,
const struct iovec *  iov,
int  iovcnt,
off_t  offset,
uint32  wait_event_info 
)

Definition at line 2136 of file fd.c.

2138 {
2139  ssize_t returnCode;
2140  Vfd *vfdP;
2141 
2142  Assert(FileIsValid(file));
2143 
2144  DO_DB(elog(LOG, "FileReadV: %d (%s) " INT64_FORMAT " %d",
2145  file, VfdCache[file].fileName,
2146  (int64) offset,
2147  iovcnt));
2148 
2149  returnCode = FileAccess(file);
2150  if (returnCode < 0)
2151  return returnCode;
2152 
2153  vfdP = &VfdCache[file];
2154 
2155 retry:
2156  pgstat_report_wait_start(wait_event_info);
2157  returnCode = pg_preadv(vfdP->fd, iov, iovcnt, offset);
2159 
2160  if (returnCode < 0)
2161  {
2162  /*
2163  * Windows may run out of kernel buffers and return "Insufficient
2164  * system resources" error. Wait a bit and retry to solve it.
2165  *
2166  * It is rumored that EINTR is also possible on some Unix filesystems,
2167  * in which case immediate retry is indicated.
2168  */
2169 #ifdef WIN32
2170  DWORD error = GetLastError();
2171 
2172  switch (error)
2173  {
2174  case ERROR_NO_SYSTEM_RESOURCES:
2175  pg_usleep(1000L);
2176  errno = EINTR;
2177  break;
2178  default:
2179  _dosmaperr(error);
2180  break;
2181  }
2182 #endif
2183  /* OK to retry if interrupted */
2184  if (errno == EINTR)
2185  goto retry;
2186  }
2187 
2188  return returnCode;
2189 }
static ssize_t pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
Definition: pg_iovec.h:44
void pg_usleep(long microsec)
Definition: signal.c:53
static void error(void)
Definition: sql-dyntest.c:147
void _dosmaperr(unsigned long)
Definition: win32error.c:177

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

Referenced by FileRead(), and mdreadv().

◆ FileSize()

off_t FileSize ( File  file)

Definition at line 2409 of file fd.c.

2410 {
2411  Assert(FileIsValid(file));
2412 
2413  DO_DB(elog(LOG, "FileSize %d (%s)",
2414  file, VfdCache[file].fileName));
2415 
2416  if (FileIsNotOpen(file))
2417  {
2418  if (FileAccess(file) < 0)
2419  return (off_t) -1;
2420  }
2421 
2422  return lseek(VfdCache[file].fd, 0, SEEK_END);
2423 }

References Assert, DO_DB, elog, fd(), FileAccess(), FileIsNotOpen, FileIsValid, LOG, and VfdCache.

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

◆ FileSync()

int FileSync ( File  file,
uint32  wait_event_info 
)

Definition at line 2297 of file fd.c.

2298 {
2299  int returnCode;
2300 
2301  Assert(FileIsValid(file));
2302 
2303  DO_DB(elog(LOG, "FileSync: %d (%s)",
2304  file, VfdCache[file].fileName));
2305 
2306  returnCode = FileAccess(file);
2307  if (returnCode < 0)
2308  return returnCode;
2309 
2310  pgstat_report_wait_start(wait_event_info);
2311  returnCode = pg_fsync(VfdCache[file].fd);
2313 
2314  return returnCode;
2315 }

References Assert, DO_DB, elog, fd(), FileAccess(), FileIsValid, LOG, pg_fsync(), pgstat_report_wait_end(), pgstat_report_wait_start(), and VfdCache.

Referenced by bbsink_server_end_archive(), logical_end_heap_rewrite(), mdimmedsync(), mdsyncfiletag(), and register_dirty_segment().

◆ FileTruncate()

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

Definition at line 2426 of file fd.c.

2427 {
2428  int returnCode;
2429 
2430  Assert(FileIsValid(file));
2431 
2432  DO_DB(elog(LOG, "FileTruncate %d (%s)",
2433  file, VfdCache[file].fileName));
2434 
2435  returnCode = FileAccess(file);
2436  if (returnCode < 0)
2437  return returnCode;
2438 
2439  pgstat_report_wait_start(wait_event_info);
2440  returnCode = pg_ftruncate(VfdCache[file].fd, offset);
2442 
2443  if (returnCode == 0 && VfdCache[file].fileSize > offset)
2444  {
2445  /* adjust our state for truncation of a temp file */
2446  Assert(VfdCache[file].fdstate & FD_TEMP_FILE_LIMIT);
2447  temporary_files_size -= VfdCache[file].fileSize - offset;
2448  VfdCache[file].fileSize = offset;
2449  }
2450 
2451  return returnCode;
2452 }
static int pg_ftruncate(int fd, off_t length)
Definition: fd.c:703

References Assert, DO_DB, elog, fd(), FD_TEMP_FILE_LIMIT, FileAccess(), FileIsValid, vfd::fileSize, LOG, pg_ftruncate(), pgstat_report_wait_end(), pgstat_report_wait_start(), temporary_files_size, and VfdCache.

Referenced by BufFileTruncateFileSet(), and mdtruncate().

◆ FileWriteback()

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

Definition at line 2110 of file fd.c.

2111 {
2112  int returnCode;
2113 
2114  Assert(FileIsValid(file));
2115 
2116  DO_DB(elog(LOG, "FileWriteback: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
2117  file, VfdCache[file].fileName,
2118  (int64) offset, (int64) nbytes));
2119 
2120  if (nbytes <= 0)
2121  return;
2122 
2123  if (VfdCache[file].fileFlags & PG_O_DIRECT)
2124  return;
2125 
2126  returnCode = FileAccess(file);
2127  if (returnCode < 0)
2128  return;
2129 
2130  pgstat_report_wait_start(wait_event_info);
2131  pg_flush_data(VfdCache[file].fd, offset, nbytes);
2133 }
void pg_flush_data(int fd, off_t offset, off_t nbytes)
Definition: fd.c:525

References Assert, DO_DB, elog, fd(), FileAccess(), FileIsValid, INT64_FORMAT, LOG, pg_flush_data(), PG_O_DIRECT, pgstat_report_wait_end(), pgstat_report_wait_start(), and VfdCache.

Referenced by mdwriteback().

◆ FileWriteV()

ssize_t FileWriteV ( File  file,
const struct iovec *  iov,
int  iovcnt,
off_t  offset,
uint32  wait_event_info 
)

Definition at line 2192 of file fd.c.

2194 {
2195  ssize_t returnCode;
2196  Vfd *vfdP;
2197 
2198  Assert(FileIsValid(file));
2199 
2200  DO_DB(elog(LOG, "FileWriteV: %d (%s) " INT64_FORMAT " %d",
2201  file, VfdCache[file].fileName,
2202  (int64) offset,
2203  iovcnt));
2204 
2205  returnCode = FileAccess(file);
2206  if (returnCode < 0)
2207  return returnCode;
2208 
2209  vfdP = &VfdCache[file];
2210 
2211  /*
2212  * If enforcing temp_file_limit and it's a temp file, check to see if the
2213  * write would overrun temp_file_limit, and throw error if so. Note: it's
2214  * really a modularity violation to throw error here; we should set errno
2215  * and return -1. However, there's no way to report a suitable error
2216  * message if we do that. All current callers would just throw error
2217  * immediately anyway, so this is safe at present.
2218  */
2219  if (temp_file_limit >= 0 && (vfdP->fdstate & FD_TEMP_FILE_LIMIT))
2220  {
2221  off_t past_write = offset;
2222 
2223  for (int i = 0; i < iovcnt; ++i)
2224  past_write += iov[i].iov_len;
2225 
2226  if (past_write > vfdP->fileSize)
2227  {
2228  uint64 newTotal = temporary_files_size;
2229 
2230  newTotal += past_write - vfdP->fileSize;
2231  if (newTotal > (uint64) temp_file_limit * (uint64) 1024)
2232  ereport(ERROR,
2233  (errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED),
2234  errmsg("temporary file size exceeds temp_file_limit (%dkB)",
2235  temp_file_limit)));
2236  }
2237  }
2238 
2239 retry:
2240  pgstat_report_wait_start(wait_event_info);
2241  returnCode = pg_pwritev(vfdP->fd, iov, iovcnt, offset);
2243 
2244  if (returnCode >= 0)
2245  {
2246  /*
2247  * Some callers expect short writes to set errno, and traditionally we
2248  * have assumed that they imply disk space shortage. We don't want to
2249  * waste CPU cycles adding up the total size here, so we'll just set
2250  * it for all successful writes in case such a caller determines that
2251  * the write was short and ereports "%m".
2252  */
2253  errno = ENOSPC;
2254 
2255  /*
2256  * Maintain fileSize and temporary_files_size if it's a temp file.
2257  */
2258  if (vfdP->fdstate & FD_TEMP_FILE_LIMIT)
2259  {
2260  off_t past_write = offset + returnCode;
2261 
2262  if (past_write > vfdP->fileSize)
2263  {
2264  temporary_files_size += past_write - vfdP->fileSize;
2265  vfdP->fileSize = past_write;
2266  }
2267  }
2268  }
2269  else
2270  {
2271  /*
2272  * See comments in FileReadV()
2273  */
2274 #ifdef WIN32
2275  DWORD error = GetLastError();
2276 
2277  switch (error)
2278  {
2279  case ERROR_NO_SYSTEM_RESOURCES:
2280  pg_usleep(1000L);
2281  errno = EINTR;
2282  break;
2283  default:
2284  _dosmaperr(error);
2285  break;
2286  }
2287 #endif
2288  /* OK to retry if interrupted */
2289  if (errno == EINTR)
2290  goto retry;
2291  }
2292 
2293  return returnCode;
2294 }
int temp_file_limit
Definition: guc_tables.c:536
static ssize_t pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
Definition: pg_iovec.h:83

References _dosmaperr(), Assert, DO_DB, EINTR, elog, ereport, errcode(), errmsg(), ERROR, error(), vfd::fd, FD_TEMP_FILE_LIMIT, vfd::fdstate, FileAccess(), FileIsValid, vfd::fileSize, i, INT64_FORMAT, LOG, pg_pwritev(), pg_usleep(), pgstat_report_wait_end(), pgstat_report_wait_start(), temp_file_limit, temporary_files_size, and VfdCache.

Referenced by FileWrite(), and mdwritev().

◆ FileZero()

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

Definition at line 2324 of file fd.c.

2325 {
2326  int returnCode;
2327  ssize_t written;
2328 
2329  Assert(FileIsValid(file));
2330 
2331  DO_DB(elog(LOG, "FileZero: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
2332  file, VfdCache[file].fileName,
2333  (int64) offset, (int64) amount));
2334 
2335  returnCode = FileAccess(file);
2336  if (returnCode < 0)
2337  return returnCode;
2338 
2339  pgstat_report_wait_start(wait_event_info);
2340  written = pg_pwrite_zeros(VfdCache[file].fd, amount, offset);
2342 
2343  if (written < 0)
2344  return -1;
2345  else if (written != amount)
2346  {
2347  /* if errno is unset, assume problem is no disk space */
2348  if (errno == 0)
2349  errno = ENOSPC;
2350  return -1;
2351  }
2352 
2353  return 0;
2354 }
ssize_t pg_pwrite_zeros(int fd, size_t size, off_t offset)
Definition: file_utils.c:687

References Assert, DO_DB, elog, fd(), FileAccess(), FileIsValid, INT64_FORMAT, LOG, pg_pwrite_zeros(), pgstat_report_wait_end(), pgstat_report_wait_start(), and VfdCache.

Referenced by FileFallocate(), and mdzeroextend().

◆ FreeDesc()

static int FreeDesc ( AllocateDesc desc)
static

Definition at line 2742 of file fd.c.

2743 {
2744  int result;
2745 
2746  /* Close the underlying object */
2747  switch (desc->kind)
2748  {
2749  case AllocateDescFile:
2750  result = fclose(desc->desc.file);
2751  break;
2752  case AllocateDescPipe:
2753  result = pclose(desc->desc.file);
2754  break;
2755  case AllocateDescDir:
2756  result = closedir(desc->desc.dir);
2757  break;
2758  case AllocateDescRawFD:
2759  result = close(desc->desc.fd);
2760  break;
2761  default:
2762  elog(ERROR, "AllocateDesc kind not recognized");
2763  result = 0; /* keep compiler quiet */
2764  break;
2765  }
2766 
2767  /* Compact storage in the allocatedDescs array */
2770 
2771  return result;
2772 }
int closedir(DIR *)
Definition: dirent.c:127

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

◆ FreeDir()

int FreeDir ( DIR dir)

Definition at line 2961 of file fd.c.

2962 {
2963  int i;
2964 
2965  /* Nothing to do if AllocateDir failed */
2966  if (dir == NULL)
2967  return 0;
2968 
2969  DO_DB(elog(LOG, "FreeDir: Allocated %d", numAllocatedDescs));
2970 
2971  /* Remove dir from list of allocated dirs, if it's present */
2972  for (i = numAllocatedDescs; --i >= 0;)
2973  {
2974  AllocateDesc *desc = &allocatedDescs[i];
2975 
2976  if (desc->kind == AllocateDescDir && desc->desc.dir == dir)
2977  return FreeDesc(desc);
2978  }
2979 
2980  /* Only get here if someone passes us a dir not in allocatedDescs */
2981  elog(WARNING, "dir passed to FreeDir was not obtained from AllocateDir");
2982 
2983  return closedir(dir);
2984 }

References allocatedDescs, 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_backup_start(), dsm_cleanup_for_mmap(), extension_file_exists(), get_ext_ver_list(), GetConfFilesInDir(), getInstallationPaths(), GetWalSummaries(), movedb(), ParseTzFile(), perform_base_backup(), pg_available_extension_versions(), pg_available_extensions(), pg_ls_dir(), pg_ls_dir_files(), pg_tablespace_databases(), pg_tzenumerate_end(), pg_tzenumerate_next(), pgarch_readyXlog(), RelationCacheInitFileRemove(), RelationCacheInitFileRemoveInDir(), RemoveNonParentXlogFiles(), RemoveOldXlogFiles(), RemovePgTempFiles(), RemovePgTempFilesInDir(), RemovePgTempRelationFiles(), RemovePgTempRelationFilesInDbspace(), RemoveTempXlogFiles(), ReorderBufferCleanupSerializedTXNs(), ResetUnloggedRelations(), ResetUnloggedRelationsInDbspaceDir(), ResetUnloggedRelationsInTablespaceDir(), restoreTwoPhaseData(), scan_directory_ci(), sendDir(), SlruScanDirectory(), StartupReorderBuffer(), StartupReplicationSlots(), SyncDataDirectory(), UpdateLogicalMappings(), walkdir(), and XLogGetOldestSegno().

◆ FreeFile()

int FreeFile ( FILE *  file)

Definition at line 2781 of file fd.c.

2782 {
2783  int i;
2784 
2785  DO_DB(elog(LOG, "FreeFile: Allocated %d", numAllocatedDescs));
2786 
2787  /* Remove file from list of allocated files, if it's present */
2788  for (i = numAllocatedDescs; --i >= 0;)
2789  {
2790  AllocateDesc *desc = &allocatedDescs[i];
2791 
2792  if (desc->kind == AllocateDescFile && desc->desc.file == file)
2793  return FreeDesc(desc);
2794  }
2795 
2796  /* Only get here if someone passes us a file not in allocatedDescs */
2797  elog(WARNING, "file passed to FreeFile was not obtained from AllocateFile");
2798 
2799  return fclose(file);
2800 }

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

Referenced by AlterSystemSetConfigFile(), apw_dump_now(), apw_load_buffers(), checkControlFile(), do_pg_backup_stop(), EndCopy(), EndCopyFrom(), entry_reset(), existsTimeLineHistory(), ExportSnapshot(), free_auth_file(), gc_qtexts(), GetHugePageSize(), ImportSnapshot(), load_dh_file(), load_relcache_init_file(), parse_extension_control_file(), ParseTzFile(), pg_current_logfile(), pg_promote(), pgss_shmem_shutdown(), pgss_shmem_startup(), pgstat_read_statsfile(), pgstat_write_statsfile(), read_backup_label(), read_binary_file(), read_tablespace_map(), read_whole_file(), readTimeLineHistory(), tsearch_readline_end(), ValidatePgVersion(), write_relcache_init_file(), XLogArchiveForceDone(), and XLogArchiveNotify().

◆ FreeVfd()

static void FreeVfd ( File  file)
static

Definition at line 1472 of file fd.c.

1473 {
1474  Vfd *vfdP = &VfdCache[file];
1475 
1476  DO_DB(elog(LOG, "FreeVfd: %d (%s)",
1477  file, vfdP->fileName ? vfdP->fileName : ""));
1478 
1479  if (vfdP->fileName != NULL)
1480  {
1481  free(vfdP->fileName);
1482  vfdP->fileName = NULL;
1483  }
1484  vfdP->fdstate = 0x0;
1485 
1486  vfdP->nextFree = VfdCache[0].nextFree;
1487  VfdCache[0].nextFree = file;
1488 }
#define free(a)
Definition: header.h:65

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

Referenced by FileClose(), and PathNameOpenFilePerm().

◆ fsync_fname()

◆ fsync_fname_ext()

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

Definition at line 3797 of file fd.c.

3798 {
3799  int fd;
3800  int flags;
3801  int returncode;
3802 
3803  /*
3804  * Some OSs require directories to be opened read-only whereas other
3805  * systems don't allow us to fsync files opened read-only; so we need both
3806  * cases here. Using O_RDWR will cause us to fail to fsync files that are
3807  * not writable by our userid, but we assume that's OK.
3808  */
3809  flags = PG_BINARY;
3810  if (!isdir)
3811  flags |= O_RDWR;
3812  else
3813  flags |= O_RDONLY;
3814 
3815  fd = OpenTransientFile(fname, flags);
3816 
3817  /*
3818  * Some OSs don't allow us to open directories at all (Windows returns
3819  * EACCES), just ignore the error in that case. If desired also silently
3820  * ignoring errors about unreadable files. Log others.
3821  */
3822  if (fd < 0 && isdir && (errno == EISDIR || errno == EACCES))
3823  return 0;
3824  else if (fd < 0 && ignore_perm && errno == EACCES)
3825  return 0;
3826  else if (fd < 0)
3827  {
3828  ereport(elevel,
3830  errmsg("could not open file \"%s\": %m", fname)));
3831  return -1;
3832  }
3833 
3834  returncode = pg_fsync(fd);
3835 
3836  /*
3837  * Some OSes don't allow us to fsync directories at all, so we can ignore
3838  * those errors. Anything else needs to be logged.
3839  */
3840  if (returncode != 0 && !(isdir && (errno == EBADF || errno == EINVAL)))
3841  {
3842  int save_errno;
3843 
3844  /* close file upon error, might not be in transaction context */
3845  save_errno = errno;
3846  (void) CloseTransientFile(fd);
3847  errno = save_errno;
3848 
3849  ereport(elevel,
3851  errmsg("could not fsync file \"%s\": %m", fname)));
3852  return -1;
3853  }
3854 
3855  if (CloseTransientFile(fd) != 0)
3856  {
3857  ereport(elevel,
3859  errmsg("could not close file \"%s\": %m", fname)));
3860  return -1;
3861  }
3862 
3863  return 0;
3864 }

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

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

◆ fsync_parent_path()

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

Definition at line 3873 of file fd.c.

3874 {
3875  char parentpath[MAXPGPATH];
3876 
3877  strlcpy(parentpath, fname, MAXPGPATH);
3878  get_parent_directory(parentpath);
3879 
3880  /*
3881  * get_parent_directory() returns an empty string if the input argument is
3882  * just a file name (see comments in path.c), so handle that as being the
3883  * current directory.
3884  */
3885  if (strlen(parentpath) == 0)
3886  strlcpy(parentpath, ".", MAXPGPATH);
3887 
3888  if (fsync_fname_ext(parentpath, true, false, elevel) != 0)
3889  return -1;
3890 
3891  return 0;
3892 }
#define MAXPGPATH
void get_parent_directory(char *path)
Definition: path.c:976
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45

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

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

◆ GetNextTempTableSpace()

Oid GetNextTempTableSpace ( void  )

Definition at line 3111 of file fd.c.

3112 {
3113  if (numTempTableSpaces > 0)
3114  {
3115  /* Advance nextTempTableSpace counter with wraparound */
3117  nextTempTableSpace = 0;
3119  }
3120  return InvalidOid;
3121 }
static int nextTempTableSpace
Definition: fd.c:290
#define InvalidOid
Definition: postgres_ext.h:36

References InvalidOid, nextTempTableSpace, numTempTableSpaces, and tempTableSpaces.

Referenced by GetDefaultTablespace(), and OpenTemporaryFile().

◆ GetTempTablespaces()

int GetTempTablespaces ( Oid tableSpaces,
int  numSpaces 
)

Definition at line 3093 of file fd.c.

3094 {
3095  int i;
3096 
3098  for (i = 0; i < numTempTableSpaces && i < numSpaces; ++i)
3099  tableSpaces[i] = tempTableSpaces[i];
3100 
3101  return i;
3102 }
bool TempTablespacesAreSet(void)
Definition: fd.c:3078

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

Referenced by FileSetInit().

◆ InitFileAccess()

void InitFileAccess ( void  )

Definition at line 903 of file fd.c.

904 {
905  Assert(SizeVfdCache == 0); /* call me only once */
906 
907  /* initialize cache header entry */
908  VfdCache = (Vfd *) malloc(sizeof(Vfd));
909  if (VfdCache == NULL)
910  ereport(FATAL,
911  (errcode(ERRCODE_OUT_OF_MEMORY),
912  errmsg("out of memory")));
913 
914  MemSet((char *) &(VfdCache[0]), 0, sizeof(Vfd));
916 
917  SizeVfdCache = 1;
918 }
#define FATAL
Definition: elog.h:41
#define malloc(a)
Definition: header.h:50

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

Referenced by BaseInit().

◆ InitTemporaryFileAccess()

void InitTemporaryFileAccess ( void  )

Definition at line 933 of file fd.c.

934 {
935  Assert(SizeVfdCache != 0); /* InitFileAccess() needs to have run */
936  Assert(!temporary_files_allowed); /* call me only once */
937 
938  /*
939  * Register before-shmem-exit hook to ensure temp files are dropped while
940  * we can still report stats.
941  */
943 
944 #ifdef USE_ASSERT_CHECKING
945  temporary_files_allowed = true;
946 #endif
947 }
static void BeforeShmemExit_Files(int code, Datum arg)
Definition: fd.c:3179
void before_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:337

References Assert, before_shmem_exit(), BeforeShmemExit_Files(), and SizeVfdCache.

Referenced by BaseInit().

◆ Insert()

static void Insert ( File  file)
static

Definition at line 1313 of file fd.c.

1314 {
1315  Vfd *vfdP;
1316 
1317  Assert(file != 0);
1318 
1319  DO_DB(elog(LOG, "Insert %d (%s)",
1320  file, VfdCache[file].fileName));
1321  DO_DB(_dump_lru());
1322 
1323  vfdP = &VfdCache[file];
1324 
1325  vfdP->lruMoreRecently = 0;
1327  VfdCache[0].lruLessRecently = file;
1329 
1330  DO_DB(_dump_lru());
1331 }

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

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

◆ looks_like_temp_rel_name()

bool looks_like_temp_rel_name ( const char *  name)

Definition at line 3449 of file fd.c.

3450 {
3451  int pos;
3452  int savepos;
3453 
3454  /* Must start with "t". */
3455  if (name[0] != 't')
3456  return false;
3457 
3458  /* Followed by a non-empty string of digits and then an underscore. */
3459  for (pos = 1; isdigit((unsigned char) name[pos]); ++pos)
3460  ;
3461  if (pos == 1 || name[pos] != '_')
3462  return false;
3463 
3464  /* Followed by another nonempty string of digits. */
3465  for (savepos = ++pos; isdigit((unsigned char) name[pos]); ++pos)
3466  ;
3467  if (savepos == pos)
3468  return false;
3469 
3470  /* We might have _forkname or .segment or both. */
3471  if (name[pos] == '_')
3472  {
3473  int forkchar = forkname_chars(&name[pos + 1], NULL);
3474 
3475  if (forkchar <= 0)
3476  return false;
3477  pos += forkchar + 1;
3478  }
3479  if (name[pos] == '.')
3480  {
3481  int segchar;
3482 
3483  for (segchar = 1; isdigit((unsigned char) name[pos + segchar]); ++segchar)
3484  ;
3485  if (segchar <= 1)
3486  return false;
3487  pos += segchar;
3488  }
3489 
3490  /* Now we should be at the end. */
3491  if (name[pos] != '\0')
3492  return false;
3493  return true;
3494 }
int forkname_chars(const char *str, ForkNumber *fork)
Definition: relpath.c:81

References forkname_chars(), and name.

Referenced by RemovePgTempRelationFilesInDbspace(), and sendDir().

◆ LruDelete()

static void LruDelete ( File  file)
static

Definition at line 1287 of file fd.c.

1288 {
1289  Vfd *vfdP;
1290 
1291  Assert(file != 0);
1292 
1293  DO_DB(elog(LOG, "LruDelete %d (%s)",
1294  file, VfdCache[file].fileName));
1295 
1296  vfdP = &VfdCache[file];
1297 
1298  /*
1299  * Close the file. We aren't expecting this to fail; if it does, better
1300  * to leak the FD than to mess up our internal state.
1301  */
1302  if (close(vfdP->fd) != 0)
1304  "could not close file \"%s\": %m", vfdP->fileName);
1305  vfdP->fd = VFD_CLOSED;
1306  --nfile;
1307 
1308  /* delete the vfd record from the LRU ring */
1309  Delete(file);
1310 }

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

Referenced by closeAllVfds(), and ReleaseLruFile().

◆ LruInsert()

static int LruInsert ( File  file)
static

Definition at line 1335 of file fd.c.

1336 {
1337  Vfd *vfdP;
1338 
1339  Assert(file != 0);
1340 
1341  DO_DB(elog(LOG, "LruInsert %d (%s)",
1342  file, VfdCache[file].fileName));
1343 
1344  vfdP = &VfdCache[file];
1345 
1346  if (FileIsNotOpen(file))
1347  {
1348  /* Close excess kernel FDs. */
1349  ReleaseLruFiles();
1350 
1351  /*
1352  * The open could still fail for lack of file descriptors, eg due to
1353  * overall system file table being full. So, be prepared to release
1354  * another FD if necessary...
1355  */
1356  vfdP->fd = BasicOpenFilePerm(vfdP->fileName, vfdP->fileFlags,
1357  vfdP->fileMode);
1358  if (vfdP->fd < 0)
1359  {
1360  DO_DB(elog(LOG, "re-open failed: %m"));
1361  return -1;
1362  }
1363  else
1364  {
1365  ++nfile;
1366  }
1367  }
1368 
1369  /*
1370  * put it at the head of the Lru ring
1371  */
1372 
1373  Insert(file);
1374 
1375  return 0;
1376 }

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

Referenced by FileAccess().

◆ MakePGDirectory()

int MakePGDirectory ( const char *  directoryName)

◆ OpenPipeStream()

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

Definition at line 2686 of file fd.c.

2687 {
2688  FILE *file;
2689  int save_errno;
2690 
2691  DO_DB(elog(LOG, "OpenPipeStream: Allocated %d (%s)",
2692  numAllocatedDescs, command));
2693 
2694  /* Can we allocate another non-virtual FD? */
2695  if (!reserveAllocatedDesc())
2696  ereport(ERROR,
2697  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2698  errmsg("exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"",
2699  maxAllocatedDescs, command)));
2700 
2701  /* Close excess kernel FDs. */
2702  ReleaseLruFiles();
2703 
2704 TryAgain:
2705  fflush(NULL);
2707  errno = 0;
2708  file = popen(command, mode);
2709  save_errno = errno;
2711  errno = save_errno;
2712  if (file != NULL)
2713  {
2715 
2716  desc->kind = AllocateDescPipe;
2717  desc->desc.file = file;
2720  return desc->desc.file;
2721  }
2722 
2723  if (errno == EMFILE || errno == ENFILE)
2724  {
2725  ereport(LOG,
2726  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2727  errmsg("out of file descriptors: %m; release and retry")));
2728  if (ReleaseLruFile())
2729  goto TryAgain;
2730  errno = save_errno;
2731  }
2732 
2733  return NULL;
2734 }
static void const char fflush(stdout)
pqsigfunc pqsignal(int signo, pqsigfunc func)
#define SIG_DFL
Definition: win32_port.h:163
#define SIGPIPE
Definition: win32_port.h:173
#define SIG_IGN
Definition: win32_port.h:165

References allocatedDescs, AllocateDescPipe, AllocateDesc::create_subid, AllocateDesc::desc, DO_DB, elog, ereport, errcode(), errmsg(), ERROR, fflush(), AllocateDesc::file, GetCurrentSubTransactionId(), AllocateDesc::kind, LOG, maxAllocatedDescs, mode, numAllocatedDescs, pqsignal(), ReleaseLruFile(), ReleaseLruFiles(), reserveAllocatedDesc(), SIG_DFL, SIG_IGN, and SIGPIPE.

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

◆ OpenTemporaryFile()

File OpenTemporaryFile ( bool  interXact)

Definition at line 1724 of file fd.c.

1725 {
1726  File file = 0;
1727 
1728  Assert(temporary_files_allowed); /* check temp file access is up */
1729 
1730  /*
1731  * Make sure the current resource owner has space for this File before we
1732  * open it, if we'll be registering it below.
1733  */
1734  if (!interXact)
1736 
1737  /*
1738  * If some temp tablespace(s) have been given to us, try to use the next
1739  * one. If a given tablespace can't be found, we silently fall back to
1740  * the database's default tablespace.
1741  *
1742  * BUT: if the temp file is slated to outlive the current transaction,
1743  * force it into the database's default tablespace, so that it will not
1744  * pose a threat to possible tablespace drop attempts.
1745  */
1746  if (numTempTableSpaces > 0 && !interXact)
1747  {
1748  Oid tblspcOid = GetNextTempTableSpace();
1749 
1750  if (OidIsValid(tblspcOid))
1751  file = OpenTemporaryFileInTablespace(tblspcOid, false);
1752  }
1753 
1754  /*
1755  * If not, or if tablespace is bad, create in database's default
1756  * tablespace. MyDatabaseTableSpace should normally be set before we get
1757  * here, but just in case it isn't, fall back to pg_default tablespace.
1758  */
1759  if (file <= 0)
1762  DEFAULTTABLESPACE_OID,
1763  true);
1764 
1765  /* Mark it for deletion at close and temporary file size limit */
1767 
1768  /* Register it with the current resource owner */
1769  if (!interXact)
1770  RegisterTemporaryFile(file);
1771 
1772  return file;
1773 }
#define OidIsValid(objectId)
Definition: c.h:775
Oid GetNextTempTableSpace(void)
Definition: fd.c:3111
static File OpenTemporaryFileInTablespace(Oid tblspcOid, bool rejectError)
Definition: fd.c:1804
static void RegisterTemporaryFile(File file)
Definition: fd.c:1547
Oid MyDatabaseTableSpace
Definition: globals.c:93
unsigned int Oid
Definition: postgres_ext.h:31
ResourceOwner CurrentResourceOwner
Definition: resowner.c:165
void ResourceOwnerEnlarge(ResourceOwner owner)
Definition: resowner.c:442

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

Referenced by BufFileCreateTemp(), and extendBufFile().

◆ OpenTemporaryFileInTablespace()

static File OpenTemporaryFileInTablespace ( Oid  tblspcOid,
bool  rejectError 
)
static

Definition at line 1804 of file fd.c.

1805 {
1806  char tempdirpath[MAXPGPATH];
1807  char tempfilepath[MAXPGPATH];
1808  File file;
1809 
1810  TempTablespacePath(tempdirpath, tblspcOid);
1811 
1812  /*
1813  * Generate a tempfile name that should be unique within the current
1814  * database instance.
1815  */
1816  snprintf(tempfilepath, sizeof(tempfilepath), "%s/%s%d.%ld",
1817  tempdirpath, PG_TEMP_FILE_PREFIX, MyProcPid, tempFileCounter++);
1818 
1819  /*
1820  * Open the file. Note: we don't use O_EXCL, in case there is an orphaned
1821  * temp file that can be reused.
1822  */
1823  file = PathNameOpenFile(tempfilepath,
1824  O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1825  if (file <= 0)
1826  {
1827  /*
1828  * We might need to create the tablespace's tempfile directory, if no
1829  * one has yet done so.
1830  *
1831  * Don't check for an error from MakePGDirectory; it could fail if
1832  * someone else just did the same thing. If it doesn't work then
1833  * we'll bomb out on the second create attempt, instead.
1834  */
1835  (void) MakePGDirectory(tempdirpath);
1836 
1837  file = PathNameOpenFile(tempfilepath,
1838  O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1839  if (file <= 0 && rejectError)
1840  elog(ERROR, "could not create temporary file \"%s\": %m",
1841  tempfilepath);
1842  }
1843 
1844  return file;
1845 }
int MakePGDirectory(const char *directoryName)
Definition: fd.c:3913
static long tempFileCounter
Definition: fd.c:280
File PathNameOpenFile(const char *fileName, int fileFlags)
Definition: fd.c:1575
void TempTablespacePath(char *path, Oid tablespace)
Definition: fd.c:1779
#define PG_TEMP_FILE_PREFIX
Definition: file_utils.h:63
int MyProcPid
Definition: globals.c:45
#define snprintf
Definition: port.h:238

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

Referenced by OpenTemporaryFile().

◆ OpenTransientFile()

◆ OpenTransientFilePerm()

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

Definition at line 2642 of file fd.c.

2643 {
2644  int fd;
2645 
2646  DO_DB(elog(LOG, "OpenTransientFile: Allocated %d (%s)",
2647  numAllocatedDescs, fileName));
2648 
2649  /* Can we allocate another non-virtual FD? */
2650  if (!reserveAllocatedDesc())
2651  ereport(ERROR,
2652  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2653  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2654  maxAllocatedDescs, fileName)));
2655 
2656  /* Close excess kernel FDs. */
2657  ReleaseLruFiles();
2658 
2659  fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
2660 
2661  if (fd >= 0)
2662  {
2664 
2665  desc->kind = AllocateDescRawFD;
2666  desc->desc.fd = fd;
2669 
2670  return fd;
2671  }
2672 
2673  return -1; /* failure */
2674 }

References allocatedDescs, AllocateDescRawFD, BasicOpenFilePerm(), AllocateDesc::create_subid, AllocateDesc::desc, DO_DB, elog, ereport, errcode(), errmsg(), ERROR, AllocateDesc::fd, fd(), GetCurrentSubTransactionId(), AllocateDesc::kind, LOG, maxAllocatedDescs, numAllocatedDescs, ReleaseLruFiles(), and reserveAllocatedDesc().

Referenced by be_lo_export(), and OpenTransientFile().

◆ PathNameCreateTemporaryDir()

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

Definition at line 1660 of file fd.c.

1661 {
1662  if (MakePGDirectory(directory) < 0)
1663  {
1664  if (errno == EEXIST)
1665  return;
1666 
1667  /*
1668  * Failed. Try to create basedir first in case it's missing. Tolerate
1669  * EEXIST to close a race against another process following the same
1670  * algorithm.
1671  */
1672  if (MakePGDirectory(basedir) < 0 && errno != EEXIST)
1673  ereport(ERROR,
1675  errmsg("cannot create temporary directory \"%s\": %m",
1676  basedir)));
1677 
1678  /* Try again. */
1679  if (MakePGDirectory(directory) < 0 && errno != EEXIST)
1680  ereport(ERROR,
1682  errmsg("cannot create temporary subdirectory \"%s\": %m",
1683  directory)));
1684  }
1685 }
static char * basedir
static const char * directory
Definition: zic.c:634

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

Referenced by FileSetCreate().

◆ PathNameCreateTemporaryFile()

File PathNameCreateTemporaryFile ( const char *  path,
bool  error_on_failure 
)

Definition at line 1861 of file fd.c.

1862 {
1863  File file;
1864 
1865  Assert(temporary_files_allowed); /* check temp file access is up */
1866 
1868 
1869  /*
1870  * Open the file. Note: we don't use O_EXCL, in case there is an orphaned
1871  * temp file that can be reused.
1872  */
1873  file = PathNameOpenFile(path, O_RDWR | O_CREAT | O_TRUNC | PG_BINARY);
1874  if (file <= 0)
1875  {
1876  if (error_on_failure)
1877  ereport(ERROR,
1879  errmsg("could not create temporary file \"%s\": %m",
1880  path)));
1881  else
1882  return file;
1883  }
1884 
1885  /* Mark it for temp_file_limit accounting. */
1887 
1888  /* Register it for automatic close. */
1889  RegisterTemporaryFile(file);
1890 
1891  return file;
1892 }

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

Referenced by FileSetCreate().

◆ PathNameDeleteTemporaryDir()

void PathNameDeleteTemporaryDir ( const char *  dirname)

Definition at line 1691 of file fd.c.

1692 {
1693  struct stat statbuf;
1694 
1695  /* Silently ignore missing directory. */
1696  if (stat(dirname, &statbuf) != 0 && errno == ENOENT)
1697  return;
1698 
1699  /*
1700  * Currently, walkdir doesn't offer a way for our passed in function to
1701  * maintain state. Perhaps it should, so that we could tell the caller
1702  * whether this operation succeeded or failed. Since this operation is
1703  * used in a cleanup path, we wouldn't actually behave differently: we'll
1704  * just log failures.
1705  */
1706  walkdir(dirname, unlink_if_exists_fname, false, LOG);
1707 }
static void unlink_if_exists_fname(const char *fname, bool isdir, int elevel)
Definition: fd.c:3772
static void walkdir(const char *path, void(*action)(const char *fname, bool isdir, int elevel), bool process_symlinks, int elevel)
Definition: fd.c:3658

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

Referenced by FileSetDeleteAll().

◆ PathNameDeleteTemporaryFile()

bool PathNameDeleteTemporaryFile ( const char *  path,
bool  error_on_failure 
)

Definition at line 1932 of file fd.c.

1933 {
1934  struct stat filestats;
1935  int stat_errno;
1936 
1937  /* Get the final size for pgstat reporting. */
1938  if (stat(path, &filestats) != 0)
1939  stat_errno = errno;
1940  else
1941  stat_errno = 0;
1942 
1943  /*
1944  * Unlike FileClose's automatic file deletion code, we tolerate
1945  * non-existence to support BufFileDeleteFileSet which doesn't know how
1946  * many segments it has to delete until it runs out.
1947  */
1948  if (stat_errno == ENOENT)
1949  return false;
1950 
1951  if (unlink(path) < 0)
1952  {
1953  if (errno != ENOENT)
1954  ereport(error_on_failure ? ERROR : LOG,
1956  errmsg("could not unlink temporary file \"%s\": %m",
1957  path)));
1958  return false;
1959  }
1960 
1961  if (stat_errno == 0)
1962  ReportTemporaryFileUsage(path, filestats.st_size);
1963  else
1964  {
1965  errno = stat_errno;
1966  ereport(LOG,
1968  errmsg("could not stat file \"%s\": %m", path)));
1969  }
1970 
1971  return true;
1972 }

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

Referenced by FileSetDelete(), and unlink_if_exists_fname().

◆ PathNameOpenFile()

File PathNameOpenFile ( const char *  fileName,
int  fileFlags 
)

◆ PathNameOpenFilePerm()

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

Definition at line 1588 of file fd.c.

1589 {
1590  char *fnamecopy;
1591  File file;
1592  Vfd *vfdP;
1593 
1594  DO_DB(elog(LOG, "PathNameOpenFilePerm: %s %x %o",
1595  fileName, fileFlags, fileMode));
1596 
1597  /*
1598  * We need a malloc'd copy of the file name; fail cleanly if no room.
1599  */
1600  fnamecopy = strdup(fileName);
1601  if (fnamecopy == NULL)
1602  ereport(ERROR,
1603  (errcode(ERRCODE_OUT_OF_MEMORY),
1604  errmsg("out of memory")));
1605 
1606  file = AllocateVfd();
1607  vfdP = &VfdCache[file];
1608 
1609  /* Close excess kernel FDs. */
1610  ReleaseLruFiles();
1611 
1612  /*
1613  * Descriptors managed by VFDs are implicitly marked O_CLOEXEC. The
1614  * client shouldn't be expected to know which kernel descriptors are
1615  * currently open, so it wouldn't make sense for them to be inherited by
1616  * executed subprograms.
1617  */
1618  fileFlags |= O_CLOEXEC;
1619 
1620  vfdP->fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
1621 
1622  if (vfdP->fd < 0)
1623  {
1624  int save_errno = errno;
1625 
1626  FreeVfd(file);
1627  free(fnamecopy);
1628  errno = save_errno;
1629  return -1;
1630  }
1631  ++nfile;
1632  DO_DB(elog(LOG, "PathNameOpenFile: success %d",
1633  vfdP->fd));
1634 
1635  vfdP->fileName = fnamecopy;
1636  /* Saved flags are adjusted to be OK for re-opening file */
1637  vfdP->fileFlags = fileFlags & ~(O_CREAT | O_TRUNC | O_EXCL);
1638  vfdP->fileMode = fileMode;
1639  vfdP->fileSize = 0;
1640  vfdP->fdstate = 0x0;
1641  vfdP->resowner = NULL;
1642 
1643  Insert(file);
1644 
1645  return file;
1646 }
static File AllocateVfd(void)
Definition: fd.c:1414

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, O_CLOEXEC, ReleaseLruFiles(), vfd::resowner, and VfdCache.

Referenced by PathNameOpenFile().

◆ PathNameOpenTemporaryFile()

File PathNameOpenTemporaryFile ( const char *  path,
int  mode 
)

Definition at line 1901 of file fd.c.

1902 {
1903  File file;
1904 
1905  Assert(temporary_files_allowed); /* check temp file access is up */
1906 
1908 
1909  file = PathNameOpenFile(path, mode | PG_BINARY);
1910 
1911  /* If no such file, then we don't raise an error. */
1912  if (file <= 0 && errno != ENOENT)
1913  ereport(ERROR,
1915  errmsg("could not open temporary file \"%s\": %m",
1916  path)));
1917 
1918  if (file > 0)
1919  {
1920  /* Register it for automatic close. */
1921  RegisterTemporaryFile(file);
1922  }
1923 
1924  return file;
1925 }

References Assert, CurrentResourceOwner, ereport, errcode_for_file_access(), errmsg(), ERROR, mode, PathNameOpenFile(), PG_BINARY, RegisterTemporaryFile(), and ResourceOwnerEnlarge().

Referenced by FileSetOpen().

◆ pg_fdatasync()

int pg_fdatasync ( int  fd)

Definition at line 480 of file fd.c.

481 {
482  int rc;
483 
484  if (!enableFsync)
485  return 0;
486 
487 retry:
488  rc = fdatasync(fd);
489 
490  if (rc == -1 && errno == EINTR)
491  goto retry;
492 
493  return rc;
494 }
int fdatasync(int fildes)
bool enableFsync
Definition: globals.c:126

References EINTR, enableFsync, fd(), and fdatasync().

Referenced by issue_xlog_fsync().

◆ pg_file_exists()

bool pg_file_exists ( const char *  name)

Definition at line 503 of file fd.c.

504 {
505  struct stat st;
506 
507  Assert(name != NULL);
508 
509  if (stat(name, &st) == 0)
510  return !S_ISDIR(st.st_mode);
511  else if (!(errno == ENOENT || errno == ENOTDIR || errno == EACCES))
512  ereport(ERROR,
514  errmsg("could not access file \"%s\": %m", name)));
515 
516  return false;
517 }
#define S_ISDIR(m)
Definition: win32_port.h:325

References Assert, ereport, errcode_for_file_access(), errmsg(), ERROR, name, S_ISDIR, stat::st_mode, and stat.

Referenced by expand_dynamic_library_name(), find_in_dynamic_libpath(), InjectionPointRun(), and provider_init().

◆ pg_flush_data()

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

Definition at line 525 of file fd.c.

526 {
527  /*
528  * Right now file flushing is primarily used to avoid making later
529  * fsync()/fdatasync() calls have less impact. Thus don't trigger flushes
530  * if fsyncs are disabled - that's a decision we might want to make
531  * configurable at some point.
532  */
533  if (!enableFsync)
534  return;
535 
536  /*
537  * We compile all alternatives that are supported on the current platform,
538  * to find portability problems more easily.
539  */
540 #if defined(HAVE_SYNC_FILE_RANGE)
541  {
542  int rc;
543  static bool not_implemented_by_kernel = false;
544 
545  if (not_implemented_by_kernel)
546  return;
547 
548 retry:
549 
550  /*
551  * sync_file_range(SYNC_FILE_RANGE_WRITE), currently linux specific,
552  * tells the OS that writeback for the specified blocks should be
553  * started, but that we don't want to wait for completion. Note that
554  * this call might block if too much dirty data exists in the range.
555  * This is the preferable method on OSs supporting it, as it works
556  * reliably when available (contrast to msync()) and doesn't flush out
557  * clean data (like FADV_DONTNEED).
558  */
559  rc = sync_file_range(fd, offset, nbytes,
560  SYNC_FILE_RANGE_WRITE);
561  if (rc != 0)
562  {
563  int elevel;
564 
565  if (rc == EINTR)
566  goto retry;
567 
568  /*
569  * For systems that don't have an implementation of
570  * sync_file_range() such as Windows WSL, generate only one
571  * warning and then suppress all further attempts by this process.
572  */
573  if (errno == ENOSYS)
574  {
575  elevel = WARNING;
576  not_implemented_by_kernel = true;
577  }
578  else
579  elevel = data_sync_elevel(WARNING);
580 
581  ereport(elevel,
583  errmsg("could not flush dirty data: %m")));
584  }
585 
586  return;
587  }
588 #endif
589 #if !defined(WIN32) && defined(MS_ASYNC)
590  {
591  void *p;
592  static int pagesize = 0;
593 
594  /*
595  * On several OSs msync(MS_ASYNC) on a mmap'ed file triggers
596  * writeback. On linux it only does so if MS_SYNC is specified, but
597  * then it does the writeback synchronously. Luckily all common linux
598  * systems have sync_file_range(). This is preferable over
599  * FADV_DONTNEED because it doesn't flush out clean data.
600  *
601  * We map the file (mmap()), tell the kernel to sync back the contents
602  * (msync()), and then remove the mapping again (munmap()).
603  */
604 
605  /* mmap() needs actual length if we want to map whole file */
606  if (offset == 0 && nbytes == 0)
607  {
608  nbytes = lseek(fd, 0, SEEK_END);
609  if (nbytes < 0)
610  {
613  errmsg("could not determine dirty data size: %m")));
614  return;
615  }
616  }
617 
618  /*
619  * Some platforms reject partial-page mmap() attempts. To deal with
620  * that, just truncate the request to a page boundary. If any extra
621  * bytes don't get flushed, well, it's only a hint anyway.
622  */
623 
624  /* fetch pagesize only once */
625  if (pagesize == 0)
626  pagesize = sysconf(_SC_PAGESIZE);
627 
628  /* align length to pagesize, dropping any fractional page */
629  if (pagesize > 0)
630  nbytes = (nbytes / pagesize) * pagesize;
631 
632  /* fractional-page request is a no-op */
633  if (nbytes <= 0)
634  return;
635 
636  /*
637  * mmap could well fail, particularly on 32-bit platforms where there
638  * may simply not be enough address space. If so, silently fall
639  * through to the next implementation.
640  */
641  if (nbytes <= (off_t) SSIZE_MAX)
642  p = mmap(NULL, nbytes, PROT_READ, MAP_SHARED, fd, offset);
643  else
644  p = MAP_FAILED;
645 
646  if (p != MAP_FAILED)
647  {
648  int rc;
649 
650  rc = msync(p, (size_t) nbytes, MS_ASYNC);
651  if (rc != 0)
652  {
655  errmsg("could not flush dirty data: %m")));
656  /* NB: need to fall through to munmap()! */
657  }
658 
659  rc = munmap(p, (size_t) nbytes);
660  if (rc != 0)
661  {
662  /* FATAL error because mapping would remain */
663  ereport(FATAL,
665  errmsg("could not munmap() while flushing data: %m")));
666  }
667 
668  return;
669  }
670  }
671 #endif
672 #if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED)
673  {
674  int rc;
675 
676  /*
677  * Signal the kernel that the passed in range should not be cached
678  * anymore. This has the, desired, side effect of writing out dirty
679  * data, and the, undesired, side effect of likely discarding useful
680  * clean cached blocks. For the latter reason this is the least
681  * preferable method.
682  */
683 
684  rc = posix_fadvise(fd, offset, nbytes, POSIX_FADV_DONTNEED);
685 
686  if (rc != 0)
687  {
688  /* don't error out, this is just a performance optimization */
691  errmsg("could not flush dirty data: %m")));
692  }
693 
694  return;
695  }
696 #endif
697 }
#define MAP_FAILED
Definition: mem.h:45

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

Referenced by copy_file(), and FileWriteback().

◆ pg_fsync()

int pg_fsync ( int  fd)

Definition at line 386 of file fd.c.

387 {
388 #if !defined(WIN32) && defined(USE_ASSERT_CHECKING)
389  struct stat st;
390 
391  /*
392  * Some operating system implementations of fsync() have requirements
393  * about the file access modes that were used when their file descriptor
394  * argument was opened, and these requirements differ depending on whether
395  * the file descriptor is for a directory.
396  *
397  * For any file descriptor that may eventually be handed to fsync(), we
398  * should have opened it with access modes that are compatible with
399  * fsync() on all supported systems, otherwise the code may not be
400  * portable, even if it runs ok on the current system.
401  *
402  * We assert here that a descriptor for a file was opened with write
403  * permissions (either O_RDWR or O_WRONLY) and for a directory without
404  * write permissions (O_RDONLY).
405  *
406  * Ignore any fstat errors and let the follow-up fsync() do its work.
407  * Doing this sanity check here counts for the case where fsync() is
408  * disabled.
409  */
410  if (fstat(fd, &st) == 0)
411  {
412  int desc_flags = fcntl(fd, F_GETFL);
413 
414  /*
415  * O_RDONLY is historically 0, so just make sure that for directories
416  * no write flags are used.
417  */
418  if (S_ISDIR(st.st_mode))
419  Assert((desc_flags & (O_RDWR | O_WRONLY)) == 0);
420  else
421  Assert((desc_flags & (O_RDWR | O_WRONLY)) != 0);
422  }
423  errno = 0;
424 #endif
425 
426  /* #if is to skip the wal_sync_method test if there's no need for it */
427 #if defined(HAVE_FSYNC_WRITETHROUGH)
429  return pg_fsync_writethrough(fd);
430  else
431 #endif
433 }
int pg_fsync_no_writethrough(int fd)
Definition: fd.c:441
int pg_fsync_writethrough(int fd)
Definition: fd.c:461
#define fstat
Definition: win32_port.h:283
int wal_sync_method
Definition: xlog.c:130
@ WAL_SYNC_METHOD_FSYNC_WRITETHROUGH
Definition: xlog.h:27

References Assert, fd(), fstat, pg_fsync_no_writethrough(), pg_fsync_writethrough(), S_ISDIR, stat::st_mode, wal_sync_method, and WAL_SYNC_METHOD_FSYNC_WRITETHROUGH.

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

◆ pg_fsync_no_writethrough()

int pg_fsync_no_writethrough ( int  fd)

Definition at line 441 of file fd.c.

442 {
443  int rc;
444 
445  if (!enableFsync)
446  return 0;
447 
448 retry:
449  rc = fsync(fd);
450 
451  if (rc == -1 && errno == EINTR)
452  goto retry;
453 
454  return rc;
455 }
#define fsync(fd)
Definition: win32_port.h:85

References EINTR, enableFsync, fd(), and fsync.

Referenced by issue_xlog_fsync(), and pg_fsync().

◆ pg_fsync_writethrough()

int pg_fsync_writethrough ( int  fd)

Definition at line 461 of file fd.c.

462 {
463  if (enableFsync)
464  {
465 #if defined(F_FULLFSYNC)
466  return (fcntl(fd, F_FULLFSYNC, 0) == -1) ? -1 : 0;
467 #else
468  errno = ENOSYS;
469  return -1;
470 #endif
471  }
472  else
473  return 0;
474 }

References enableFsync, and fd().

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

◆ pg_ftruncate()

static int pg_ftruncate ( int  fd,
off_t  length 
)
static

Definition at line 703 of file fd.c.

704 {
705  int ret;
706 
707 retry:
708  ret = ftruncate(fd, length);
709 
710  if (ret == -1 && errno == EINTR)
711  goto retry;
712 
713  return ret;
714 }
#define ftruncate(a, b)
Definition: win32_port.h:82

References EINTR, fd(), and ftruncate.

Referenced by FileTruncate(), and pg_truncate().

◆ pg_truncate()

int pg_truncate ( const char *  path,
off_t  length 
)

Definition at line 720 of file fd.c.

721 {
722  int ret;
723 #ifdef WIN32
724  int save_errno;
725  int fd;
726 
727  fd = OpenTransientFile(path, O_RDWR | PG_BINARY);
728  if (fd >= 0)
729  {
730  ret = pg_ftruncate(fd, length);
731  save_errno = errno;
733  errno = save_errno;
734  }
735  else
736  ret = -1;
737 #else
738 
739 retry:
740  ret = truncate(path, length);
741 
742  if (ret == -1 && errno == EINTR)
743  goto retry;
744 #endif
745 
746  return ret;
747 }

References CloseTransientFile(), EINTR, fd(), OpenTransientFile(), PG_BINARY, and pg_ftruncate().

Referenced by do_truncate().

◆ ReadDir()

◆ ReadDirExtended()

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

Definition at line 2924 of file fd.c.

2925 {
2926  struct dirent *dent;
2927 
2928  /* Give a generic message for AllocateDir failure, if caller didn't */
2929  if (dir == NULL)
2930  {
2931  ereport(elevel,
2933  errmsg("could not open directory \"%s\": %m",
2934  dirname)));
2935  return NULL;
2936  }
2937 
2938  errno = 0;
2939  if ((dent = readdir(dir)) != NULL)
2940  return dent;
2941 
2942  if (errno)
2943  ereport(elevel,
2945  errmsg("could not read directory \"%s\": %m",
2946  dirname)));
2947  return NULL;
2948 }
struct dirent * readdir(DIR *)
Definition: dirent.c:78
Definition: dirent.h:10

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

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

◆ RegisterTemporaryFile()

static void RegisterTemporaryFile ( File  file)
static

Definition at line 1547 of file fd.c.

1548 {
1551 
1552  /* Backup mechanism for closing at end of xact. */
1555 }
static void ResourceOwnerRememberFile(ResourceOwner owner, File file)
Definition: fd.c:372

References CurrentResourceOwner, FD_CLOSE_AT_EOXACT, vfd::fdstate, have_xact_temporary_files, ResourceOwnerRememberFile(), vfd::resowner, and VfdCache.

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

◆ ReleaseExternalFD()

◆ ReleaseLruFile()

static bool ReleaseLruFile ( void  )
static

Definition at line 1382 of file fd.c.

1383 {
1384  DO_DB(elog(LOG, "ReleaseLruFile. Opened %d", nfile));
1385 
1386  if (nfile > 0)
1387  {
1388  /*
1389  * There are opened files and so there should be at least one used vfd
1390  * in the ring.
1391  */
1392  Assert(VfdCache[0].lruMoreRecently != 0);
1393  LruDelete(VfdCache[0].lruMoreRecently);
1394  return true; /* freed a file */
1395  }
1396  return false; /* no files available to free */
1397 }

References Assert, DO_DB, elog, LOG, LruDelete(), nfile, and VfdCache.

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

◆ ReleaseLruFiles()

static void ReleaseLruFiles ( void  )
static

Definition at line 1404 of file fd.c.

1405 {
1407  {
1408  if (!ReleaseLruFile())
1409  break;
1410  }
1411 }

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

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

◆ RemovePgTempFiles()

void RemovePgTempFiles ( void  )

Definition at line 3274 of file fd.c.

3275 {
3276  char temp_path[MAXPGPATH + 10 + sizeof(TABLESPACE_VERSION_DIRECTORY) + sizeof(PG_TEMP_FILES_DIR)];
3277  DIR *spc_dir;
3278  struct dirent *spc_de;
3279 
3280  /*
3281  * First process temp files in pg_default ($PGDATA/base)
3282  */
3283  snprintf(temp_path, sizeof(temp_path), "base/%s", PG_TEMP_FILES_DIR);
3284  RemovePgTempFilesInDir(temp_path, true, false);
3285  RemovePgTempRelationFiles("base");
3286 
3287  /*
3288  * Cycle through temp directories for all non-default tablespaces.
3289  */
3290  spc_dir = AllocateDir("pg_tblspc");
3291 
3292  while ((spc_de = ReadDirExtended(spc_dir, "pg_tblspc", LOG)) != NULL)
3293  {
3294  if (strcmp(spc_de->d_name, ".") == 0 ||
3295  strcmp(spc_de->d_name, "..") == 0)
3296  continue;
3297 
3298  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s/%s",
3300  RemovePgTempFilesInDir(temp_path, true, false);
3301 
3302  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s",
3304  RemovePgTempRelationFiles(temp_path);
3305  }
3306 
3307  FreeDir(spc_dir);
3308 
3309  /*
3310  * In EXEC_BACKEND case there is a pgsql_tmp directory at the top level of
3311  * DataDir as well. However, that is *not* cleaned here because doing so
3312  * would create a race condition. It's done separately, earlier in
3313  * postmaster startup.
3314  */
3315 }
int FreeDir(DIR *dir)
Definition: fd.c:2961
static void RemovePgTempRelationFiles(const char *tsdirname)
Definition: fd.c:3393
void RemovePgTempFilesInDir(const char *tmpdirname, bool missing_ok, bool unlink_all)
Definition: fd.c:3333
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2843
#define PG_TEMP_FILES_DIR
Definition: file_utils.h:62
#define TABLESPACE_VERSION_DIRECTORY
Definition: relpath.h:33
char d_name[MAX_PATH]
Definition: dirent.h:15

References AllocateDir(), dirent::d_name, FreeDir(), LOG, MAXPGPATH, PG_TEMP_FILES_DIR, ReadDirExtended(), RemovePgTempFilesInDir(), RemovePgTempRelationFiles(), snprintf, and TABLESPACE_VERSION_DIRECTORY.

Referenced by PostmasterMain(), and PostmasterStateMachine().

◆ RemovePgTempFilesInDir()

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

Definition at line 3333 of file fd.c.

3334 {
3335  DIR *temp_dir;
3336  struct dirent *temp_de;
3337  char rm_path[MAXPGPATH * 2];
3338 
3339  temp_dir = AllocateDir(tmpdirname);
3340 
3341  if (temp_dir == NULL && errno == ENOENT && missing_ok)
3342  return;
3343 
3344  while ((temp_de = ReadDirExtended(temp_dir, tmpdirname, LOG)) != NULL)
3345  {
3346  if (strcmp(temp_de->d_name, ".") == 0 ||
3347  strcmp(temp_de->d_name, "..") == 0)
3348  continue;
3349 
3350  snprintf(rm_path, sizeof(rm_path), "%s/%s",
3351  tmpdirname, temp_de->d_name);
3352 
3353  if (unlink_all ||
3354  strncmp(temp_de->d_name,
3356  strlen(PG_TEMP_FILE_PREFIX)) == 0)
3357  {
3358  PGFileType type = get_dirent_type(rm_path, temp_de, false, LOG);
3359 
3360  if (type == PGFILETYPE_ERROR)
3361  continue;
3362  else if (type == PGFILETYPE_DIR)
3363  {
3364  /* recursively remove contents, then directory itself */
3365  RemovePgTempFilesInDir(rm_path, false, true);
3366 
3367  if (rmdir(rm_path) < 0)
3368  ereport(LOG,
3370  errmsg("could not remove directory \"%s\": %m",
3371  rm_path)));
3372  }
3373  else
3374  {
3375  if (unlink(rm_path) < 0)
3376  ereport(LOG,
3378  errmsg("could not remove file \"%s\": %m",
3379  rm_path)));
3380  }
3381  }
3382  else
3383  ereport(LOG,
3384  (errmsg("unexpected file found in temporary-files directory: \"%s\"",
3385  rm_path)));
3386  }
3387 
3388  FreeDir(temp_dir);
3389 }
PGFileType get_dirent_type(const char *path, const struct dirent *de, bool look_through_symlinks, int elevel)
Definition: file_utils.c:525
PGFileType
Definition: file_utils.h:19
@ PGFILETYPE_DIR
Definition: file_utils.h:23
@ PGFILETYPE_ERROR
Definition: file_utils.h:20
const char * type

References AllocateDir(), dirent::d_name, ereport, errcode_for_file_access(), errmsg(), FreeDir(), get_dirent_type(), LOG, MAXPGPATH, PG_TEMP_FILE_PREFIX, PGFILETYPE_DIR, PGFILETYPE_ERROR, ReadDirExtended(), snprintf, and type.

Referenced by PostmasterMain(), and RemovePgTempFiles().

◆ RemovePgTempRelationFiles()

static void RemovePgTempRelationFiles ( const char *  tsdirname)
static

Definition at line 3393 of file fd.c.

3394 {
3395  DIR *ts_dir;
3396  struct dirent *de;
3397  char dbspace_path[MAXPGPATH * 2];
3398 
3399  ts_dir = AllocateDir(tsdirname);
3400 
3401  while ((de = ReadDirExtended(ts_dir, tsdirname, LOG)) != NULL)
3402  {
3403  /*
3404  * We're only interested in the per-database directories, which have
3405  * numeric names. Note that this code will also (properly) ignore "."
3406  * and "..".
3407  */
3408  if (strspn(de->d_name, "0123456789") != strlen(de->d_name))
3409  continue;
3410 
3411  snprintf(dbspace_path, sizeof(dbspace_path), "%s/%s",
3412  tsdirname, de->d_name);
3413  RemovePgTempRelationFilesInDbspace(dbspace_path);
3414  }
3415 
3416  FreeDir(ts_dir);
3417 }
static void RemovePgTempRelationFilesInDbspace(const char *dbspacedirname)
Definition: fd.c:3421

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

Referenced by RemovePgTempFiles().

◆ RemovePgTempRelationFilesInDbspace()

static void RemovePgTempRelationFilesInDbspace ( const char *  dbspacedirname)
static

Definition at line 3421 of file fd.c.

3422 {
3423  DIR *dbspace_dir;
3424  struct dirent *de;
3425  char rm_path[MAXPGPATH * 2];
3426 
3427  dbspace_dir = AllocateDir(dbspacedirname);
3428 
3429  while ((de = ReadDirExtended(dbspace_dir, dbspacedirname, LOG)) != NULL)
3430  {
3431  if (!looks_like_temp_rel_name(de->d_name))
3432  continue;
3433 
3434  snprintf(rm_path, sizeof(rm_path), "%s/%s",
3435  dbspacedirname, de->d_name);
3436 
3437  if (unlink(rm_path) < 0)
3438  ereport(LOG,
3440  errmsg("could not remove file \"%s\": %m",
3441  rm_path)));
3442  }
3443 
3444  FreeDir(dbspace_dir);
3445 }
bool looks_like_temp_rel_name(const char *name)
Definition: fd.c:3449

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().

◆ ReportTemporaryFileUsage()

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

Definition at line 1528 of file fd.c.

1529 {
1531 
1532  if (log_temp_files >= 0)
1533  {
1534  if ((size / 1024) >= log_temp_files)
1535  ereport(LOG,
1536  (errmsg("temporary file: path \"%s\", size %lu",
1537  path, (unsigned long) size)));
1538  }
1539 }
int log_temp_files
Definition: guc_tables.c:530
void pgstat_report_tempfile(size_t filesize)

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

Referenced by FileClose(), and PathNameDeleteTemporaryFile().

◆ reserveAllocatedDesc()

static bool reserveAllocatedDesc ( void  )
static

Definition at line 2508 of file fd.c.

2509 {
2510  AllocateDesc *newDescs;
2511  int newMax;
2512 
2513  /* Quick out if array already has a free slot. */
2515  return true;
2516 
2517  /*
2518  * If the array hasn't yet been created in the current process, initialize
2519  * it with FD_MINFREE / 3 elements. In many scenarios this is as many as
2520  * we will ever need, anyway. We don't want to look at max_safe_fds
2521  * immediately because set_max_safe_fds() may not have run yet.
2522  */
2523  if (allocatedDescs == NULL)
2524  {
2525  newMax = FD_MINFREE / 3;
2526  newDescs = (AllocateDesc *) malloc(newMax * sizeof(AllocateDesc));
2527  /* Out of memory already? Treat as fatal error. */
2528  if (newDescs == NULL)
2529  ereport(ERROR,
2530  (errcode(ERRCODE_OUT_OF_MEMORY),
2531  errmsg("out of memory")));
2532  allocatedDescs = newDescs;
2533  maxAllocatedDescs = newMax;
2534  return true;
2535  }
2536 
2537  /*
2538  * Consider enlarging the array beyond the initial allocation used above.
2539  * By the time this happens, max_safe_fds should be known accurately.
2540  *
2541  * We mustn't let allocated descriptors hog all the available FDs, and in
2542  * practice we'd better leave a reasonable number of FDs for VFD use. So
2543  * set the maximum to max_safe_fds / 3. (This should certainly be at
2544  * least as large as the initial size, FD_MINFREE / 3, so we aren't
2545  * tightening the restriction here.) Recall that "external" FDs are
2546  * allowed to consume another third of max_safe_fds.
2547  */
2548  newMax = max_safe_fds / 3;
2549  if (newMax > maxAllocatedDescs)
2550  {
2551  newDescs = (AllocateDesc *) realloc(allocatedDescs,
2552  newMax * sizeof(AllocateDesc));
2553  /* Treat out-of-memory as a non-fatal error. */
2554  if (newDescs == NULL)
2555  return false;
2556  allocatedDescs = newDescs;
2557  maxAllocatedDescs = newMax;
2558  return true;
2559  }
2560 
2561  /* Can't enlarge allocatedDescs[] any more. */
2562  return false;
2563 }
#define FD_MINFREE
Definition: fd.c:138

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

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

◆ ReserveExternalFD()

void ReserveExternalFD ( void  )

Definition at line 1221 of file fd.c.

1222 {
1223  /*
1224  * Release VFDs if needed to stay safe. Because we do this before
1225  * incrementing numExternalFDs, the final state will be as desired, i.e.,
1226  * nfile + numAllocatedDescs + numExternalFDs <= max_safe_fds.
1227  */
1228  ReleaseLruFiles();
1229 
1230  numExternalFDs++;
1231 }

References numExternalFDs, and ReleaseLruFiles().

Referenced by AcquireExternalFD(), BackendInitialize(), dsm_impl_posix(), InitializeLatchSupport(), InitPostmasterDeathWatchHandle(), and XLogWrite().

◆ ResourceOwnerForgetFile()

static void ResourceOwnerForgetFile ( ResourceOwner  owner,
File  file 
)
inlinestatic

Definition at line 377 of file fd.c.

378 {
380 }
static const ResourceOwnerDesc file_resowner_desc
Definition: fd.c:361
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:212
void ResourceOwnerForget(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition: resowner.c:554

References file_resowner_desc, Int32GetDatum(), and ResourceOwnerForget().

Referenced by FileClose().

◆ ResourceOwnerRememberFile()

static void ResourceOwnerRememberFile ( ResourceOwner  owner,
File  file 
)
inlinestatic

Definition at line 372 of file fd.c.

373 {
375 }
void ResourceOwnerRemember(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition: resowner.c:514

References file_resowner_desc, Int32GetDatum(), and ResourceOwnerRemember().

Referenced by RegisterTemporaryFile().

◆ ResOwnerPrintFile()

static char * ResOwnerPrintFile ( Datum  res)
static

Definition at line 4048 of file fd.c.

4049 {
4050  return psprintf("File %d", DatumGetInt32(res));
4051 }
static int32 DatumGetInt32(Datum X)
Definition: postgres.h:202
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46

References DatumGetInt32(), psprintf(), and res.

◆ ResOwnerReleaseFile()

static void ResOwnerReleaseFile ( Datum  res)
static

Definition at line 4034 of file fd.c.

4035 {
4036  File file = (File) DatumGetInt32(res);
4037  Vfd *vfdP;
4038 
4039  Assert(FileIsValid(file));
4040 
4041  vfdP = &VfdCache[file];
4042  vfdP->resowner = NULL;
4043 
4044  FileClose(file);
4045 }

References Assert, DatumGetInt32(), FileClose(), FileIsValid, res, vfd::resowner, and VfdCache.

◆ set_max_safe_fds()

void set_max_safe_fds ( void  )

Definition at line 1044 of file fd.c.

1045 {
1046  int usable_fds;
1047  int already_open;
1048 
1049  /*----------
1050  * We want to set max_safe_fds to
1051  * MIN(usable_fds, max_files_per_process - already_open)
1052  * less the slop factor for files that are opened without consulting
1053  * fd.c. This ensures that we won't exceed either max_files_per_process
1054  * or the experimentally-determined EMFILE limit.
1055  *----------
1056  */
1058  &usable_fds, &already_open);
1059 
1060  max_safe_fds = Min(usable_fds, max_files_per_process - already_open);
1061 
1062  /*
1063  * Take off the FDs reserved for system() etc.
1064  */
1066 
1067  /*
1068  * Make sure we still have enough to get by.
1069  */
1070  if (max_safe_fds < FD_MINFREE)
1071  ereport(FATAL,
1072  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
1073  errmsg("insufficient file descriptors available to start server process"),
1074  errdetail("System allows %d, server needs at least %d.",
1077 
1078  elog(DEBUG2, "max_safe_fds = %d, usable_fds = %d, already_open = %d",
1079  max_safe_fds, usable_fds, already_open);
1080 }
#define Min(x, y)
Definition: c.h:1004
int errdetail(const char *fmt,...)
Definition: elog.c:1205
#define DEBUG2
Definition: elog.h:29
int max_files_per_process
Definition: fd.c:146
static void count_usable_fds(int max_to_probe, int *usable_fds, int *already_open)
Definition: fd.c:964
#define NUM_RESERVED_FDS
Definition: fd.c:129

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().

◆ SetTempTablespaces()

void SetTempTablespaces ( Oid tableSpaces,
int  numSpaces 
)

Definition at line 3049 of file fd.c.

3050 {
3051  Assert(numSpaces >= 0);
3052  tempTableSpaces = tableSpaces;
3053  numTempTableSpaces = numSpaces;
3054 
3055  /*
3056  * Select a random starting point in the list. This is to minimize
3057  * conflicts between backends that are most likely sharing the same list
3058  * of temp tablespaces. Note that if we create multiple temp files in the
3059  * same transaction, we'll advance circularly through the list --- this
3060  * ensures that large temporary sort files are nicely spread across all
3061  * available tablespaces.
3062  */
3063  if (numSpaces > 1)
3065  0, numSpaces - 1);
3066  else
3067  nextTempTableSpace = 0;
3068 }
uint64 pg_prng_uint64_range(pg_prng_state *state, uint64 rmin, uint64 rmax)
Definition: pg_prng.c:144
pg_prng_state pg_global_prng_state
Definition: pg_prng.c:34

References Assert, nextTempTableSpace, numTempTableSpaces, pg_global_prng_state, pg_prng_uint64_range(), and tempTableSpaces.

Referenced by assign_temp_tablespaces(), and PrepareTempTablespaces().

◆ SyncDataDirectory()

void SyncDataDirectory ( void  )

Definition at line 3544 of file fd.c.

3545 {
3546  bool xlog_is_symlink;
3547 
3548  /* We can skip this whole thing if fsync is disabled. */
3549  if (!enableFsync)
3550  return;
3551 
3552  /*
3553  * If pg_wal is a symlink, we'll need to recurse into it separately,
3554  * because the first walkdir below will ignore it.
3555  */
3556  xlog_is_symlink = false;
3557 
3558  {
3559  struct stat st;
3560 
3561  if (lstat("pg_wal", &st) < 0)
3562  ereport(LOG,
3564  errmsg("could not stat file \"%s\": %m",
3565  "pg_wal")));
3566  else if (S_ISLNK(st.st_mode))
3567  xlog_is_symlink = true;
3568  }
3569 
3570 #ifdef HAVE_SYNCFS
3572  {
3573  DIR *dir;
3574  struct dirent *de;
3575 
3576  /*
3577  * On Linux, we don't have to open every single file one by one. We
3578  * can use syncfs() to sync whole filesystems. We only expect
3579  * filesystem boundaries to exist where we tolerate symlinks, namely
3580  * pg_wal and the tablespaces, so we call syncfs() for each of those
3581  * directories.
3582  */
3583 
3584  /* Prepare to report progress syncing the data directory via syncfs. */
3586 
3587  /* Sync the top level pgdata directory. */
3588  do_syncfs(".");
3589  /* If any tablespaces are configured, sync each of those. */
3590  dir = AllocateDir("pg_tblspc");
3591  while ((de = ReadDirExtended(dir, "pg_tblspc", LOG)))
3592  {
3593  char path[MAXPGPATH];
3594 
3595  if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
3596  continue;
3597 
3598  snprintf(path, MAXPGPATH, "pg_tblspc/%s", de->d_name);
3599  do_syncfs(path);
3600  }
3601  FreeDir(dir);
3602  /* If pg_wal is a symlink, process that too. */
3603  if (xlog_is_symlink)
3604  do_syncfs("pg_wal");
3605  return;
3606  }
3607 #endif /* !HAVE_SYNCFS */
3608 
3609 #ifdef PG_FLUSH_DATA_WORKS
3610  /* Prepare to report progress of the pre-fsync phase. */
3612 
3613  /*
3614  * If possible, hint to the kernel that we're soon going to fsync the data
3615  * directory and its contents. Errors in this step are even less
3616  * interesting than normal, so log them only at DEBUG1.
3617  */
3618  walkdir(".", pre_sync_fname, false, DEBUG1);
3619  if (xlog_is_symlink)
3620  walkdir("pg_wal", pre_sync_fname, false, DEBUG1);
3621  walkdir("pg_tblspc", pre_sync_fname, true, DEBUG1);
3622 #endif
3623 
3624  /* Prepare to report progress syncing the data directory via fsync. */
3626 
3627  /*
3628  * Now we do the fsync()s in the same order.
3629  *
3630  * The main call ignores symlinks, so in addition to specially processing
3631  * pg_wal if it's a symlink, pg_tblspc has to be visited separately with
3632  * process_symlinks = true. Note that if there are any plain directories
3633  * in pg_tblspc, they'll get fsync'd twice. That's not an expected case
3634  * so we don't worry about optimizing it.
3635  */
3636  walkdir(".", datadir_fsync_fname, false, LOG);
3637  if (xlog_is_symlink)
3638  walkdir("pg_wal", datadir_fsync_fname, false, LOG);
3639  walkdir("pg_tblspc", datadir_fsync_fname, true, LOG);
3640 }
void begin_startup_progress_phase(void)
Definition: startup.c:343
#define DEBUG1
Definition: elog.h:30
int recovery_init_sync_method
Definition: fd.c:165
static void datadir_fsync_fname(const char *fname, bool isdir, int elevel)
Definition: fd.c:3759
@ DATA_DIR_SYNC_METHOD_SYNCFS
Definition: file_utils.h:30
#define lstat(path, sb)
Definition: win32_port.h:285
#define S_ISLNK(m)
Definition: win32_port.h:344

References AllocateDir(), begin_startup_progress_phase(), dirent::d_name, DATA_DIR_SYNC_METHOD_SYNCFS, datadir_fsync_fname(), DEBUG1, enableFsync, ereport, errcode_for_file_access(), errmsg(), FreeDir(), LOG, lstat, MAXPGPATH, ReadDirExtended(), recovery_init_sync_method, S_ISLNK, snprintf, stat::st_mode, and walkdir().

Referenced by StartupXLOG().

◆ TempTablespacePath()

void TempTablespacePath ( char *  path,
Oid  tablespace 
)

Definition at line 1779 of file fd.c.

1780 {
1781  /*
1782  * Identify the tempfile directory for this tablespace.
1783  *
1784  * If someone tries to specify pg_global, use pg_default instead.
1785  */
1786  if (tablespace == InvalidOid ||
1787  tablespace == DEFAULTTABLESPACE_OID ||
1788  tablespace == GLOBALTABLESPACE_OID)
1789  snprintf(path, MAXPGPATH, "base/%s", PG_TEMP_FILES_DIR);
1790  else
1791  {
1792  /* All other tablespaces are accessed via symlinks */
1793  snprintf(path, MAXPGPATH, "pg_tblspc/%u/%s/%s",
1796  }
1797 }
char * tablespace
Definition: pgbench.c:216

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

Referenced by FileSetCreate(), FileSetPath(), OpenTemporaryFileInTablespace(), and pg_ls_tmpdir().

◆ TempTablespacesAreSet()

bool TempTablespacesAreSet ( void  )

Definition at line 3078 of file fd.c.

3079 {
3080  return (numTempTableSpaces >= 0);
3081 }

References numTempTableSpaces.

Referenced by GetTempTablespaces(), and PrepareTempTablespaces().

◆ unlink_if_exists_fname()

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

Definition at line 3772 of file fd.c.

3773 {
3774  if (isdir)
3775  {
3776  if (rmdir(fname) != 0 && errno != ENOENT)
3777  ereport(elevel,
3779  errmsg("could not remove directory \"%s\": %m", fname)));
3780  }
3781  else
3782  {
3783  /* Use PathNameDeleteTemporaryFile to report filesize */
3784  PathNameDeleteTemporaryFile(fname, false);
3785  }
3786 }
bool PathNameDeleteTemporaryFile(const char *path, bool error_on_failure)
Definition: fd.c:1932

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

Referenced by PathNameDeleteTemporaryDir().

◆ 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 3658 of file fd.c.

3662 {
3663  DIR *dir;
3664  struct dirent *de;
3665 
3666  dir = AllocateDir(path);
3667 
3668  while ((de = ReadDirExtended(dir, path, elevel)) != NULL)
3669  {
3670  char subpath[MAXPGPATH * 2];
3671 
3673 
3674  if (strcmp(de->d_name, ".") == 0 ||
3675  strcmp(de->d_name, "..") == 0)
3676  continue;
3677 
3678  snprintf(subpath, sizeof(subpath), "%s/%s", path, de->d_name);
3679 
3680  switch (get_dirent_type(subpath, de, process_symlinks, elevel))
3681  {
3682  case PGFILETYPE_REG:
3683  (*action) (subpath, false, elevel);
3684  break;
3685  case PGFILETYPE_DIR:
3686  walkdir(subpath, action, false, elevel);
3687  break;
3688  default:
3689 
3690  /*
3691  * Errors are already reported directly by get_dirent_type(),
3692  * and any remaining symlinks and unknown file types are
3693  * ignored.
3694  */
3695  break;
3696  }
3697  }
3698 
3699  FreeDir(dir); /* we ignore any error here */
3700 
3701  /*
3702  * It's important to fsync the destination directory itself as individual
3703  * file fsyncs don't guarantee that the directory entry for the file is
3704  * synced. However, skip this if AllocateDir failed; the action function
3705  * might not be robust against that.
3706  */
3707  if (dir)
3708  (*action) (path, true, elevel);
3709 }
@ PGFILETYPE_REG
Definition: file_utils.h:22
Datum subpath(PG_FUNCTION_ARGS)
Definition: ltree_op.c:310
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:122

References generate_unaccent_rules::action, AllocateDir(), CHECK_FOR_INTERRUPTS, dirent::d_name, FreeDir(), get_dirent_type(), MAXPGPATH, PGFILETYPE_DIR, PGFILETYPE_REG, ReadDirExtended(), snprintf, and subpath().

Referenced by PathNameDeleteTemporaryDir(), and SyncDataDirectory().

Variable Documentation

◆ allocatedDescs

◆ data_sync_retry

bool data_sync_retry = false

Definition at line 162 of file fd.c.

Referenced by data_sync_elevel().

◆ file_resowner_desc

const ResourceOwnerDesc file_resowner_desc
static
Initial value:
=
{
.name = "File",
.release_phase = RESOURCE_RELEASE_AFTER_LOCKS,
.release_priority = RELEASE_PRIO_FILES,
.ReleaseResource = ResOwnerReleaseFile,
.DebugPrint = ResOwnerPrintFile
}
static char * ResOwnerPrintFile(Datum res)
Definition: fd.c:4048
static void ResOwnerReleaseFile(Datum res)
Definition: fd.c:4034
@ RESOURCE_RELEASE_AFTER_LOCKS
Definition: resowner.h:56
#define RELEASE_PRIO_FILES
Definition: resowner.h:76

Definition at line 361 of file fd.c.

Referenced by ResourceOwnerForgetFile(), and ResourceOwnerRememberFile().

◆ have_xact_temporary_files

bool have_xact_temporary_files = false
static

Definition at line 228 of file fd.c.

Referenced by CleanupTempFiles(), and RegisterTemporaryFile().

◆ io_direct_flags

◆ max_files_per_process

int max_files_per_process = 1000

Definition at line 146 of file fd.c.

Referenced by set_max_safe_fds().

◆ max_safe_fds

int max_safe_fds = FD_MINFREE

Definition at line 159 of file fd.c.

Referenced by AcquireExternalFD(), ReleaseLruFiles(), reserveAllocatedDesc(), and set_max_safe_fds().

◆ maxAllocatedDescs

int maxAllocatedDescs = 0
static

◆ nextTempTableSpace

int nextTempTableSpace = 0
static

Definition at line 290 of file fd.c.

Referenced by GetNextTempTableSpace(), and SetTempTablespaces().

◆ nfile

int nfile = 0
static

◆ numAllocatedDescs

◆ numExternalFDs

int numExternalFDs = 0
static

Definition at line 274 of file fd.c.

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

◆ numTempTableSpaces

int numTempTableSpaces = -1
static

◆ recovery_init_sync_method

int recovery_init_sync_method = DATA_DIR_SYNC_METHOD_FSYNC

Definition at line 165 of file fd.c.

Referenced by SyncDataDirectory().

◆ SizeVfdCache

Size SizeVfdCache = 0
static

◆ tempFileCounter

long tempFileCounter = 0
static

Definition at line 280 of file fd.c.

Referenced by OpenTemporaryFileInTablespace().

◆ temporary_files_size

uint64 temporary_files_size = 0
static

Definition at line 236 of file fd.c.

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

◆ tempTableSpaces

Oid* tempTableSpaces = NULL
static

◆ VfdCache