37#if defined(HAVE_SYNC_FILE_RANGE)
38#define PG_FLUSH_DATA_WORKS 1
39#elif defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED)
40#define PG_FLUSH_DATA_WORKS 1
46#define MINIMUM_VERSION_FOR_PG_WAL 100000
48#ifdef PG_FLUSH_DATA_WORKS
49static int pre_sync_fname(
const char *fname,
bool isdir);
51static void walkdir(
const char *path,
52 int (*
action) (
const char *fname,
bool isdir),
53 bool process_symlinks);
63do_syncfs(
const char *path)
67 fd = open(path, O_RDONLY, 0);
77 pg_log_error(
"could not synchronize file system for file \"%s\": %m", path);
102 bool xlog_is_symlink;
115 xlog_is_symlink =
false;
120 if (
lstat(pg_wal, &st) < 0)
123 xlog_is_symlink =
true;
131 pg_log_error(
"this build does not support sync method \"%s\"",
156 while (errno = 0, (de =
readdir(dir)) != NULL)
160 if (strcmp(de->
d_name,
".") == 0 ||
161 strcmp(de->
d_name,
"..") == 0)
189#ifdef PG_FLUSH_DATA_WORKS
192 walkdir(pg_wal, pre_sync_fname,
false);
193 walkdir(pg_tblspc, pre_sync_fname,
true);
228 pg_log_error(
"this build does not support sync method \"%s\"",
247#ifdef PG_FLUSH_DATA_WORKS
248 walkdir(dir, pre_sync_fname,
false);
273 int (*
action) (
const char *fname,
bool isdir),
274 bool process_symlinks)
282 pg_log_error(
"could not open directory \"%s\": %m", path);
286 while (errno = 0, (de =
readdir(dir)) != NULL)
290 if (strcmp(de->
d_name,
".") == 0 ||
291 strcmp(de->
d_name,
"..") == 0)
316 pg_log_error(
"could not read directory \"%s\": %m", path);
326 (*action) (path,
true);
335#ifdef PG_FLUSH_DATA_WORKS
338pre_sync_fname(
const char *fname,
bool isdir)
346 if (errno == EACCES || (isdir && errno == EISDIR))
357#if defined(HAVE_SYNC_FILE_RANGE)
358 (void) sync_file_range(
fd, 0, 0, SYNC_FILE_RANGE_WRITE);
359#elif defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED)
360 (void) posix_fadvise(
fd, 0, 0, POSIX_FADV_DONTNEED);
362#error PG_FLUSH_DATA_WORKS should not have been defined
402 fd = open(fname, flags, 0);
405 if (errno == EACCES || (isdir && errno == EISDIR))
417 if (returncode != 0 && !(isdir && (errno == EBADF || errno == EINVAL)))
447 if (strlen(parentpath) == 0)
481 pg_log_error(
"could not open file \"%s\": %m", newfile);
489 pg_log_error(
"could not fsync file \"%s\": %m", newfile);
497 if (rename(oldfile, newfile) != 0)
499 pg_log_error(
"could not rename file \"%s\" to \"%s\": %m",
528 bool look_through_symlinks,
539#if defined(DT_REG) && defined(DT_DIR) && defined(DT_LNK)
544 else if (de->
d_type ==
DT_LNK && !look_through_symlinks)
558 if (look_through_symlinks)
559 sret =
stat(path, &fst);
561 sret =
lstat(path, &fst);
571 errmsg(
"could not stat file \"%s\": %m", path)));
594 const struct iovec *
source,
601 while (
source->iov_len <= transferred)
603 transferred -=
source->iov_len;
620 if (
source != destination)
624 Assert(destination->iov_len > transferred);
625 destination->iov_base = (
char *) destination->iov_base + transferred;
626 destination->iov_len -= transferred;
658#ifdef SIMULATE_SHORT_WRITE
659 part =
Min(part, 4096);
673 }
while (iovcnt > 0);
693 size_t remaining_size =
size;
694 ssize_t total_written = 0;
697 while (remaining_size > 0)
702 for (; iovcnt < PG_IOV_MAX && remaining_size > 0; iovcnt++)
704 size_t this_iov_size;
706 iov[iovcnt].iov_base = zerobuf_addr;
708 if (remaining_size < BLCKSZ)
709 this_iov_size = remaining_size;
711 this_iov_size = BLCKSZ;
713 iov[iovcnt].iov_len = this_iov_size;
714 remaining_size -= this_iov_size;
723 total_written += written;
728 return total_written;
#define unconstify(underlying_type, expr)
#define Assert(condition)
struct dirent * readdir(DIR *)
DIR * opendir(const char *)
int errcode_for_file_access(void)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
int durable_rename(const char *oldfile, const char *newfile, int elevel)
void fsync_fname(const char *fname, bool isdir)
static int fsync_parent_path(const char *fname, int elevel)
static void walkdir(const char *path, void(*action)(const char *fname, bool isdir, int elevel), bool process_symlinks, int elevel)
int compute_remaining_iovec(struct iovec *destination, const struct iovec *source, int iovcnt, size_t transferred)
ssize_t pg_pwrite_zeros(int fd, size_t size, off_t offset)
ssize_t pg_pwritev_with_retry(int fd, const struct iovec *iov, int iovcnt, off_t offset)
PGFileType get_dirent_type(const char *path, const struct dirent *de, bool look_through_symlinks, int elevel)
@ DATA_DIR_SYNC_METHOD_SYNCFS
@ DATA_DIR_SYNC_METHOD_FSYNC
static DataDirSyncMethod sync_method
void pg_log_generic(enum pg_log_level level, enum pg_log_part part, const char *pg_restrict fmt,...)
#define pg_log_error(...)
Datum subpath(PG_FUNCTION_ARGS)
#define MINIMUM_VERSION_FOR_PG_WAL
static ssize_t pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
static rewind_source * source
void get_parent_directory(char *path)
size_t strlcpy(char *dst, const char *src, size_t siz)
static int fd(const char *x, int i)
static pg_noinline void Size size