PostgreSQL Source Code git master
file_utils.h File Reference
#include <dirent.h>
Include dependency graph for file_utils.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define PG_TEMP_FILES_DIR   "pgsql_tmp"
 
#define PG_TEMP_FILE_PREFIX   "pgsql_tmp"
 

Typedefs

typedef enum PGFileType PGFileType
 
typedef enum DataDirSyncMethod DataDirSyncMethod
 

Enumerations

enum  PGFileType {
  PGFILETYPE_ERROR , PGFILETYPE_UNKNOWN , PGFILETYPE_REG , PGFILETYPE_DIR ,
  PGFILETYPE_LNK
}
 
enum  DataDirSyncMethod { DATA_DIR_SYNC_METHOD_FSYNC , DATA_DIR_SYNC_METHOD_SYNCFS }
 

Functions

PGFileType get_dirent_type (const char *path, const struct dirent *de, bool look_through_symlinks, int elevel)
 
int compute_remaining_iovec (struct iovec *destination, const struct iovec *source, int iovcnt, size_t transferred)
 
ssize_t pg_pwritev_with_retry (int fd, const struct iovec *iov, int iovcnt, off_t offset)
 
ssize_t pg_pwrite_zeros (int fd, size_t size, off_t offset)
 

Macro Definition Documentation

◆ PG_TEMP_FILE_PREFIX

#define PG_TEMP_FILE_PREFIX   "pgsql_tmp"

Definition at line 63 of file file_utils.h.

◆ PG_TEMP_FILES_DIR

#define PG_TEMP_FILES_DIR   "pgsql_tmp"

Definition at line 62 of file file_utils.h.

Typedef Documentation

◆ DataDirSyncMethod

◆ PGFileType

typedef enum PGFileType PGFileType

Enumeration Type Documentation

◆ DataDirSyncMethod

Enumerator
DATA_DIR_SYNC_METHOD_FSYNC 
DATA_DIR_SYNC_METHOD_SYNCFS 

Definition at line 27 of file file_utils.h.

28{
DataDirSyncMethod
Definition: file_utils.h:28
@ DATA_DIR_SYNC_METHOD_SYNCFS
Definition: file_utils.h:30
@ DATA_DIR_SYNC_METHOD_FSYNC
Definition: file_utils.h:29

◆ PGFileType

enum PGFileType
Enumerator
PGFILETYPE_ERROR 
PGFILETYPE_UNKNOWN 
PGFILETYPE_REG 
PGFILETYPE_DIR 
PGFILETYPE_LNK 

Definition at line 18 of file file_utils.h.

19{
PGFileType
Definition: file_utils.h:19
@ PGFILETYPE_LNK
Definition: file_utils.h:24
@ PGFILETYPE_UNKNOWN
Definition: file_utils.h:21
@ PGFILETYPE_DIR
Definition: file_utils.h:23
@ PGFILETYPE_REG
Definition: file_utils.h:22
@ PGFILETYPE_ERROR
Definition: file_utils.h:20

Function Documentation

◆ compute_remaining_iovec()

int compute_remaining_iovec ( struct iovec *  destination,
const struct iovec *  source,
int  iovcnt,
size_t  transferred 
)

Definition at line 593 of file file_utils.c.

597{
598 Assert(iovcnt > 0);
599
600 /* Skip wholly transferred iovecs. */
601 while (source->iov_len <= transferred)
602 {
603 transferred -= source->iov_len;
604 source++;
605 iovcnt--;
606
607 /* All iovecs transferred? */
608 if (iovcnt == 0)
609 {
610 /*
611 * We don't expect the kernel to transfer more than we asked it
612 * to, or something is out of sync.
613 */
614 Assert(transferred == 0);
615 return 0;
616 }
617 }
618
619 /* Copy the remaining iovecs to the front of the array. */
620 if (source != destination)
621 memmove(destination, source, sizeof(*source) * iovcnt);
622
623 /* Adjust leading iovec, which may have been partially transferred. */
624 Assert(destination->iov_len > transferred);
625 destination->iov_base = (char *) destination->iov_base + transferred;
626 destination->iov_len -= transferred;
627
628 return iovcnt;
629}
#define Assert(condition)
Definition: c.h:815
static rewind_source * source
Definition: pg_rewind.c:89

References Assert, and source.

Referenced by mdreadv(), mdwritev(), and pg_pwritev_with_retry().

◆ get_dirent_type()

PGFileType get_dirent_type ( const char *  path,
const struct dirent de,
bool  look_through_symlinks,
int  elevel 
)

Definition at line 526 of file file_utils.c.

530{
531 PGFileType result;
532
533 /*
534 * Some systems tell us the type directly in the dirent struct, but that's
535 * a BSD and Linux extension not required by POSIX. Even when the
536 * interface is present, sometimes the type is unknown, depending on the
537 * filesystem.
538 */
539#if defined(DT_REG) && defined(DT_DIR) && defined(DT_LNK)
540 if (de->d_type == DT_REG)
541 result = PGFILETYPE_REG;
542 else if (de->d_type == DT_DIR)
543 result = PGFILETYPE_DIR;
544 else if (de->d_type == DT_LNK && !look_through_symlinks)
545 result = PGFILETYPE_LNK;
546 else
547 result = PGFILETYPE_UNKNOWN;
548#else
549 result = PGFILETYPE_UNKNOWN;
550#endif
551
552 if (result == PGFILETYPE_UNKNOWN)
553 {
554 struct stat fst;
555 int sret;
556
557
558 if (look_through_symlinks)
559 sret = stat(path, &fst);
560 else
561 sret = lstat(path, &fst);
562
563 if (sret < 0)
564 {
565 result = PGFILETYPE_ERROR;
566#ifdef FRONTEND
567 pg_log_generic(elevel, PG_LOG_PRIMARY, "could not stat file \"%s\": %m", path);
568#else
569 ereport(elevel,
571 errmsg("could not stat file \"%s\": %m", path)));
572#endif
573 }
574 else if (S_ISREG(fst.st_mode))
575 result = PGFILETYPE_REG;
576 else if (S_ISDIR(fst.st_mode))
577 result = PGFILETYPE_DIR;
578 else if (S_ISLNK(fst.st_mode))
579 result = PGFILETYPE_LNK;
580 }
581
582 return result;
583}
#define DT_DIR
Definition: dirent.h:28
#define DT_REG
Definition: dirent.h:30
#define DT_LNK
Definition: dirent.h:31
int errcode_for_file_access(void)
Definition: elog.c:876
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ereport(elevel,...)
Definition: elog.h:149
void pg_log_generic(enum pg_log_level level, enum pg_log_part part, const char *pg_restrict fmt,...)
Definition: logging.c:208
@ PG_LOG_PRIMARY
Definition: logging.h:67
unsigned char d_type
Definition: dirent.h:13
#define stat
Definition: win32_port.h:274
#define lstat(path, sb)
Definition: win32_port.h:275
#define S_ISDIR(m)
Definition: win32_port.h:315
#define S_ISLNK(m)
Definition: win32_port.h:334
#define S_ISREG(m)
Definition: win32_port.h:318

References dirent::d_type, DT_DIR, DT_LNK, DT_REG, ereport, errcode_for_file_access(), errmsg(), lstat, pg_log_generic(), PG_LOG_PRIMARY, PGFILETYPE_DIR, PGFILETYPE_ERROR, PGFILETYPE_LNK, PGFILETYPE_REG, PGFILETYPE_UNKNOWN, S_ISDIR, S_ISLNK, S_ISREG, stat::st_mode, and stat.

Referenced by CheckPointLogicalRewriteHeap(), CheckPointSnapBuild(), CheckTablespaceDirectory(), copydir(), do_pg_backup_start(), GetConfFilesInDir(), pg_tzenumerate_next(), process_directory_recursively(), RemovePgTempFilesInDir(), RemoveXlogFile(), rmtree(), scan_for_existing_tablespaces(), StartupReplicationSlots(), and walkdir().

◆ pg_pwrite_zeros()

ssize_t pg_pwrite_zeros ( int  fd,
size_t  size,
off_t  offset 
)

Definition at line 688 of file file_utils.c.

689{
690 static const PGIOAlignedBlock zbuffer = {{0}}; /* worth BLCKSZ */
691 void *zerobuf_addr = unconstify(PGIOAlignedBlock *, &zbuffer)->data;
692 struct iovec iov[PG_IOV_MAX];
693 size_t remaining_size = size;
694 ssize_t total_written = 0;
695
696 /* Loop, writing as many blocks as we can for each system call. */
697 while (remaining_size > 0)
698 {
699 int iovcnt = 0;
700 ssize_t written;
701
702 for (; iovcnt < PG_IOV_MAX && remaining_size > 0; iovcnt++)
703 {
704 size_t this_iov_size;
705
706 iov[iovcnt].iov_base = zerobuf_addr;
707
708 if (remaining_size < BLCKSZ)
709 this_iov_size = remaining_size;
710 else
711 this_iov_size = BLCKSZ;
712
713 iov[iovcnt].iov_len = this_iov_size;
714 remaining_size -= this_iov_size;
715 }
716
717 written = pg_pwritev_with_retry(fd, iov, iovcnt, offset);
718
719 if (written < 0)
720 return written;
721
722 offset += written;
723 total_written += written;
724 }
725
726 Assert(total_written == size);
727
728 return total_written;
729}
#define unconstify(underlying_type, expr)
Definition: c.h:1202
ssize_t pg_pwritev_with_retry(int fd, const struct iovec *iov, int iovcnt, off_t offset)
Definition: file_utils.c:638
#define PG_IOV_MAX
Definition: pg_iovec.h:37
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static pg_noinline void Size size
Definition: slab.c:607

References Assert, fd(), PG_IOV_MAX, pg_pwritev_with_retry(), size, and unconstify.

Referenced by dir_open_for_write(), FileZero(), and XLogFileInitInternal().

◆ pg_pwritev_with_retry()

ssize_t pg_pwritev_with_retry ( int  fd,
const struct iovec *  iov,
int  iovcnt,
off_t  offset 
)

Definition at line 638 of file file_utils.c.

639{
640 struct iovec iov_copy[PG_IOV_MAX];
641 ssize_t sum = 0;
642 ssize_t part;
643
644 /* We'd better have space to make a copy, in case we need to retry. */
645 if (iovcnt > PG_IOV_MAX)
646 {
647 errno = EINVAL;
648 return -1;
649 }
650
651 do
652 {
653 /* Write as much as we can. */
654 part = pg_pwritev(fd, iov, iovcnt, offset);
655 if (part < 0)
656 return -1;
657
658#ifdef SIMULATE_SHORT_WRITE
659 part = Min(part, 4096);
660#endif
661
662 /* Count our progress. */
663 sum += part;
664 offset += part;
665
666 /*
667 * See what is left. On the first loop we used the caller's array,
668 * but in later loops we'll use our local copy that we are allowed to
669 * mutate.
670 */
671 iovcnt = compute_remaining_iovec(iov_copy, iov, iovcnt, part);
672 iov = iov_copy;
673 } while (iovcnt > 0);
674
675 return sum;
676}
#define Min(x, y)
Definition: c.h:961
int compute_remaining_iovec(struct iovec *destination, const struct iovec *source, int iovcnt, size_t transferred)
Definition: file_utils.c:593
static ssize_t pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
Definition: pg_iovec.h:83

References compute_remaining_iovec(), fd(), Min, PG_IOV_MAX, and pg_pwritev().

Referenced by pg_pwrite_zeros().