PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
fd.c File Reference
#include "postgres.h"
#include <sys/file.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <limits.h>
#include <unistd.h>
#include <fcntl.h>
#include "miscadmin.h"
#include "access/xact.h"
#include "access/xlog.h"
#include "catalog/catalog.h"
#include "catalog/pg_tablespace.h"
#include "pgstat.h"
#include "portability/mem.h"
#include "storage/fd.h"
#include "storage/ipc.h"
#include "utils/guc.h"
#include "utils/resowner_private.h"
Include dependency graph for fd.c:

Go to the source code of this file.

Data Structures

struct  vfd
 
struct  AllocateDesc
 

Macros

#define NUM_RESERVED_FDS   10
 
#define FD_MINFREE   10
 
#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 FileUnknownPos   ((off_t) -1)
 
#define FilePosIsUnknown(pos)   ((pos) < 0)
 
#define FD_TEMPORARY   (1 << 0) /* T = delete when closed */
 
#define FD_XACT_TEMPORARY   (1 << 1) /* T = delete at eoXact */
 

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 struct direntReadDirExtended (DIR *dir, const char *dirname, int elevel)
 
static void AtProcExit_Files (int code, Datum arg)
 
static void CleanupTempFiles (bool isProcExit)
 
static void RemovePgTempFilesInDir (const char *tmpdirname)
 
static void RemovePgTempRelationFiles (const char *tsdirname)
 
static void RemovePgTempRelationFilesInDbspace (const char *dbspacedirname)
 
static bool looks_like_temp_rel_name (const char *name)
 
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 int fsync_fname_ext (const char *fname, bool isdir, bool ignore_perm, int elevel)
 
static int fsync_parent_path (const char *fname, int elevel)
 
int pg_fsync (int fd)
 
int pg_fsync_no_writethrough (int fd)
 
int pg_fsync_writethrough (int fd)
 
int pg_fdatasync (int fd)
 
void pg_flush_data (int fd, off_t offset, off_t nbytes)
 
void fsync_fname (const char *fname, bool isdir)
 
int durable_rename (const char *oldfile, const char *newfile, int elevel)
 
int durable_unlink (const char *fname, int elevel)
 
int durable_link_or_rename (const char *oldfile, const char *newfile, int elevel)
 
void InitFileAccess (void)
 
static void count_usable_fds (int max_to_probe, int *usable_fds, int *already_open)
 
void set_max_safe_fds (void)
 
int BasicOpenFile (FileName fileName, int fileFlags, int fileMode)
 
File PathNameOpenFile (FileName fileName, int fileFlags, int fileMode)
 
File OpenTemporaryFile (bool interXact)
 
void FileClose (File file)
 
int FilePrefetch (File file, off_t offset, int amount, uint32 wait_event_info)
 
void FileWriteback (File file, off_t offset, off_t nbytes, uint32 wait_event_info)
 
int FileRead (File file, char *buffer, int amount, uint32 wait_event_info)
 
int FileWrite (File file, char *buffer, int amount, uint32 wait_event_info)
 
int FileSync (File file, uint32 wait_event_info)
 
off_t FileSeek (File file, off_t offset, int whence)
 
int FileTruncate (File file, off_t offset, uint32 wait_event_info)
 
char * FilePathName (File file)
 
int FileGetRawDesc (File file)
 
int FileGetRawFlags (File file)
 
int FileGetRawMode (File file)
 
FILE * AllocateFile (const char *name, const char *mode)
 
int OpenTransientFile (FileName fileName, int fileFlags, int 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)
 
int FreeDir (DIR *dir)
 
int ClosePipeStream (FILE *file)
 
void closeAllVfds (void)
 
void SetTempTablespaces (Oid *tableSpaces, int numSpaces)
 
bool TempTablespacesAreSet (void)
 
Oid GetNextTempTableSpace (void)
 
void AtEOSubXact_Files (bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
 
void AtEOXact_Files (void)
 
void RemovePgTempFiles (void)
 
void SyncDataDirectory (void)
 

Variables

int max_files_per_process = 1000
 
int max_safe_fds = 32
 
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 long tempFileCounter = 0
 
static OidtempTableSpaces = NULL
 
static int numTempTableSpaces = -1
 
static int nextTempTableSpace = 0
 

Macro Definition Documentation

#define FD_MINFREE   10

Definition at line 117 of file fd.c.

Referenced by reserveAllocatedDesc(), and set_max_safe_fds().

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

Definition at line 173 of file fd.c.

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

#define FD_XACT_TEMPORARY   (1 << 1) /* T = delete at eoXact */

Definition at line 174 of file fd.c.

Referenced by CleanupTempFiles(), and OpenTemporaryFile().

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

Definition at line 161 of file fd.c.

Referenced by CleanupTempFiles(), closeAllVfds(), FileAccess(), FileClose(), FileSeek(), and LruInsert().

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

Definition at line 170 of file fd.c.

Referenced by FileRead(), FileSeek(), FileWrite(), and LruDelete().

#define FileUnknownPos   ((off_t) -1)

Definition at line 169 of file fd.c.

Referenced by FileRead(), and FileWrite().

#define NUM_RESERVED_FDS   10

Definition at line 111 of file fd.c.

Referenced by set_max_safe_fds().

#define VFD_CLOSED   (-1)

Definition at line 156 of file fd.c.

Referenced by AllocateVfd(), FileClose(), InitFileAccess(), LruDelete(), and LruInsert().

Typedef Documentation

typedef struct vfd Vfd

Enumeration Type Documentation

Enumerator
AllocateDescFile 
AllocateDescPipe 
AllocateDescDir 
AllocateDescRawFD 

Definition at line 223 of file fd.c.

Function Documentation

DIR* AllocateDir ( const char *  dirname)

Definition at line 2335 of file fd.c.

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

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

2336 {
2337  DIR *dir;
2338 
2339  DO_DB(elog(LOG, "AllocateDir: Allocated %d (%s)",
2340  numAllocatedDescs, dirname));
2341 
2342  /* Can we allocate another non-virtual FD? */
2343  if (!reserveAllocatedDesc())
2344  ereport(ERROR,
2345  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2346  errmsg("exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"",
2347  maxAllocatedDescs, dirname)));
2348 
2349  /* Close excess kernel FDs. */
2350  ReleaseLruFiles();
2351 
2352 TryAgain:
2353  if ((dir = opendir(dirname)) != NULL)
2354  {
2356 
2357  desc->kind = AllocateDescDir;
2358  desc->desc.dir = dir;
2361  return desc->desc.dir;
2362  }
2363 
2364  if (errno == EMFILE || errno == ENFILE)
2365  {
2366  int save_errno = errno;
2367 
2368  ereport(LOG,
2369  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2370  errmsg("out of file descriptors: %m; release and retry")));
2371  errno = 0;
2372  if (ReleaseLruFile())
2373  goto TryAgain;
2374  errno = save_errno;
2375  }
2376 
2377  return NULL;
2378 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
DIR * dir
Definition: fd.c:238
#define DO_DB(A)
Definition: fd.c:152
int errcode(int sqlerrcode)
Definition: elog.c:575
static bool reserveAllocatedDesc(void)
Definition: fd.c:2021
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static bool ReleaseLruFile(void)
Definition: fd.c:1140
Definition: dirent.c:25
#define ERROR
Definition: elog.h:43
DIR * opendir(const char *)
Definition: dirent.c:33
#define ereport(elevel, rest)
Definition: elog.h:122
static void ReleaseLruFiles(void)
Definition: fd.c:1162
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:650
SubTransactionId create_subid
Definition: fd.c:234
int errmsg(const char *fmt,...)
Definition: elog.c:797
union AllocateDesc::@27 desc
#define elog
Definition: elog.h:219
static int maxAllocatedDescs
Definition: fd.c:244
static int numAllocatedDescs
Definition: fd.c:243
FILE* AllocateFile ( const char *  name,
const char *  mode 
)

Definition at line 2094 of file fd.c.

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

Referenced by AlterSystemSetConfigFile(), apw_dump_now(), apw_load_buffers(), BeginCopyFrom(), BeginCopyTo(), checkDataDir(), do_pg_start_backup(), do_pg_stop_backup(), entry_reset(), existsTimeLineHistory(), ExportSnapshot(), fill_hba_view(), gc_qtexts(), ImportSnapshot(), load_dh_file(), load_hba(), load_ident(), load_relcache_init_file(), parse_extension_control_file(), ParseTzFile(), perform_base_backup(), pg_backup_start_time(), pg_current_logfile(), pg_file_write(), pgss_shmem_shutdown(), pgss_shmem_startup(), pgstat_read_db_statsfile(), pgstat_read_db_statsfile_timestamp(), pgstat_read_statsfiles(), pgstat_write_db_statsfile(), pgstat_write_statsfiles(), read_backup_label(), read_binary_file(), read_tablespace_map(), read_whole_file(), readRecoveryCommandFile(), readTimeLineHistory(), sendFile(), tokenize_inc_file(), tsearch_readline_begin(), ValidatePgVersion(), write_relcache_init_file(), XLogArchiveForceDone(), and XLogArchiveNotify().

2095 {
2096  FILE *file;
2097 
2098  DO_DB(elog(LOG, "AllocateFile: Allocated %d (%s)",
2100 
2101  /* Can we allocate another non-virtual FD? */
2102  if (!reserveAllocatedDesc())
2103  ereport(ERROR,
2104  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2105  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2106  maxAllocatedDescs, name)));
2107 
2108  /* Close excess kernel FDs. */
2109  ReleaseLruFiles();
2110 
2111 TryAgain:
2112  if ((file = fopen(name, mode)) != NULL)
2113  {
2115 
2116  desc->kind = AllocateDescFile;
2117  desc->desc.file = file;
2120  return desc->desc.file;
2121  }
2122 
2123  if (errno == EMFILE || errno == ENFILE)
2124  {
2125  int save_errno = errno;
2126 
2127  ereport(LOG,
2128  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2129  errmsg("out of file descriptors: %m; release and retry")));
2130  errno = 0;
2131  if (ReleaseLruFile())
2132  goto TryAgain;
2133  errno = save_errno;
2134  }
2135 
2136  return NULL;
2137 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
#define DO_DB(A)
Definition: fd.c:152
int errcode(int sqlerrcode)
Definition: elog.c:575
static bool reserveAllocatedDesc(void)
Definition: fd.c:2021
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static bool ReleaseLruFile(void)
Definition: fd.c:1140
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
static void ReleaseLruFiles(void)
Definition: fd.c:1162
FILE * file
Definition: fd.c:237
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:650
SubTransactionId create_subid
Definition: fd.c:234
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:797
union AllocateDesc::@27 desc
#define elog
Definition: elog.h:219
static int maxAllocatedDescs
Definition: fd.c:244
static int numAllocatedDescs
Definition: fd.c:243
static File AllocateVfd ( void  )
static

Definition at line 1172 of file fd.c.

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

Referenced by PathNameOpenFile().

1173 {
1174  Index i;
1175  File file;
1176 
1177  DO_DB(elog(LOG, "AllocateVfd. Size %zu", SizeVfdCache));
1178 
1179  Assert(SizeVfdCache > 0); /* InitFileAccess not called? */
1180 
1181  if (VfdCache[0].nextFree == 0)
1182  {
1183  /*
1184  * The free list is empty so it is time to increase the size of the
1185  * array. We choose to double it each time this happens. However,
1186  * there's not much point in starting *real* small.
1187  */
1188  Size newCacheSize = SizeVfdCache * 2;
1189  Vfd *newVfdCache;
1190 
1191  if (newCacheSize < 32)
1192  newCacheSize = 32;
1193 
1194  /*
1195  * Be careful not to clobber VfdCache ptr if realloc fails.
1196  */
1197  newVfdCache = (Vfd *) realloc(VfdCache, sizeof(Vfd) * newCacheSize);
1198  if (newVfdCache == NULL)
1199  ereport(ERROR,
1200  (errcode(ERRCODE_OUT_OF_MEMORY),
1201  errmsg("out of memory")));
1202  VfdCache = newVfdCache;
1203 
1204  /*
1205  * Initialize the new entries and link them into the free list.
1206  */
1207  for (i = SizeVfdCache; i < newCacheSize; i++)
1208  {
1209  MemSet((char *) &(VfdCache[i]), 0, sizeof(Vfd));
1210  VfdCache[i].nextFree = i + 1;
1211  VfdCache[i].fd = VFD_CLOSED;
1212  }
1213  VfdCache[newCacheSize - 1].nextFree = 0;
1215 
1216  /*
1217  * Record the new size
1218  */
1219  SizeVfdCache = newCacheSize;
1220  }
1221 
1222  file = VfdCache[0].nextFree;
1223 
1224  VfdCache[0].nextFree = VfdCache[file].nextFree;
1225 
1226  return file;
1227 }
File nextFree
Definition: fd.c:181
static Size SizeVfdCache
Definition: fd.c:198
#define DO_DB(A)
Definition: fd.c:152
static Vfd * VfdCache
Definition: fd.c:197
int errcode(int sqlerrcode)
Definition: elog.c:575
#define MemSet(start, val, len)
Definition: c.h:846
#define LOG
Definition: elog.h:26
#define ERROR
Definition: elog.h:43
Definition: fd.c:176
int fd
Definition: fd.c:178
#define ereport(elevel, rest)
Definition: elog.h:122
unsigned int Index
Definition: c.h:359
#define VFD_CLOSED
Definition: fd.c:156
#define Assert(condition)
Definition: c.h:664
size_t Size
Definition: c.h:350
#define realloc(a, b)
Definition: header.h:60
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
#define elog
Definition: elog.h:219
int File
Definition: fd.h:51
void AtEOSubXact_Files ( bool  isCommit,
SubTransactionId  mySubid,
SubTransactionId  parentSubid 
)

Definition at line 2586 of file fd.c.

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

Referenced by AbortSubTransaction(), and CommitSubTransaction().

2588 {
2589  Index i;
2590 
2591  for (i = 0; i < numAllocatedDescs; i++)
2592  {
2593  if (allocatedDescs[i].create_subid == mySubid)
2594  {
2595  if (isCommit)
2596  allocatedDescs[i].create_subid = parentSubid;
2597  else
2598  {
2599  /* have to recheck the item after FreeDesc (ugly) */
2600  FreeDesc(&allocatedDescs[i--]);
2601  }
2602  }
2603  }
2604 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2238
unsigned int Index
Definition: c.h:359
SubTransactionId create_subid
Definition: fd.c:234
int i
static int numAllocatedDescs
Definition: fd.c:243
void AtEOXact_Files ( void  )

Definition at line 2617 of file fd.c.

References CleanupTempFiles(), numTempTableSpaces, and tempTableSpaces.

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

2618 {
2619  CleanupTempFiles(false);
2620  tempTableSpaces = NULL;
2621  numTempTableSpaces = -1;
2622 }
static int numTempTableSpaces
Definition: fd.c:258
static void CleanupTempFiles(bool isProcExit)
Definition: fd.c:2646
static Oid * tempTableSpaces
Definition: fd.c:257
static void AtProcExit_Files ( int  code,
Datum  arg 
)
static

Definition at line 2631 of file fd.c.

References CleanupTempFiles().

Referenced by InitFileAccess().

2632 {
2633  CleanupTempFiles(true);
2634 }
static void CleanupTempFiles(bool isProcExit)
Definition: fd.c:2646
int BasicOpenFile ( FileName  fileName,
int  fileFlags,
int  fileMode 
)

Definition at line 936 of file fd.c.

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

Referenced by AlterSystemSetConfigFile(), GetNewRelFileNode(), LruInsert(), OpenTransientFile(), PathNameOpenFile(), ReadControlFile(), UpdateControlFile(), WriteControlFile(), XLogFileInit(), XLogFileOpen(), XLogFileRead(), and XLogRead().

937 {
938  int fd;
939 
940 tryAgain:
941  fd = open(fileName, fileFlags, fileMode);
942 
943  if (fd >= 0)
944  return fd; /* success! */
945 
946  if (errno == EMFILE || errno == ENFILE)
947  {
948  int save_errno = errno;
949 
950  ereport(LOG,
951  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
952  errmsg("out of file descriptors: %m; release and retry")));
953  errno = 0;
954  if (ReleaseLruFile())
955  goto tryAgain;
956  errno = save_errno;
957  }
958 
959  return -1; /* failure */
960 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static bool ReleaseLruFile(void)
Definition: fd.c:1140
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797
static void CleanupTempFiles ( bool  isProcExit)
static

Definition at line 2646 of file fd.c.

References Assert, elog, FD_TEMPORARY, FD_XACT_TEMPORARY, vfd::fdstate, FileClose(), FileIsNotOpen, FreeDesc(), have_xact_temporary_files, i, numAllocatedDescs, SizeVfdCache, and WARNING.

Referenced by AtEOXact_Files(), and AtProcExit_Files().

2647 {
2648  Index i;
2649 
2650  /*
2651  * Careful here: at proc_exit we need extra cleanup, not just
2652  * xact_temporary files.
2653  */
2654  if (isProcExit || have_xact_temporary_files)
2655  {
2656  Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
2657  for (i = 1; i < SizeVfdCache; i++)
2658  {
2659  unsigned short fdstate = VfdCache[i].fdstate;
2660 
2661  if ((fdstate & FD_TEMPORARY) && VfdCache[i].fileName != NULL)
2662  {
2663  /*
2664  * If we're in the process of exiting a backend process, close
2665  * all temporary files. Otherwise, only close temporary files
2666  * local to the current transaction. They should be closed by
2667  * the ResourceOwner mechanism already, so this is just a
2668  * debugging cross-check.
2669  */
2670  if (isProcExit)
2671  FileClose(i);
2672  else if (fdstate & FD_XACT_TEMPORARY)
2673  {
2674  elog(WARNING,
2675  "temporary file %s not closed at end-of-transaction",
2676  VfdCache[i].fileName);
2677  FileClose(i);
2678  }
2679  }
2680  }
2681 
2682  have_xact_temporary_files = false;
2683  }
2684 
2685  /* Clean up "allocated" stdio files, dirs and fds. */
2686  while (numAllocatedDescs > 0)
2687  FreeDesc(&allocatedDescs[0]);
2688 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
static Size SizeVfdCache
Definition: fd.c:198
static Vfd * VfdCache
Definition: fd.c:197
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2238
static bool have_xact_temporary_files
Definition: fd.c:209
unsigned short fdstate
Definition: fd.c:179
#define WARNING
Definition: elog.h:40
#define FileIsNotOpen(file)
Definition: fd.c:161
#define FD_TEMPORARY
Definition: fd.c:173
#define FD_XACT_TEMPORARY
Definition: fd.c:174
unsigned int Index
Definition: c.h:359
void FileClose(File file)
Definition: fd.c:1493
#define Assert(condition)
Definition: c.h:664
int i
#define elog
Definition: elog.h:219
static int numAllocatedDescs
Definition: fd.c:243
void closeAllVfds ( void  )

Definition at line 2499 of file fd.c.

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

Referenced by standard_ProcessUtility().

2500 {
2501  Index i;
2502 
2503  if (SizeVfdCache > 0)
2504  {
2505  Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
2506  for (i = 1; i < SizeVfdCache; i++)
2507  {
2508  if (!FileIsNotOpen(i))
2509  LruDelete(i);
2510  }
2511  }
2512 }
static Size SizeVfdCache
Definition: fd.c:198
static void LruDelete(File file)
Definition: fd.c:1003
#define FileIsNotOpen(file)
Definition: fd.c:161
unsigned int Index
Definition: c.h:359
#define Assert(condition)
Definition: c.h:664
int i
int ClosePipeStream ( FILE *  file)

Definition at line 2470 of file fd.c.

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

Referenced by ClosePipeToProgram(), and pg_import_system_collations().

2471 {
2472  int i;
2473 
2474  DO_DB(elog(LOG, "ClosePipeStream: Allocated %d", numAllocatedDescs));
2475 
2476  /* Remove file from list of allocated files, if it's present */
2477  for (i = numAllocatedDescs; --i >= 0;)
2478  {
2479  AllocateDesc *desc = &allocatedDescs[i];
2480 
2481  if (desc->kind == AllocateDescPipe && desc->desc.file == file)
2482  return FreeDesc(desc);
2483  }
2484 
2485  /* Only get here if someone passes us a file not in allocatedDescs */
2486  elog(WARNING, "file passed to ClosePipeStream was not obtained from OpenPipeStream");
2487 
2488  return pclose(file);
2489 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
#define DO_DB(A)
Definition: fd.c:152
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2238
#define WARNING
Definition: elog.h:40
FILE * file
Definition: fd.c:237
union AllocateDesc::@27 desc
int i
#define elog
Definition: elog.h:219
static int numAllocatedDescs
Definition: fd.c:243
int CloseTransientFile ( int  fd)

Definition at line 2305 of file fd.c.

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

Referenced by be_lo_export(), CheckPointLogicalRewriteHeap(), CheckPointReplicationOrigin(), copy_file(), dsm_impl_mmap(), durable_rename(), fsync_fname_ext(), heap_xlog_logical_rewrite(), lo_import_internal(), load_relmap_file(), mdunlinkfork(), qtext_load_file(), qtext_store(), ReadTwoPhaseFile(), RecreateTwoPhaseFile(), ReorderBufferIterTXNFinish(), ReorderBufferRestoreChanges(), ReorderBufferSerializeChange(), ReorderBufferSerializeTXN(), RestoreSlotFromDisk(), SaveSlotToPath(), SendTimeLineHistory(), SimpleLruDoesPhysicalPageExist(), SimpleLruFlush(), SlruInternalWritePage(), SlruPhysicalReadPage(), SlruPhysicalWritePage(), SnapBuildRestore(), SnapBuildSerialize(), StartupReplicationOrigin(), write_relmap_file(), writeTimeLineHistory(), writeTimeLineHistoryFile(), and XLogFileCopy().

2306 {
2307  int i;
2308 
2309  DO_DB(elog(LOG, "CloseTransientFile: Allocated %d", numAllocatedDescs));
2310 
2311  /* Remove fd from list of allocated files, if it's present */
2312  for (i = numAllocatedDescs; --i >= 0;)
2313  {
2314  AllocateDesc *desc = &allocatedDescs[i];
2315 
2316  if (desc->kind == AllocateDescRawFD && desc->desc.fd == fd)
2317  return FreeDesc(desc);
2318  }
2319 
2320  /* Only get here if someone passes us a file not in allocatedDescs */
2321  elog(WARNING, "fd passed to CloseTransientFile was not obtained from OpenTransientFile");
2322 
2323  return close(fd);
2324 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
#define DO_DB(A)
Definition: fd.c:152
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2238
#define WARNING
Definition: elog.h:40
int fd
Definition: fd.c:239
union AllocateDesc::@27 desc
int i
#define elog
Definition: elog.h:219
#define close(a)
Definition: win32.h:12
static int numAllocatedDescs
Definition: fd.c:243
static void count_usable_fds ( int  max_to_probe,
int *  usable_fds,
int *  already_open 
)
static

Definition at line 797 of file fd.c.

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

Referenced by set_max_safe_fds().

798 {
799  int *fd;
800  int size;
801  int used = 0;
802  int highestfd = 0;
803  int j;
804 
805 #ifdef HAVE_GETRLIMIT
806  struct rlimit rlim;
807  int getrlimit_status;
808 #endif
809 
810  size = 1024;
811  fd = (int *) palloc(size * sizeof(int));
812 
813 #ifdef HAVE_GETRLIMIT
814 #ifdef RLIMIT_NOFILE /* most platforms use RLIMIT_NOFILE */
815  getrlimit_status = getrlimit(RLIMIT_NOFILE, &rlim);
816 #else /* but BSD doesn't ... */
817  getrlimit_status = getrlimit(RLIMIT_OFILE, &rlim);
818 #endif /* RLIMIT_NOFILE */
819  if (getrlimit_status != 0)
820  ereport(WARNING, (errmsg("getrlimit failed: %m")));
821 #endif /* HAVE_GETRLIMIT */
822 
823  /* dup until failure or probe limit reached */
824  for (;;)
825  {
826  int thisfd;
827 
828 #ifdef HAVE_GETRLIMIT
829 
830  /*
831  * don't go beyond RLIMIT_NOFILE; causes irritating kernel logs on
832  * some platforms
833  */
834  if (getrlimit_status == 0 && highestfd >= rlim.rlim_cur - 1)
835  break;
836 #endif
837 
838  thisfd = dup(0);
839  if (thisfd < 0)
840  {
841  /* Expect EMFILE or ENFILE, else it's fishy */
842  if (errno != EMFILE && errno != ENFILE)
843  elog(WARNING, "dup(0) failed after %d successes: %m", used);
844  break;
845  }
846 
847  if (used >= size)
848  {
849  size *= 2;
850  fd = (int *) repalloc(fd, size * sizeof(int));
851  }
852  fd[used++] = thisfd;
853 
854  if (highestfd < thisfd)
855  highestfd = thisfd;
856 
857  if (used >= max_to_probe)
858  break;
859  }
860 
861  /* release the files we opened */
862  for (j = 0; j < used; j++)
863  close(fd[j]);
864 
865  pfree(fd);
866 
867  /*
868  * Return results. usable_fds is just the number of successful dups. We
869  * assume that the system limit is highestfd+1 (remember 0 is a legal FD
870  * number) and so already_open is highestfd+1 - usable_fds.
871  */
872  *usable_fds = used;
873  *already_open = highestfd + 1 - used;
874 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
void pfree(void *pointer)
Definition: mcxt.c:949
#define ereport(elevel, rest)
Definition: elog.h:122
#define WARNING
Definition: elog.h:40
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:962
void * palloc(Size size)
Definition: mcxt.c:848
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219
#define close(a)
Definition: win32.h:12
static void datadir_fsync_fname ( const char *  fname,
bool  isdir,
int  elevel 
)
static

Definition at line 3108 of file fd.c.

References fsync_fname_ext().

Referenced by SyncDataDirectory().

3109 {
3110  /*
3111  * We want to silently ignoring errors about unreadable files. Pass that
3112  * desire on to fsync_fname_ext().
3113  */
3114  fsync_fname_ext(fname, isdir, true, elevel);
3115 }
static int elevel
Definition: vacuumlazy.c:136
static int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3126
static void Delete ( File  file)
static

Definition at line 984 of file fd.c.

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

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

985 {
986  Vfd *vfdP;
987 
988  Assert(file != 0);
989 
990  DO_DB(elog(LOG, "Delete %d (%s)",
991  file, VfdCache[file].fileName));
992  DO_DB(_dump_lru());
993 
994  vfdP = &VfdCache[file];
995 
998 
999  DO_DB(_dump_lru());
1000 }
File lruLessRecently
Definition: fd.c:183
#define DO_DB(A)
Definition: fd.c:152
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
Definition: fd.c:176
#define Assert(condition)
Definition: c.h:664
File lruMoreRecently
Definition: fd.c:182
#define elog
Definition: elog.h:219
int durable_link_or_rename ( const char *  oldfile,
const char *  newfile,
int  elevel 
)

Definition at line 712 of file fd.c.

References ereport, errcode_for_file_access(), errmsg(), fsync_fname_ext(), fsync_parent_path(), link(), and unlink().

Referenced by InstallXLogFileSegment(), writeTimeLineHistory(), and writeTimeLineHistoryFile().

713 {
714  /*
715  * Ensure that, if we crash directly after the rename/link, a file with
716  * valid contents is moved into place.
717  */
718  if (fsync_fname_ext(oldfile, false, false, elevel) != 0)
719  return -1;
720 
721 #if HAVE_WORKING_LINK
722  if (link(oldfile, newfile) < 0)
723  {
724  ereport(elevel,
726  errmsg("could not link file \"%s\" to \"%s\": %m",
727  oldfile, newfile)));
728  return -1;
729  }
730  unlink(oldfile);
731 #else
732  /* XXX: Add racy file existence check? */
733  if (rename(oldfile, newfile) < 0)
734  {
735  ereport(elevel,
737  errmsg("could not rename file \"%s\" to \"%s\": %m",
738  oldfile, newfile)));
739  return -1;
740  }
741 #endif
742 
743  /*
744  * Make change persistent in case of an OS crash, both the new entry and
745  * its parent directory need to be flushed.
746  */
747  if (fsync_fname_ext(newfile, false, false, elevel) != 0)
748  return -1;
749 
750  /* Same for parent directory */
751  if (fsync_parent_path(newfile, elevel) != 0)
752  return -1;
753 
754  return 0;
755 }
int errcode_for_file_access(void)
Definition: elog.c:598
int unlink(const char *filename)
#define ereport(elevel, rest)
Definition: elog.h:122
int link(const char *fromname, const char *toname)
static int elevel
Definition: vacuumlazy.c:136
int errmsg(const char *fmt,...)
Definition: elog.c:797
static int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3126
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3196
int durable_rename ( const char *  oldfile,
const char *  newfile,
int  elevel 
)

Definition at line 593 of file fd.c.

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(), CancelBackup(), CheckPointReplicationOrigin(), dir_close(), exitArchiveRecovery(), KeepFileRestoredFromArchive(), pgarch_archiveDone(), pgss_shmem_shutdown(), StartupXLOG(), and XLogArchiveForceDone().

594 {
595  int fd;
596 
597  /*
598  * First fsync the old and target path (if it exists), to ensure that they
599  * are properly persistent on disk. Syncing the target file is not
600  * strictly necessary, but it makes it easier to reason about crashes;
601  * because it's then guaranteed that either source or target file exists
602  * after a crash.
603  */
604  if (fsync_fname_ext(oldfile, false, false, elevel) != 0)
605  return -1;
606 
607  fd = OpenTransientFile((char *) newfile, PG_BINARY | O_RDWR, 0);
608  if (fd < 0)
609  {
610  if (errno != ENOENT)
611  {
612  ereport(elevel,
614  errmsg("could not open file \"%s\": %m", newfile)));
615  return -1;
616  }
617  }
618  else
619  {
620  if (pg_fsync(fd) != 0)
621  {
622  int save_errno;
623 
624  /* close file upon error, might not be in transaction context */
625  save_errno = errno;
626  CloseTransientFile(fd);
627  errno = save_errno;
628 
629  ereport(elevel,
631  errmsg("could not fsync file \"%s\": %m", newfile)));
632  return -1;
633  }
634  CloseTransientFile(fd);
635  }
636 
637  /* Time to do the real deal... */
638  if (rename(oldfile, newfile) < 0)
639  {
640  ereport(elevel,
642  errmsg("could not rename file \"%s\" to \"%s\": %m",
643  oldfile, newfile)));
644  return -1;
645  }
646 
647  /*
648  * To guarantee renaming the file is persistent, fsync the file with its
649  * new name, and its containing directory.
650  */
651  if (fsync_fname_ext(newfile, false, false, elevel) != 0)
652  return -1;
653 
654  if (fsync_parent_path(newfile, elevel) != 0)
655  return -1;
656 
657  return 0;
658 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1027
int OpenTransientFile(FileName fileName, int fileFlags, int fileMode)
Definition: fd.c:2144
int errcode_for_file_access(void)
Definition: elog.c:598
#define ereport(elevel, rest)
Definition: elog.h:122
int CloseTransientFile(int fd)
Definition: fd.c:2305
static int elevel
Definition: vacuumlazy.c:136
int errmsg(const char *fmt,...)
Definition: elog.c:797
static int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3126
int pg_fsync(int fd)
Definition: fd.c:333
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3196
int durable_unlink ( const char *  fname,
int  elevel 
)

Definition at line 676 of file fd.c.

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

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

677 {
678  if (unlink(fname) < 0)
679  {
680  ereport(elevel,
682  errmsg("could not remove file \"%s\": %m",
683  fname)));
684  return -1;
685  }
686 
687  /*
688  * To guarantee that the removal of the file is persistent, fsync its
689  * parent directory.
690  */
691  if (fsync_parent_path(fname, elevel) != 0)
692  return -1;
693 
694  return 0;
695 }
int errcode_for_file_access(void)
Definition: elog.c:598
int unlink(const char *filename)
#define ereport(elevel, rest)
Definition: elog.h:122
static int elevel
Definition: vacuumlazy.c:136
int errmsg(const char *fmt,...)
Definition: elog.c:797
static int fsync_parent_path(const char *fname, int elevel)
Definition: fd.c:3196
static int FileAccess ( File  file)
static

Definition at line 1250 of file fd.c.

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

Referenced by FilePrefetch(), FileRead(), FileSeek(), FileSync(), FileTruncate(), FileWrite(), and FileWriteback().

1251 {
1252  int returnValue;
1253 
1254  DO_DB(elog(LOG, "FileAccess %d (%s)",
1255  file, VfdCache[file].fileName));
1256 
1257  /*
1258  * Is the file open? If not, open it and put it at the head of the LRU
1259  * ring (possibly closing the least recently used file to get an FD).
1260  */
1261 
1262  if (FileIsNotOpen(file))
1263  {
1264  returnValue = LruInsert(file);
1265  if (returnValue != 0)
1266  return returnValue;
1267  }
1268  else if (VfdCache[0].lruLessRecently != file)
1269  {
1270  /*
1271  * We now know that the file is open and that it is not the last one
1272  * accessed, so we need to move it to the head of the Lru ring.
1273  */
1274 
1275  Delete(file);
1276  Insert(file);
1277  }
1278 
1279  return 0;
1280 }
#define DO_DB(A)
Definition: fd.c:152
static Vfd * VfdCache
Definition: fd.c:197
static void Delete(File file)
Definition: fd.c:984
#define LOG
Definition: elog.h:26
static int LruInsert(File file)
Definition: fd.c:1066
static void Insert(File file)
Definition: fd.c:1044
#define FileIsNotOpen(file)
Definition: fd.c:161
#define elog
Definition: elog.h:219
void FileClose ( File  file)

Definition at line 1493 of file fd.c.

References Assert, close, Delete(), DO_DB, elog, ereport, errmsg(), vfd::fd, FD_TEMPORARY, vfd::fdstate, FileIsNotOpen, FileIsValid, vfd::fileName, vfd::fileSize, FreeVfd(), LOG, log_temp_files, nfile, pgstat_report_tempfile(), ResourceOwnerForgetFile(), vfd::resowner, temporary_files_size, unlink(), and VFD_CLOSED.

Referenced by BufFileClose(), CleanupTempFiles(), logical_end_heap_rewrite(), mdclose(), mdtruncate(), and ResourceOwnerReleaseInternal().

1494 {
1495  Vfd *vfdP;
1496 
1497  Assert(FileIsValid(file));
1498 
1499  DO_DB(elog(LOG, "FileClose: %d (%s)",
1500  file, VfdCache[file].fileName));
1501 
1502  vfdP = &VfdCache[file];
1503 
1504  if (!FileIsNotOpen(file))
1505  {
1506  /* close the file */
1507  if (close(vfdP->fd))
1508  elog(LOG, "could not close file \"%s\": %m", vfdP->fileName);
1509 
1510  --nfile;
1511  vfdP->fd = VFD_CLOSED;
1512 
1513  /* remove the file from the lru ring */
1514  Delete(file);
1515  }
1516 
1517  /*
1518  * Delete the file if it was temporary, and make a log entry if wanted
1519  */
1520  if (vfdP->fdstate & FD_TEMPORARY)
1521  {
1522  struct stat filestats;
1523  int stat_errno;
1524 
1525  /*
1526  * If we get an error, as could happen within the ereport/elog calls,
1527  * we'll come right back here during transaction abort. Reset the
1528  * flag to ensure that we can't get into an infinite loop. This code
1529  * is arranged to ensure that the worst-case consequence is failing to
1530  * emit log message(s), not failing to attempt the unlink.
1531  */
1532  vfdP->fdstate &= ~FD_TEMPORARY;
1533 
1534  /* Subtract its size from current usage (do first in case of error) */
1535  temporary_files_size -= vfdP->fileSize;
1536  vfdP->fileSize = 0;
1537 
1538  /* first try the stat() */
1539  if (stat(vfdP->fileName, &filestats))
1540  stat_errno = errno;
1541  else
1542  stat_errno = 0;
1543 
1544  /* in any case do the unlink */
1545  if (unlink(vfdP->fileName))
1546  elog(LOG, "could not unlink file \"%s\": %m", vfdP->fileName);
1547 
1548  /* and last report the stat results */
1549  if (stat_errno == 0)
1550  {
1551  pgstat_report_tempfile(filestats.st_size);
1552 
1553  if (log_temp_files >= 0)
1554  {
1555  if ((filestats.st_size / 1024) >= log_temp_files)
1556  ereport(LOG,
1557  (errmsg("temporary file: path \"%s\", size %lu",
1558  vfdP->fileName,
1559  (unsigned long) filestats.st_size)));
1560  }
1561  }
1562  else
1563  {
1564  errno = stat_errno;
1565  elog(LOG, "could not stat file \"%s\": %m", vfdP->fileName);
1566  }
1567  }
1568 
1569  /* Unregister it from the resource owner */
1570  if (vfdP->resowner)
1571  ResourceOwnerForgetFile(vfdP->resowner, file);
1572 
1573  /*
1574  * Return the Vfd slot to the free list
1575  */
1576  FreeVfd(file);
1577 }
#define DO_DB(A)
Definition: fd.c:152
int log_temp_files
Definition: guc.c:454
static Vfd * VfdCache
Definition: fd.c:197
static void Delete(File file)
Definition: fd.c:984
void pgstat_report_tempfile(size_t filesize)
Definition: pgstat.c:1525
#define LOG
Definition: elog.h:26
char * fileName
Definition: fd.c:186
static int nfile
Definition: fd.c:203
unsigned short fdstate
Definition: fd.c:179
Definition: fd.c:176
off_t fileSize
Definition: fd.c:185
int fd
Definition: fd.c:178
int unlink(const char *filename)
#define ereport(elevel, rest)
Definition: elog.h:122
ResourceOwner resowner
Definition: fd.c:180
#define FileIsNotOpen(file)
Definition: fd.c:161
#define FD_TEMPORARY
Definition: fd.c:173
#define FileIsValid(file)
Definition: fd.c:158
#define VFD_CLOSED
Definition: fd.c:156
static uint64 temporary_files_size
Definition: fd.c:217
#define Assert(condition)
Definition: c.h:664
int errmsg(const char *fmt,...)
Definition: elog.c:797
static void FreeVfd(File file)
Definition: fd.c:1230
#define elog
Definition: elog.h:219
#define close(a)
Definition: win32.h:12
void ResourceOwnerForgetFile(ResourceOwner owner, File file)
Definition: resowner.c:1209
int FileGetRawDesc ( File  file)

Definition at line 1990 of file fd.c.

References Assert, vfd::fd, and FileIsValid.

1991 {
1992  Assert(FileIsValid(file));
1993  return VfdCache[file].fd;
1994 }
static Vfd * VfdCache
Definition: fd.c:197
int fd
Definition: fd.c:178
#define FileIsValid(file)
Definition: fd.c:158
#define Assert(condition)
Definition: c.h:664
int FileGetRawFlags ( File  file)

Definition at line 2000 of file fd.c.

References Assert, vfd::fileFlags, and FileIsValid.

2001 {
2002  Assert(FileIsValid(file));
2003  return VfdCache[file].fileFlags;
2004 }
static Vfd * VfdCache
Definition: fd.c:197
#define FileIsValid(file)
Definition: fd.c:158
#define Assert(condition)
Definition: c.h:664
int fileFlags
Definition: fd.c:188
int FileGetRawMode ( File  file)

Definition at line 2010 of file fd.c.

References Assert, FileIsValid, and vfd::fileMode.

2011 {
2012  Assert(FileIsValid(file));
2013  return VfdCache[file].fileMode;
2014 }
static Vfd * VfdCache
Definition: fd.c:197
int fileMode
Definition: fd.c:189
#define FileIsValid(file)
Definition: fd.c:158
#define Assert(condition)
Definition: c.h:664
char* FilePathName ( File  file)

Definition at line 1974 of file fd.c.

References Assert, FileIsValid, and vfd::fileName.

Referenced by _mdnblocks(), mdextend(), mdimmedsync(), mdread(), mdsync(), mdtruncate(), mdwrite(), and register_dirty_segment().

1975 {
1976  Assert(FileIsValid(file));
1977 
1978  return VfdCache[file].fileName;
1979 }
static Vfd * VfdCache
Definition: fd.c:197
char * fileName
Definition: fd.c:186
#define FileIsValid(file)
Definition: fd.c:158
#define Assert(condition)
Definition: c.h:664
int FilePrefetch ( File  file,
off_t  offset,
int  amount,
uint32  wait_event_info 
)

Definition at line 1590 of file fd.c.

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

Referenced by mdprefetch().

1591 {
1592 #if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
1593  int returnCode;
1594 
1595  Assert(FileIsValid(file));
1596 
1597  DO_DB(elog(LOG, "FilePrefetch: %d (%s) " INT64_FORMAT " %d",
1598  file, VfdCache[file].fileName,
1599  (int64) offset, amount));
1600 
1601  returnCode = FileAccess(file);
1602  if (returnCode < 0)
1603  return returnCode;
1604 
1605  pgstat_report_wait_start(wait_event_info);
1606  returnCode = posix_fadvise(VfdCache[file].fd, offset, amount,
1607  POSIX_FADV_WILLNEED);
1609 
1610  return returnCode;
1611 #else
1612  Assert(FileIsValid(file));
1613  return 0;
1614 #endif
1615 }
#define DO_DB(A)
Definition: fd.c:152
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1244
#define FileIsValid(file)
Definition: fd.c:158
static int FileAccess(File file)
Definition: fd.c:1250
#define Assert(condition)
Definition: c.h:664
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1220
#define INT64_FORMAT
Definition: c.h:300
#define elog
Definition: elog.h:219
int FileRead ( File  file,
char *  buffer,
int  amount,
uint32  wait_event_info 
)

Definition at line 1645 of file fd.c.

References _dosmaperr(), Assert, DO_DB, EINTR, elog, error(), vfd::fd, FileAccess(), FileIsValid, FilePosIsUnknown, FileUnknownPos, INT64_FORMAT, LOG, pg_usleep(), pgstat_report_wait_end(), pgstat_report_wait_start(), read, and vfd::seekPos.

Referenced by BufFileLoadBuffer(), and mdread().

1646 {
1647  int returnCode;
1648  Vfd *vfdP;
1649 
1650  Assert(FileIsValid(file));
1651 
1652  DO_DB(elog(LOG, "FileRead: %d (%s) " INT64_FORMAT " %d %p",
1653  file, VfdCache[file].fileName,
1654  (int64) VfdCache[file].seekPos,
1655  amount, buffer));
1656 
1657  returnCode = FileAccess(file);
1658  if (returnCode < 0)
1659  return returnCode;
1660 
1661  vfdP = &VfdCache[file];
1662 
1663 retry:
1664  pgstat_report_wait_start(wait_event_info);
1665  returnCode = read(vfdP->fd, buffer, amount);
1667 
1668  if (returnCode >= 0)
1669  {
1670  /* if seekPos is unknown, leave it that way */
1671  if (!FilePosIsUnknown(vfdP->seekPos))
1672  vfdP->seekPos += returnCode;
1673  }
1674  else
1675  {
1676  /*
1677  * Windows may run out of kernel buffers and return "Insufficient
1678  * system resources" error. Wait a bit and retry to solve it.
1679  *
1680  * It is rumored that EINTR is also possible on some Unix filesystems,
1681  * in which case immediate retry is indicated.
1682  */
1683 #ifdef WIN32
1684  DWORD error = GetLastError();
1685 
1686  switch (error)
1687  {
1688  case ERROR_NO_SYSTEM_RESOURCES:
1689  pg_usleep(1000L);
1690  errno = EINTR;
1691  break;
1692  default:
1693  _dosmaperr(error);
1694  break;
1695  }
1696 #endif
1697  /* OK to retry if interrupted */
1698  if (errno == EINTR)
1699  goto retry;
1700 
1701  /* Trouble, so assume we don't know the file position anymore */
1702  vfdP->seekPos = FileUnknownPos;
1703  }
1704 
1705  return returnCode;
1706 }
static void error(void)
Definition: sql-dyntest.c:147
#define DO_DB(A)
Definition: fd.c:152
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
#define FilePosIsUnknown(pos)
Definition: fd.c:170
void pg_usleep(long microsec)
Definition: signal.c:53
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1244
off_t seekPos
Definition: fd.c:184
Definition: fd.c:176
int fd
Definition: fd.c:178
#define EINTR
Definition: win32.h:285
#define FileIsValid(file)
Definition: fd.c:158
static int FileAccess(File file)
Definition: fd.c:1250
#define Assert(condition)
Definition: c.h:664
void _dosmaperr(unsigned long)
Definition: win32error.c:171
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1220
#define INT64_FORMAT
Definition: c.h:300
#define elog
Definition: elog.h:219
#define FileUnknownPos
Definition: fd.c:169
#define read(a, b, c)
Definition: win32.h:13
off_t FileSeek ( File  file,
off_t  offset,
int  whence 
)

Definition at line 1851 of file fd.c.

References Assert, DO_DB, elog, ERROR, vfd::fd, FileAccess(), FileIsNotOpen, FileIsValid, FilePosIsUnknown, INT64_FORMAT, LOG, and vfd::seekPos.

Referenced by _mdnblocks(), BufFileDumpBuffer(), BufFileLoadBuffer(), mdextend(), mdread(), and mdwrite().

1852 {
1853  Vfd *vfdP;
1854 
1855  Assert(FileIsValid(file));
1856 
1857  DO_DB(elog(LOG, "FileSeek: %d (%s) " INT64_FORMAT " " INT64_FORMAT " %d",
1858  file, VfdCache[file].fileName,
1859  (int64) VfdCache[file].seekPos,
1860  (int64) offset, whence));
1861 
1862  vfdP = &VfdCache[file];
1863 
1864  if (FileIsNotOpen(file))
1865  {
1866  switch (whence)
1867  {
1868  case SEEK_SET:
1869  if (offset < 0)
1870  {
1871  errno = EINVAL;
1872  return (off_t) -1;
1873  }
1874  vfdP->seekPos = offset;
1875  break;
1876  case SEEK_CUR:
1877  if (FilePosIsUnknown(vfdP->seekPos) ||
1878  vfdP->seekPos + offset < 0)
1879  {
1880  errno = EINVAL;
1881  return (off_t) -1;
1882  }
1883  vfdP->seekPos += offset;
1884  break;
1885  case SEEK_END:
1886  if (FileAccess(file) < 0)
1887  return (off_t) -1;
1888  vfdP->seekPos = lseek(vfdP->fd, offset, whence);
1889  break;
1890  default:
1891  elog(ERROR, "invalid whence: %d", whence);
1892  break;
1893  }
1894  }
1895  else
1896  {
1897  switch (whence)
1898  {
1899  case SEEK_SET:
1900  if (offset < 0)
1901  {
1902  errno = EINVAL;
1903  return (off_t) -1;
1904  }
1905  if (vfdP->seekPos != offset)
1906  vfdP->seekPos = lseek(vfdP->fd, offset, whence);
1907  break;
1908  case SEEK_CUR:
1909  if (offset != 0 || FilePosIsUnknown(vfdP->seekPos))
1910  vfdP->seekPos = lseek(vfdP->fd, offset, whence);
1911  break;
1912  case SEEK_END:
1913  vfdP->seekPos = lseek(vfdP->fd, offset, whence);
1914  break;
1915  default:
1916  elog(ERROR, "invalid whence: %d", whence);
1917  break;
1918  }
1919  }
1920 
1921  return vfdP->seekPos;
1922 }
#define DO_DB(A)
Definition: fd.c:152
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
#define FilePosIsUnknown(pos)
Definition: fd.c:170
#define ERROR
Definition: elog.h:43
off_t seekPos
Definition: fd.c:184
Definition: fd.c:176
int fd
Definition: fd.c:178
#define FileIsNotOpen(file)
Definition: fd.c:161
#define FileIsValid(file)
Definition: fd.c:158
static int FileAccess(File file)
Definition: fd.c:1250
#define Assert(condition)
Definition: c.h:664
#define INT64_FORMAT
Definition: c.h:300
#define elog
Definition: elog.h:219
int FileSync ( File  file,
uint32  wait_event_info 
)

Definition at line 1830 of file fd.c.

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

Referenced by logical_end_heap_rewrite(), mdimmedsync(), mdsync(), and register_dirty_segment().

1831 {
1832  int returnCode;
1833 
1834  Assert(FileIsValid(file));
1835 
1836  DO_DB(elog(LOG, "FileSync: %d (%s)",
1837  file, VfdCache[file].fileName));
1838 
1839  returnCode = FileAccess(file);
1840  if (returnCode < 0)
1841  return returnCode;
1842 
1843  pgstat_report_wait_start(wait_event_info);
1844  returnCode = pg_fsync(VfdCache[file].fd);
1846 
1847  return returnCode;
1848 }
#define DO_DB(A)
Definition: fd.c:152
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1244
#define FileIsValid(file)
Definition: fd.c:158
static int FileAccess(File file)
Definition: fd.c:1250
#define Assert(condition)
Definition: c.h:664
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1220
int pg_fsync(int fd)
Definition: fd.c:333
#define elog
Definition: elog.h:219
int FileTruncate ( File  file,
off_t  offset,
uint32  wait_event_info 
)

Definition at line 1939 of file fd.c.

References Assert, DO_DB, elog, fd(), FD_TEMPORARY, FileAccess(), FileIsValid, vfd::fileSize, ftruncate, LOG, pgstat_report_wait_end(), pgstat_report_wait_start(), and temporary_files_size.

Referenced by mdtruncate().

1940 {
1941  int returnCode;
1942 
1943  Assert(FileIsValid(file));
1944 
1945  DO_DB(elog(LOG, "FileTruncate %d (%s)",
1946  file, VfdCache[file].fileName));
1947 
1948  returnCode = FileAccess(file);
1949  if (returnCode < 0)
1950  return returnCode;
1951 
1952  pgstat_report_wait_start(wait_event_info);
1953  returnCode = ftruncate(VfdCache[file].fd, offset);
1955 
1956  if (returnCode == 0 && VfdCache[file].fileSize > offset)
1957  {
1958  /* adjust our state for truncation of a temp file */
1959  Assert(VfdCache[file].fdstate & FD_TEMPORARY);
1960  temporary_files_size -= VfdCache[file].fileSize - offset;
1961  VfdCache[file].fileSize = offset;
1962  }
1963 
1964  return returnCode;
1965 }
#define DO_DB(A)
Definition: fd.c:152
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1244
off_t fileSize
Definition: fd.c:185
#define FD_TEMPORARY
Definition: fd.c:173
#define FileIsValid(file)
Definition: fd.c:158
static uint64 temporary_files_size
Definition: fd.c:217
#define ftruncate(a, b)
Definition: win32.h:59
static int FileAccess(File file)
Definition: fd.c:1250
#define Assert(condition)
Definition: c.h:664
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1220
#define elog
Definition: elog.h:219
int FileWrite ( File  file,
char *  buffer,
int  amount,
uint32  wait_event_info 
)

Definition at line 1709 of file fd.c.

References _dosmaperr(), Assert, DO_DB, EINTR, elog, ereport, errcode(), errmsg(), ERROR, error(), vfd::fd, FD_TEMPORARY, vfd::fdstate, FileAccess(), FileIsValid, vfd::fileName, FilePosIsUnknown, vfd::fileSize, FileUnknownPos, INT64_FORMAT, LOG, pg_usleep(), pgstat_report_wait_end(), pgstat_report_wait_start(), vfd::seekPos, temp_file_limit, temporary_files_size, and write.

Referenced by BufFileDumpBuffer(), logical_heap_rewrite_flush_mappings(), mdextend(), and mdwrite().

1710 {
1711  int returnCode;
1712  Vfd *vfdP;
1713 
1714  Assert(FileIsValid(file));
1715 
1716  DO_DB(elog(LOG, "FileWrite: %d (%s) " INT64_FORMAT " %d %p",
1717  file, VfdCache[file].fileName,
1718  (int64) VfdCache[file].seekPos,
1719  amount, buffer));
1720 
1721  returnCode = FileAccess(file);
1722  if (returnCode < 0)
1723  return returnCode;
1724 
1725  vfdP = &VfdCache[file];
1726 
1727  /*
1728  * If enforcing temp_file_limit and it's a temp file, check to see if the
1729  * write would overrun temp_file_limit, and throw error if so. Note: it's
1730  * really a modularity violation to throw error here; we should set errno
1731  * and return -1. However, there's no way to report a suitable error
1732  * message if we do that. All current callers would just throw error
1733  * immediately anyway, so this is safe at present.
1734  */
1735  if (temp_file_limit >= 0 && (vfdP->fdstate & FD_TEMPORARY))
1736  {
1737  off_t newPos;
1738 
1739  /*
1740  * Normally we should know the seek position, but if for some reason
1741  * we have lost track of it, try again to get it. Here, it's fine to
1742  * throw an error if we still can't get it.
1743  */
1744  if (FilePosIsUnknown(vfdP->seekPos))
1745  {
1746  vfdP->seekPos = lseek(vfdP->fd, (off_t) 0, SEEK_CUR);
1747  if (FilePosIsUnknown(vfdP->seekPos))
1748  elog(ERROR, "could not seek file \"%s\": %m", vfdP->fileName);
1749  }
1750 
1751  newPos = vfdP->seekPos + amount;
1752  if (newPos > vfdP->fileSize)
1753  {
1754  uint64 newTotal = temporary_files_size;
1755 
1756  newTotal += newPos - vfdP->fileSize;
1757  if (newTotal > (uint64) temp_file_limit * (uint64) 1024)
1758  ereport(ERROR,
1759  (errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED),
1760  errmsg("temporary file size exceeds temp_file_limit (%dkB)",
1761  temp_file_limit)));
1762  }
1763  }
1764 
1765 retry:
1766  errno = 0;
1767  pgstat_report_wait_start(wait_event_info);
1768  returnCode = write(vfdP->fd, buffer, amount);
1770 
1771  /* if write didn't set errno, assume problem is no disk space */
1772  if (returnCode != amount && errno == 0)
1773  errno = ENOSPC;
1774 
1775  if (returnCode >= 0)
1776  {
1777  /* if seekPos is unknown, leave it that way */
1778  if (!FilePosIsUnknown(vfdP->seekPos))
1779  vfdP->seekPos += returnCode;
1780 
1781  /*
1782  * Maintain fileSize and temporary_files_size if it's a temp file.
1783  *
1784  * If seekPos is -1 (unknown), this will do nothing; but we could only
1785  * get here in that state if we're not enforcing temporary_files_size,
1786  * so we don't care.
1787  */
1788  if (vfdP->fdstate & FD_TEMPORARY)
1789  {
1790  off_t newPos = vfdP->seekPos;
1791 
1792  if (newPos > vfdP->fileSize)
1793  {
1794  temporary_files_size += newPos - vfdP->fileSize;
1795  vfdP->fileSize = newPos;
1796  }
1797  }
1798  }
1799  else
1800  {
1801  /*
1802  * See comments in FileRead()
1803  */
1804 #ifdef WIN32
1805  DWORD error = GetLastError();
1806 
1807  switch (error)
1808  {
1809  case ERROR_NO_SYSTEM_RESOURCES:
1810  pg_usleep(1000L);
1811  errno = EINTR;
1812  break;
1813  default:
1814  _dosmaperr(error);
1815  break;
1816  }
1817 #endif
1818  /* OK to retry if interrupted */
1819  if (errno == EINTR)
1820  goto retry;
1821 
1822  /* Trouble, so assume we don't know the file position anymore */
1823  vfdP->seekPos = FileUnknownPos;
1824  }
1825 
1826  return returnCode;
1827 }
static void error(void)
Definition: sql-dyntest.c:147
#define write(a, b, c)
Definition: win32.h:14
#define DO_DB(A)
Definition: fd.c:152
static Vfd * VfdCache
Definition: fd.c:197
int errcode(int sqlerrcode)
Definition: elog.c:575
#define LOG
Definition: elog.h:26
#define FilePosIsUnknown(pos)
Definition: fd.c:170
void pg_usleep(long microsec)
Definition: signal.c:53
#define ERROR
Definition: elog.h:43
char * fileName
Definition: fd.c:186
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1244
off_t seekPos
Definition: fd.c:184
unsigned short fdstate
Definition: fd.c:179
Definition: fd.c:176
off_t fileSize
Definition: fd.c:185
int fd
Definition: fd.c:178
#define ereport(elevel, rest)
Definition: elog.h:122
#define FD_TEMPORARY
Definition: fd.c:173
#define EINTR
Definition: win32.h:285
#define FileIsValid(file)
Definition: fd.c:158
static uint64 temporary_files_size
Definition: fd.c:217
static int FileAccess(File file)
Definition: fd.c:1250
#define Assert(condition)
Definition: c.h:664
void _dosmaperr(unsigned long)
Definition: win32error.c:171
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1220
#define INT64_FORMAT
Definition: c.h:300
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219
#define FileUnknownPos
Definition: fd.c:169
int temp_file_limit
Definition: guc.c:457
void FileWriteback ( File  file,
off_t  offset,
off_t  nbytes,
uint32  wait_event_info 
)

Definition at line 1618 of file fd.c.

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

Referenced by mdwriteback().

1619 {
1620  int returnCode;
1621 
1622  Assert(FileIsValid(file));
1623 
1624  DO_DB(elog(LOG, "FileWriteback: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
1625  file, VfdCache[file].fileName,
1626  (int64) offset, (int64) nbytes));
1627 
1628  /*
1629  * Caution: do not call pg_flush_data with nbytes = 0, it could trash the
1630  * file's seek position. We prefer to define that as a no-op here.
1631  */
1632  if (nbytes <= 0)
1633  return;
1634 
1635  returnCode = FileAccess(file);
1636  if (returnCode < 0)
1637  return;
1638 
1639  pgstat_report_wait_start(wait_event_info);
1640  pg_flush_data(VfdCache[file].fd, offset, nbytes);
1642 }
#define DO_DB(A)
Definition: fd.c:152
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1244
void pg_flush_data(int fd, off_t offset, off_t nbytes)
Definition: fd.c:407
#define FileIsValid(file)
Definition: fd.c:158
static int FileAccess(File file)
Definition: fd.c:1250
#define Assert(condition)
Definition: c.h:664
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1220
#define INT64_FORMAT
Definition: c.h:300
#define elog
Definition: elog.h:219
static int FreeDesc ( AllocateDesc desc)
static

Definition at line 2238 of file fd.c.

References AllocateDescDir, AllocateDescFile, AllocateDescPipe, AllocateDescRawFD, close, closedir(), AllocateDesc::desc, AllocateDesc::dir, elog, ERROR, AllocateDesc::fd, AllocateDesc::file, AllocateDesc::kind, numAllocatedDescs, and result.

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

2239 {
2240  int result;
2241 
2242  /* Close the underlying object */
2243  switch (desc->kind)
2244  {
2245  case AllocateDescFile:
2246  result = fclose(desc->desc.file);
2247  break;
2248  case AllocateDescPipe:
2249  result = pclose(desc->desc.file);
2250  break;
2251  case AllocateDescDir:
2252  result = closedir(desc->desc.dir);
2253  break;
2254  case AllocateDescRawFD:
2255  result = close(desc->desc.fd);
2256  break;
2257  default:
2258  elog(ERROR, "AllocateDesc kind not recognized");
2259  result = 0; /* keep compiler quiet */
2260  break;
2261  }
2262 
2263  /* Compact storage in the allocatedDescs array */
2266 
2267  return result;
2268 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
DIR * dir
Definition: fd.c:238
int closedir(DIR *)
Definition: dirent.c:111
return result
Definition: formatting.c:1633
AllocateDescKind kind
Definition: fd.c:233
#define ERROR
Definition: elog.h:43
FILE * file
Definition: fd.c:237
int fd
Definition: fd.c:239
union AllocateDesc::@27 desc
#define elog
Definition: elog.h:219
#define close(a)
Definition: win32.h:12
static int numAllocatedDescs
Definition: fd.c:243
int FreeDir ( DIR dir)

Definition at line 2444 of file fd.c.

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

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

2445 {
2446  int i;
2447 
2448  DO_DB(elog(LOG, "FreeDir: Allocated %d", numAllocatedDescs));
2449 
2450  /* Remove dir from list of allocated dirs, if it's present */
2451  for (i = numAllocatedDescs; --i >= 0;)
2452  {
2453  AllocateDesc *desc = &allocatedDescs[i];
2454 
2455  if (desc->kind == AllocateDescDir && desc->desc.dir == dir)
2456  return FreeDesc(desc);
2457  }
2458 
2459  /* Only get here if someone passes us a dir not in allocatedDescs */
2460  elog(WARNING, "dir passed to FreeDir was not obtained from AllocateDir");
2461 
2462  return closedir(dir);
2463 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
DIR * dir
Definition: fd.c:238
#define DO_DB(A)
Definition: fd.c:152
int closedir(DIR *)
Definition: dirent.c:111
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2238
#define WARNING
Definition: elog.h:40
union AllocateDesc::@27 desc
int i
#define elog
Definition: elog.h:219
static int numAllocatedDescs
Definition: fd.c:243
int FreeFile ( FILE *  file)

Definition at line 2277 of file fd.c.

References 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(), checkDataDir(), do_pg_start_backup(), do_pg_stop_backup(), EndCopy(), entry_reset(), existsTimeLineHistory(), ExportSnapshot(), fill_hba_view(), gc_qtexts(), ImportSnapshot(), load_dh_file(), load_hba(), load_ident(), load_relcache_init_file(), parse_extension_control_file(), ParseTzFile(), perform_base_backup(), pg_backup_start_time(), pg_current_logfile(), pg_file_write(), pgss_shmem_shutdown(), pgss_shmem_startup(), pgstat_read_db_statsfile(), pgstat_read_db_statsfile_timestamp(), pgstat_read_statsfiles(), pgstat_write_db_statsfile(), pgstat_write_statsfiles(), read_backup_label(), read_binary_file(), read_tablespace_map(), read_whole_file(), readRecoveryCommandFile(), readTimeLineHistory(), sendFile(), tokenize_inc_file(), tsearch_readline_end(), ValidatePgVersion(), write_relcache_init_file(), XLogArchiveForceDone(), and XLogArchiveNotify().

2278 {
2279  int i;
2280 
2281  DO_DB(elog(LOG, "FreeFile: Allocated %d", numAllocatedDescs));
2282 
2283  /* Remove file from list of allocated files, if it's present */
2284  for (i = numAllocatedDescs; --i >= 0;)
2285  {
2286  AllocateDesc *desc = &allocatedDescs[i];
2287 
2288  if (desc->kind == AllocateDescFile && desc->desc.file == file)
2289  return FreeDesc(desc);
2290  }
2291 
2292  /* Only get here if someone passes us a file not in allocatedDescs */
2293  elog(WARNING, "file passed to FreeFile was not obtained from AllocateFile");
2294 
2295  return fclose(file);
2296 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
#define DO_DB(A)
Definition: fd.c:152
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static int FreeDesc(AllocateDesc *desc)
Definition: fd.c:2238
#define WARNING
Definition: elog.h:40
FILE * file
Definition: fd.c:237
union AllocateDesc::@27 desc
int i
#define elog
Definition: elog.h:219
static int numAllocatedDescs
Definition: fd.c:243
static void FreeVfd ( File  file)
static

Definition at line 1230 of file fd.c.

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

Referenced by FileClose(), and PathNameOpenFile().

1231 {
1232  Vfd *vfdP = &VfdCache[file];
1233 
1234  DO_DB(elog(LOG, "FreeVfd: %d (%s)",
1235  file, vfdP->fileName ? vfdP->fileName : ""));
1236 
1237  if (vfdP->fileName != NULL)
1238  {
1239  free(vfdP->fileName);
1240  vfdP->fileName = NULL;
1241  }
1242  vfdP->fdstate = 0x0;
1243 
1244  vfdP->nextFree = VfdCache[0].nextFree;
1245  VfdCache[0].nextFree = file;
1246 }
File nextFree
Definition: fd.c:181
#define DO_DB(A)
Definition: fd.c:152
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
char * fileName
Definition: fd.c:186
unsigned short fdstate
Definition: fd.c:179
Definition: fd.c:176
#define free(a)
Definition: header.h:65
#define elog
Definition: elog.h:219
void fsync_fname ( const char *  fname,
bool  isdir 
)
static int fsync_fname_ext ( const char *  fname,
bool  isdir,
bool  ignore_perm,
int  elevel 
)
static

Definition at line 3126 of file fd.c.

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

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

3127 {
3128  int fd;
3129  int flags;
3130  int returncode;
3131 
3132  /*
3133  * Some OSs require directories to be opened read-only whereas other
3134  * systems don't allow us to fsync files opened read-only; so we need both
3135  * cases here. Using O_RDWR will cause us to fail to fsync files that are
3136  * not writable by our userid, but we assume that's OK.
3137  */
3138  flags = PG_BINARY;
3139  if (!isdir)
3140  flags |= O_RDWR;
3141  else
3142  flags |= O_RDONLY;
3143 
3144  fd = OpenTransientFile((char *) fname, flags, 0);
3145 
3146  /*
3147  * Some OSs don't allow us to open directories at all (Windows returns
3148  * EACCES), just ignore the error in that case. If desired also silently
3149  * ignoring errors about unreadable files. Log others.
3150  */
3151  if (fd < 0 && isdir && (errno == EISDIR || errno == EACCES))
3152  return 0;
3153  else if (fd < 0 && ignore_perm && errno == EACCES)
3154  return 0;
3155  else if (fd < 0)
3156  {
3157  ereport(elevel,
3159  errmsg("could not open file \"%s\": %m", fname)));
3160  return -1;
3161  }
3162 
3163  returncode = pg_fsync(fd);
3164 
3165  /*
3166  * Some OSes don't allow us to fsync directories at all, so we can ignore
3167  * those errors. Anything else needs to be logged.
3168  */
3169  if (returncode != 0 && !(isdir && errno == EBADF))
3170  {
3171  int save_errno;
3172 
3173  /* close file upon error, might not be in transaction context */
3174  save_errno = errno;
3175  (void) CloseTransientFile(fd);
3176  errno = save_errno;
3177 
3178  ereport(elevel,
3180  errmsg("could not fsync file \"%s\": %m", fname)));
3181  return -1;
3182  }
3183 
3184  (void) CloseTransientFile(fd);
3185 
3186  return 0;
3187 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1027
int OpenTransientFile(FileName fileName, int fileFlags, int fileMode)
Definition: fd.c:2144
int errcode_for_file_access(void)
Definition: elog.c:598
#define ereport(elevel, rest)
Definition: elog.h:122
int CloseTransientFile(int fd)
Definition: fd.c:2305
static int elevel
Definition: vacuumlazy.c:136
int errmsg(const char *fmt,...)
Definition: elog.c:797
int pg_fsync(int fd)
Definition: fd.c:333
static int fsync_parent_path ( const char *  fname,
int  elevel 
)
static

Definition at line 3196 of file fd.c.

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

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

3197 {
3198  char parentpath[MAXPGPATH];
3199 
3200  strlcpy(parentpath, fname, MAXPGPATH);
3201  get_parent_directory(parentpath);
3202 
3203  /*
3204  * get_parent_directory() returns an empty string if the input argument is
3205  * just a file name (see comments in path.c), so handle that as being the
3206  * current directory.
3207  */
3208  if (strlen(parentpath) == 0)
3209  strlcpy(parentpath, ".", MAXPGPATH);
3210 
3211  if (fsync_fname_ext(parentpath, true, false, elevel) != 0)
3212  return -1;
3213 
3214  return 0;
3215 }
#define MAXPGPATH
void get_parent_directory(char *path)
Definition: path.c:854
static int elevel
Definition: vacuumlazy.c:136
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
static int fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel)
Definition: fd.c:3126
Oid GetNextTempTableSpace ( void  )

Definition at line 2565 of file fd.c.

References InvalidOid, nextTempTableSpace, numTempTableSpaces, and tempTableSpaces.

Referenced by GetDefaultTablespace(), and OpenTemporaryFile().

2566 {
2567  if (numTempTableSpaces > 0)
2568  {
2569  /* Advance nextTempTableSpace counter with wraparound */
2571  nextTempTableSpace = 0;
2573  }
2574  return InvalidOid;
2575 }
static int numTempTableSpaces
Definition: fd.c:258
static int nextTempTableSpace
Definition: fd.c:259
#define InvalidOid
Definition: postgres_ext.h:36
static Oid * tempTableSpaces
Definition: fd.c:257
void InitFileAccess ( void  )

Definition at line 764 of file fd.c.

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

Referenced by BaseInit().

765 {
766  Assert(SizeVfdCache == 0); /* call me only once */
767 
768  /* initialize cache header entry */
769  VfdCache = (Vfd *) malloc(sizeof(Vfd));
770  if (VfdCache == NULL)
771  ereport(FATAL,
772  (errcode(ERRCODE_OUT_OF_MEMORY),
773  errmsg("out of memory")));
774 
775  MemSet((char *) &(VfdCache[0]), 0, sizeof(Vfd));
777 
778  SizeVfdCache = 1;
779 
780  /* register proc-exit hook to ensure temp files are dropped at exit */
782 }
static void AtProcExit_Files(int code, Datum arg)
Definition: fd.c:2631
static Size SizeVfdCache
Definition: fd.c:198
void on_proc_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:292
static Vfd * VfdCache
Definition: fd.c:197
int errcode(int sqlerrcode)
Definition: elog.c:575
#define MemSet(start, val, len)
Definition: c.h:846
#define malloc(a)
Definition: header.h:50
#define FATAL
Definition: elog.h:52
Definition: fd.c:176
int fd
Definition: fd.c:178
#define ereport(elevel, rest)
Definition: elog.h:122
#define VFD_CLOSED
Definition: fd.c:156
#define Assert(condition)
Definition: c.h:664
int errmsg(const char *fmt,...)
Definition: elog.c:797
static void Insert ( File  file)
static

Definition at line 1044 of file fd.c.

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

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

1045 {
1046  Vfd *vfdP;
1047 
1048  Assert(file != 0);
1049 
1050  DO_DB(elog(LOG, "Insert %d (%s)",
1051  file, VfdCache[file].fileName));
1052  DO_DB(_dump_lru());
1053 
1054  vfdP = &VfdCache[file];
1055 
1056  vfdP->lruMoreRecently = 0;
1058  VfdCache[0].lruLessRecently = file;
1060 
1061  DO_DB(_dump_lru());
1062 }
File lruLessRecently
Definition: fd.c:183
#define DO_DB(A)
Definition: fd.c:152
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
Definition: fd.c:176
#define Assert(condition)
Definition: c.h:664
File lruMoreRecently
Definition: fd.c:182
#define elog
Definition: elog.h:219
static bool looks_like_temp_rel_name ( const char *  name)
static

Definition at line 2866 of file fd.c.

References forkname_chars().

Referenced by RemovePgTempRelationFilesInDbspace().

2867 {
2868  int pos;
2869  int savepos;
2870 
2871  /* Must start with "t". */
2872  if (name[0] != 't')
2873  return false;
2874 
2875  /* Followed by a non-empty string of digits and then an underscore. */
2876  for (pos = 1; isdigit((unsigned char) name[pos]); ++pos)
2877  ;
2878  if (pos == 1 || name[pos] != '_')
2879  return false;
2880 
2881  /* Followed by another nonempty string of digits. */
2882  for (savepos = ++pos; isdigit((unsigned char) name[pos]); ++pos)
2883  ;
2884  if (savepos == pos)
2885  return false;
2886 
2887  /* We might have _forkname or .segment or both. */
2888  if (name[pos] == '_')
2889  {
2890  int forkchar = forkname_chars(&name[pos + 1], NULL);
2891 
2892  if (forkchar <= 0)
2893  return false;
2894  pos += forkchar + 1;
2895  }
2896  if (name[pos] == '.')
2897  {
2898  int segchar;
2899 
2900  for (segchar = 1; isdigit((unsigned char) name[pos + segchar]); ++segchar)
2901  ;
2902  if (segchar <= 1)
2903  return false;
2904  pos += segchar;
2905  }
2906 
2907  /* Now we should be at the end. */
2908  if (name[pos] != '\0')
2909  return false;
2910  return true;
2911 }
int forkname_chars(const char *str, ForkNumber *fork)
Definition: relpath.c:79
const char * name
Definition: encode.c:521
static void LruDelete ( File  file)
static

Definition at line 1003 of file fd.c.

References Assert, close, Delete(), DO_DB, elog, vfd::fd, vfd::fileName, FilePosIsUnknown, LOG, nfile, vfd::seekPos, and VFD_CLOSED.

Referenced by closeAllVfds(), and ReleaseLruFile().

1004 {
1005  Vfd *vfdP;
1006 
1007  Assert(file != 0);
1008 
1009  DO_DB(elog(LOG, "LruDelete %d (%s)",
1010  file, VfdCache[file].fileName));
1011 
1012  vfdP = &VfdCache[file];
1013 
1014  /*
1015  * Normally we should know the seek position, but if for some reason we
1016  * have lost track of it, try again to get it. If we still can't get it,
1017  * we have a problem: we will be unable to restore the file seek position
1018  * when and if the file is re-opened. But we can't really throw an error
1019  * and refuse to close the file, or activities such as transaction cleanup
1020  * will be broken.
1021  */
1022  if (FilePosIsUnknown(vfdP->seekPos))
1023  {
1024  vfdP->seekPos = lseek(vfdP->fd, (off_t) 0, SEEK_CUR);
1025  if (FilePosIsUnknown(vfdP->seekPos))
1026  elog(LOG, "could not seek file \"%s\" before closing: %m",
1027  vfdP->fileName);
1028  }
1029 
1030  /*
1031  * Close the file. We aren't expecting this to fail; if it does, better
1032  * to leak the FD than to mess up our internal state.
1033  */
1034  if (close(vfdP->fd))
1035  elog(LOG, "could not close file \"%s\": %m", vfdP->fileName);
1036  vfdP->fd = VFD_CLOSED;
1037  --nfile;
1038 
1039  /* delete the vfd record from the LRU ring */
1040  Delete(file);
1041 }
#define DO_DB(A)
Definition: fd.c:152
static Vfd * VfdCache
Definition: fd.c:197
static void Delete(File file)
Definition: fd.c:984
#define LOG
Definition: elog.h:26
#define FilePosIsUnknown(pos)
Definition: fd.c:170
char * fileName
Definition: fd.c:186
static int nfile
Definition: fd.c:203
off_t seekPos
Definition: fd.c:184
Definition: fd.c:176
int fd
Definition: fd.c:178
#define VFD_CLOSED
Definition: fd.c:156
#define Assert(condition)
Definition: c.h:664
#define elog
Definition: elog.h:219
#define close(a)
Definition: win32.h:12
static int LruInsert ( File  file)
static

Definition at line 1066 of file fd.c.

References Assert, BasicOpenFile(), close, DO_DB, elog, vfd::fd, vfd::fileFlags, FileIsNotOpen, vfd::fileMode, vfd::fileName, Insert(), LOG, nfile, ReleaseLruFiles(), vfd::seekPos, and VFD_CLOSED.

Referenced by FileAccess().

1067 {
1068  Vfd *vfdP;
1069 
1070  Assert(file != 0);
1071 
1072  DO_DB(elog(LOG, "LruInsert %d (%s)",
1073  file, VfdCache[file].fileName));
1074 
1075  vfdP = &VfdCache[file];
1076 
1077  if (FileIsNotOpen(file))
1078  {
1079  /* Close excess kernel FDs. */
1080  ReleaseLruFiles();
1081 
1082  /*
1083  * The open could still fail for lack of file descriptors, eg due to
1084  * overall system file table being full. So, be prepared to release
1085  * another FD if necessary...
1086  */
1087  vfdP->fd = BasicOpenFile(vfdP->fileName, vfdP->fileFlags,
1088  vfdP->fileMode);
1089  if (vfdP->fd < 0)
1090  {
1091  DO_DB(elog(LOG, "re-open failed: %m"));
1092  return -1;
1093  }
1094  else
1095  {
1096  ++nfile;
1097  }
1098 
1099  /*
1100  * Seek to the right position. We need no special case for seekPos
1101  * equal to FileUnknownPos, as lseek() will certainly reject that
1102  * (thus completing the logic noted in LruDelete() that we will fail
1103  * to re-open a file if we couldn't get its seek position before
1104  * closing).
1105  */
1106  if (vfdP->seekPos != (off_t) 0)
1107  {
1108  if (lseek(vfdP->fd, vfdP->seekPos, SEEK_SET) < 0)
1109  {
1110  /*
1111  * If we fail to restore the seek position, treat it like an
1112  * open() failure.
1113  */
1114  int save_errno = errno;
1115 
1116  elog(LOG, "could not seek file \"%s\" after re-opening: %m",
1117  vfdP->fileName);
1118  (void) close(vfdP->fd);
1119  vfdP->fd = VFD_CLOSED;
1120  --nfile;
1121  errno = save_errno;
1122  return -1;
1123  }
1124  }
1125  }
1126 
1127  /*
1128  * put it at the head of the Lru ring
1129  */
1130 
1131  Insert(file);
1132 
1133  return 0;
1134 }
#define DO_DB(A)
Definition: fd.c:152
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
int fileMode
Definition: fd.c:189
char * fileName
Definition: fd.c:186
static int nfile
Definition: fd.c:203
off_t seekPos
Definition: fd.c:184
Definition: fd.c:176
int fd
Definition: fd.c:178
static void Insert(File file)
Definition: fd.c:1044
static void ReleaseLruFiles(void)
Definition: fd.c:1162
#define FileIsNotOpen(file)
Definition: fd.c:161
#define VFD_CLOSED
Definition: fd.c:156
#define Assert(condition)
Definition: c.h:664
#define elog
Definition: elog.h:219
#define close(a)
Definition: win32.h:12
int fileFlags
Definition: fd.c:188
int BasicOpenFile(FileName fileName, int fileFlags, int fileMode)
Definition: fd.c:936
FILE* OpenPipeStream ( const char *  command,
const char *  mode 
)

Definition at line 2184 of file fd.c.

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

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

2185 {
2186  FILE *file;
2187 
2188  DO_DB(elog(LOG, "OpenPipeStream: Allocated %d (%s)",
2189  numAllocatedDescs, command));
2190 
2191  /* Can we allocate another non-virtual FD? */
2192  if (!reserveAllocatedDesc())
2193  ereport(ERROR,
2194  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2195  errmsg("exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"",
2196  maxAllocatedDescs, command)));
2197 
2198  /* Close excess kernel FDs. */
2199  ReleaseLruFiles();
2200 
2201 TryAgain:
2202  fflush(stdout);
2203  fflush(stderr);
2204  errno = 0;
2205  if ((file = popen(command, mode)) != NULL)
2206  {
2208 
2209  desc->kind = AllocateDescPipe;
2210  desc->desc.file = file;
2213  return desc->desc.file;
2214  }
2215 
2216  if (errno == EMFILE || errno == ENFILE)
2217  {
2218  int save_errno = errno;
2219 
2220  ereport(LOG,
2221  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2222  errmsg("out of file descriptors: %m; release and retry")));
2223  errno = 0;
2224  if (ReleaseLruFile())
2225  goto TryAgain;
2226  errno = save_errno;
2227  }
2228 
2229  return NULL;
2230 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
#define DO_DB(A)
Definition: fd.c:152
int errcode(int sqlerrcode)
Definition: elog.c:575
static bool reserveAllocatedDesc(void)
Definition: fd.c:2021
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static bool ReleaseLruFile(void)
Definition: fd.c:1140
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
static void ReleaseLruFiles(void)
Definition: fd.c:1162
FILE * file
Definition: fd.c:237
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:650
SubTransactionId create_subid
Definition: fd.c:234
int errmsg(const char *fmt,...)
Definition: elog.c:797
union AllocateDesc::@27 desc
#define elog
Definition: elog.h:219
static int maxAllocatedDescs
Definition: fd.c:244
static int numAllocatedDescs
Definition: fd.c:243
File OpenTemporaryFile ( bool  interXact)

Definition at line 1371 of file fd.c.

References CurrentResourceOwner, DEFAULTTABLESPACE_OID, FD_TEMPORARY, FD_XACT_TEMPORARY, vfd::fdstate, GetNextTempTableSpace(), have_xact_temporary_files, MyDatabaseTableSpace, numTempTableSpaces, OidIsValid, OpenTemporaryFileInTablespace(), ResourceOwnerEnlargeFiles(), ResourceOwnerRememberFile(), and vfd::resowner.

Referenced by BufFileCreateTemp(), and extendBufFile().

1372 {
1373  File file = 0;
1374 
1375  /*
1376  * If some temp tablespace(s) have been given to us, try to use the next
1377  * one. If a given tablespace can't be found, we silently fall back to
1378  * the database's default tablespace.
1379  *
1380  * BUT: if the temp file is slated to outlive the current transaction,
1381  * force it into the database's default tablespace, so that it will not
1382  * pose a threat to possible tablespace drop attempts.
1383  */
1384  if (numTempTableSpaces > 0 && !interXact)
1385  {
1386  Oid tblspcOid = GetNextTempTableSpace();
1387 
1388  if (OidIsValid(tblspcOid))
1389  file = OpenTemporaryFileInTablespace(tblspcOid, false);
1390  }
1391 
1392  /*
1393  * If not, or if tablespace is bad, create in database's default
1394  * tablespace. MyDatabaseTableSpace should normally be set before we get
1395  * here, but just in case it isn't, fall back to pg_default tablespace.
1396  */
1397  if (file <= 0)
1401  true);
1402 
1403  /* Mark it for deletion at close */
1404  VfdCache[file].fdstate |= FD_TEMPORARY;
1405 
1406  /* Register it with the current resource owner */
1407  if (!interXact)
1408  {
1410 
1414 
1415  /* ensure cleanup happens at eoxact */
1417  }
1418 
1419  return file;
1420 }
static File OpenTemporaryFileInTablespace(Oid tblspcOid, bool rejectError)
Definition: fd.c:1427
ResourceOwner CurrentResourceOwner
Definition: resowner.c:138
static Vfd * VfdCache
Definition: fd.c:197
static int numTempTableSpaces
Definition: fd.c:258
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:532
Oid MyDatabaseTableSpace
Definition: globals.c:79
static bool have_xact_temporary_files
Definition: fd.c:209
Oid GetNextTempTableSpace(void)
Definition: fd.c:2565
void ResourceOwnerRememberFile(ResourceOwner owner, File file)
Definition: resowner.c:1200
#define DEFAULTTABLESPACE_OID
Definition: pg_tablespace.h:63
unsigned short fdstate
Definition: fd.c:179
ResourceOwner resowner
Definition: fd.c:180
#define FD_TEMPORARY
Definition: fd.c:173
#define FD_XACT_TEMPORARY
Definition: fd.c:174
void ResourceOwnerEnlargeFiles(ResourceOwner owner)
Definition: resowner.c:1189
int File
Definition: fd.h:51
static File OpenTemporaryFileInTablespace ( Oid  tblspcOid,
bool  rejectError 
)
static

Definition at line 1427 of file fd.c.

References DEFAULTTABLESPACE_OID, elog, ERROR, GLOBALTABLESPACE_OID, MAXPGPATH, mkdir, MyProcPid, PathNameOpenFile(), PG_BINARY, PG_TEMP_FILE_PREFIX, PG_TEMP_FILES_DIR, snprintf(), TABLESPACE_VERSION_DIRECTORY, and tempFileCounter.

Referenced by OpenTemporaryFile().

1428 {
1429  char tempdirpath[MAXPGPATH];
1430  char tempfilepath[MAXPGPATH];
1431  File file;
1432 
1433  /*
1434  * Identify the tempfile directory for this tablespace.
1435  *
1436  * If someone tries to specify pg_global, use pg_default instead.
1437  */
1438  if (tblspcOid == DEFAULTTABLESPACE_OID ||
1439  tblspcOid == GLOBALTABLESPACE_OID)
1440  {
1441  /* The default tablespace is {datadir}/base */
1442  snprintf(tempdirpath, sizeof(tempdirpath), "base/%s",
1444  }
1445  else
1446  {
1447  /* All other tablespaces are accessed via symlinks */
1448  snprintf(tempdirpath, sizeof(tempdirpath), "pg_tblspc/%u/%s/%s",
1450  }
1451 
1452  /*
1453  * Generate a tempfile name that should be unique within the current
1454  * database instance.
1455  */
1456  snprintf(tempfilepath, sizeof(tempfilepath), "%s/%s%d.%ld",
1457  tempdirpath, PG_TEMP_FILE_PREFIX, MyProcPid, tempFileCounter++);
1458 
1459  /*
1460  * Open the file. Note: we don't use O_EXCL, in case there is an orphaned
1461  * temp file that can be reused.
1462  */
1463  file = PathNameOpenFile(tempfilepath,
1464  O_RDWR | O_CREAT | O_TRUNC | PG_BINARY,
1465  0600);
1466  if (file <= 0)
1467  {
1468  /*
1469  * We might need to create the tablespace's tempfile directory, if no
1470  * one has yet done so.
1471  *
1472  * Don't check for error from mkdir; it could fail if someone else
1473  * just did the same thing. If it doesn't work then we'll bomb out on
1474  * the second create attempt, instead.
1475  */
1476  mkdir(tempdirpath, S_IRWXU);
1477 
1478  file = PathNameOpenFile(tempfilepath,
1479  O_RDWR | O_CREAT | O_TRUNC | PG_BINARY,
1480  0600);
1481  if (file <= 0 && rejectError)
1482  elog(ERROR, "could not create temporary file \"%s\": %m",
1483  tempfilepath);
1484  }
1485 
1486  return file;
1487 }
File PathNameOpenFile(FileName fileName, int fileFlags, int fileMode)
Definition: fd.c:1303
int MyProcPid
Definition: globals.c:39
#define mkdir(a, b)
Definition: win32.h:57
#define GLOBALTABLESPACE_OID
Definition: pg_tablespace.h:64
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#define PG_TEMP_FILE_PREFIX
Definition: fd.h:128
#define PG_BINARY
Definition: c.h:1027
#define ERROR
Definition: elog.h:43
#define MAXPGPATH
#define DEFAULTTABLESPACE_OID
Definition: pg_tablespace.h:63
#define PG_TEMP_FILES_DIR
Definition: fd.h:127
#define TABLESPACE_VERSION_DIRECTORY
Definition: catalog.h:26
static long tempFileCounter
Definition: fd.c:251
#define elog
Definition: elog.h:219
int File
Definition: fd.h:51
int OpenTransientFile ( FileName  fileName,
int  fileFlags,
int  fileMode 
)

Definition at line 2144 of file fd.c.

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

Referenced by ApplyLogicalMappingFile(), be_lo_export(), CheckPointLogicalRewriteHeap(), CheckPointReplicationOrigin(), copy_file(), dsm_impl_mmap(), durable_rename(), fsync_fname_ext(), heap_xlog_logical_rewrite(), lo_import_internal(), load_relmap_file(), mdunlinkfork(), qtext_load_file(), qtext_store(), ReadTwoPhaseFile(), RecreateTwoPhaseFile(), ReorderBufferRestoreChanges(), ReorderBufferSerializeTXN(), RestoreSlotFromDisk(), SaveSlotToPath(), SendTimeLineHistory(), SimpleLruDoesPhysicalPageExist(), SlruPhysicalReadPage(), SlruPhysicalWritePage(), SnapBuildRestore(), SnapBuildSerialize(), StartupReplicationOrigin(), write_relmap_file(), writeTimeLineHistory(), writeTimeLineHistoryFile(), and XLogFileCopy().

2145 {
2146  int fd;
2147 
2148  DO_DB(elog(LOG, "OpenTransientFile: Allocated %d (%s)",
2149  numAllocatedDescs, fileName));
2150 
2151  /* Can we allocate another non-virtual FD? */
2152  if (!reserveAllocatedDesc())
2153  ereport(ERROR,
2154  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
2155  errmsg("exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"",
2156  maxAllocatedDescs, fileName)));
2157 
2158  /* Close excess kernel FDs. */
2159  ReleaseLruFiles();
2160 
2161  fd = BasicOpenFile(fileName, fileFlags, fileMode);
2162 
2163  if (fd >= 0)
2164  {
2166 
2167  desc->kind = AllocateDescRawFD;
2168  desc->desc.fd = fd;
2171 
2172  return fd;
2173  }
2174 
2175  return -1; /* failure */
2176 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
#define DO_DB(A)
Definition: fd.c:152
int errcode(int sqlerrcode)
Definition: elog.c:575
static bool reserveAllocatedDesc(void)
Definition: fd.c:2021
#define LOG
Definition: elog.h:26
AllocateDescKind kind
Definition: fd.c:233
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
static void ReleaseLruFiles(void)
Definition: fd.c:1162
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:650
SubTransactionId create_subid
Definition: fd.c:234
int fd
Definition: fd.c:239
int errmsg(const char *fmt,...)
Definition: elog.c:797
union AllocateDesc::@27 desc
#define elog
Definition: elog.h:219
static int maxAllocatedDescs
Definition: fd.c:244
static int numAllocatedDescs
Definition: fd.c:243
int BasicOpenFile(FileName fileName, int fileFlags, int fileMode)
Definition: fd.c:936
File PathNameOpenFile ( FileName  fileName,
int  fileFlags,
int  fileMode 
)

Definition at line 1303 of file fd.c.

References AllocateVfd(), BasicOpenFile(), DO_DB, elog, ereport, errcode(), errmsg(), ERROR, vfd::fd, vfd::fdstate, vfd::fileFlags, vfd::fileMode, vfd::fileName, vfd::fileSize, free, FreeVfd(), Insert(), LOG, nfile, ReleaseLruFiles(), vfd::resowner, and vfd::seekPos.

Referenced by _mdfd_openseg(), logical_rewrite_log_mapping(), mdcreate(), mdopen(), and OpenTemporaryFileInTablespace().

1304 {
1305  char *fnamecopy;
1306  File file;
1307  Vfd *vfdP;
1308 
1309  DO_DB(elog(LOG, "PathNameOpenFile: %s %x %o",
1310  fileName, fileFlags, fileMode));
1311 
1312  /*
1313  * We need a malloc'd copy of the file name; fail cleanly if no room.
1314  */
1315  fnamecopy = strdup(fileName);
1316  if (fnamecopy == NULL)
1317  ereport(ERROR,
1318  (errcode(ERRCODE_OUT_OF_MEMORY),
1319  errmsg("out of memory")));
1320 
1321  file = AllocateVfd();
1322  vfdP = &VfdCache[file];
1323 
1324  /* Close excess kernel FDs. */
1325  ReleaseLruFiles();
1326 
1327  vfdP->fd = BasicOpenFile(fileName, fileFlags, fileMode);
1328 
1329  if (vfdP->fd < 0)
1330  {
1331  int save_errno = errno;
1332 
1333  FreeVfd(file);
1334  free(fnamecopy);
1335  errno = save_errno;
1336  return -1;
1337  }
1338  ++nfile;
1339  DO_DB(elog(LOG, "PathNameOpenFile: success %d",
1340  vfdP->fd));
1341 
1342  Insert(file);
1343 
1344  vfdP->fileName = fnamecopy;
1345  /* Saved flags are adjusted to be OK for re-opening file */
1346  vfdP->fileFlags = fileFlags & ~(O_CREAT | O_TRUNC | O_EXCL);
1347  vfdP->fileMode = fileMode;
1348  vfdP->seekPos = 0;
1349  vfdP->fileSize = 0;
1350  vfdP->fdstate = 0x0;
1351  vfdP->resowner = NULL;
1352 
1353  return file;
1354 }
#define DO_DB(A)
Definition: fd.c:152
static Vfd * VfdCache
Definition: fd.c:197
int errcode(int sqlerrcode)
Definition: elog.c:575
#define LOG
Definition: elog.h:26
int fileMode
Definition: fd.c:189
#define ERROR
Definition: elog.h:43
char * fileName
Definition: fd.c:186
static int nfile
Definition: fd.c:203
static File AllocateVfd(void)
Definition: fd.c:1172
off_t seekPos
Definition: fd.c:184
unsigned short fdstate
Definition: fd.c:179
Definition: fd.c:176
off_t fileSize
Definition: fd.c:185
int fd
Definition: fd.c:178
#define ereport(elevel, rest)
Definition: elog.h:122
static void Insert(File file)
Definition: fd.c:1044
ResourceOwner resowner
Definition: fd.c:180
static void ReleaseLruFiles(void)
Definition: fd.c:1162
#define free(a)
Definition: header.h:65
int errmsg(const char *fmt,...)
Definition: elog.c:797
static void FreeVfd(File file)
Definition: fd.c:1230
#define elog
Definition: elog.h:219
int fileFlags
Definition: fd.c:188
int File
Definition: fd.h:51
int BasicOpenFile(FileName fileName, int fileFlags, int fileMode)
Definition: fd.c:936
int pg_fdatasync ( int  fd)

Definition at line 385 of file fd.c.

References enableFsync, and fsync.

Referenced by issue_xlog_fsync().

386 {
387  if (enableFsync)
388  {
389 #ifdef HAVE_FDATASYNC
390  return fdatasync(fd);
391 #else
392  return fsync(fd);
393 #endif
394  }
395  else
396  return 0;
397 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define fsync(fd)
Definition: win32.h:62
bool enableFsync
Definition: globals.c:111
void pg_flush_data ( int  fd,
off_t  offset,
off_t  nbytes 
)

Definition at line 407 of file fd.c.

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

Referenced by copy_file(), and FileWriteback().

408 {
409  /*
410  * Right now file flushing is primarily used to avoid making later
411  * fsync()/fdatasync() calls have less impact. Thus don't trigger flushes
412  * if fsyncs are disabled - that's a decision we might want to make
413  * configurable at some point.
414  */
415  if (!enableFsync)
416  return;
417 
418  /*
419  * We compile all alternatives that are supported on the current platform,
420  * to find portability problems more easily.
421  */
422 #if defined(HAVE_SYNC_FILE_RANGE)
423  {
424  int rc;
425 
426  /*
427  * sync_file_range(SYNC_FILE_RANGE_WRITE), currently linux specific,
428  * tells the OS that writeback for the specified blocks should be
429  * started, but that we don't want to wait for completion. Note that
430  * this call might block if too much dirty data exists in the range.
431  * This is the preferable method on OSs supporting it, as it works
432  * reliably when available (contrast to msync()) and doesn't flush out
433  * clean data (like FADV_DONTNEED).
434  */
435  rc = sync_file_range(fd, offset, nbytes,
436  SYNC_FILE_RANGE_WRITE);
437 
438  /* don't error out, this is just a performance optimization */
439  if (rc != 0)
440  {
443  errmsg("could not flush dirty data: %m")));
444  }
445 
446  return;
447  }
448 #endif
449 #if !defined(WIN32) && defined(MS_ASYNC)
450  {
451  void *p;
452  static int pagesize = 0;
453 
454  /*
455  * On several OSs msync(MS_ASYNC) on a mmap'ed file triggers
456  * writeback. On linux it only does so if MS_SYNC is specified, but
457  * then it does the writeback synchronously. Luckily all common linux
458  * systems have sync_file_range(). This is preferable over
459  * FADV_DONTNEED because it doesn't flush out clean data.
460  *
461  * We map the file (mmap()), tell the kernel to sync back the contents
462  * (msync()), and then remove the mapping again (munmap()).
463  */
464 
465  /* mmap() needs actual length if we want to map whole file */
466  if (offset == 0 && nbytes == 0)
467  {
468  nbytes = lseek(fd, 0, SEEK_END);
469  if (nbytes < 0)
470  {
473  errmsg("could not determine dirty data size: %m")));
474  return;
475  }
476  }
477 
478  /*
479  * Some platforms reject partial-page mmap() attempts. To deal with
480  * that, just truncate the request to a page boundary. If any extra
481  * bytes don't get flushed, well, it's only a hint anyway.
482  */
483 
484  /* fetch pagesize only once */
485  if (pagesize == 0)
486  pagesize = sysconf(_SC_PAGESIZE);
487 
488  /* align length to pagesize, dropping any fractional page */
489  if (pagesize > 0)
490  nbytes = (nbytes / pagesize) * pagesize;
491 
492  /* fractional-page request is a no-op */
493  if (nbytes <= 0)
494  return;
495 
496  /*
497  * mmap could well fail, particularly on 32-bit platforms where there
498  * may simply not be enough address space. If so, silently fall
499  * through to the next implementation.
500  */
501  if (nbytes <= (off_t) SSIZE_MAX)
502  p = mmap(NULL, nbytes, PROT_READ, MAP_SHARED, fd, offset);
503  else
504  p = MAP_FAILED;
505 
506  if (p != MAP_FAILED)
507  {
508  int rc;
509 
510  rc = msync(p, (size_t) nbytes, MS_ASYNC);
511  if (rc != 0)
512  {
515  errmsg("could not flush dirty data: %m")));
516  /* NB: need to fall through to munmap()! */
517  }
518 
519  rc = munmap(p, (size_t) nbytes);
520  if (rc != 0)
521  {
522  /* FATAL error because mapping would remain */
523  ereport(FATAL,
525  errmsg("could not munmap() while flushing data: %m")));
526  }
527 
528  return;
529  }
530  }
531 #endif
532 #if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED)
533  {
534  int rc;
535 
536  /*
537  * Signal the kernel that the passed in range should not be cached
538  * anymore. This has the, desired, side effect of writing out dirty
539  * data, and the, undesired, side effect of likely discarding useful
540  * clean cached blocks. For the latter reason this is the least
541  * preferable method.
542  */
543 
544  rc = posix_fadvise(fd, offset, nbytes, POSIX_FADV_DONTNEED);
545 
546  if (rc != 0)
547  {
548  /* don't error out, this is just a performance optimization */
551  errmsg("could not flush dirty data: %m")));
552  }
553 
554  return;
555  }
556 #endif
557 }
#define MAP_FAILED
Definition: mem.h:45
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define FATAL
Definition: elog.h:52
int errcode_for_file_access(void)
Definition: elog.c:598
#define ereport(elevel, rest)
Definition: elog.h:122
#define WARNING
Definition: elog.h:40
bool enableFsync
Definition: globals.c:111
int errmsg(const char *fmt,...)
Definition: elog.c:797
int pg_fsync ( int  fd)

Definition at line 333 of file fd.c.

References pg_fsync_no_writethrough(), pg_fsync_writethrough(), sync_method, and SYNC_METHOD_FSYNC_WRITETHROUGH.

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

334 {
335  /* #if is to skip the sync_method test if there's no need for it */
336 #if defined(HAVE_FSYNC_WRITETHROUGH) && !defined(FSYNC_WRITETHROUGH_IS_FSYNC)
338  return pg_fsync_writethrough(fd);
339  else
340 #endif
342 }
#define SYNC_METHOD_FSYNC_WRITETHROUGH
Definition: xlog.h:28
int pg_fsync_writethrough(int fd)
Definition: fd.c:362
int pg_fsync_no_writethrough(int fd)
Definition: fd.c:350
static int fd(const char *x, int i)
Definition: preproc-init.c:105
int sync_method
Definition: xlog.c:103
int pg_fsync_no_writethrough ( int  fd)

Definition at line 350 of file fd.c.

References enableFsync, and fsync.

Referenced by issue_xlog_fsync(), and pg_fsync().

351 {
352  if (enableFsync)
353  return fsync(fd);
354  else
355  return 0;
356 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define fsync(fd)
Definition: win32.h:62
bool enableFsync
Definition: globals.c:111
int pg_fsync_writethrough ( int  fd)

Definition at line 362 of file fd.c.

References enableFsync.

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

363 {
364  if (enableFsync)
365  {
366 #ifdef WIN32
367  return _commit(fd);
368 #elif defined(F_FULLFSYNC)
369  return (fcntl(fd, F_FULLFSYNC, 0) == -1) ? -1 : 0;
370 #else
371  errno = ENOSYS;
372  return -1;
373 #endif
374  }
375  else
376  return 0;
377 }
static int fd(const char *x, int i)
Definition: preproc-init.c:105
bool enableFsync
Definition: globals.c:111
static struct dirent * ReadDirExtended ( DIR dir,
const char *  dirname,
int  elevel 
)
static

Definition at line 2411 of file fd.c.

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

Referenced by ReadDir(), and walkdir().

2412 {
2413  struct dirent *dent;
2414 
2415  /* Give a generic message for AllocateDir failure, if caller didn't */
2416  if (dir == NULL)
2417  {
2418  ereport(elevel,
2420  errmsg("could not open directory \"%s\": %m",
2421  dirname)));
2422  return NULL;
2423  }
2424 
2425  errno = 0;
2426  if ((dent = readdir(dir)) != NULL)
2427  return dent;
2428 
2429  if (errno)
2430  ereport(elevel,
2432  errmsg("could not read directory \"%s\": %m",
2433  dirname)));
2434  return NULL;
2435 }
Definition: dirent.h:9
int errcode_for_file_access(void)
Definition: elog.c:598
#define ereport(elevel, rest)
Definition: elog.h:122
static int elevel
Definition: vacuumlazy.c:136
struct dirent * readdir(DIR *)
Definition: dirent.c:77
int errmsg(const char *fmt,...)
Definition: elog.c:797
static bool ReleaseLruFile ( void  )
static

Definition at line 1140 of file fd.c.

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

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

1141 {
1142  DO_DB(elog(LOG, "ReleaseLruFile. Opened %d", nfile));
1143 
1144  if (nfile > 0)
1145  {
1146  /*
1147  * There are opened files and so there should be at least one used vfd
1148  * in the ring.
1149  */
1150  Assert(VfdCache[0].lruMoreRecently != 0);
1151  LruDelete(VfdCache[0].lruMoreRecently);
1152  return true; /* freed a file */
1153  }
1154  return false; /* no files available to free */
1155 }
#define DO_DB(A)
Definition: fd.c:152
static Vfd * VfdCache
Definition: fd.c:197
#define LOG
Definition: elog.h:26
static void LruDelete(File file)
Definition: fd.c:1003
static int nfile
Definition: fd.c:203
#define Assert(condition)
Definition: c.h:664
#define elog
Definition: elog.h:219
static void ReleaseLruFiles ( void  )
static

Definition at line 1162 of file fd.c.

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

Referenced by AllocateDir(), AllocateFile(), LruInsert(), OpenPipeStream(), OpenTransientFile(), and PathNameOpenFile().

1163 {
1164  while (nfile + numAllocatedDescs >= max_safe_fds)
1165  {
1166  if (!ReleaseLruFile())
1167  break;
1168  }
1169 }
int max_safe_fds
Definition: fd.c:139
static bool ReleaseLruFile(void)
Definition: fd.c:1140
static int nfile
Definition: fd.c:203
static int numAllocatedDescs
Definition: fd.c:243
void RemovePgTempFiles ( void  )

Definition at line 2706 of file fd.c.

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

Referenced by PostmasterMain().

2707 {
2708  char temp_path[MAXPGPATH + 10 + sizeof(TABLESPACE_VERSION_DIRECTORY) + sizeof(PG_TEMP_FILES_DIR)];
2709  DIR *spc_dir;
2710  struct dirent *spc_de;
2711 
2712  /*
2713  * First process temp files in pg_default ($PGDATA/base)
2714  */
2715  snprintf(temp_path, sizeof(temp_path), "base/%s", PG_TEMP_FILES_DIR);
2716  RemovePgTempFilesInDir(temp_path);
2717  RemovePgTempRelationFiles("base");
2718 
2719  /*
2720  * Cycle through temp directories for all non-default tablespaces.
2721  */
2722  spc_dir = AllocateDir("pg_tblspc");
2723 
2724  while ((spc_de = ReadDir(spc_dir, "pg_tblspc")) != NULL)
2725  {
2726  if (strcmp(spc_de->d_name, ".") == 0 ||
2727  strcmp(spc_de->d_name, "..") == 0)
2728  continue;
2729 
2730  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s/%s",
2732  RemovePgTempFilesInDir(temp_path);
2733 
2734  snprintf(temp_path, sizeof(temp_path), "pg_tblspc/%s/%s",
2736  RemovePgTempRelationFiles(temp_path);
2737  }
2738 
2739  FreeDir(spc_dir);
2740 
2741  /*
2742  * In EXEC_BACKEND case there is a pgsql_tmp directory at the top level of
2743  * DataDir as well.
2744  */
2745 #ifdef EXEC_BACKEND
2747 #endif
2748 }
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
static void RemovePgTempFilesInDir(const char *tmpdirname)
Definition: fd.c:2752
Definition: dirent.h:9
static void RemovePgTempRelationFiles(const char *tsdirname)
Definition: fd.c:2793
Definition: dirent.c:25
#define MAXPGPATH
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2335
#define PG_TEMP_FILES_DIR
Definition: fd.h:127
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2401
#define TABLESPACE_VERSION_DIRECTORY
Definition: catalog.h:26
char d_name[MAX_PATH]
Definition: dirent.h:14
int FreeDir(DIR *dir)
Definition: fd.c:2444
static void RemovePgTempFilesInDir ( const char *  tmpdirname)
static

Definition at line 2752 of file fd.c.

References AllocateDir(), dirent::d_name, elog, FreeDir(), LOG, MAXPGPATH, PG_TEMP_FILE_PREFIX, ReadDir(), snprintf(), and unlink().

Referenced by RemovePgTempFiles().

2753 {
2754  DIR *temp_dir;
2755  struct dirent *temp_de;
2756  char rm_path[MAXPGPATH * 2];
2757 
2758  temp_dir = AllocateDir(tmpdirname);
2759  if (temp_dir == NULL)
2760  {
2761  /* anything except ENOENT is fishy */
2762  if (errno != ENOENT)
2763  elog(LOG,
2764  "could not open temporary-files directory \"%s\": %m",
2765  tmpdirname);
2766  return;
2767  }
2768 
2769  while ((temp_de = ReadDir(temp_dir, tmpdirname)) != NULL)
2770  {
2771  if (strcmp(temp_de->d_name, ".") == 0 ||
2772  strcmp(temp_de->d_name, "..") == 0)
2773  continue;
2774 
2775  snprintf(rm_path, sizeof(rm_path), "%s/%s",
2776  tmpdirname, temp_de->d_name);
2777 
2778  if (strncmp(temp_de->d_name,
2780  strlen(PG_TEMP_FILE_PREFIX)) == 0)
2781  unlink(rm_path); /* note we ignore any error */
2782  else
2783  elog(LOG,
2784  "unexpected file found in temporary-files directory: \"%s\"",
2785  rm_path);
2786  }
2787 
2788  FreeDir(temp_dir);
2789 }
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#define PG_TEMP_FILE_PREFIX
Definition: fd.h:128
#define LOG
Definition: elog.h:26
Definition: dirent.h:9
Definition: dirent.c:25
#define MAXPGPATH
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2335
int unlink(const char *filename)
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2401
char d_name[MAX_PATH]
Definition: dirent.h:14
#define elog
Definition: elog.h:219
int FreeDir(DIR *dir)
Definition: fd.c:2444
static void RemovePgTempRelationFiles ( const char *  tsdirname)
static

Definition at line 2793 of file fd.c.

References AllocateDir(), dirent::d_name, elog, FreeDir(), i, LOG, MAXPGPATH, ReadDir(), RemovePgTempRelationFilesInDbspace(), and snprintf().

Referenced by RemovePgTempFiles().

2794 {
2795  DIR *ts_dir;
2796  struct dirent *de;
2797  char dbspace_path[MAXPGPATH * 2];
2798 
2799  ts_dir = AllocateDir(tsdirname);
2800  if (ts_dir == NULL)
2801  {
2802  /* anything except ENOENT is fishy */
2803  if (errno != ENOENT)
2804  elog(LOG,
2805  "could not open tablespace directory \"%s\": %m",
2806  tsdirname);
2807  return;
2808  }
2809 
2810  while ((de = ReadDir(ts_dir, tsdirname)) != NULL)
2811  {
2812  int i = 0;
2813 
2814  /*
2815  * We're only interested in the per-database directories, which have
2816  * numeric names. Note that this code will also (properly) ignore "."
2817  * and "..".
2818  */
2819  while (isdigit((unsigned char) de->d_name[i]))
2820  ++i;
2821  if (de->d_name[i] != '\0' || i == 0)
2822  continue;
2823 
2824  snprintf(dbspace_path, sizeof(dbspace_path), "%s/%s",
2825  tsdirname, de->d_name);
2826  RemovePgTempRelationFilesInDbspace(dbspace_path);
2827  }
2828 
2829  FreeDir(ts_dir);
2830 }
static void RemovePgTempRelationFilesInDbspace(const char *dbspacedirname)
Definition: fd.c:2834
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#define LOG
Definition: elog.h:26
Definition: dirent.h:9
Definition: dirent.c:25
#define MAXPGPATH
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2335
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2401
int i
char d_name[MAX_PATH]
Definition: dirent.h:14
#define elog
Definition: elog.h:219
int FreeDir(DIR *dir)
Definition: fd.c:2444
static void RemovePgTempRelationFilesInDbspace ( const char *  dbspacedirname)
static

Definition at line 2834 of file fd.c.

References AllocateDir(), dirent::d_name, elog, FreeDir(), LOG, looks_like_temp_rel_name(), MAXPGPATH, ReadDir(), snprintf(), and unlink().

Referenced by RemovePgTempRelationFiles().

2835 {
2836  DIR *dbspace_dir;
2837  struct dirent *de;
2838  char rm_path[MAXPGPATH * 2];
2839 
2840  dbspace_dir = AllocateDir(dbspacedirname);
2841  if (dbspace_dir == NULL)
2842  {
2843  /* we just saw this directory, so it really ought to be there */
2844  elog(LOG,
2845  "could not open dbspace directory \"%s\": %m",
2846  dbspacedirname);
2847  return;
2848  }
2849 
2850  while ((de = ReadDir(dbspace_dir, dbspacedirname)) != NULL)
2851  {
2852  if (!looks_like_temp_rel_name(de->d_name))
2853  continue;
2854 
2855  snprintf(rm_path, sizeof(rm_path), "%s/%s",
2856  dbspacedirname, de->d_name);
2857 
2858  unlink(rm_path); /* note we ignore any error */
2859  }
2860 
2861  FreeDir(dbspace_dir);
2862 }
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#define LOG
Definition: elog.h:26
Definition: dirent.h:9
Definition: dirent.c:25
#define MAXPGPATH
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2335
int unlink(const char *filename)
static bool looks_like_temp_rel_name(const char *name)
Definition: fd.c:2866
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2401
char d_name[MAX_PATH]
Definition: dirent.h:14
#define elog
Definition: elog.h:219
int FreeDir(DIR *dir)
Definition: fd.c:2444
static bool reserveAllocatedDesc ( void  )
static

Definition at line 2021 of file fd.c.

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

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

2022 {
2023  AllocateDesc *newDescs;
2024  int newMax;
2025 
2026  /* Quick out if array already has a free slot. */
2028  return true;
2029 
2030  /*
2031  * If the array hasn't yet been created in the current process, initialize
2032  * it with FD_MINFREE / 2 elements. In many scenarios this is as many as
2033  * we will ever need, anyway. We don't want to look at max_safe_fds
2034  * immediately because set_max_safe_fds() may not have run yet.
2035  */
2036  if (allocatedDescs == NULL)
2037  {
2038  newMax = FD_MINFREE / 2;
2039  newDescs = (AllocateDesc *) malloc(newMax * sizeof(AllocateDesc));
2040  /* Out of memory already? Treat as fatal error. */
2041  if (newDescs == NULL)
2042  ereport(ERROR,
2043  (errcode(ERRCODE_OUT_OF_MEMORY),
2044  errmsg("out of memory")));
2045  allocatedDescs = newDescs;
2046  maxAllocatedDescs = newMax;
2047  return true;
2048  }
2049 
2050  /*
2051  * Consider enlarging the array beyond the initial allocation used above.
2052  * By the time this happens, max_safe_fds should be known accurately.
2053  *
2054  * We mustn't let allocated descriptors hog all the available FDs, and in
2055  * practice we'd better leave a reasonable number of FDs for VFD use. So
2056  * set the maximum to max_safe_fds / 2. (This should certainly be at
2057  * least as large as the initial size, FD_MINFREE / 2.)
2058  */
2059  newMax = max_safe_fds / 2;
2060  if (newMax > maxAllocatedDescs)
2061  {
2062  newDescs = (AllocateDesc *) realloc(allocatedDescs,
2063  newMax * sizeof(AllocateDesc));
2064  /* Treat out-of-memory as a non-fatal error. */
2065  if (newDescs == NULL)
2066  return false;
2067  allocatedDescs = newDescs;
2068  maxAllocatedDescs = newMax;
2069  return true;
2070  }
2071 
2072  /* Can't enlarge allocatedDescs[] any more. */
2073  return false;
2074 }
static AllocateDesc * allocatedDescs
Definition: fd.c:245
int max_safe_fds
Definition: fd.c:139
int errcode(int sqlerrcode)
Definition: elog.c:575
#define malloc(a)
Definition: header.h:50
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
#define FD_MINFREE
Definition: fd.c:117
#define realloc(a, b)
Definition: header.h:60
int errmsg(const char *fmt,...)
Definition: elog.c:797
static int maxAllocatedDescs
Definition: fd.c:244
static int numAllocatedDescs
Definition: fd.c:243
void set_max_safe_fds ( void  )

Definition at line 881 of file fd.c.

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

Referenced by PostmasterMain().

882 {
883  int usable_fds;
884  int already_open;
885 
886  /*----------
887  * We want to set max_safe_fds to
888  * MIN(usable_fds, max_files_per_process - already_open)
889  * less the slop factor for files that are opened without consulting
890  * fd.c. This ensures that we won't exceed either max_files_per_process
891  * or the experimentally-determined EMFILE limit.
892  *----------
893  */
895  &usable_fds, &already_open);
896 
897  max_safe_fds = Min(usable_fds, max_files_per_process - already_open);
898 
899  /*
900  * Take off the FDs reserved for system() etc.
901  */
903 
904  /*
905  * Make sure we still have enough to get by.
906  */
907  if (max_safe_fds < FD_MINFREE)
908  ereport(FATAL,
909  (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
910  errmsg("insufficient file descriptors available to start server process"),
911  errdetail("System allows %d, we need at least %d.",
914 
915  elog(DEBUG2, "max_safe_fds = %d, usable_fds = %d, already_open = %d",
916  max_safe_fds, usable_fds, already_open);
917 }
static void count_usable_fds(int max_to_probe, int *usable_fds, int *already_open)
Definition: fd.c:797
#define NUM_RESERVED_FDS
Definition: fd.c:111
int max_safe_fds
Definition: fd.c:139
#define Min(x, y)
Definition: c.h:795
int errcode(int sqlerrcode)
Definition: elog.c:575
#define FATAL
Definition: elog.h:52
#define DEBUG2
Definition: elog.h:24
int errdetail(const char *fmt,...)
Definition: elog.c:873
int max_files_per_process
Definition: fd.c:126
#define ereport(elevel, rest)
Definition: elog.h:122
#define FD_MINFREE
Definition: fd.c:117
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219
void SetTempTablespaces ( Oid tableSpaces,
int  numSpaces 
)

Definition at line 2525 of file fd.c.

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

Referenced by assign_temp_tablespaces(), and PrepareTempTablespaces().

2526 {
2527  Assert(numSpaces >= 0);
2528  tempTableSpaces = tableSpaces;
2529  numTempTableSpaces = numSpaces;
2530 
2531  /*
2532  * Select a random starting point in the list. This is to minimize
2533  * conflicts between backends that are most likely sharing the same list
2534  * of temp tablespaces. Note that if we create multiple temp files in the
2535  * same transaction, we'll advance circularly through the list --- this
2536  * ensures that large temporary sort files are nicely spread across all
2537  * available tablespaces.
2538  */
2539  if (numSpaces > 1)
2540  nextTempTableSpace = random() % numSpaces;
2541  else
2542  nextTempTableSpace = 0;
2543 }
long random(void)
Definition: random.c:22
static int numTempTableSpaces
Definition: fd.c:258
static int nextTempTableSpace
Definition: fd.c:259
#define Assert(condition)
Definition: c.h:664
static Oid * tempTableSpaces
Definition: fd.c:257
void SyncDataDirectory ( void  )

Definition at line 2933 of file fd.c.

References datadir_fsync_fname(), DEBUG1, enableFsync, ereport, errcode_for_file_access(), errmsg(), LOG, lstat, and walkdir().

Referenced by StartupXLOG().

2934 {
2935  bool xlog_is_symlink;
2936 
2937  /* We can skip this whole thing if fsync is disabled. */
2938  if (!enableFsync)
2939  return;
2940 
2941  /*
2942  * If pg_wal is a symlink, we'll need to recurse into it separately,
2943  * because the first walkdir below will ignore it.
2944  */
2945  xlog_is_symlink = false;
2946 
2947 #ifndef WIN32
2948  {
2949  struct stat st;
2950 
2951  if (lstat("pg_wal", &st) < 0)
2952  ereport(LOG,
2954  errmsg("could not stat file \"%s\": %m",
2955  "pg_wal")));
2956  else if (S_ISLNK(st.st_mode))
2957  xlog_is_symlink = true;
2958  }
2959 #else
2960  if (pgwin32_is_junction("pg_wal"))
2961  xlog_is_symlink = true;
2962 #endif
2963 
2964  /*
2965  * If possible, hint to the kernel that we're soon going to fsync the data
2966  * directory and its contents. Errors in this step are even less
2967  * interesting than normal, so log them only at DEBUG1.
2968  */
2969 #ifdef PG_FLUSH_DATA_WORKS
2970  walkdir(".", pre_sync_fname, false, DEBUG1);
2971  if (xlog_is_symlink)
2972  walkdir("pg_wal", pre_sync_fname, false, DEBUG1);
2973  walkdir("pg_tblspc", pre_sync_fname, true, DEBUG1);
2974 #endif
2975 
2976  /*
2977  * Now we do the fsync()s in the same order.
2978  *
2979  * The main call ignores symlinks, so in addition to specially processing
2980  * pg_wal if it's a symlink, pg_tblspc has to be visited separately with
2981  * process_symlinks = true. Note that if there are any plain directories
2982  * in pg_tblspc, they'll get fsync'd twice. That's not an expected case
2983  * so we don't worry about optimizing it.
2984  */
2985  walkdir(".", datadir_fsync_fname, false, LOG);
2986  if (xlog_is_symlink)
2987  walkdir("pg_wal", datadir_fsync_fname, false, LOG);
2988  walkdir("pg_tblspc", datadir_fsync_fname, true, LOG);
2989 }
#define DEBUG1
Definition: elog.h:25
static void walkdir(const char *path, void(*action)(const char *fname, bool isdir, int elevel), bool process_symlinks, int elevel)
Definition: fd.c:3006
#define LOG
Definition: elog.h:26
int errcode_for_file_access(void)
Definition: elog.c:598
#define ereport(elevel, rest)
Definition: elog.h:122
static void datadir_fsync_fname(const char *fname, bool isdir, int elevel)
Definition: fd.c:3108
bool enableFsync
Definition: globals.c:111
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define lstat(path, sb)
Definition: win32.h:262
bool TempTablespacesAreSet ( void  )

Definition at line 2553 of file fd.c.

References numTempTableSpaces.

Referenced by PrepareTempTablespaces().

2554 {
2555  return (numTempTableSpaces >= 0);
2556 }
static int numTempTableSpaces
Definition: fd.c:258
static void walkdir ( const char *  path,
void(*)(const char *fname, bool isdir, int elevel action,
bool  process_symlinks,
int  elevel 
)
static

Definition at line 3006 of file fd.c.

References AllocateDir(), CHECK_FOR_INTERRUPTS, dirent::d_name, elevel, ereport, errcode_for_file_access(), errmsg(), FreeDir(), lstat, MAXPGPATH, ReadDirExtended(), snprintf(), and subpath().

Referenced by SyncDataDirectory().

3010 {
3011  DIR *dir;
3012  struct dirent *de;
3013 
3014  dir = AllocateDir(path);
3015  if (dir == NULL)
3016  {
3017  ereport(elevel,
3019  errmsg("could not open directory \"%s\": %m", path)));
3020  return;
3021  }
3022 
3023  while ((de = ReadDirExtended(dir, path, elevel)) != NULL)
3024  {
3025  char subpath[MAXPGPATH * 2];
3026  struct stat fst;
3027  int sret;
3028 
3030 
3031  if (strcmp(de->d_name, ".") == 0 ||
3032  strcmp(de->d_name, "..") == 0)
3033  continue;
3034 
3035  snprintf(subpath, sizeof(subpath), "%s/%s", path, de->d_name);
3036 
3037  if (process_symlinks)
3038  sret = stat(subpath, &fst);
3039  else
3040  sret = lstat(subpath, &fst);
3041 
3042  if (sret < 0)
3043  {
3044  ereport(elevel,
3046  errmsg("could not stat file \"%s\": %m", subpath)));
3047  continue;
3048  }
3049 
3050  if (S_ISREG(fst.st_mode))
3051  (*action) (subpath, false, elevel);
3052  else if (S_ISDIR(fst.st_mode))
3053  walkdir(subpath, action, false, elevel);
3054  }
3055 
3056  FreeDir(dir); /* we ignore any error here */
3057 
3058  /*
3059  * It's important to fsync the destination directory itself as individual
3060  * file fsyncs don't guarantee that the directory entry for the file is
3061  * synced.
3062  */
3063  (*action) (path, true, elevel);
3064 }
static void walkdir(const char *path, void(*action)(const char *fname, bool isdir, int elevel), bool process_symlinks, int elevel)
Definition: fd.c:3006
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
Definition: dirent.h:9
Definition: dirent.c:25
#define MAXPGPATH
static struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition: fd.c:2411
int errcode_for_file_access(void)
Definition: elog.c:598
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2335
#define ereport(elevel, rest)
Definition: elog.h:122
static int elevel
Definition: vacuumlazy.c:136
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:98
char d_name[MAX_PATH]
Definition: dirent.h:14
#define lstat(path, sb)
Definition: win32.h:262
int FreeDir(DIR *dir)
Definition: fd.c:2444
Datum subpath(PG_FUNCTION_ARGS)
Definition: ltree_op.c:234

Variable Documentation

AllocateDesc* allocatedDescs = NULL
static

Definition at line 245 of file fd.c.

bool have_xact_temporary_files = false
static

Definition at line 209 of file fd.c.

Referenced by CleanupTempFiles(), and OpenTemporaryFile().

int max_files_per_process = 1000

Definition at line 126 of file fd.c.

Referenced by set_max_safe_fds().

int max_safe_fds = 32

Definition at line 139 of file fd.c.

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

int maxAllocatedDescs = 0
static
int nextTempTableSpace = 0
static

Definition at line 259 of file fd.c.

Referenced by GetNextTempTableSpace(), and SetTempTablespaces().

int nfile = 0
static

Definition at line 203 of file fd.c.

Referenced by FileClose(), LruDelete(), LruInsert(), PathNameOpenFile(), ReleaseLruFile(), and ReleaseLruFiles().

int numTempTableSpaces = -1
static
Size SizeVfdCache = 0
static

Definition at line 198 of file fd.c.

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

long tempFileCounter = 0
static

Definition at line 251 of file fd.c.

Referenced by OpenTemporaryFileInTablespace().

uint64 temporary_files_size = 0
static

Definition at line 217 of file fd.c.

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

Oid* tempTableSpaces = NULL
static

Definition at line 257 of file fd.c.

Referenced by AtEOXact_Files(), GetNextTempTableSpace(), and SetTempTablespaces().

Vfd* VfdCache
static

Definition at line 197 of file fd.c.