@@ -395,8 +395,10 @@ pg_fdatasync(int fd)
395395 * flushed.
396396 */
397397void
398- pg_flush_data (int fd , off_t offset , off_t nbytes )
398+ pg_flush_data (int fd , off_t offset , off_t nbytes , bool isdir )
399399{
400+ (void ) isdir ; /* this can be unused on some archs */
401+
400402 /*
401403 * Right now file flushing is primarily used to avoid making later
402404 * fsync()/fdatasync() calls have a less impact. Thus don't trigger
@@ -452,15 +454,26 @@ pg_flush_data(int fd, off_t offset, off_t nbytes)
452454 * (msync()), and then remove the mapping again (munmap()).
453455 */
454456
457+ /* mmap will not work with dirs */
458+ if (isdir )
459+ return ;
460+
455461 /* mmap() need exact length when we want to map whole file */
456462 if ((offset == 0 ) && (nbytes == 0 ))
457463 {
458- int pagesize = getpagesize ();
459- nbytes = (lseek (fd , offset , SEEK_END )/pagesize + 1 )* pagesize ;
464+ int pagesize = sysconf (_SC_PAGESIZE );
465+
466+ nbytes = lseek (fd , 0 , SEEK_END );
460467 if (nbytes < 0 )
461468 ereport (WARNING ,
462469 (errcode_for_file_access (),
463470 errmsg ("could not determine dirty data size: %m" )));
471+
472+ /* aling to pagesize with underestimation */
473+ nbytes = (nbytes /pagesize )* pagesize ;
474+
475+ if (nbytes == 0 )
476+ return ;
464477 }
465478
466479 p = mmap (NULL , nbytes ,
@@ -1526,7 +1539,7 @@ FileWriteback(File file, off_t offset, int amount)
15261539 if (returnCode < 0 )
15271540 return ;
15281541
1529- pg_flush_data (VfdCache [file ].fd , offset , amount );
1542+ pg_flush_data (VfdCache [file ].fd , offset , amount , false );
15301543}
15311544
15321545int
@@ -2932,7 +2945,7 @@ pre_sync_fname(const char *fname, bool isdir, int elevel)
29322945 * pg_flush_data() ignores errors, which is ok because this is only a
29332946 * hint.
29342947 */
2935- pg_flush_data (fd , 0 , 0 );
2948+ pg_flush_data (fd , 0 , 0 , isdir );
29362949
29372950 (void ) CloseTransientFile (fd );
29382951}
0 commit comments