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/aio.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)
 
int FileStartReadV (PgAioHandle *ioh, File file, int iovcnt, off_t offset, uint32 wait_event_info)
 
ssize_t FileWriteV (File file, const struct iovec *iov, int iovcnt, off_t offset, uint32 wait_event_info)
 
int FileSync (File file, uint32 wait_event_info)
 
int FileZero (File file, off_t offset, off_t amount, uint32 wait_event_info)
 
int FileFallocate (File file, off_t offset, off_t amount, uint32 wait_event_info)
 
off_t FileSize (File file)
 
int FileTruncate (File file, off_t offset, uint32 wait_event_info)
 
char * FilePathName (File file)
 
int FileGetRawDesc (File file)
 
int FileGetRawFlags (File file)
 
mode_t FileGetRawMode (File file)
 
FILE * AllocateFile (const char *name, const char *mode)
 
int OpenTransientFile (const char *fileName, int fileFlags)
 
int OpenTransientFilePerm (const char *fileName, int fileFlags, mode_t fileMode)
 
FILE * OpenPipeStream (const char *command, const char *mode)
 
int FreeFile (FILE *file)
 
int CloseTransientFile (int fd)
 
DIRAllocateDir (const char *dirname)
 
struct direntReadDir (DIR *dir, const char *dirname)
 
struct direntReadDirExtended (DIR *dir, const char *dirname, int elevel)
 
int FreeDir (DIR *dir)
 
int ClosePipeStream (FILE *file)
 
void closeAllVfds (void)
 
void SetTempTablespaces (Oid *tableSpaces, int numSpaces)
 
bool TempTablespacesAreSet (void)
 
int GetTempTablespaces (Oid *tableSpaces, int numSpaces)
 
Oid GetNextTempTableSpace (void)
 
void AtEOSubXact_Files (bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
 
void AtEOXact_Files (bool isCommit)
 
void RemovePgTempFiles (void)
 
void RemovePgTempFilesInDir (const char *tmpdirname, bool missing_ok, bool unlink_all)
 
bool looks_like_temp_rel_name (const char *name)
 
void SyncDataDirectory (void)
 
int fsync_fname_ext (const char *fname, bool isdir, bool ignore_perm, int elevel)
 
int MakePGDirectory (const char *directoryName)
 
int data_sync_elevel (int elevel)
 
bool check_debug_io_direct (char **newval, void **extra, GucSource source)
 
void assign_debug_io_direct (const char *newval, void *extra)
 

Variables

int max_files_per_process = 1000
 
int max_safe_fds = FD_MINFREE
 
bool data_sync_retry = false
 
int recovery_init_sync_method = DATA_DIR_SYNC_METHOD_FSYNC
 
int io_direct_flags
 
static VfdVfdCache
 
static Size SizeVfdCache = 0
 
static int nfile = 0
 
static bool have_xact_temporary_files = false
 
static uint64 temporary_files_size = 0
 
static int numAllocatedDescs = 0
 
static int maxAllocatedDescs = 0
 
static AllocateDescallocatedDescs = NULL
 
static int numExternalFDs = 0
 
static long tempFileCounter = 0
 
static OidtempTableSpaces = NULL
 
static int numTempTableSpaces = -1
 
static int nextTempTableSpace = 0
 
static const ResourceOwnerDesc file_resowner_desc
 

Macro Definition Documentation

◆ DO_DB

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

Definition at line 180 of file fd.c.

◆ FD_CLOSE_AT_EOXACT

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

Definition at line 193 of file fd.c.

◆ FD_DELETE_AT_CLOSE

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

Definition at line 192 of file fd.c.

◆ FD_MINFREE

#define FD_MINFREE   48

Definition at line 138 of file fd.c.

◆ FD_TEMP_FILE_LIMIT

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

Definition at line 194 of file fd.c.

◆ FileIsNotOpen

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

Definition at line 189 of file fd.c.

◆ FileIsValid

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

Definition at line 186 of file fd.c.

◆ NUM_RESERVED_FDS

#define NUM_RESERVED_FDS   10

Definition at line 129 of file fd.c.

◆ VFD_CLOSED

#define VFD_CLOSED   (-1)

Definition at line 184 of file fd.c.

Typedef Documentation

◆ Vfd

typedef struct vfd Vfd

Enumeration Type Documentation

◆ AllocateDescKind

Enumerator
AllocateDescFile 
AllocateDescPipe 
AllocateDescDir 
AllocateDescRawFD 

Definition at line 247 of file fd.c.

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

Function Documentation

◆ AcquireExternalFD()

bool AcquireExternalFD ( void  )

Definition at line 1188 of file fd.c.

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

References max_safe_fds, numExternalFDs, and ReserveExternalFD().

Referenced by CreateWaitEventSet(), and libpqsrv_connect_prepare().

◆ AllocateDir()

DIR * AllocateDir ( const char *  dirname)

Definition at line 2907 of file fd.c.

2908{
2909 DIR *dir;
2910
2911 DO_DB(elog(LOG, "AllocateDir: Allocated %d (%s)",
2912 numAllocatedDescs, dirname));
2913
2914 /* Can we allocate another non-virtual FD? */
2915 if (!reserveAllocatedDesc())
2916 ereport(ERROR,
2917 (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2918 errmsg("exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"",
2919 maxAllocatedDescs, dirname)));
2920
2921 /* Close excess kernel FDs. */
2923
2924TryAgain:
2925 if ((dir = opendir(dirname)) != NULL)
2926 {
2928
2929 desc->kind = AllocateDescDir;
2930 desc->desc.dir = dir;
2933 return desc->desc.dir;
2934 }
2935
2936 if (errno == EMFILE || errno == ENFILE)
2937 {
2938 int save_errno = errno;
2939
2940 ereport(LOG,
2941 (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2942 errmsg("out of file descriptors: %m; release and retry")));
2943 errno = 0;
2944 if (ReleaseLruFile())
2945 goto TryAgain;
2946 errno = save_errno;
2947 }
2948
2949 return NULL;
2950}
DIR * opendir(const char *)
Definition: dirent.c:33
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define LOG
Definition: elog.h:31
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:226
#define ereport(elevel,...)
Definition: elog.h:149
static bool ReleaseLruFile(void)
Definition: fd.c:1386
static int maxAllocatedDescs
Definition: fd.c:268
static int numAllocatedDescs
Definition: fd.c:267
#define DO_DB(A)
Definition: fd.c:180
static AllocateDesc * allocatedDescs
Definition: fd.c:269
static bool reserveAllocatedDesc(void)
Definition: fd.c:2569
static void ReleaseLruFiles(void)
Definition: fd.c:1408
SubTransactionId create_subid
Definition: fd.c:258
DIR * dir
Definition: fd.c:262
union AllocateDesc::@20 desc
AllocateDescKind kind
Definition: fd.c:257
Definition: dirent.c:26
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:791

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

2645{
2646 FILE *file;
2647
2648 DO_DB(elog(LOG, "AllocateFile: Allocated %d (%s)",
2650
2651 /* Can we allocate another non-virtual FD? */
2652 if (!reserveAllocatedDesc())
2653 ereport(ERROR,
2654 (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2655 errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2657
2658 /* Close excess kernel FDs. */
2660
2661TryAgain:
2662 if ((file = fopen(name, mode)) != NULL)
2663 {
2665
2666 desc->kind = AllocateDescFile;
2667 desc->desc.file = file;
2670 return desc->desc.file;
2671 }
2672
2673 if (errno == EMFILE || errno == ENFILE)
2674 {
2675 int save_errno = errno;
2676
2677 ereport(LOG,
2678 (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2679 errmsg("out of file descriptors: %m; release and retry")));
2680 errno = 0;
2681 if (ReleaseLruFile())
2682 goto TryAgain;
2683 errno = save_errno;
2684 }
2685
2686 return NULL;
2687}
static PgChecksumMode mode
Definition: pg_checksums.c:55
FILE * file
Definition: fd.c:261
const char * name

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

Referenced by AlterSystemSetConfigFile(), apw_dump_now(), apw_load_buffers(), BeginCopyFrom(), BeginCopyTo(), checkControlFile(), do_pg_backup_stop(), entry_reset(), existsTimeLineHistory(), ExportSnapshot(), gc_qtexts(), GetHugePageSize(), ImportSnapshot(), load_dh_file(), load_relcache_init_file(), open_auth_file(), parse_extension_control_file(), ParseConfigFile(), 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 1418 of file fd.c.

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

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

Referenced by PathNameOpenFilePerm().

◆ assign_debug_io_direct()

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

Definition at line 4094 of file fd.c.

4095{
4096 int *flags = (int *) extra;
4097
4098 io_direct_flags = *flags;
4099}
int io_direct_flags
Definition: fd.c:168

References io_direct_flags.

◆ AtEOSubXact_Files()

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

Definition at line 3196 of file fd.c.

3198{
3199 Index i;
3200
3201 for (i = 0; i < numAllocatedDescs; i++)
3202 {
3203 if (allocatedDescs[i].create_subid == mySubid)
3204 {
3205 if (isCommit)
3206 allocatedDescs[i].create_subid = parentSubid;
3207 else
3208 {
3209 /* have to recheck the item after FreeDesc (ugly) */
3211 }
3212 }
3213 }
3214}
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2803

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

◆ AtEOXact_Files()

void AtEOXact_Files ( bool  isCommit)

Definition at line 3229 of file fd.c.

3230{
3231 CleanupTempFiles(isCommit, false);
3232 tempTableSpaces = NULL;
3233 numTempTableSpaces = -1;
3234}
static int numTempTableSpaces
Definition: fd.c:289
static Oid * tempTableSpaces
Definition: fd.c:288
static void CleanupTempFiles(bool isCommit, bool isProcExit)
Definition: fd.c:3266

References CleanupTempFiles(), numTempTableSpaces, and tempTableSpaces.

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

◆ BasicOpenFile()

int BasicOpenFile ( const char *  fileName,
int  fileFlags 
)

Definition at line 1089 of file fd.c.

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

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

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

3244{
3245 CleanupTempFiles(false, true);
3246
3247 /* prevent further temp files from being created */
3248#ifdef USE_ASSERT_CHECKING
3249 temporary_files_allowed = false;
3250#endif
3251}

References CleanupTempFiles().

Referenced by InitTemporaryFileAccess().

◆ check_debug_io_direct()

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

Definition at line 4007 of file fd.c.

4008{
4009 bool result = true;
4010 int flags;
4011
4012#if PG_O_DIRECT == 0
4013 if (strcmp(*newval, "") != 0)
4014 {
4015 GUC_check_errdetail("\"%s\" is not supported on this platform.",
4016 "debug_io_direct");
4017 result = false;
4018 }
4019 flags = 0;
4020#else
4021 List *elemlist;
4022 ListCell *l;
4023 char *rawstring;
4024
4025 /* Need a modifiable copy of string */
4026 rawstring = pstrdup(*newval);
4027
4028 if (!SplitGUCList(rawstring, ',', &elemlist))
4029 {
4030 GUC_check_errdetail("Invalid list syntax in parameter \"%s\".",
4031 "debug_io_direct");
4032 pfree(rawstring);
4033 list_free(elemlist);
4034 return false;
4035 }
4036
4037 flags = 0;
4038 foreach(l, elemlist)
4039 {
4040 char *item = (char *) lfirst(l);
4041
4042 if (pg_strcasecmp(item, "data") == 0)
4043 flags |= IO_DIRECT_DATA;
4044 else if (pg_strcasecmp(item, "wal") == 0)
4045 flags |= IO_DIRECT_WAL;
4046 else if (pg_strcasecmp(item, "wal_init") == 0)
4047 flags |= IO_DIRECT_WAL_INIT;
4048 else
4049 {
4050 GUC_check_errdetail("Invalid option \"%s\".", item);
4051 result = false;
4052 break;
4053 }
4054 }
4055
4056 /*
4057 * It's possible to configure block sizes smaller than our assumed I/O
4058 * alignment size, which could result in invalid I/O requests.
4059 */
4060#if XLOG_BLCKSZ < PG_IO_ALIGN_SIZE
4061 if (result && (flags & (IO_DIRECT_WAL | IO_DIRECT_WAL_INIT)))
4062 {
4063 GUC_check_errdetail("\"%s\" is not supported for WAL because %s is too small.",
4064 "debug_io_direct", "XLOG_BLCKSZ");
4065 result = false;
4066 }
4067#endif
4068#if BLCKSZ < PG_IO_ALIGN_SIZE
4069 if (result && (flags & IO_DIRECT_DATA))
4070 {
4071 GUC_check_errdetail("\"%s\" is not supported for data because %s is too small.",
4072 "debug_io_direct", "BLCKSZ");
4073 result = false;
4074 }
4075#endif
4076
4077 pfree(rawstring);
4078 list_free(elemlist);
4079#endif
4080
4081 if (!result)
4082 return result;
4083
4084 /* Save the flags in *extra, for use by assign_debug_io_direct */
4085 *extra = guc_malloc(LOG, sizeof(int));
4086 if (!*extra)
4087 return false;
4088 *((int *) *extra) = flags;
4089
4090 return result;
4091}
#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:481
void list_free(List *list)
Definition: list.c:1546
char * pstrdup(const char *in)
Definition: mcxt.c:2322
void pfree(void *pointer)
Definition: mcxt.c:2147
#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:3773

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

◆ CleanupTempFiles()

static void CleanupTempFiles ( bool  isCommit,
bool  isProcExit 
)
static

Definition at line 3266 of file fd.c.

3267{
3268 Index i;
3269
3270 /*
3271 * Careful here: at proc_exit we need extra cleanup, not just
3272 * xact_temporary files.
3273 */
3274 if (isProcExit || have_xact_temporary_files)
3275 {
3276 Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
3277 for (i = 1; i < SizeVfdCache; i++)
3278 {
3279 unsigned short fdstate = VfdCache[i].fdstate;
3280
3281 if (((fdstate & FD_DELETE_AT_CLOSE) || (fdstate & FD_CLOSE_AT_EOXACT)) &&
3282 VfdCache[i].fileName != NULL)
3283 {
3284 /*
3285 * If we're in the process of exiting a backend process, close
3286 * all temporary files. Otherwise, only close temporary files
3287 * local to the current transaction. They should be closed by
3288 * the ResourceOwner mechanism already, so this is just a
3289 * debugging cross-check.
3290 */
3291 if (isProcExit)
3292 FileClose(i);
3293 else if (fdstate & FD_CLOSE_AT_EOXACT)
3294 {
3295 elog(WARNING,
3296 "temporary file %s not closed at end-of-transaction",
3297 VfdCache[i].fileName);
3298 FileClose(i);
3299 }
3300 }
3301 }
3302
3304 }
3305
3306 /* Complain if any allocated files remain open at commit. */
3307 if (isCommit && numAllocatedDescs > 0)
3308 elog(WARNING, "%d temporary files and directories not closed at end-of-transaction",
3310
3311 /* Clean up "allocated" stdio files, dirs and fds. */
3312 while (numAllocatedDescs > 0)
3314}
#define WARNING
Definition: elog.h:36
#define FD_DELETE_AT_CLOSE
Definition: fd.c:192
#define FD_CLOSE_AT_EOXACT
Definition: fd.c:193
void FileClose(File file)
Definition: fd.c:1982
#define FileIsNotOpen(file)
Definition: fd.c:189
static bool have_xact_temporary_files
Definition: fd.c:228
unsigned short fdstate
Definition: fd.c:199

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

Referenced by AtEOXact_Files(), and BeforeShmemExit_Files().

◆ closeAllVfds()

void closeAllVfds ( void  )

Definition at line 3084 of file fd.c.

3085{
3086 Index i;
3087
3088 if (SizeVfdCache > 0)
3089 {
3090 Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
3091 for (i = 1; i < SizeVfdCache; i++)
3092 {
3093 if (!FileIsNotOpen(i))
3094 LruDelete(i);
3095 }
3096 }
3097}
static void LruDelete(File file)
Definition: fd.c:1289

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

Referenced by standard_ProcessUtility().

◆ ClosePipeStream()

int ClosePipeStream ( FILE *  file)

Definition at line 3055 of file fd.c.

3056{
3057 int i;
3058
3059 DO_DB(elog(LOG, "ClosePipeStream: Allocated %d", numAllocatedDescs));
3060
3061 /* Remove file from list of allocated files, if it's present */
3062 for (i = numAllocatedDescs; --i >= 0;)
3063 {
3064 AllocateDesc *desc = &allocatedDescs[i];
3065
3066 if (desc->kind == AllocateDescPipe && desc->desc.file == file)
3067 return FreeDesc(desc);
3068 }
3069
3070 /* Only get here if someone passes us a file not in allocatedDescs */
3071 elog(WARNING, "file passed to ClosePipeStream was not obtained from OpenPipeStream");
3072
3073 return pclose(file);
3074}

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

2872{
2873 int i;
2874
2875 DO_DB(elog(LOG, "CloseTransientFile: Allocated %d", numAllocatedDescs));
2876
2877 /* Remove fd from list of allocated files, if it's present */
2878 for (i = numAllocatedDescs; --i >= 0;)
2879 {
2880 AllocateDesc *desc = &allocatedDescs[i];
2881
2882 if (desc->kind == AllocateDescRawFD && desc->desc.fd == fd)
2883 return FreeDesc(desc);
2884 }
2885
2886 /* Only get here if someone passes us a file not in allocatedDescs */
2887 elog(WARNING, "fd passed to CloseTransientFile was not obtained from OpenTransientFile");
2888
2890
2891 return close(fd);
2892}
void pgaio_closing_fd(int fd)
Definition: aio.c:1117
int fd
Definition: fd.c:263

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

Referenced by ApplyLogicalMappingFile(), be_lo_export(), CheckPointLogicalRewriteHeap(), CheckPointReplicationOrigin(), clone_file(), 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 964 of file fd.c.

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

References close, elog, ereport, errmsg(), fd(), j, palloc(), pfree(), repalloc(), 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 3824 of file fd.c.

3825{
3826 ereport_startup_progress("syncing data directory (fsync), elapsed time: %ld.%02d s, current path: %s",
3827 fname);
3828
3829 /*
3830 * We want to silently ignoring errors about unreadable files. Pass that
3831 * desire on to fsync_fname_ext().
3832 */
3833 fsync_fname_ext(fname, isdir, true, elevel);
3834}
int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3862
#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 1270 of file fd.c.

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

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

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

◆ durable_rename()

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

Definition at line 782 of file fd.c.

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

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

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

◆ durable_unlink()

int durable_unlink ( const char *  fname,
int  elevel 
)

Definition at line 872 of file fd.c.

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

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

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

◆ FileAccess()

static int FileAccess ( File  file)
static

Definition at line 1496 of file fd.c.

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

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

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

◆ FileClose()

void FileClose ( File  file)

Definition at line 1982 of file fd.c.

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

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, pgaio_closing_fd(), 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 2424 of file fd.c.

2425{
2426#ifdef HAVE_POSIX_FALLOCATE
2427 int returnCode;
2428
2429 Assert(FileIsValid(file));
2430
2431 DO_DB(elog(LOG, "FileFallocate: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
2432 file, VfdCache[file].fileName,
2433 (int64) offset, (int64) amount));
2434
2435 returnCode = FileAccess(file);
2436 if (returnCode < 0)
2437 return -1;
2438
2439retry:
2440 pgstat_report_wait_start(wait_event_info);
2441 returnCode = posix_fallocate(VfdCache[file].fd, offset, amount);
2443
2444 if (returnCode == 0)
2445 return 0;
2446 else if (returnCode == EINTR)
2447 goto retry;
2448
2449 /* for compatibility with %m printing etc */
2450 errno = returnCode;
2451
2452 /*
2453 * Return in cases of a "real" failure, if fallocate is not supported,
2454 * fall through to the FileZero() backed implementation.
2455 */
2456 if (returnCode != EINVAL && returnCode != EOPNOTSUPP)
2457 return -1;
2458#endif
2459
2460 return FileZero(file, offset, amount, wait_event_info);
2461}
#define INT64_FORMAT
Definition: c.h:520
int64_t int64
Definition: c.h:499
static int FileAccess(File file)
Definition: fd.c:1496
int FileZero(File file, off_t offset, off_t amount, uint32 wait_event_info)
Definition: fd.c:2379
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:364
#define EOPNOTSUPP
Definition: win32_port.h:388

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

2533{
2534 int returnCode;
2535
2536 returnCode = FileAccess(file);
2537 if (returnCode < 0)
2538 return returnCode;
2539
2540 Assert(FileIsValid(file));
2541 return VfdCache[file].fd;
2542}

References Assert(), vfd::fd, FileAccess(), FileIsValid, and VfdCache.

Referenced by mdfd().

◆ FileGetRawFlags()

int FileGetRawFlags ( File  file)

Definition at line 2548 of file fd.c.

2549{
2550 Assert(FileIsValid(file));
2551 return VfdCache[file].fileFlags;
2552}
int fileFlags
Definition: fd.c:207

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

◆ FileGetRawMode()

mode_t FileGetRawMode ( File  file)

Definition at line 2558 of file fd.c.

2559{
2560 Assert(FileIsValid(file));
2561 return VfdCache[file].fileMode;
2562}
mode_t fileMode
Definition: fd.c:208

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

◆ FilePathName()

◆ FilePrefetch()

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

Definition at line 2083 of file fd.c.

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

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

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

2465{
2466 Assert(FileIsValid(file));
2467
2468 DO_DB(elog(LOG, "FileSize %d (%s)",
2469 file, VfdCache[file].fileName));
2470
2471 if (FileIsNotOpen(file))
2472 {
2473 if (FileAccess(file) < 0)
2474 return (off_t) -1;
2475 }
2476
2477 return lseek(VfdCache[file].fd, 0, SEEK_END);
2478}

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

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

◆ FileStartReadV()

int FileStartReadV ( PgAioHandle ioh,
File  file,
int  iovcnt,
off_t  offset,
uint32  wait_event_info 
)

Definition at line 2221 of file fd.c.

2224{
2225 int returnCode;
2226 Vfd *vfdP;
2227
2228 Assert(FileIsValid(file));
2229
2230 DO_DB(elog(LOG, "FileStartReadV: %d (%s) " INT64_FORMAT " %d",
2231 file, VfdCache[file].fileName,
2232 (int64) offset,
2233 iovcnt));
2234
2235 returnCode = FileAccess(file);
2236 if (returnCode < 0)
2237 return returnCode;
2238
2239 vfdP = &VfdCache[file];
2240
2241 pgaio_io_start_readv(ioh, vfdP->fd, iovcnt, offset);
2242
2243 return 0;
2244}
void pgaio_io_start_readv(PgAioHandle *ioh, int fd, int iovcnt, uint64 offset)
Definition: aio_io.c:78

References Assert(), DO_DB, elog, vfd::fd, FileAccess(), FileIsValid, INT64_FORMAT, LOG, pgaio_io_start_readv(), and VfdCache.

Referenced by mdstartreadv().

◆ FileSync()

int FileSync ( File  file,
uint32  wait_event_info 
)

Definition at line 2352 of file fd.c.

2353{
2354 int returnCode;
2355
2356 Assert(FileIsValid(file));
2357
2358 DO_DB(elog(LOG, "FileSync: %d (%s)",
2359 file, VfdCache[file].fileName));
2360
2361 returnCode = FileAccess(file);
2362 if (returnCode < 0)
2363 return returnCode;
2364
2365 pgstat_report_wait_start(wait_event_info);
2366 returnCode = pg_fsync(VfdCache[file].fd);
2368
2369 return returnCode;
2370}

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

2482{
2483 int returnCode;
2484
2485 Assert(FileIsValid(file));
2486
2487 DO_DB(elog(LOG, "FileTruncate %d (%s)",
2488 file, VfdCache[file].fileName));
2489
2490 returnCode = FileAccess(file);
2491 if (returnCode < 0)
2492 return returnCode;
2493
2494 pgstat_report_wait_start(wait_event_info);
2495 returnCode = pg_ftruncate(VfdCache[file].fd, offset);
2497
2498 if (returnCode == 0 && VfdCache[file].fileSize > offset)
2499 {
2500 /* adjust our state for truncation of a temp file */
2501 Assert(VfdCache[file].fdstate & FD_TEMP_FILE_LIMIT);
2502 temporary_files_size -= VfdCache[file].fileSize - offset;
2503 VfdCache[file].fileSize = offset;
2504 }
2505
2506 return returnCode;
2507}
static int pg_ftruncate(int fd, off_t length)
Definition: fd.c:703

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

Referenced by BufFileTruncateFileSet(), and mdtruncate().

◆ FileWriteback()

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

Definition at line 2139 of file fd.c.

2140{
2141 int returnCode;
2142
2143 Assert(FileIsValid(file));
2144
2145 DO_DB(elog(LOG, "FileWriteback: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
2146 file, VfdCache[file].fileName,
2147 (int64) offset, (int64) nbytes));
2148
2149 if (nbytes <= 0)
2150 return;
2151
2152 if (VfdCache[file].fileFlags & PG_O_DIRECT)
2153 return;
2154
2155 returnCode = FileAccess(file);
2156 if (returnCode < 0)
2157 return;
2158
2159 pgstat_report_wait_start(wait_event_info);
2160 pg_flush_data(VfdCache[file].fd, offset, nbytes);
2162}
void pg_flush_data(int fd, off_t offset, off_t nbytes)
Definition: fd.c:525

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

Referenced by mdwriteback().

◆ FileWriteV()

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

Definition at line 2247 of file fd.c.

2249{
2250 ssize_t returnCode;
2251 Vfd *vfdP;
2252
2253 Assert(FileIsValid(file));
2254
2255 DO_DB(elog(LOG, "FileWriteV: %d (%s) " INT64_FORMAT " %d",
2256 file, VfdCache[file].fileName,
2257 (int64) offset,
2258 iovcnt));
2259
2260 returnCode = FileAccess(file);
2261 if (returnCode < 0)
2262 return returnCode;
2263
2264 vfdP = &VfdCache[file];
2265
2266 /*
2267 * If enforcing temp_file_limit and it's a temp file, check to see if the
2268 * write would overrun temp_file_limit, and throw error if so. Note: it's
2269 * really a modularity violation to throw error here; we should set errno
2270 * and return -1. However, there's no way to report a suitable error
2271 * message if we do that. All current callers would just throw error
2272 * immediately anyway, so this is safe at present.
2273 */
2274 if (temp_file_limit >= 0 && (vfdP->fdstate & FD_TEMP_FILE_LIMIT))
2275 {
2276 off_t past_write = offset;
2277
2278 for (int i = 0; i < iovcnt; ++i)
2279 past_write += iov[i].iov_len;
2280
2281 if (past_write > vfdP->fileSize)
2282 {
2283 uint64 newTotal = temporary_files_size;
2284
2285 newTotal += past_write - vfdP->fileSize;
2286 if (newTotal > (uint64) temp_file_limit * (uint64) 1024)
2287 ereport(ERROR,
2288 (errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED),
2289 errmsg("temporary file size exceeds \"temp_file_limit\" (%dkB)",
2290 temp_file_limit)));
2291 }
2292 }
2293
2294retry:
2295 pgstat_report_wait_start(wait_event_info);
2296 returnCode = pg_pwritev(vfdP->fd, iov, iovcnt, offset);
2298
2299 if (returnCode >= 0)
2300 {
2301 /*
2302 * Some callers expect short writes to set errno, and traditionally we
2303 * have assumed that they imply disk space shortage. We don't want to
2304 * waste CPU cycles adding up the total size here, so we'll just set
2305 * it for all successful writes in case such a caller determines that
2306 * the write was short and ereports "%m".
2307 */
2308 errno = ENOSPC;
2309
2310 /*
2311 * Maintain fileSize and temporary_files_size if it's a temp file.
2312 */
2313 if (vfdP->fdstate & FD_TEMP_FILE_LIMIT)
2314 {
2315 off_t past_write = offset + returnCode;
2316
2317 if (past_write > vfdP->fileSize)
2318 {
2319 temporary_files_size += past_write - vfdP->fileSize;
2320 vfdP->fileSize = past_write;
2321 }
2322 }
2323 }
2324 else
2325 {
2326 /*
2327 * See comments in FileReadV()
2328 */
2329#ifdef WIN32
2330 DWORD error = GetLastError();
2331
2332 switch (error)
2333 {
2334 case ERROR_NO_SYSTEM_RESOURCES:
2335 pg_usleep(1000L);
2336 errno = EINTR;
2337 break;
2338 default:
2340 break;
2341 }
2342#endif
2343 /* OK to retry if interrupted */
2344 if (errno == EINTR)
2345 goto retry;
2346 }
2347
2348 return returnCode;
2349}
uint64_t uint64
Definition: c.h:503
int temp_file_limit
Definition: guc_tables.c:550
static ssize_t pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
Definition: pg_iovec.h:87

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

2380{
2381 int returnCode;
2382 ssize_t written;
2383
2384 Assert(FileIsValid(file));
2385
2386 DO_DB(elog(LOG, "FileZero: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
2387 file, VfdCache[file].fileName,
2388 (int64) offset, (int64) amount));
2389
2390 returnCode = FileAccess(file);
2391 if (returnCode < 0)
2392 return returnCode;
2393
2394 pgstat_report_wait_start(wait_event_info);
2395 written = pg_pwrite_zeros(VfdCache[file].fd, amount, offset);
2397
2398 if (written < 0)
2399 return -1;
2400 else if (written != amount)
2401 {
2402 /* if errno is unset, assume problem is no disk space */
2403 if (errno == 0)
2404 errno = ENOSPC;
2405 return -1;
2406 }
2407
2408 return 0;
2409}
ssize_t pg_pwrite_zeros(int fd, size_t size, off_t offset)
Definition: file_utils.c:709

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

2804{
2805 int result;
2806
2807 /* Close the underlying object */
2808 switch (desc->kind)
2809 {
2810 case AllocateDescFile:
2811 result = fclose(desc->desc.file);
2812 break;
2813 case AllocateDescPipe:
2814 result = pclose(desc->desc.file);
2815 break;
2816 case AllocateDescDir:
2817 result = closedir(desc->desc.dir);
2818 break;
2819 case AllocateDescRawFD:
2820 pgaio_closing_fd(desc->desc.fd);
2821 result = close(desc->desc.fd);
2822 break;
2823 default:
2824 elog(ERROR, "AllocateDesc kind not recognized");
2825 result = 0; /* keep compiler quiet */
2826 break;
2827 }
2828
2829 /* Compact storage in the allocatedDescs array */
2832
2833 return result;
2834}
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, numAllocatedDescs, and pgaio_closing_fd().

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

◆ FreeDir()

int FreeDir ( DIR dir)

Definition at line 3025 of file fd.c.

3026{
3027 int i;
3028
3029 /* Nothing to do if AllocateDir failed */
3030 if (dir == NULL)
3031 return 0;
3032
3033 DO_DB(elog(LOG, "FreeDir: Allocated %d", numAllocatedDescs));
3034
3035 /* Remove dir from list of allocated dirs, if it's present */
3036 for (i = numAllocatedDescs; --i >= 0;)
3037 {
3038 AllocateDesc *desc = &allocatedDescs[i];
3039
3040 if (desc->kind == AllocateDescDir && desc->desc.dir == dir)
3041 return FreeDesc(desc);
3042 }
3043
3044 /* Only get here if someone passes us a dir not in allocatedDescs */
3045 elog(WARNING, "dir passed to FreeDir was not obtained from AllocateDir");
3046
3047 return closedir(dir);
3048}

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

2844{
2845 int i;
2846
2847 DO_DB(elog(LOG, "FreeFile: Allocated %d", numAllocatedDescs));
2848
2849 /* Remove file from list of allocated files, if it's present */
2850 for (i = numAllocatedDescs; --i >= 0;)
2851 {
2852 AllocateDesc *desc = &allocatedDescs[i];
2853
2854 if (desc->kind == AllocateDescFile && desc->desc.file == file)
2855 return FreeDesc(desc);
2856 }
2857
2858 /* Only get here if someone passes us a file not in allocatedDescs */
2859 elog(WARNING, "file passed to FreeFile was not obtained from AllocateFile");
2860
2861 return fclose(file);
2862}

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(), ParseConfigFile(), 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 1476 of file fd.c.

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

3863{
3864 int fd;
3865 int flags;
3866 int returncode;
3867
3868 /*
3869 * Some OSs require directories to be opened read-only whereas other
3870 * systems don't allow us to fsync files opened read-only; so we need both
3871 * cases here. Using O_RDWR will cause us to fail to fsync files that are
3872 * not writable by our userid, but we assume that's OK.
3873 */
3874 flags = PG_BINARY;
3875 if (!isdir)
3876 flags |= O_RDWR;
3877 else
3878 flags |= O_RDONLY;
3879
3880 fd = OpenTransientFile(fname, flags);
3881
3882 /*
3883 * Some OSs don't allow us to open directories at all (Windows returns
3884 * EACCES), just ignore the error in that case. If desired also silently
3885 * ignoring errors about unreadable files. Log others.
3886 */
3887 if (fd < 0 && isdir && (errno == EISDIR || errno == EACCES))
3888 return 0;
3889 else if (fd < 0 && ignore_perm && errno == EACCES)
3890 return 0;
3891 else if (fd < 0)
3892 {
3893 ereport(elevel,
3895 errmsg("could not open file \"%s\": %m", fname)));
3896 return -1;
3897 }
3898
3899 returncode = pg_fsync(fd);
3900
3901 /*
3902 * Some OSes don't allow us to fsync directories at all, so we can ignore
3903 * those errors. Anything else needs to be logged.
3904 */
3905 if (returncode != 0 && !(isdir && (errno == EBADF || errno == EINVAL)))
3906 {
3907 int save_errno;
3908
3909 /* close file upon error, might not be in transaction context */
3910 save_errno = errno;
3911 (void) CloseTransientFile(fd);
3912 errno = save_errno;
3913
3914 ereport(elevel,
3916 errmsg("could not fsync file \"%s\": %m", fname)));
3917 return -1;
3918 }
3919
3920 if (CloseTransientFile(fd) != 0)
3921 {
3922 ereport(elevel,
3924 errmsg("could not close file \"%s\": %m", fname)));
3925 return -1;
3926 }
3927
3928 return 0;
3929}

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

3939{
3940 char parentpath[MAXPGPATH];
3941
3942 strlcpy(parentpath, fname, MAXPGPATH);
3943 get_parent_directory(parentpath);
3944
3945 /*
3946 * get_parent_directory() returns an empty string if the input argument is
3947 * just a file name (see comments in path.c), so handle that as being the
3948 * current directory.
3949 */
3950 if (strlen(parentpath) == 0)
3951 strlcpy(parentpath, ".", MAXPGPATH);
3952
3953 if (fsync_fname_ext(parentpath, true, false, elevel) != 0)
3954 return -1;
3955
3956 return 0;
3957}
#define MAXPGPATH
void get_parent_directory(char *path)
Definition: path.c:1068
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(), swap_catalog_files(), and tar_finish().

◆ GetNextTempTableSpace()

Oid GetNextTempTableSpace ( void  )

Definition at line 3175 of file fd.c.

3176{
3177 if (numTempTableSpaces > 0)
3178 {
3179 /* Advance nextTempTableSpace counter with wraparound */
3183 }
3184 return InvalidOid;
3185}
static int nextTempTableSpace
Definition: fd.c:290
#define InvalidOid
Definition: postgres_ext.h:35

References InvalidOid, nextTempTableSpace, numTempTableSpaces, and tempTableSpaces.

Referenced by GetDefaultTablespace(), and OpenTemporaryFile().

◆ GetTempTablespaces()

int GetTempTablespaces ( Oid tableSpaces,
int  numSpaces 
)

Definition at line 3157 of file fd.c.

3158{
3159 int i;
3160
3162 for (i = 0; i < numTempTableSpaces && i < numSpaces; ++i)
3163 tableSpaces[i] = tempTableSpaces[i];
3164
3165 return i;
3166}
bool TempTablespacesAreSet(void)
Definition: fd.c:3142

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

Referenced by FileSetInit().

◆ InitFileAccess()

void InitFileAccess ( void  )

Definition at line 903 of file fd.c.

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

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

Referenced by BaseInit().

◆ InitTemporaryFileAccess()

void InitTemporaryFileAccess ( void  )

Definition at line 933 of file fd.c.

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

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

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

3515{
3516 int pos;
3517 int savepos;
3518
3519 /* Must start with "t". */
3520 if (name[0] != 't')
3521 return false;
3522
3523 /* Followed by a non-empty string of digits and then an underscore. */
3524 for (pos = 1; isdigit((unsigned char) name[pos]); ++pos)
3525 ;
3526 if (pos == 1 || name[pos] != '_')
3527 return false;
3528
3529 /* Followed by another nonempty string of digits. */
3530 for (savepos = ++pos; isdigit((unsigned char) name[pos]); ++pos)
3531 ;
3532 if (savepos == pos)
3533 return false;
3534
3535 /* We might have _forkname or .segment or both. */
3536 if (name[pos] == '_')
3537 {
3538 int forkchar = forkname_chars(&name[pos + 1], NULL);
3539
3540 if (forkchar <= 0)
3541 return false;
3542 pos += forkchar + 1;
3543 }
3544 if (name[pos] == '.')
3545 {
3546 int segchar;
3547
3548 for (segchar = 1; isdigit((unsigned char) name[pos + segchar]); ++segchar)
3549 ;
3550 if (segchar <= 1)
3551 return false;
3552 pos += segchar;
3553 }
3554
3555 /* Now we should be at the end. */
3556 if (name[pos] != '\0')
3557 return false;
3558 return true;
3559}
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 1289 of file fd.c.

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

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

Referenced by closeAllVfds(), and ReleaseLruFile().

◆ LruInsert()

static int LruInsert ( File  file)
static

Definition at line 1339 of file fd.c.

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

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

2748{
2749 FILE *file;
2750 int save_errno;
2751
2752 DO_DB(elog(LOG, "OpenPipeStream: Allocated %d (%s)",
2753 numAllocatedDescs, command));
2754
2755 /* Can we allocate another non-virtual FD? */
2756 if (!reserveAllocatedDesc())
2757 ereport(ERROR,
2758 (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2759 errmsg("exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"",
2760 maxAllocatedDescs, command)));
2761
2762 /* Close excess kernel FDs. */
2764
2765TryAgain:
2766 fflush(NULL);
2767 pqsignal(SIGPIPE, SIG_DFL);
2768 errno = 0;
2769 file = popen(command, mode);
2770 save_errno = errno;
2771 pqsignal(SIGPIPE, SIG_IGN);
2772 errno = save_errno;
2773 if (file != NULL)
2774 {
2776
2777 desc->kind = AllocateDescPipe;
2778 desc->desc.file = file;
2781 return desc->desc.file;
2782 }
2783
2784 if (errno == EMFILE || errno == ENFILE)
2785 {
2786 ereport(LOG,
2787 (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2788 errmsg("out of file descriptors: %m; release and retry")));
2789 if (ReleaseLruFile())
2790 goto TryAgain;
2791 errno = save_errno;
2792 }
2793
2794 return NULL;
2795}
#define pqsignal
Definition: port.h:531
#define SIGPIPE
Definition: win32_port.h:163

References allocatedDescs, AllocateDescPipe, AllocateDesc::create_subid, AllocateDesc::desc, DO_DB, elog, ereport, errcode(), errmsg(), ERROR, AllocateDesc::file, GetCurrentSubTransactionId(), AllocateDesc::kind, LOG, maxAllocatedDescs, mode, numAllocatedDescs, pqsignal, ReleaseLruFile(), ReleaseLruFiles(), reserveAllocatedDesc(), 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 1728 of file fd.c.

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

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

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

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

2704{
2705 int fd;
2706
2707 DO_DB(elog(LOG, "OpenTransientFile: Allocated %d (%s)",
2708 numAllocatedDescs, fileName));
2709
2710 /* Can we allocate another non-virtual FD? */
2711 if (!reserveAllocatedDesc())
2712 ereport(ERROR,
2713 (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2714 errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2715 maxAllocatedDescs, fileName)));
2716
2717 /* Close excess kernel FDs. */
2719
2720 fd = BasicOpenFilePerm(fileName, fileFlags, fileMode);
2721
2722 if (fd >= 0)
2723 {
2725
2726 desc->kind = AllocateDescRawFD;
2727 desc->desc.fd = fd;
2730
2731 return fd;
2732 }
2733
2734 return -1; /* failure */
2735}

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

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

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

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

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

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

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

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

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

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

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

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

Referenced by FileSetOpen().

◆ pg_fdatasync()

int pg_fdatasync ( int  fd)

Definition at line 480 of file fd.c.

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

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

Referenced by issue_xlog_fsync().

◆ pg_file_exists()

bool pg_file_exists ( const char *  name)

Definition at line 503 of file fd.c.

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

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_path(), and provider_init().

◆ pg_flush_data()

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

Definition at line 525 of file fd.c.

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

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

Referenced by copy_file(), and FileWriteback().

◆ pg_fsync()

int pg_fsync ( int  fd)

Definition at line 386 of file fd.c.

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

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

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

◆ pg_fsync_no_writethrough()

int pg_fsync_no_writethrough ( int  fd)

Definition at line 441 of file fd.c.

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

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

Referenced by issue_xlog_fsync(), and pg_fsync().

◆ pg_fsync_writethrough()

int pg_fsync_writethrough ( int  fd)

Definition at line 461 of file fd.c.

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

References enableFsync, and fd().

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

◆ pg_ftruncate()

static int pg_ftruncate ( int  fd,
off_t  length 
)
static

Definition at line 703 of file fd.c.

704{
705 int ret;
706
707retry:
708 ret = ftruncate(fd, length);
709
710 if (ret == -1 && errno == EINTR)
711 goto retry;
712
713 return ret;
714}

References EINTR, and fd().

Referenced by FileTruncate(), and pg_truncate().

◆ pg_truncate()

int pg_truncate ( const char *  path,
off_t  length 
)

Definition at line 720 of file fd.c.

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

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

Referenced by do_truncate().

◆ ReadDir()

◆ ReadDirExtended()

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

Definition at line 2988 of file fd.c.

2989{
2990 struct dirent *dent;
2991
2992 /* Give a generic message for AllocateDir failure, if caller didn't */
2993 if (dir == NULL)
2994 {
2995 ereport(elevel,
2997 errmsg("could not open directory \"%s\": %m",
2998 dirname)));
2999 return NULL;
3000 }
3001
3002 errno = 0;
3003 if ((dent = readdir(dir)) != NULL)
3004 return dent;
3005
3006 if (errno)
3007 ereport(elevel,
3009 errmsg("could not read directory \"%s\": %m",
3010 dirname)));
3011 return NULL;
3012}
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 1551 of file fd.c.

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

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

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

◆ ReleaseExternalFD()

◆ ReleaseLruFile()

static bool ReleaseLruFile ( void  )
static

Definition at line 1386 of file fd.c.

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

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

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

◆ ReleaseLruFiles()

static void ReleaseLruFiles ( void  )
static

◆ RemovePgTempFiles()

void RemovePgTempFiles ( void  )

Definition at line 3338 of file fd.c.

3339{
3340 char temp_path[MAXPGPATH + sizeof(PG_TBLSPC_DIR) + sizeof(TABLESPACE_VERSION_DIRECTORY) + sizeof(PG_TEMP_FILES_DIR)];
3341 DIR *spc_dir;
3342 struct dirent *spc_de;
3343
3344 /*
3345 * First process temp files in pg_default ($PGDATA/base)
3346 */
3347 snprintf(temp_path, sizeof(temp_path), "base/%s", PG_TEMP_FILES_DIR);
3348 RemovePgTempFilesInDir(temp_path, true, false);
3350
3351 /*
3352 * Cycle through temp directories for all non-default tablespaces.
3353 */
3354 spc_dir = AllocateDir(PG_TBLSPC_DIR);
3355
3356 while ((spc_de = ReadDirExtended(spc_dir, PG_TBLSPC_DIR, LOG)) != NULL)
3357 {
3358 if (strcmp(spc_de->d_name, ".") == 0 ||
3359 strcmp(spc_de->d_name, "..") == 0)
3360 continue;
3361
3362 snprintf(temp_path, sizeof(temp_path), "%s/%s/%s/%s",
3365 RemovePgTempFilesInDir(temp_path, true, false);
3366
3367 snprintf(temp_path, sizeof(temp_path), "%s/%s/%s",
3369 RemovePgTempRelationFiles(temp_path);
3370 }
3371
3372 FreeDir(spc_dir);
3373
3374 /*
3375 * In EXEC_BACKEND case there is a pgsql_tmp directory at the top level of
3376 * DataDir as well. However, that is *not* cleaned here because doing so
3377 * would create a race condition. It's done separately, earlier in
3378 * postmaster startup.
3379 */
3380}
int FreeDir(DIR *dir)
Definition: fd.c:3025
static void RemovePgTempRelationFiles(const char *tsdirname)
Definition: fd.c:3458
void RemovePgTempFilesInDir(const char *tmpdirname, bool missing_ok, bool unlink_all)
Definition: fd.c:3398
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2907
#define PG_TEMP_FILES_DIR
Definition: file_utils.h:63
#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 3398 of file fd.c.

3399{
3400 DIR *temp_dir;
3401 struct dirent *temp_de;
3402 char rm_path[MAXPGPATH * 2];
3403
3404 temp_dir = AllocateDir(tmpdirname);
3405
3406 if (temp_dir == NULL && errno == ENOENT && missing_ok)
3407 return;
3408
3409 while ((temp_de = ReadDirExtended(temp_dir, tmpdirname, LOG)) != NULL)
3410 {
3411 if (strcmp(temp_de->d_name, ".") == 0 ||
3412 strcmp(temp_de->d_name, "..") == 0)
3413 continue;
3414
3415 snprintf(rm_path, sizeof(rm_path), "%s/%s",
3416 tmpdirname, temp_de->d_name);
3417
3418 if (unlink_all ||
3419 strncmp(temp_de->d_name,
3421 strlen(PG_TEMP_FILE_PREFIX)) == 0)
3422 {
3423 PGFileType type = get_dirent_type(rm_path, temp_de, false, LOG);
3424
3425 if (type == PGFILETYPE_ERROR)
3426 continue;
3427 else if (type == PGFILETYPE_DIR)
3428 {
3429 /* recursively remove contents, then directory itself */
3430 RemovePgTempFilesInDir(rm_path, false, true);
3431
3432 if (rmdir(rm_path) < 0)
3433 ereport(LOG,
3435 errmsg("could not remove directory \"%s\": %m",
3436 rm_path)));
3437 }
3438 else
3439 {
3440 if (unlink(rm_path) < 0)
3441 ereport(LOG,
3443 errmsg("could not remove file \"%s\": %m",
3444 rm_path)));
3445 }
3446 }
3447 else
3448 ereport(LOG,
3449 (errmsg("unexpected file found in temporary-files directory: \"%s\"",
3450 rm_path)));
3451 }
3452
3453 FreeDir(temp_dir);
3454}
PGFileType get_dirent_type(const char *path, const struct dirent *de, bool look_through_symlinks, int elevel)
Definition: file_utils.c:547
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(), RemovePgTempFilesInDir(), snprintf, and type.

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

◆ RemovePgTempRelationFiles()

static void RemovePgTempRelationFiles ( const char *  tsdirname)
static

Definition at line 3458 of file fd.c.

3459{
3460 DIR *ts_dir;
3461 struct dirent *de;
3462 char dbspace_path[MAXPGPATH * 2];
3463
3464 ts_dir = AllocateDir(tsdirname);
3465
3466 while ((de = ReadDirExtended(ts_dir, tsdirname, LOG)) != NULL)
3467 {
3468 /*
3469 * We're only interested in the per-database directories, which have
3470 * numeric names. Note that this code will also (properly) ignore "."
3471 * and "..".
3472 */
3473 if (strspn(de->d_name, "0123456789") != strlen(de->d_name))
3474 continue;
3475
3476 snprintf(dbspace_path, sizeof(dbspace_path), "%s/%s",
3477 tsdirname, de->d_name);
3479 }
3480
3481 FreeDir(ts_dir);
3482}
static void RemovePgTempRelationFilesInDbspace(const char *dbspacedirname)
Definition: fd.c:3486

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

3487{
3488 DIR *dbspace_dir;
3489 struct dirent *de;
3490 char rm_path[MAXPGPATH * 2];
3491
3492 dbspace_dir = AllocateDir(dbspacedirname);
3493
3494 while ((de = ReadDirExtended(dbspace_dir, dbspacedirname, LOG)) != NULL)
3495 {
3497 continue;
3498
3499 snprintf(rm_path, sizeof(rm_path), "%s/%s",
3500 dbspacedirname, de->d_name);
3501
3502 if (unlink(rm_path) < 0)
3503 ereport(LOG,
3505 errmsg("could not remove file \"%s\": %m",
3506 rm_path)));
3507 }
3508
3509 FreeDir(dbspace_dir);
3510}
bool looks_like_temp_rel_name(const char *name)
Definition: fd.c:3514

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

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

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

Referenced by FileClose(), and PathNameDeleteTemporaryFile().

◆ reserveAllocatedDesc()

static bool reserveAllocatedDesc ( void  )
static

Definition at line 2569 of file fd.c.

2570{
2571 AllocateDesc *newDescs;
2572 int newMax;
2573
2574 /* Quick out if array already has a free slot. */
2576 return true;
2577
2578 /*
2579 * If the array hasn't yet been created in the current process, initialize
2580 * it with FD_MINFREE / 3 elements. In many scenarios this is as many as
2581 * we will ever need, anyway. We don't want to look at max_safe_fds
2582 * immediately because set_max_safe_fds() may not have run yet.
2583 */
2584 if (allocatedDescs == NULL)
2585 {
2586 newMax = FD_MINFREE / 3;
2587 newDescs = (AllocateDesc *) malloc(newMax * sizeof(AllocateDesc));
2588 /* Out of memory already? Treat as fatal error. */
2589 if (newDescs == NULL)
2590 ereport(ERROR,
2591 (errcode(ERRCODE_OUT_OF_MEMORY),
2592 errmsg("out of memory")));
2593 allocatedDescs = newDescs;
2594 maxAllocatedDescs = newMax;
2595 return true;
2596 }
2597
2598 /*
2599 * Consider enlarging the array beyond the initial allocation used above.
2600 * By the time this happens, max_safe_fds should be known accurately.
2601 *
2602 * We mustn't let allocated descriptors hog all the available FDs, and in
2603 * practice we'd better leave a reasonable number of FDs for VFD use. So
2604 * set the maximum to max_safe_fds / 3. (This should certainly be at
2605 * least as large as the initial size, FD_MINFREE / 3, so we aren't
2606 * tightening the restriction here.) Recall that "external" FDs are
2607 * allowed to consume another third of max_safe_fds.
2608 */
2609 newMax = max_safe_fds / 3;
2610 if (newMax > maxAllocatedDescs)
2611 {
2612 newDescs = (AllocateDesc *) realloc(allocatedDescs,
2613 newMax * sizeof(AllocateDesc));
2614 /* Treat out-of-memory as a non-fatal error. */
2615 if (newDescs == NULL)
2616 return false;
2617 allocatedDescs = newDescs;
2618 maxAllocatedDescs = newMax;
2619 return true;
2620 }
2621
2622 /* Can't enlarge allocatedDescs[] any more. */
2623 return false;
2624}
#define FD_MINFREE
Definition: fd.c:138

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

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

◆ ReserveExternalFD()

void ReserveExternalFD ( void  )

Definition at line 1223 of file fd.c.

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

References numExternalFDs, and ReleaseLruFiles().

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

◆ ResourceOwnerForgetFile()

static void ResourceOwnerForgetFile ( ResourceOwner  owner,
File  file 
)
inlinestatic

Definition at line 377 of file fd.c.

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

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

Referenced by FileClose().

◆ ResourceOwnerRememberFile()

static void ResourceOwnerRememberFile ( ResourceOwner  owner,
File  file 
)
inlinestatic

Definition at line 372 of file fd.c.

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

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

Referenced by RegisterTemporaryFile().

◆ ResOwnerPrintFile()

static char * ResOwnerPrintFile ( Datum  res)
static

Definition at line 4118 of file fd.c.

4119{
4120 return psprintf("File %d", DatumGetInt32(res));
4121}
static int32 DatumGetInt32(Datum X)
Definition: postgres.h:207
char * psprintf(const char *fmt,...)
Definition: psprintf.c:43

References DatumGetInt32(), and psprintf().

◆ ResOwnerReleaseFile()

static void ResOwnerReleaseFile ( Datum  res)
static

Definition at line 4104 of file fd.c.

4105{
4106 File file = (File) DatumGetInt32(res);
4107 Vfd *vfdP;
4108
4109 Assert(FileIsValid(file));
4110
4111 vfdP = &VfdCache[file];
4112 vfdP->resowner = NULL;
4113
4114 FileClose(file);
4115}

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

◆ set_max_safe_fds()

void set_max_safe_fds ( void  )

Definition at line 1044 of file fd.c.

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

References count_usable_fds(), DEBUG2, elog, ereport, errcode(), errdetail(), errmsg(), FATAL, FD_MINFREE, max_files_per_process, max_safe_fds, Min, and NUM_RESERVED_FDS.

Referenced by BootstrapModeMain(), PostgresSingleUserMain(), and PostmasterMain().

◆ SetTempTablespaces()

void SetTempTablespaces ( Oid tableSpaces,
int  numSpaces 
)

Definition at line 3113 of file fd.c.

3114{
3115 Assert(numSpaces >= 0);
3116 tempTableSpaces = tableSpaces;
3117 numTempTableSpaces = numSpaces;
3118
3119 /*
3120 * Select a random starting point in the list. This is to minimize
3121 * conflicts between backends that are most likely sharing the same list
3122 * of temp tablespaces. Note that if we create multiple temp files in the
3123 * same transaction, we'll advance circularly through the list --- this
3124 * ensures that large temporary sort files are nicely spread across all
3125 * available tablespaces.
3126 */
3127 if (numSpaces > 1)
3129 0, numSpaces - 1);
3130 else
3132}
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 3609 of file fd.c.

3610{
3611 bool xlog_is_symlink;
3612
3613 /* We can skip this whole thing if fsync is disabled. */
3614 if (!enableFsync)
3615 return;
3616
3617 /*
3618 * If pg_wal is a symlink, we'll need to recurse into it separately,
3619 * because the first walkdir below will ignore it.
3620 */
3621 xlog_is_symlink = false;
3622
3623 {
3624 struct stat st;
3625
3626 if (lstat("pg_wal", &st) < 0)
3627 ereport(LOG,
3629 errmsg("could not stat file \"%s\": %m",
3630 "pg_wal")));
3631 else if (S_ISLNK(st.st_mode))
3632 xlog_is_symlink = true;
3633 }
3634
3635#ifdef HAVE_SYNCFS
3637 {
3638 DIR *dir;
3639 struct dirent *de;
3640
3641 /*
3642 * On Linux, we don't have to open every single file one by one. We
3643 * can use syncfs() to sync whole filesystems. We only expect
3644 * filesystem boundaries to exist where we tolerate symlinks, namely
3645 * pg_wal and the tablespaces, so we call syncfs() for each of those
3646 * directories.
3647 */
3648
3649 /* Prepare to report progress syncing the data directory via syncfs. */
3651
3652 /* Sync the top level pgdata directory. */
3653 do_syncfs(".");
3654 /* If any tablespaces are configured, sync each of those. */
3656 while ((de = ReadDirExtended(dir, PG_TBLSPC_DIR, LOG)))
3657 {
3658 char path[MAXPGPATH];
3659
3660 if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
3661 continue;
3662
3663 snprintf(path, MAXPGPATH, "%s/%s", PG_TBLSPC_DIR, de->d_name);
3664 do_syncfs(path);
3665 }
3666 FreeDir(dir);
3667 /* If pg_wal is a symlink, process that too. */
3668 if (xlog_is_symlink)
3669 do_syncfs("pg_wal");
3670 return;
3671 }
3672#endif /* !HAVE_SYNCFS */
3673
3674#ifdef PG_FLUSH_DATA_WORKS
3675 /* Prepare to report progress of the pre-fsync phase. */
3677
3678 /*
3679 * If possible, hint to the kernel that we're soon going to fsync the data
3680 * directory and its contents. Errors in this step are even less
3681 * interesting than normal, so log them only at DEBUG1.
3682 */
3683 walkdir(".", pre_sync_fname, false, DEBUG1);
3684 if (xlog_is_symlink)
3685 walkdir("pg_wal", pre_sync_fname, false, DEBUG1);
3686 walkdir(PG_TBLSPC_DIR, pre_sync_fname, true, DEBUG1);
3687#endif
3688
3689 /* Prepare to report progress syncing the data directory via fsync. */
3691
3692 /*
3693 * Now we do the fsync()s in the same order.
3694 *
3695 * The main call ignores symlinks, so in addition to specially processing
3696 * pg_wal if it's a symlink, pg_tblspc has to be visited separately with
3697 * process_symlinks = true. Note that if there are any plain directories
3698 * in pg_tblspc, they'll get fsync'd twice. That's not an expected case
3699 * so we don't worry about optimizing it.
3700 */
3701 walkdir(".", datadir_fsync_fname, false, LOG);
3702 if (xlog_is_symlink)
3703 walkdir("pg_wal", datadir_fsync_fname, false, LOG);
3705}
void begin_startup_progress_phase(void)
Definition: startup.c:347
#define DEBUG1
Definition: elog.h:30
int recovery_init_sync_method
Definition: fd.c:165
static void datadir_fsync_fname(const char *fname, bool isdir, int elevel)
Definition: fd.c:3824
@ DATA_DIR_SYNC_METHOD_SYNCFS
Definition: file_utils.h:30
#define lstat(path, sb)
Definition: win32_port.h:275
#define S_ISLNK(m)
Definition: win32_port.h:334

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

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

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

3143{
3144 return (numTempTableSpaces >= 0);
3145}

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

3838{
3839 if (isdir)
3840 {
3841 if (rmdir(fname) != 0 && errno != ENOENT)
3842 ereport(elevel,
3844 errmsg("could not remove directory \"%s\": %m", fname)));
3845 }
3846 else
3847 {
3848 /* Use PathNameDeleteTemporaryFile to report filesize */
3849 PathNameDeleteTemporaryFile(fname, false);
3850 }
3851}
bool PathNameDeleteTemporaryFile(const char *path, bool error_on_failure)
Definition: fd.c:1936

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

3727{
3728 DIR *dir;
3729 struct dirent *de;
3730
3731 dir = AllocateDir(path);
3732
3733 while ((de = ReadDirExtended(dir, path, elevel)) != NULL)
3734 {
3735 char subpath[MAXPGPATH * 2];
3736
3738
3739 if (strcmp(de->d_name, ".") == 0 ||
3740 strcmp(de->d_name, "..") == 0)
3741 continue;
3742
3743 snprintf(subpath, sizeof(subpath), "%s/%s", path, de->d_name);
3744
3745 switch (get_dirent_type(subpath, de, process_symlinks, elevel))
3746 {
3747 case PGFILETYPE_REG:
3748 (*action) (subpath, false, elevel);
3749 break;
3750 case PGFILETYPE_DIR:
3751 walkdir(subpath, action, false, elevel);
3752 break;
3753 default:
3754
3755 /*
3756 * Errors are already reported directly by get_dirent_type(),
3757 * and any remaining symlinks and unknown file types are
3758 * ignored.
3759 */
3760 break;
3761 }
3762 }
3763
3764 FreeDir(dir); /* we ignore any error here */
3765
3766 /*
3767 * It's important to fsync the destination directory itself as individual
3768 * file fsyncs don't guarantee that the directory entry for the file is
3769 * synced. However, skip this if AllocateDir failed; the action function
3770 * might not be robust against that.
3771 */
3772 if (dir)
3773 (*action) (path, true, elevel);
3774}
@ PGFILETYPE_REG
Definition: file_utils.h:22
Datum subpath(PG_FUNCTION_ARGS)
Definition: ltree_op.c:311
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:123

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

Referenced by PathNameDeleteTemporaryDir(), SyncDataDirectory(), and walkdir().

Variable Documentation

◆ allocatedDescs

◆ data_sync_retry

bool data_sync_retry = false

Definition at line 162 of file fd.c.

Referenced by data_sync_elevel().

◆ file_resowner_desc

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

Definition at line 361 of file fd.c.

Referenced by ResourceOwnerForgetFile(), and ResourceOwnerRememberFile().

◆ have_xact_temporary_files

bool have_xact_temporary_files = false
static

Definition at line 228 of file fd.c.

Referenced by CleanupTempFiles(), and RegisterTemporaryFile().

◆ io_direct_flags

◆ max_files_per_process

int max_files_per_process = 1000

Definition at line 146 of file fd.c.

Referenced by set_max_safe_fds().

◆ max_safe_fds

int max_safe_fds = FD_MINFREE

Definition at line 159 of file fd.c.

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

◆ maxAllocatedDescs

int maxAllocatedDescs = 0
static

◆ nextTempTableSpace

int nextTempTableSpace = 0
static

Definition at line 290 of file fd.c.

Referenced by GetNextTempTableSpace(), and SetTempTablespaces().

◆ nfile

int nfile = 0
static

◆ numAllocatedDescs

◆ numExternalFDs

int numExternalFDs = 0
static

Definition at line 274 of file fd.c.

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

◆ numTempTableSpaces

int numTempTableSpaces = -1
static

◆ recovery_init_sync_method

int recovery_init_sync_method = DATA_DIR_SYNC_METHOD_FSYNC

Definition at line 165 of file fd.c.

Referenced by SyncDataDirectory().

◆ SizeVfdCache

Size SizeVfdCache = 0
static

◆ tempFileCounter

long tempFileCounter = 0
static

Definition at line 280 of file fd.c.

Referenced by OpenTemporaryFileInTablespace().

◆ temporary_files_size

uint64 temporary_files_size = 0
static

Definition at line 236 of file fd.c.

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

◆ tempTableSpaces

Oid* tempTableSpaces = NULL
static

◆ VfdCache