PostgreSQL Source Code  git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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 "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 179 of file fd.c.

◆ FD_CLOSE_AT_EOXACT

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

Definition at line 192 of file fd.c.

◆ FD_DELETE_AT_CLOSE

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

Definition at line 191 of file fd.c.

◆ FD_MINFREE

#define FD_MINFREE   48

Definition at line 137 of file fd.c.

◆ FD_TEMP_FILE_LIMIT

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

Definition at line 193 of file fd.c.

◆ FileIsNotOpen

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

Definition at line 188 of file fd.c.

◆ FileIsValid

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

Definition at line 185 of file fd.c.

◆ NUM_RESERVED_FDS

#define NUM_RESERVED_FDS   10

Definition at line 128 of file fd.c.

◆ VFD_CLOSED

#define VFD_CLOSED   (-1)

Definition at line 183 of file fd.c.

Typedef Documentation

◆ Vfd

typedef struct vfd Vfd

Enumeration Type Documentation

◆ AllocateDescKind

Enumerator
AllocateDescFile 
AllocateDescPipe 
AllocateDescDir 
AllocateDescRawFD 

Definition at line 246 of file fd.c.

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

Function Documentation

◆ AcquireExternalFD()

bool AcquireExternalFD ( void  )

Definition at line 1185 of file fd.c.

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

References max_safe_fds, numExternalFDs, and ReserveExternalFD().

Referenced by CreateWaitEventSet(), and libpqsrv_connect_prepare().

◆ AllocateDir()

DIR* AllocateDir ( const char *  dirname)

Definition at line 2865 of file fd.c.

2866 {
2867  DIR *dir;
2868 
2869  DO_DB(elog(LOG, "AllocateDir: Allocated %d (%s)",
2870  numAllocatedDescs, dirname));
2871 
2872  /* Can we allocate another non-virtual FD? */
2873  if (!reserveAllocatedDesc())
2874  ereport(ERROR,
2875  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2876  errmsg("exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"",
2877  maxAllocatedDescs, dirname)));
2878 
2879  /* Close excess kernel FDs. */
2880  ReleaseLruFiles();
2881 
2882 TryAgain:
2883  if ((dir = opendir(dirname)) != NULL)
2884  {
2886 
2887  desc->kind = AllocateDescDir;
2888  desc->desc.dir = dir;
2891  return desc->desc.dir;
2892  }
2893 
2894  if (errno == EMFILE || errno == ENFILE)
2895  {
2896  int save_errno = errno;
2897 
2898  ereport(LOG,
2899  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2900  errmsg("out of file descriptors: %m; release and retry")));
2901  errno = 0;
2902  if (ReleaseLruFile())
2903  goto TryAgain;
2904  errno = save_errno;
2905  }
2906 
2907  return NULL;
2908 }
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:1381
static int maxAllocatedDescs
Definition: fd.c:267
static int numAllocatedDescs
Definition: fd.c:266
#define DO_DB(A)
Definition: fd.c:179
static AllocateDesc * allocatedDescs
Definition: fd.c:268
static bool reserveAllocatedDesc(void)
Definition: fd.c:2530
static void ReleaseLruFiles(void)
Definition: fd.c:1403
SubTransactionId create_subid
Definition: fd.c:257
DIR * dir
Definition: fd.c:261
union AllocateDesc::@20 desc
AllocateDescKind kind
Definition: fd.c:256
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 2605 of file fd.c.

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

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

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

4051 {
4052  int *flags = (int *) extra;
4053 
4054  io_direct_flags = *flags;
4055 }
int io_direct_flags
Definition: fd.c:167

References io_direct_flags.

◆ AtEOSubXact_Files()

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

Definition at line 3154 of file fd.c.

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

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

◆ AtEOXact_Files()

void AtEOXact_Files ( bool  isCommit)

Definition at line 3187 of file fd.c.

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

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

1087 {
1088  return BasicOpenFilePerm(fileName, fileFlags, pg_file_create_mode);
1089 }
int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode)
Definition: fd.c:1108
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 1108 of file fd.c.

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

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

References CleanupTempFiles().

Referenced by InitTemporaryFileAccess().

◆ check_debug_io_direct()

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

Definition at line 3965 of file fd.c.

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

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

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

3043 {
3044  Index i;
3045 
3046  if (SizeVfdCache > 0)
3047  {
3048  Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
3049  for (i = 1; i < SizeVfdCache; i++)
3050  {
3051  if (!FileIsNotOpen(i))
3052  LruDelete(i);
3053  }
3054  }
3055 }
static void LruDelete(File file)
Definition: fd.c:1286

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

Referenced by standard_ProcessUtility().

◆ ClosePipeStream()

int ClosePipeStream ( FILE *  file)

Definition at line 3013 of file fd.c.

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

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

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

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(), SnapBuildRestoreContents(), SnapBuildRestoreSnapshot(), 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 963 of file fd.c.

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

3783 {
3784  ereport_startup_progress("syncing data directory (fsync), elapsed time: %ld.%02d s, current path: %s",
3785  fname);
3786 
3787  /*
3788  * We want to silently ignoring errors about unreadable files. Pass that
3789  * desire on to fsync_fname_ext().
3790  */
3791  fsync_fname_ext(fname, isdir, true, elevel);
3792 }
int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3820
#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 1267 of file fd.c.

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

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

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

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

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

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

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

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

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

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

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

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

◆ FileGetRawFlags()

int FileGetRawFlags ( File  file)

Definition at line 2509 of file fd.c.

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

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

◆ FileGetRawMode()

mode_t FileGetRawMode ( File  file)

Definition at line 2519 of file fd.c.

2520 {
2521  Assert(FileIsValid(file));
2522  return VfdCache[file].fileMode;
2523 }
mode_t fileMode
Definition: fd.c:207

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

2077 {
2078  Assert(FileIsValid(file));
2079 
2080  DO_DB(elog(LOG, "FilePrefetch: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
2081  file, VfdCache[file].fileName,
2082  (int64) offset, (int64) amount));
2083 
2084 #if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
2085  {
2086  int returnCode;
2087 
2088  returnCode = FileAccess(file);
2089  if (returnCode < 0)
2090  return returnCode;
2091 
2092 retry:
2093  pgstat_report_wait_start(wait_event_info);
2094  returnCode = posix_fadvise(VfdCache[file].fd, offset, amount,
2095  POSIX_FADV_WILLNEED);
2097 
2098  if (returnCode == EINTR)
2099  goto retry;
2100 
2101  return returnCode;
2102  }
2103 #elif defined(__darwin__)
2104  {
2105  struct radvisory
2106  {
2107  off_t ra_offset; /* offset into the file */
2108  int ra_count; /* size of the read */
2109  } ra;
2110  int returnCode;
2111 
2112  returnCode = FileAccess(file);
2113  if (returnCode < 0)
2114  return returnCode;
2115 
2116  ra.ra_offset = offset;
2117  ra.ra_count = amount;
2118  pgstat_report_wait_start(wait_event_info);
2119  returnCode = fcntl(VfdCache[file].fd, F_RDADVISE, &ra);
2121  if (returnCode != -1)
2122  return 0;
2123  else
2124  return errno;
2125  }
2126 #else
2127  return 0;
2128 #endif
2129 }

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

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

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

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

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

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

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

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

2133 {
2134  int returnCode;
2135 
2136  Assert(FileIsValid(file));
2137 
2138  DO_DB(elog(LOG, "FileWriteback: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
2139  file, VfdCache[file].fileName,
2140  (int64) offset, (int64) nbytes));
2141 
2142  if (nbytes <= 0)
2143  return;
2144 
2145  if (VfdCache[file].fileFlags & PG_O_DIRECT)
2146  return;
2147 
2148  returnCode = FileAccess(file);
2149  if (returnCode < 0)
2150  return;
2151 
2152  pgstat_report_wait_start(wait_event_info);
2153  pg_flush_data(VfdCache[file].fd, offset, nbytes);
2155 }
void pg_flush_data(int fd, off_t offset, off_t nbytes)
Definition: fd.c:524

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

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

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

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

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

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

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

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

1472 {
1473  Vfd *vfdP = &VfdCache[file];
1474 
1475  DO_DB(elog(LOG, "FreeVfd: %d (%s)",
1476  file, vfdP->fileName ? vfdP->fileName : ""));
1477 
1478  if (vfdP->fileName != NULL)
1479  {
1480  free(vfdP->fileName);
1481  vfdP->fileName = NULL;
1482  }
1483  vfdP->fdstate = 0x0;
1484 
1485  vfdP->nextFree = VfdCache[0].nextFree;
1486  VfdCache[0].nextFree = file;
1487 }
#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 3820 of file fd.c.

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

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

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

3134 {
3135  if (numTempTableSpaces > 0)
3136  {
3137  /* Advance nextTempTableSpace counter with wraparound */
3139  nextTempTableSpace = 0;
3141  }
3142  return InvalidOid;
3143 }
static int nextTempTableSpace
Definition: fd.c:289
#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 3115 of file fd.c.

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

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

Referenced by FileSetInit().

◆ InitFileAccess()

void InitFileAccess ( void  )

Definition at line 902 of file fd.c.

903 {
904  Assert(SizeVfdCache == 0); /* call me only once */
905 
906  /* initialize cache header entry */
907  VfdCache = (Vfd *) malloc(sizeof(Vfd));
908  if (VfdCache == NULL)
909  ereport(FATAL,
910  (errcode(ERRCODE_OUT_OF_MEMORY),
911  errmsg("out of memory")));
912 
913  MemSet((char *) &(VfdCache[0]), 0, sizeof(Vfd));
915 
916  SizeVfdCache = 1;
917 }
#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 932 of file fd.c.

933 {
934  Assert(SizeVfdCache != 0); /* InitFileAccess() needs to have run */
935  Assert(!temporary_files_allowed); /* call me only once */
936 
937  /*
938  * Register before-shmem-exit hook to ensure temp files are dropped while
939  * we can still report stats.
940  */
942 
943 #ifdef USE_ASSERT_CHECKING
944  temporary_files_allowed = true;
945 #endif
946 }
static void BeforeShmemExit_Files(int code, Datum arg)
Definition: fd.c:3201
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 1312 of file fd.c.

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

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

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

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

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

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

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

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

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

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

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

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

1660 {
1661  if (MakePGDirectory(directory) < 0)
1662  {
1663  if (errno == EEXIST)
1664  return;
1665 
1666  /*
1667  * Failed. Try to create basedir first in case it's missing. Tolerate
1668  * EEXIST to close a race against another process following the same
1669  * algorithm.
1670  */
1671  if (MakePGDirectory(basedir) < 0 && errno != EEXIST)
1672  ereport(ERROR,
1674  errmsg("cannot create temporary directory \"%s\": %m",
1675  basedir)));
1676 
1677  /* Try again. */
1678  if (MakePGDirectory(directory) < 0 && errno != EEXIST)
1679  ereport(ERROR,
1681  errmsg("cannot create temporary subdirectory \"%s\": %m",
1682  directory)));
1683  }
1684 }
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 1860 of file fd.c.

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

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

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

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

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

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

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

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

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

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

480 {
481  int rc;
482 
483  if (!enableFsync)
484  return 0;
485 
486 retry:
487  rc = fdatasync(fd);
488 
489  if (rc == -1 && errno == EINTR)
490  goto retry;
491 
492  return rc;
493 }
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 502 of file fd.c.

503 {
504  struct stat st;
505 
506  Assert(name != NULL);
507 
508  if (stat(name, &st) == 0)
509  return !S_ISDIR(st.st_mode);
510  else if (!(errno == ENOENT || errno == ENOTDIR || errno == EACCES))
511  ereport(ERROR,
513  errmsg("could not access file \"%s\": %m", name)));
514 
515  return false;
516 }
#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 524 of file fd.c.

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

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

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

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

◆ pg_fsync_no_writethrough()

int pg_fsync_no_writethrough ( int  fd)

Definition at line 440 of file fd.c.

441 {
442  int rc;
443 
444  if (!enableFsync)
445  return 0;
446 
447 retry:
448  rc = fsync(fd);
449 
450  if (rc == -1 && errno == EINTR)
451  goto retry;
452 
453  return rc;
454 }
#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 460 of file fd.c.

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

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

703 {
704  int ret;
705 
706 retry:
707  ret = ftruncate(fd, length);
708 
709  if (ret == -1 && errno == EINTR)
710  goto retry;
711 
712  return ret;
713 }
#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 719 of file fd.c.

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

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

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

1547 {
1550 
1551  /* Backup mechanism for closing at end of xact. */
1554 }
static void ResourceOwnerRememberFile(ResourceOwner owner, File file)
Definition: fd.c:371

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

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

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

1404 {
1406  {
1407  if (!ReleaseLruFile())
1408  break;
1409  }
1410 }

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

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

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

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

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

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

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

1528 {
1530 
1531  if (log_temp_files >= 0)
1532  {
1533  if ((size / 1024) >= log_temp_files)
1534  ereport(LOG,
1535  (errmsg("temporary file: path \"%s\", size %lu",
1536  path, (unsigned long) size)));
1537  }
1538 }
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 2530 of file fd.c.

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

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

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

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

377 {
379 }
static const ResourceOwnerDesc file_resowner_desc
Definition: fd.c:360
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 371 of file fd.c.

372 {
374 }
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 4074 of file fd.c.

4075 {
4076  return psprintf("File %d", DatumGetInt32(res));
4077 }
static int32 DatumGetInt32(Datum X)
Definition: postgres.h:202
char * psprintf(const char *fmt,...)
Definition: psprintf.c:43

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

◆ ResOwnerReleaseFile()

static void ResOwnerReleaseFile ( Datum  res)
static

Definition at line 4060 of file fd.c.

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

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

◆ set_max_safe_fds()

void set_max_safe_fds ( void  )

Definition at line 1043 of file fd.c.

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

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

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

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

1779 {
1780  /*
1781  * Identify the tempfile directory for this tablespace.
1782  *
1783  * If someone tries to specify pg_global, use pg_default instead.
1784  */
1785  if (tablespace == InvalidOid ||
1786  tablespace == DEFAULTTABLESPACE_OID ||
1787  tablespace == GLOBALTABLESPACE_OID)
1788  snprintf(path, MAXPGPATH, "base/%s", PG_TEMP_FILES_DIR);
1789  else
1790  {
1791  /* All other tablespaces are accessed via symlinks */
1792  snprintf(path, MAXPGPATH, "%s/%u/%s/%s",
1795  }
1796 }
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 3100 of file fd.c.

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

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

3796 {
3797  if (isdir)
3798  {
3799  if (rmdir(fname) != 0 && errno != ENOENT)
3800  ereport(elevel,
3802  errmsg("could not remove directory \"%s\": %m", fname)));
3803  }
3804  else
3805  {
3806  /* Use PathNameDeleteTemporaryFile to report filesize */
3807  PathNameDeleteTemporaryFile(fname, false);
3808  }
3809 }
bool PathNameDeleteTemporaryFile(const char *path, bool error_on_failure)
Definition: fd.c:1931

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

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

Definition at line 360 of file fd.c.

Referenced by ResourceOwnerForgetFile(), and ResourceOwnerRememberFile().

◆ have_xact_temporary_files

bool have_xact_temporary_files = false
static

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

Referenced by set_max_safe_fds().

◆ max_safe_fds

int max_safe_fds = FD_MINFREE

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

Referenced by GetNextTempTableSpace(), and SetTempTablespaces().

◆ nfile

int nfile = 0
static

◆ numAllocatedDescs

◆ numExternalFDs

int numExternalFDs = 0
static

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

Referenced by SyncDataDirectory().

◆ SizeVfdCache

Size SizeVfdCache = 0
static

◆ tempFileCounter

long tempFileCounter = 0
static

Definition at line 279 of file fd.c.

Referenced by OpenTemporaryFileInTablespace().

◆ temporary_files_size

uint64 temporary_files_size = 0
static

Definition at line 235 of file fd.c.

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

◆ tempTableSpaces

Oid* tempTableSpaces = NULL
static

◆ VfdCache