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

2867 {
2868  DIR *dir;
2869 
2870  DO_DB(elog(LOG, "AllocateDir: Allocated %d (%s)",
2871  numAllocatedDescs, dirname));
2872 
2873  /* Can we allocate another non-virtual FD? */
2874  if (!reserveAllocatedDesc())
2875  ereport(ERROR,
2876  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2877  errmsg("exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"",
2878  maxAllocatedDescs, dirname)));
2879 
2880  /* Close excess kernel FDs. */
2881  ReleaseLruFiles();
2882 
2883 TryAgain:
2884  if ((dir = opendir(dirname)) != NULL)
2885  {
2887 
2888  desc->kind = AllocateDescDir;
2889  desc->desc.dir = dir;
2892  return desc->desc.dir;
2893  }
2894 
2895  if (errno == EMFILE || errno == ENFILE)
2896  {
2897  int save_errno = errno;
2898 
2899  ereport(LOG,
2900  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2901  errmsg("out of file descriptors: %m; release and retry")));
2902  errno = 0;
2903  if (ReleaseLruFile())
2904  goto TryAgain;
2905  errno = save_errno;
2906  }
2907 
2908  return NULL;
2909 }
DIR * opendir(const char *)
Definition: dirent.c:33
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define LOG
Definition: elog.h:31
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
#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:2531
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:790

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

2607 {
2608  FILE *file;
2609 
2610  DO_DB(elog(LOG, "AllocateFile: Allocated %d (%s)",
2612 
2613  /* Can we allocate another non-virtual FD? */
2614  if (!reserveAllocatedDesc())
2615  ereport(ERROR,
2616  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2617  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2618  maxAllocatedDescs, name)));
2619 
2620  /* Close excess kernel FDs. */
2621  ReleaseLruFiles();
2622 
2623 TryAgain:
2624  if ((file = fopen(name, mode)) != NULL)
2625  {
2627 
2628  desc->kind = AllocateDescFile;
2629  desc->desc.file = file;
2632  return desc->desc.file;
2633  }
2634 
2635  if (errno == EMFILE || errno == ENFILE)
2636  {
2637  int save_errno = errno;
2638 
2639  ereport(LOG,
2640  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2641  errmsg("out of file descriptors: %m; release and retry")));
2642  errno = 0;
2643  if (ReleaseLruFile())
2644  goto TryAgain;
2645  errno = save_errno;
2646  }
2647 
2648  return NULL;
2649 }
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 4051 of file fd.c.

4052 {
4053  int *flags = (int *) extra;
4054 
4055  io_direct_flags = *flags;
4056 }
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 3155 of file fd.c.

3157 {
3158  Index i;
3159 
3160  for (i = 0; i < numAllocatedDescs; i++)
3161  {
3162  if (allocatedDescs[i].create_subid == mySubid)
3163  {
3164  if (isCommit)
3165  allocatedDescs[i].create_subid = parentSubid;
3166  else
3167  {
3168  /* have to recheck the item after FreeDesc (ugly) */
3169  FreeDesc(&allocatedDescs[i--]);
3170  }
3171  }
3172  }
3173 }
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2765

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

◆ AtEOXact_Files()

void AtEOXact_Files ( bool  isCommit)

Definition at line 3188 of file fd.c.

3189 {
3190  CleanupTempFiles(isCommit, false);
3191  tempTableSpaces = NULL;
3192  numTempTableSpaces = -1;
3193 }
static int numTempTableSpaces
Definition: fd.c:289
static Oid * tempTableSpaces
Definition: fd.c:288
static void CleanupTempFiles(bool isCommit, bool isProcExit)
Definition: fd.c:3225

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

3203 {
3204  CleanupTempFiles(false, true);
3205 
3206  /* prevent further temp files from being created */
3207 #ifdef USE_ASSERT_CHECKING
3208  temporary_files_allowed = false;
3209 #endif
3210 }

References CleanupTempFiles().

Referenced by InitTemporaryFileAccess().

◆ check_debug_io_direct()

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

Definition at line 3966 of file fd.c.

3967 {
3968  bool result = true;
3969  int flags;
3970 
3971 #if PG_O_DIRECT == 0
3972  if (strcmp(*newval, "") != 0)
3973  {
3974  GUC_check_errdetail("\"%s\" is not supported on this platform.",
3975  "debug_io_direct");
3976  result = false;
3977  }
3978  flags = 0;
3979 #else
3980  List *elemlist;
3981  ListCell *l;
3982  char *rawstring;
3983 
3984  /* Need a modifiable copy of string */
3985  rawstring = pstrdup(*newval);
3986 
3987  if (!SplitGUCList(rawstring, ',', &elemlist))
3988  {
3989  GUC_check_errdetail("Invalid list syntax in parameter \"%s\"",
3990  "debug_io_direct");
3991  pfree(rawstring);
3992  list_free(elemlist);
3993  return false;
3994  }
3995 
3996  flags = 0;
3997  foreach(l, elemlist)
3998  {
3999  char *item = (char *) lfirst(l);
4000 
4001  if (pg_strcasecmp(item, "data") == 0)
4002  flags |= IO_DIRECT_DATA;
4003  else if (pg_strcasecmp(item, "wal") == 0)
4004  flags |= IO_DIRECT_WAL;
4005  else if (pg_strcasecmp(item, "wal_init") == 0)
4006  flags |= IO_DIRECT_WAL_INIT;
4007  else
4008  {
4009  GUC_check_errdetail("Invalid option \"%s\"", item);
4010  result = false;
4011  break;
4012  }
4013  }
4014 
4015  /*
4016  * It's possible to configure block sizes smaller than our assumed I/O
4017  * alignment size, which could result in invalid I/O requests.
4018  */
4019 #if XLOG_BLCKSZ < PG_IO_ALIGN_SIZE
4020  if (result && (flags & (IO_DIRECT_WAL | IO_DIRECT_WAL_INIT)))
4021  {
4022  GUC_check_errdetail("\"%s\" is not supported for WAL because %s is too small",
4023  "debug_io_direct", "XLOG_BLCKSZ");
4024  result = false;
4025  }
4026 #endif
4027 #if BLCKSZ < PG_IO_ALIGN_SIZE
4028  if (result && (flags & IO_DIRECT_DATA))
4029  {
4030  GUC_check_errdetail("\"%s\" is not supported for WAL because %s is too small",
4031  "debug_io_direct", "BLCKSZ");
4032  result = false;
4033  }
4034 #endif
4035 
4036  pfree(rawstring);
4037  list_free(elemlist);
4038 #endif
4039 
4040  if (!result)
4041  return result;
4042 
4043  /* Save the flags in *extra, for use by assign_debug_io_direct */
4044  *extra = guc_malloc(ERROR, sizeof(int));
4045  *((int *) *extra) = flags;
4046 
4047  return result;
4048 }
#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:637
#define newval
#define GUC_check_errdetail
Definition: guc.h:476
void list_free(List *list)
Definition: list.c:1546
char * pstrdup(const char *in)
Definition: mcxt.c:1696
void pfree(void *pointer)
Definition: mcxt.c:1521
#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:3680

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

3226 {
3227  Index i;
3228 
3229  /*
3230  * Careful here: at proc_exit we need extra cleanup, not just
3231  * xact_temporary files.
3232  */
3233  if (isProcExit || have_xact_temporary_files)
3234  {
3235  Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
3236  for (i = 1; i < SizeVfdCache; i++)
3237  {
3238  unsigned short fdstate = VfdCache[i].fdstate;
3239 
3240  if (((fdstate & FD_DELETE_AT_CLOSE) || (fdstate & FD_CLOSE_AT_EOXACT)) &&
3241  VfdCache[i].fileName != NULL)
3242  {
3243  /*
3244  * If we're in the process of exiting a backend process, close
3245  * all temporary files. Otherwise, only close temporary files
3246  * local to the current transaction. They should be closed by
3247  * the ResourceOwner mechanism already, so this is just a
3248  * debugging cross-check.
3249  */
3250  if (isProcExit)
3251  FileClose(i);
3252  else if (fdstate & FD_CLOSE_AT_EOXACT)
3253  {
3254  elog(WARNING,
3255  "temporary file %s not closed at end-of-transaction",
3256  VfdCache[i].fileName);
3257  FileClose(i);
3258  }
3259  }
3260  }
3261 
3262  have_xact_temporary_files = false;
3263  }
3264 
3265  /* Complain if any allocated files remain open at commit. */
3266  if (isCommit && numAllocatedDescs > 0)
3267  elog(WARNING, "%d temporary files and directories not closed at end-of-transaction",
3269 
3270  /* Clean up "allocated" stdio files, dirs and fds. */
3271  while (numAllocatedDescs > 0)
3272  FreeDesc(&allocatedDescs[0]);
3273 }
#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 3043 of file fd.c.

3044 {
3045  Index i;
3046 
3047  if (SizeVfdCache > 0)
3048  {
3049  Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
3050  for (i = 1; i < SizeVfdCache; i++)
3051  {
3052  if (!FileIsNotOpen(i))
3053  LruDelete(i);
3054  }
3055  }
3056 }
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 3014 of file fd.c.

3015 {
3016  int i;
3017 
3018  DO_DB(elog(LOG, "ClosePipeStream: Allocated %d", numAllocatedDescs));
3019 
3020  /* Remove file from list of allocated files, if it's present */
3021  for (i = numAllocatedDescs; --i >= 0;)
3022  {
3023  AllocateDesc *desc = &allocatedDescs[i];
3024 
3025  if (desc->kind == AllocateDescPipe && desc->desc.file == file)
3026  return FreeDesc(desc);
3027  }
3028 
3029  /* Only get here if someone passes us a file not in allocatedDescs */
3030  elog(WARNING, "file passed to ClosePipeStream was not obtained from OpenPipeStream");
3031 
3032  return pclose(file);
3033 }

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

2833 {
2834  int i;
2835 
2836  DO_DB(elog(LOG, "CloseTransientFile: Allocated %d", numAllocatedDescs));
2837 
2838  /* Remove fd from list of allocated files, if it's present */
2839  for (i = numAllocatedDescs; --i >= 0;)
2840  {
2841  AllocateDesc *desc = &allocatedDescs[i];
2842 
2843  if (desc->kind == AllocateDescRawFD && desc->desc.fd == fd)
2844  return FreeDesc(desc);
2845  }
2846 
2847  /* Only get here if someone passes us a file not in allocatedDescs */
2848  elog(WARNING, "fd passed to CloseTransientFile was not obtained from OpenTransientFile");
2849 
2850  return close(fd);
2851 }
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:1541
void * palloc(Size size)
Definition: mcxt.c:1317
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 3783 of file fd.c.

3784 {
3785  ereport_startup_progress("syncing data directory (fsync), elapsed time: %ld.%02d s, current path: %s",
3786  fname);
3787 
3788  /*
3789  * We want to silently ignoring errors about unreadable files. Pass that
3790  * desire on to fsync_fname_ext().
3791  */
3792  fsync_fname_ext(fname, isdir, true, elevel);
3793 }
int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3821
#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:876
int CloseTransientFile(int fd)
Definition: fd.c:2832
int pg_fsync(int fd)
Definition: fd.c:386
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3897
int OpenTransientFile(const char *fileName, int fileFlags)
Definition: fd.c:2656

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(), pgstat_write_statsfile(), 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:3960
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 2392 of file fd.c.

2393 {
2394 #ifdef HAVE_POSIX_FALLOCATE
2395  int returnCode;
2396 
2397  Assert(FileIsValid(file));
2398 
2399  DO_DB(elog(LOG, "FileFallocate: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
2400  file, VfdCache[file].fileName,
2401  (int64) offset, (int64) amount));
2402 
2403  returnCode = FileAccess(file);
2404  if (returnCode < 0)
2405  return -1;
2406 
2407 retry:
2408  pgstat_report_wait_start(wait_event_info);
2409  returnCode = posix_fallocate(VfdCache[file].fd, offset, amount);
2411 
2412  if (returnCode == 0)
2413  return 0;
2414  else if (returnCode == EINTR)
2415  goto retry;
2416 
2417  /* for compatibility with %m printing etc */
2418  errno = returnCode;
2419 
2420  /*
2421  * Return in cases of a "real" failure, if fallocate is not supported,
2422  * fall through to the FileZero() backed implementation.
2423  */
2424  if (returnCode != EINVAL && returnCode != EOPNOTSUPP)
2425  return -1;
2426 #endif
2427 
2428  return FileZero(file, offset, amount, wait_event_info);
2429 }
#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:2347
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:85
static void pgstat_report_wait_end(void)
Definition: wait_event.h:101
#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 2500 of file fd.c.

2501 {
2502  Assert(FileIsValid(file));
2503  return VfdCache[file].fd;
2504 }

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

◆ FileGetRawFlags()

int FileGetRawFlags ( File  file)

Definition at line 2510 of file fd.c.

2511 {
2512  Assert(FileIsValid(file));
2513  return VfdCache[file].fileFlags;
2514 }
int fileFlags
Definition: fd.c:207

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

◆ FileGetRawMode()

mode_t FileGetRawMode ( File  file)

Definition at line 2520 of file fd.c.

2521 {
2522  Assert(FileIsValid(file));
2523  return VfdCache[file].fileMode;
2524 }
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 2077 of file fd.c.

2078 {
2079  Assert(FileIsValid(file));
2080 
2081  DO_DB(elog(LOG, "FilePrefetch: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
2082  file, VfdCache[file].fileName,
2083  (int64) offset, (int64) amount));
2084 
2085 #if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
2086  {
2087  int returnCode;
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  }
2104 #elif defined(__darwin__)
2105  {
2106  struct radvisory
2107  {
2108  off_t ra_offset; /* offset into the file */
2109  int ra_count; /* size of the read */
2110  } ra;
2111  int returnCode;
2112 
2113  returnCode = FileAccess(file);
2114  if (returnCode < 0)
2115  return returnCode;
2116 
2117  ra.ra_offset = offset;
2118  ra.ra_count = amount;
2119  pgstat_report_wait_start(wait_event_info);
2120  returnCode = fcntl(VfdCache[file].fd, F_RDADVISE, &ra);
2122  if (returnCode != -1)
2123  return 0;
2124  else
2125  return errno;
2126  }
2127 #else
2128  return 0;
2129 #endif
2130 }

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

2161 {
2162  ssize_t returnCode;
2163  Vfd *vfdP;
2164 
2165  Assert(FileIsValid(file));
2166 
2167  DO_DB(elog(LOG, "FileReadV: %d (%s) " INT64_FORMAT " %d",
2168  file, VfdCache[file].fileName,
2169  (int64) offset,
2170  iovcnt));
2171 
2172  returnCode = FileAccess(file);
2173  if (returnCode < 0)
2174  return returnCode;
2175 
2176  vfdP = &VfdCache[file];
2177 
2178 retry:
2179  pgstat_report_wait_start(wait_event_info);
2180  returnCode = pg_preadv(vfdP->fd, iov, iovcnt, offset);
2182 
2183  if (returnCode < 0)
2184  {
2185  /*
2186  * Windows may run out of kernel buffers and return "Insufficient
2187  * system resources" error. Wait a bit and retry to solve it.
2188  *
2189  * It is rumored that EINTR is also possible on some Unix filesystems,
2190  * in which case immediate retry is indicated.
2191  */
2192 #ifdef WIN32
2193  DWORD error = GetLastError();
2194 
2195  switch (error)
2196  {
2197  case ERROR_NO_SYSTEM_RESOURCES:
2198  pg_usleep(1000L);
2199  errno = EINTR;
2200  break;
2201  default:
2202  _dosmaperr(error);
2203  break;
2204  }
2205 #endif
2206  /* OK to retry if interrupted */
2207  if (errno == EINTR)
2208  goto retry;
2209  }
2210 
2211  return returnCode;
2212 }
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 2432 of file fd.c.

2433 {
2434  Assert(FileIsValid(file));
2435 
2436  DO_DB(elog(LOG, "FileSize %d (%s)",
2437  file, VfdCache[file].fileName));
2438 
2439  if (FileIsNotOpen(file))
2440  {
2441  if (FileAccess(file) < 0)
2442  return (off_t) -1;
2443  }
2444 
2445  return lseek(VfdCache[file].fd, 0, SEEK_END);
2446 }

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

2321 {
2322  int returnCode;
2323 
2324  Assert(FileIsValid(file));
2325 
2326  DO_DB(elog(LOG, "FileSync: %d (%s)",
2327  file, VfdCache[file].fileName));
2328 
2329  returnCode = FileAccess(file);
2330  if (returnCode < 0)
2331  return returnCode;
2332 
2333  pgstat_report_wait_start(wait_event_info);
2334  returnCode = pg_fsync(VfdCache[file].fd);
2336 
2337  return returnCode;
2338 }

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

2450 {
2451  int returnCode;
2452 
2453  Assert(FileIsValid(file));
2454 
2455  DO_DB(elog(LOG, "FileTruncate %d (%s)",
2456  file, VfdCache[file].fileName));
2457 
2458  returnCode = FileAccess(file);
2459  if (returnCode < 0)
2460  return returnCode;
2461 
2462  pgstat_report_wait_start(wait_event_info);
2463  returnCode = pg_ftruncate(VfdCache[file].fd, offset);
2465 
2466  if (returnCode == 0 && VfdCache[file].fileSize > offset)
2467  {
2468  /* adjust our state for truncation of a temp file */
2469  Assert(VfdCache[file].fdstate & FD_TEMP_FILE_LIMIT);
2470  temporary_files_size -= VfdCache[file].fileSize - offset;
2471  VfdCache[file].fileSize = offset;
2472  }
2473 
2474  return returnCode;
2475 }
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 2133 of file fd.c.

2134 {
2135  int returnCode;
2136 
2137  Assert(FileIsValid(file));
2138 
2139  DO_DB(elog(LOG, "FileWriteback: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
2140  file, VfdCache[file].fileName,
2141  (int64) offset, (int64) nbytes));
2142 
2143  if (nbytes <= 0)
2144  return;
2145 
2146  if (VfdCache[file].fileFlags & PG_O_DIRECT)
2147  return;
2148 
2149  returnCode = FileAccess(file);
2150  if (returnCode < 0)
2151  return;
2152 
2153  pgstat_report_wait_start(wait_event_info);
2154  pg_flush_data(VfdCache[file].fd, offset, nbytes);
2156 }
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 2215 of file fd.c.

2217 {
2218  ssize_t returnCode;
2219  Vfd *vfdP;
2220 
2221  Assert(FileIsValid(file));
2222 
2223  DO_DB(elog(LOG, "FileWriteV: %d (%s) " INT64_FORMAT " %d",
2224  file, VfdCache[file].fileName,
2225  (int64) offset,
2226  iovcnt));
2227 
2228  returnCode = FileAccess(file);
2229  if (returnCode < 0)
2230  return returnCode;
2231 
2232  vfdP = &VfdCache[file];
2233 
2234  /*
2235  * If enforcing temp_file_limit and it's a temp file, check to see if the
2236  * write would overrun temp_file_limit, and throw error if so. Note: it's
2237  * really a modularity violation to throw error here; we should set errno
2238  * and return -1. However, there's no way to report a suitable error
2239  * message if we do that. All current callers would just throw error
2240  * immediately anyway, so this is safe at present.
2241  */
2242  if (temp_file_limit >= 0 && (vfdP->fdstate & FD_TEMP_FILE_LIMIT))
2243  {
2244  off_t past_write = offset;
2245 
2246  for (int i = 0; i < iovcnt; ++i)
2247  past_write += iov[i].iov_len;
2248 
2249  if (past_write > vfdP->fileSize)
2250  {
2251  uint64 newTotal = temporary_files_size;
2252 
2253  newTotal += past_write - vfdP->fileSize;
2254  if (newTotal > (uint64) temp_file_limit * (uint64) 1024)
2255  ereport(ERROR,
2256  (errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED),
2257  errmsg("temporary file size exceeds \"temp_file_limit\" (%dkB)",
2258  temp_file_limit)));
2259  }
2260  }
2261 
2262 retry:
2263  pgstat_report_wait_start(wait_event_info);
2264  returnCode = pg_pwritev(vfdP->fd, iov, iovcnt, offset);
2266 
2267  if (returnCode >= 0)
2268  {
2269  /*
2270  * Some callers expect short writes to set errno, and traditionally we
2271  * have assumed that they imply disk space shortage. We don't want to
2272  * waste CPU cycles adding up the total size here, so we'll just set
2273  * it for all successful writes in case such a caller determines that
2274  * the write was short and ereports "%m".
2275  */
2276  errno = ENOSPC;
2277 
2278  /*
2279  * Maintain fileSize and temporary_files_size if it's a temp file.
2280  */
2281  if (vfdP->fdstate & FD_TEMP_FILE_LIMIT)
2282  {
2283  off_t past_write = offset + returnCode;
2284 
2285  if (past_write > vfdP->fileSize)
2286  {
2287  temporary_files_size += past_write - vfdP->fileSize;
2288  vfdP->fileSize = past_write;
2289  }
2290  }
2291  }
2292  else
2293  {
2294  /*
2295  * See comments in FileReadV()
2296  */
2297 #ifdef WIN32
2298  DWORD error = GetLastError();
2299 
2300  switch (error)
2301  {
2302  case ERROR_NO_SYSTEM_RESOURCES:
2303  pg_usleep(1000L);
2304  errno = EINTR;
2305  break;
2306  default:
2307  _dosmaperr(error);
2308  break;
2309  }
2310 #endif
2311  /* OK to retry if interrupted */
2312  if (errno == EINTR)
2313  goto retry;
2314  }
2315 
2316  return returnCode;
2317 }
int temp_file_limit
Definition: guc_tables.c:533
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 2347 of file fd.c.

2348 {
2349  int returnCode;
2350  ssize_t written;
2351 
2352  Assert(FileIsValid(file));
2353 
2354  DO_DB(elog(LOG, "FileZero: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
2355  file, VfdCache[file].fileName,
2356  (int64) offset, (int64) amount));
2357 
2358  returnCode = FileAccess(file);
2359  if (returnCode < 0)
2360  return returnCode;
2361 
2362  pgstat_report_wait_start(wait_event_info);
2363  written = pg_pwrite_zeros(VfdCache[file].fd, amount, offset);
2365 
2366  if (written < 0)
2367  return -1;
2368  else if (written != amount)
2369  {
2370  /* if errno is unset, assume problem is no disk space */
2371  if (errno == 0)
2372  errno = ENOSPC;
2373  return -1;
2374  }
2375 
2376  return 0;
2377 }
ssize_t pg_pwrite_zeros(int fd, size_t size, off_t offset)
Definition: file_utils.c:688

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

2766 {
2767  int result;
2768 
2769  /* Close the underlying object */
2770  switch (desc->kind)
2771  {
2772  case AllocateDescFile:
2773  result = fclose(desc->desc.file);
2774  break;
2775  case AllocateDescPipe:
2776  result = pclose(desc->desc.file);
2777  break;
2778  case AllocateDescDir:
2779  result = closedir(desc->desc.dir);
2780  break;
2781  case AllocateDescRawFD:
2782  result = close(desc->desc.fd);
2783  break;
2784  default:
2785  elog(ERROR, "AllocateDesc kind not recognized");
2786  result = 0; /* keep compiler quiet */
2787  break;
2788  }
2789 
2790  /* Compact storage in the allocatedDescs array */
2793 
2794  return result;
2795 }
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 2984 of file fd.c.

2985 {
2986  int i;
2987 
2988  /* Nothing to do if AllocateDir failed */
2989  if (dir == NULL)
2990  return 0;
2991 
2992  DO_DB(elog(LOG, "FreeDir: Allocated %d", numAllocatedDescs));
2993 
2994  /* Remove dir from list of allocated dirs, if it's present */
2995  for (i = numAllocatedDescs; --i >= 0;)
2996  {
2997  AllocateDesc *desc = &allocatedDescs[i];
2998 
2999  if (desc->kind == AllocateDescDir && desc->desc.dir == dir)
3000  return FreeDesc(desc);
3001  }
3002 
3003  /* Only get here if someone passes us a dir not in allocatedDescs */
3004  elog(WARNING, "dir passed to FreeDir was not obtained from AllocateDir");
3005 
3006  return closedir(dir);
3007 }

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

2805 {
2806  int i;
2807 
2808  DO_DB(elog(LOG, "FreeFile: Allocated %d", numAllocatedDescs));
2809 
2810  /* Remove file from list of allocated files, if it's present */
2811  for (i = numAllocatedDescs; --i >= 0;)
2812  {
2813  AllocateDesc *desc = &allocatedDescs[i];
2814 
2815  if (desc->kind == AllocateDescFile && desc->desc.file == file)
2816  return FreeDesc(desc);
2817  }
2818 
2819  /* Only get here if someone passes us a file not in allocatedDescs */
2820  elog(WARNING, "file passed to FreeFile was not obtained from AllocateFile");
2821 
2822  return fclose(file);
2823 }

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

3822 {
3823  int fd;
3824  int flags;
3825  int returncode;
3826 
3827  /*
3828  * Some OSs require directories to be opened read-only whereas other
3829  * systems don't allow us to fsync files opened read-only; so we need both
3830  * cases here. Using O_RDWR will cause us to fail to fsync files that are
3831  * not writable by our userid, but we assume that's OK.
3832  */
3833  flags = PG_BINARY;
3834  if (!isdir)
3835  flags |= O_RDWR;
3836  else
3837  flags |= O_RDONLY;
3838 
3839  fd = OpenTransientFile(fname, flags);
3840 
3841  /*
3842  * Some OSs don't allow us to open directories at all (Windows returns
3843  * EACCES), just ignore the error in that case. If desired also silently
3844  * ignoring errors about unreadable files. Log others.
3845  */
3846  if (fd < 0 && isdir && (errno == EISDIR || errno == EACCES))
3847  return 0;
3848  else if (fd < 0 && ignore_perm && errno == EACCES)
3849  return 0;
3850  else if (fd < 0)
3851  {
3852  ereport(elevel,
3854  errmsg("could not open file \"%s\": %m", fname)));
3855  return -1;
3856  }
3857 
3858  returncode = pg_fsync(fd);
3859 
3860  /*
3861  * Some OSes don't allow us to fsync directories at all, so we can ignore
3862  * those errors. Anything else needs to be logged.
3863  */
3864  if (returncode != 0 && !(isdir && (errno == EBADF || errno == EINVAL)))
3865  {
3866  int save_errno;
3867 
3868  /* close file upon error, might not be in transaction context */
3869  save_errno = errno;
3870  (void) CloseTransientFile(fd);
3871  errno = save_errno;
3872 
3873  ereport(elevel,
3875  errmsg("could not fsync file \"%s\": %m", fname)));
3876  return -1;
3877  }
3878 
3879  if (CloseTransientFile(fd) != 0)
3880  {
3881  ereport(elevel,
3883  errmsg("could not close file \"%s\": %m", fname)));
3884  return -1;
3885  }
3886 
3887  return 0;
3888 }

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

3898 {
3899  char parentpath[MAXPGPATH];
3900 
3901  strlcpy(parentpath, fname, MAXPGPATH);
3902  get_parent_directory(parentpath);
3903 
3904  /*
3905  * get_parent_directory() returns an empty string if the input argument is
3906  * just a file name (see comments in path.c), so handle that as being the
3907  * current directory.
3908  */
3909  if (strlen(parentpath) == 0)
3910  strlcpy(parentpath, ".", MAXPGPATH);
3911 
3912  if (fsync_fname_ext(parentpath, true, false, elevel) != 0)
3913  return -1;
3914 
3915  return 0;
3916 }
#define MAXPGPATH
void get_parent_directory(char *path)
Definition: path.c:991
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 3134 of file fd.c.

3135 {
3136  if (numTempTableSpaces > 0)
3137  {
3138  /* Advance nextTempTableSpace counter with wraparound */
3140  nextTempTableSpace = 0;
3142  }
3143  return InvalidOid;
3144 }
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 3116 of file fd.c.

3117 {
3118  int i;
3119 
3121  for (i = 0; i < numTempTableSpaces && i < numSpaces; ++i)
3122  tableSpaces[i] = tempTableSpaces[i];
3123 
3124  return i;
3125 }
bool TempTablespacesAreSet(void)
Definition: fd.c:3101

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:3202
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 3473 of file fd.c.

3474 {
3475  int pos;
3476  int savepos;
3477 
3478  /* Must start with "t". */
3479  if (name[0] != 't')
3480  return false;
3481 
3482  /* Followed by a non-empty string of digits and then an underscore. */
3483  for (pos = 1; isdigit((unsigned char) name[pos]); ++pos)
3484  ;
3485  if (pos == 1 || name[pos] != '_')
3486  return false;
3487 
3488  /* Followed by another nonempty string of digits. */
3489  for (savepos = ++pos; isdigit((unsigned char) name[pos]); ++pos)
3490  ;
3491  if (savepos == pos)
3492  return false;
3493 
3494  /* We might have _forkname or .segment or both. */
3495  if (name[pos] == '_')
3496  {
3497  int forkchar = forkname_chars(&name[pos + 1], NULL);
3498 
3499  if (forkchar <= 0)
3500  return false;
3501  pos += forkchar + 1;
3502  }
3503  if (name[pos] == '.')
3504  {
3505  int segchar;
3506 
3507  for (segchar = 1; isdigit((unsigned char) name[pos + segchar]); ++segchar)
3508  ;
3509  if (segchar <= 1)
3510  return false;
3511  pos += segchar;
3512  }
3513 
3514  /* Now we should be at the end. */
3515  if (name[pos] != '\0')
3516  return false;
3517  return true;
3518 }
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 2709 of file fd.c.

2710 {
2711  FILE *file;
2712  int save_errno;
2713 
2714  DO_DB(elog(LOG, "OpenPipeStream: Allocated %d (%s)",
2715  numAllocatedDescs, command));
2716 
2717  /* Can we allocate another non-virtual FD? */
2718  if (!reserveAllocatedDesc())
2719  ereport(ERROR,
2720  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2721  errmsg("exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"",
2722  maxAllocatedDescs, command)));
2723 
2724  /* Close excess kernel FDs. */
2725  ReleaseLruFiles();
2726 
2727 TryAgain:
2728  fflush(NULL);
2730  errno = 0;
2731  file = popen(command, mode);
2732  save_errno = errno;
2734  errno = save_errno;
2735  if (file != NULL)
2736  {
2738 
2739  desc->kind = AllocateDescPipe;
2740  desc->desc.file = file;
2743  return desc->desc.file;
2744  }
2745 
2746  if (errno == EMFILE || errno == ENFILE)
2747  {
2748  ereport(LOG,
2749  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2750  errmsg("out of file descriptors: %m; release and retry")));
2751  if (ReleaseLruFile())
2752  goto TryAgain;
2753  errno = save_errno;
2754  }
2755 
2756  return NULL;
2757 }
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:3134
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:95
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:3937
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:46
#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 2665 of file fd.c.

2666 {
2667  int fd;
2668 
2669  DO_DB(elog(LOG, "OpenTransientFile: Allocated %d (%s)",
2670  numAllocatedDescs, fileName));
2671 
2672  /* Can we allocate another non-virtual FD? */
2673  if (!reserveAllocatedDesc())
2674  ereport(ERROR,
2675  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2676  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2677  maxAllocatedDescs, fileName)));
2678 
2679  /* Close excess kernel FDs. */
2680  ReleaseLruFiles();
2681 
2682  fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
2683 
2684  if (fd >= 0)
2685  {
2687 
2688  desc->kind = AllocateDescRawFD;
2689  desc->desc.fd = fd;
2692 
2693  return fd;
2694  }
2695 
2696  return -1; /* failure */
2697 }

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:3796
static void walkdir(const char *path, void(*action)(const char *fname, bool isdir, int elevel), bool process_symlinks, int elevel)
Definition: fd.c:3682

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

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(), 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:129
@ 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 2947 of file fd.c.

2948 {
2949  struct dirent *dent;
2950 
2951  /* Give a generic message for AllocateDir failure, if caller didn't */
2952  if (dir == NULL)
2953  {
2954  ereport(elevel,
2956  errmsg("could not open directory \"%s\": %m",
2957  dirname)));
2958  return NULL;
2959  }
2960 
2961  errno = 0;
2962  if ((dent = readdir(dir)) != NULL)
2963  return dent;
2964 
2965  if (errno)
2966  ereport(elevel,
2968  errmsg("could not read directory \"%s\": %m",
2969  dirname)));
2970  return NULL;
2971 }
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 3297 of file fd.c.

3298 {
3299  char temp_path[MAXPGPATH + sizeof(PG_TBLSPC_DIR) + sizeof(TABLESPACE_VERSION_DIRECTORY) + sizeof(PG_TEMP_FILES_DIR)];
3300  DIR *spc_dir;
3301  struct dirent *spc_de;
3302 
3303  /*
3304  * First process temp files in pg_default ($PGDATA/base)
3305  */
3306  snprintf(temp_path, sizeof(temp_path), "base/%s", PG_TEMP_FILES_DIR);
3307  RemovePgTempFilesInDir(temp_path, true, false);
3308  RemovePgTempRelationFiles("base");
3309 
3310  /*
3311  * Cycle through temp directories for all non-default tablespaces.
3312  */
3313  spc_dir = AllocateDir(PG_TBLSPC_DIR);
3314 
3315  while ((spc_de = ReadDirExtended(spc_dir, PG_TBLSPC_DIR, LOG)) != NULL)
3316  {
3317  if (strcmp(spc_de->d_name, ".") == 0 ||
3318  strcmp(spc_de->d_name, "..") == 0)
3319  continue;
3320 
3321  snprintf(temp_path, sizeof(temp_path), "%s/%s/%s/%s",
3324  RemovePgTempFilesInDir(temp_path, true, false);
3325 
3326  snprintf(temp_path, sizeof(temp_path), "%s/%s/%s",
3328  RemovePgTempRelationFiles(temp_path);
3329  }
3330 
3331  FreeDir(spc_dir);
3332 
3333  /*
3334  * In EXEC_BACKEND case there is a pgsql_tmp directory at the top level of
3335  * DataDir as well. However, that is *not* cleaned here because doing so
3336  * would create a race condition. It's done separately, earlier in
3337  * postmaster startup.
3338  */
3339 }
int FreeDir(DIR *dir)
Definition: fd.c:2984
static void RemovePgTempRelationFiles(const char *tsdirname)
Definition: fd.c:3417
void RemovePgTempFilesInDir(const char *tmpdirname, bool missing_ok, bool unlink_all)
Definition: fd.c:3357
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2866
#define PG_TEMP_FILES_DIR
Definition: file_utils.h:62
#define PG_TBLSPC_DIR
Definition: relpath.h:41
#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_TBLSPC_DIR, 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 3357 of file fd.c.

3358 {
3359  DIR *temp_dir;
3360  struct dirent *temp_de;
3361  char rm_path[MAXPGPATH * 2];
3362 
3363  temp_dir = AllocateDir(tmpdirname);
3364 
3365  if (temp_dir == NULL && errno == ENOENT && missing_ok)
3366  return;
3367 
3368  while ((temp_de = ReadDirExtended(temp_dir, tmpdirname, LOG)) != NULL)
3369  {
3370  if (strcmp(temp_de->d_name, ".") == 0 ||
3371  strcmp(temp_de->d_name, "..") == 0)
3372  continue;
3373 
3374  snprintf(rm_path, sizeof(rm_path), "%s/%s",
3375  tmpdirname, temp_de->d_name);
3376 
3377  if (unlink_all ||
3378  strncmp(temp_de->d_name,
3380  strlen(PG_TEMP_FILE_PREFIX)) == 0)
3381  {
3382  PGFileType type = get_dirent_type(rm_path, temp_de, false, LOG);
3383 
3384  if (type == PGFILETYPE_ERROR)
3385  continue;
3386  else if (type == PGFILETYPE_DIR)
3387  {
3388  /* recursively remove contents, then directory itself */
3389  RemovePgTempFilesInDir(rm_path, false, true);
3390 
3391  if (rmdir(rm_path) < 0)
3392  ereport(LOG,
3394  errmsg("could not remove directory \"%s\": %m",
3395  rm_path)));
3396  }
3397  else
3398  {
3399  if (unlink(rm_path) < 0)
3400  ereport(LOG,
3402  errmsg("could not remove file \"%s\": %m",
3403  rm_path)));
3404  }
3405  }
3406  else
3407  ereport(LOG,
3408  (errmsg("unexpected file found in temporary-files directory: \"%s\"",
3409  rm_path)));
3410  }
3411 
3412  FreeDir(temp_dir);
3413 }
PGFileType get_dirent_type(const char *path, const struct dirent *de, bool look_through_symlinks, int elevel)
Definition: file_utils.c:526
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 3417 of file fd.c.

3418 {
3419  DIR *ts_dir;
3420  struct dirent *de;
3421  char dbspace_path[MAXPGPATH * 2];
3422 
3423  ts_dir = AllocateDir(tsdirname);
3424 
3425  while ((de = ReadDirExtended(ts_dir, tsdirname, LOG)) != NULL)
3426  {
3427  /*
3428  * We're only interested in the per-database directories, which have
3429  * numeric names. Note that this code will also (properly) ignore "."
3430  * and "..".
3431  */
3432  if (strspn(de->d_name, "0123456789") != strlen(de->d_name))
3433  continue;
3434 
3435  snprintf(dbspace_path, sizeof(dbspace_path), "%s/%s",
3436  tsdirname, de->d_name);
3437  RemovePgTempRelationFilesInDbspace(dbspace_path);
3438  }
3439 
3440  FreeDir(ts_dir);
3441 }
static void RemovePgTempRelationFilesInDbspace(const char *dbspacedirname)
Definition: fd.c:3445

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

3446 {
3447  DIR *dbspace_dir;
3448  struct dirent *de;
3449  char rm_path[MAXPGPATH * 2];
3450 
3451  dbspace_dir = AllocateDir(dbspacedirname);
3452 
3453  while ((de = ReadDirExtended(dbspace_dir, dbspacedirname, LOG)) != NULL)
3454  {
3455  if (!looks_like_temp_rel_name(de->d_name))
3456  continue;
3457 
3458  snprintf(rm_path, sizeof(rm_path), "%s/%s",
3459  dbspacedirname, de->d_name);
3460 
3461  if (unlink(rm_path) < 0)
3462  ereport(LOG,
3464  errmsg("could not remove file \"%s\": %m",
3465  rm_path)));
3466  }
3467 
3468  FreeDir(dbspace_dir);
3469 }
bool looks_like_temp_rel_name(const char *name)
Definition: fd.c:3473

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:528
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 2531 of file fd.c.

2532 {
2533  AllocateDesc *newDescs;
2534  int newMax;
2535 
2536  /* Quick out if array already has a free slot. */
2538  return true;
2539 
2540  /*
2541  * If the array hasn't yet been created in the current process, initialize
2542  * it with FD_MINFREE / 3 elements. In many scenarios this is as many as
2543  * we will ever need, anyway. We don't want to look at max_safe_fds
2544  * immediately because set_max_safe_fds() may not have run yet.
2545  */
2546  if (allocatedDescs == NULL)
2547  {
2548  newMax = FD_MINFREE / 3;
2549  newDescs = (AllocateDesc *) malloc(newMax * sizeof(AllocateDesc));
2550  /* Out of memory already? Treat as fatal error. */
2551  if (newDescs == NULL)
2552  ereport(ERROR,
2553  (errcode(ERRCODE_OUT_OF_MEMORY),
2554  errmsg("out of memory")));
2555  allocatedDescs = newDescs;
2556  maxAllocatedDescs = newMax;
2557  return true;
2558  }
2559 
2560  /*
2561  * Consider enlarging the array beyond the initial allocation used above.
2562  * By the time this happens, max_safe_fds should be known accurately.
2563  *
2564  * We mustn't let allocated descriptors hog all the available FDs, and in
2565  * practice we'd better leave a reasonable number of FDs for VFD use. So
2566  * set the maximum to max_safe_fds / 3. (This should certainly be at
2567  * least as large as the initial size, FD_MINFREE / 3, so we aren't
2568  * tightening the restriction here.) Recall that "external" FDs are
2569  * allowed to consume another third of max_safe_fds.
2570  */
2571  newMax = max_safe_fds / 3;
2572  if (newMax > maxAllocatedDescs)
2573  {
2574  newDescs = (AllocateDesc *) realloc(allocatedDescs,
2575  newMax * sizeof(AllocateDesc));
2576  /* Treat out-of-memory as a non-fatal error. */
2577  if (newDescs == NULL)
2578  return false;
2579  allocatedDescs = newDescs;
2580  maxAllocatedDescs = newMax;
2581  return true;
2582  }
2583 
2584  /* Can't enlarge allocatedDescs[] any more. */
2585  return false;
2586 }
#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 4075 of file fd.c.

4076 {
4077  return psprintf("File %d", DatumGetInt32(res));
4078 }
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 4061 of file fd.c.

4062 {
4063  File file = (File) DatumGetInt32(res);
4064  Vfd *vfdP;
4065 
4066  Assert(FileIsValid(file));
4067 
4068  vfdP = &VfdCache[file];
4069  vfdP->resowner = NULL;
4070 
4071  FileClose(file);
4072 }

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:1203
#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 3072 of file fd.c.

3073 {
3074  Assert(numSpaces >= 0);
3075  tempTableSpaces = tableSpaces;
3076  numTempTableSpaces = numSpaces;
3077 
3078  /*
3079  * Select a random starting point in the list. This is to minimize
3080  * conflicts between backends that are most likely sharing the same list
3081  * of temp tablespaces. Note that if we create multiple temp files in the
3082  * same transaction, we'll advance circularly through the list --- this
3083  * ensures that large temporary sort files are nicely spread across all
3084  * available tablespaces.
3085  */
3086  if (numSpaces > 1)
3088  0, numSpaces - 1);
3089  else
3090  nextTempTableSpace = 0;
3091 }
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 3568 of file fd.c.

3569 {
3570  bool xlog_is_symlink;
3571 
3572  /* We can skip this whole thing if fsync is disabled. */
3573  if (!enableFsync)
3574  return;
3575 
3576  /*
3577  * If pg_wal is a symlink, we'll need to recurse into it separately,
3578  * because the first walkdir below will ignore it.
3579  */
3580  xlog_is_symlink = false;
3581 
3582  {
3583  struct stat st;
3584 
3585  if (lstat("pg_wal", &st) < 0)
3586  ereport(LOG,
3588  errmsg("could not stat file \"%s\": %m",
3589  "pg_wal")));
3590  else if (S_ISLNK(st.st_mode))
3591  xlog_is_symlink = true;
3592  }
3593 
3594 #ifdef HAVE_SYNCFS
3596  {
3597  DIR *dir;
3598  struct dirent *de;
3599 
3600  /*
3601  * On Linux, we don't have to open every single file one by one. We
3602  * can use syncfs() to sync whole filesystems. We only expect
3603  * filesystem boundaries to exist where we tolerate symlinks, namely
3604  * pg_wal and the tablespaces, so we call syncfs() for each of those
3605  * directories.
3606  */
3607 
3608  /* Prepare to report progress syncing the data directory via syncfs. */
3610 
3611  /* Sync the top level pgdata directory. */
3612  do_syncfs(".");
3613  /* If any tablespaces are configured, sync each of those. */
3614  dir = AllocateDir(PG_TBLSPC_DIR);
3615  while ((de = ReadDirExtended(dir, PG_TBLSPC_DIR, LOG)))
3616  {
3617  char path[MAXPGPATH];
3618 
3619  if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
3620  continue;
3621 
3622  snprintf(path, MAXPGPATH, "%s/%s", PG_TBLSPC_DIR, de->d_name);
3623  do_syncfs(path);
3624  }
3625  FreeDir(dir);
3626  /* If pg_wal is a symlink, process that too. */
3627  if (xlog_is_symlink)
3628  do_syncfs("pg_wal");
3629  return;
3630  }
3631 #endif /* !HAVE_SYNCFS */
3632 
3633 #ifdef PG_FLUSH_DATA_WORKS
3634  /* Prepare to report progress of the pre-fsync phase. */
3636 
3637  /*
3638  * If possible, hint to the kernel that we're soon going to fsync the data
3639  * directory and its contents. Errors in this step are even less
3640  * interesting than normal, so log them only at DEBUG1.
3641  */
3642  walkdir(".", pre_sync_fname, false, DEBUG1);
3643  if (xlog_is_symlink)
3644  walkdir("pg_wal", pre_sync_fname, false, DEBUG1);
3645  walkdir(PG_TBLSPC_DIR, pre_sync_fname, true, DEBUG1);
3646 #endif
3647 
3648  /* Prepare to report progress syncing the data directory via fsync. */
3650 
3651  /*
3652  * Now we do the fsync()s in the same order.
3653  *
3654  * The main call ignores symlinks, so in addition to specially processing
3655  * pg_wal if it's a symlink, pg_tblspc has to be visited separately with
3656  * process_symlinks = true. Note that if there are any plain directories
3657  * in pg_tblspc, they'll get fsync'd twice. That's not an expected case
3658  * so we don't worry about optimizing it.
3659  */
3660  walkdir(".", datadir_fsync_fname, false, LOG);
3661  if (xlog_is_symlink)
3662  walkdir("pg_wal", datadir_fsync_fname, false, LOG);
3664 }
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:3783
@ 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, PG_TBLSPC_DIR, 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, "%s/%u/%s/%s",
1796  }
1797 }
static char * tablespace
Definition: pgbench.c:216

References InvalidOid, MAXPGPATH, PG_TBLSPC_DIR, 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 3101 of file fd.c.

3102 {
3103  return (numTempTableSpaces >= 0);
3104 }

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

3797 {
3798  if (isdir)
3799  {
3800  if (rmdir(fname) != 0 && errno != ENOENT)
3801  ereport(elevel,
3803  errmsg("could not remove directory \"%s\": %m", fname)));
3804  }
3805  else
3806  {
3807  /* Use PathNameDeleteTemporaryFile to report filesize */
3808  PathNameDeleteTemporaryFile(fname, false);
3809  }
3810 }
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 3682 of file fd.c.

3686 {
3687  DIR *dir;
3688  struct dirent *de;
3689 
3690  dir = AllocateDir(path);
3691 
3692  while ((de = ReadDirExtended(dir, path, elevel)) != NULL)
3693  {
3694  char subpath[MAXPGPATH * 2];
3695 
3697 
3698  if (strcmp(de->d_name, ".") == 0 ||
3699  strcmp(de->d_name, "..") == 0)
3700  continue;
3701 
3702  snprintf(subpath, sizeof(subpath), "%s/%s", path, de->d_name);
3703 
3704  switch (get_dirent_type(subpath, de, process_symlinks, elevel))
3705  {
3706  case PGFILETYPE_REG:
3707  (*action) (subpath, false, elevel);
3708  break;
3709  case PGFILETYPE_DIR:
3710  walkdir(subpath, action, false, elevel);
3711  break;
3712  default:
3713 
3714  /*
3715  * Errors are already reported directly by get_dirent_type(),
3716  * and any remaining symlinks and unknown file types are
3717  * ignored.
3718  */
3719  break;
3720  }
3721  }
3722 
3723  FreeDir(dir); /* we ignore any error here */
3724 
3725  /*
3726  * It's important to fsync the destination directory itself as individual
3727  * file fsyncs don't guarantee that the directory entry for the file is
3728  * synced. However, skip this if AllocateDir failed; the action function
3729  * might not be robust against that.
3730  */
3731  if (dir)
3732  (*action) (path, true, elevel);
3733 }
@ 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:4075
static void ResOwnerReleaseFile(Datum res)
Definition: fd.c:4061
@ 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