diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c index 3e02dce..2a923d3 100644 --- a/src/backend/storage/file/fd.c +++ b/src/backend/storage/file/fd.c @@ -451,8 +451,27 @@ pg_flush_data(int fd, off_t offset, off_t nbytes) * We map the file (mmap()), tell the kernel to sync back the contents * (msync()), and then remove the mapping again (munmap()). */ + + /* mmap() need exact length when we want to map whole file */ + if ((offset == 0) && (nbytes == 0)) + { + int pagesize = sysconf(_SC_PAGESIZE); + + nbytes = lseek(fd, 0, SEEK_END); + if (nbytes < 0) + ereport(WARNING, + (errcode_for_file_access(), + errmsg("could not determine dirty data size: %m"))); + + /* aling to pagesize with underestimation */ + nbytes = (nbytes/pagesize)*pagesize; + + if (nbytes == 0) + return; + } + p = mmap(NULL, nbytes, - PROT_READ | PROT_WRITE, MAP_SHARED, + PROT_READ, MAP_SHARED, fd, offset); if (p == MAP_FAILED) { @@ -2920,7 +2939,8 @@ pre_sync_fname(const char *fname, bool isdir, int elevel) * pg_flush_data() ignores errors, which is ok because this is only a * hint. */ - pg_flush_data(fd, 0, 0); + if (!isdir) + pg_flush_data(fd, 0, 0); (void) CloseTransientFile(fd); }