@@ -31,6 +31,11 @@ typedef struct DataPage
3131 char data [BLCKSZ ];
3232} DataPage ;
3333
34+ typedef struct DataBlock
35+ {
36+ char data [BLCKSZ ];
37+ } DataBlock ;
38+
3439static bool get_page_header (FILE * in , const char * fullpath , BackupPageHeader * bph ,
3540 pg_crc32 * crc , bool use_crc32c );
3641
@@ -1792,51 +1797,49 @@ validate_file_pages(pgFile *file, const char *fullpath, XLogRecPtr stop_lsn,
17921797 return is_valid ;
17931798}
17941799
1795- /* read local data file and construct map with block checksums */
1800+ /* read local data file and construct map with block checksums
1801+ * bufsize must be divisible by BLCKSZ
1802+ */
17961803PageState *
17971804get_checksum_map (const char * fullpath , uint32 checksum_version ,
1798- int n_blocks , XLogRecPtr dest_stop_lsn , BlockNumber segmentno )
1805+ int n_blocks , XLogRecPtr dest_stop_lsn ,
1806+ BlockNumber segmentno )
17991807{
18001808 PageState * checksum_map = NULL ;
18011809 FILE * in = NULL ;
18021810 BlockNumber blknum = 0 ;
1803- char read_buffer [BLCKSZ ];
1804- char in_buf [STDIO_BUFSIZE ];
1805- off_t cur_pos = 0 ;
1811+ DataBlock * read_buffer ;
1812+ int bufsize = LARGE_CHUNK_SIZE ;
18061813
18071814 /* open file */
18081815 in = fopen (fullpath , "r+" );
18091816 if (!in )
1810- elog (ERROR , "Cannot open source file \"%s\": %s" , fullpath , strerror (errno ));
1817+ elog (ERROR , "Cannot open file \"%s\": %s" , fullpath , strerror (errno ));
1818+
1819+ setvbuf (in , NULL , _IONBF , BUFSIZ );
18111820
18121821 /* truncate up to blocks */
18131822 if (ftruncate (fileno (in ), n_blocks * BLCKSZ ) != 0 )
18141823 elog (ERROR , "Cannot truncate file to blknum %u \"%s\": %s" ,
18151824 n_blocks , fullpath , strerror (errno ));
18161825
1817- setvbuf ( in , in_buf , _IOFBF , STDIO_BUFSIZE );
1826+ read_buffer = pgut_malloc ( bufsize );
18181827
18191828 /* initialize array of checksums */
18201829 checksum_map = pgut_malloc (n_blocks * sizeof (PageState ));
18211830 memset (checksum_map , 0 , n_blocks * sizeof (PageState ));
18221831
18231832 for (;;)
18241833 {
1834+ int rc ;
1835+ int block ;
18251836 PageState page_st ;
1826- size_t read_len = 0 ;
1827-
1828- if (blknum >= n_blocks )
1829- break ;
1837+ size_t read_len = 0 ;
18301838
1831- if (cur_pos != blknum * BLCKSZ &&
1832- fseek (in , blknum * BLCKSZ , SEEK_SET ))
1833- {
1834- elog (ERROR , "Cannot seek to offset %u in file \"%s\": %s" ,
1835- blknum * BLCKSZ , fullpath , strerror (errno ));
1836- }
1839+ if (interrupted )
1840+ elog (ERROR , "Interrupted during page reading" );
18371841
1838- read_len = fread (read_buffer , 1 , BLCKSZ , in );
1839- cur_pos += read_len ;
1842+ read_len = fread (read_buffer , 1 , bufsize , in );
18401843
18411844 /* report error */
18421845 if (ferror (in ))
@@ -1846,34 +1849,37 @@ get_checksum_map(const char *fullpath, uint32 checksum_version,
18461849 if (read_len == 0 && feof (in ))
18471850 break ;
18481851
1849- if ( read_len == BLCKSZ )
1852+ for ( block = 0 ; block < read_len / BLCKSZ ; block ++ )
18501853 {
1851- int rc = validate_one_page (read_buffer , segmentno + blknum ,
1854+
1855+ if (blknum >= n_blocks )
1856+ elog (ERROR , "Concurrent writing to restored cluster detected" );
1857+
1858+ rc = validate_one_page (read_buffer [block ].data , segmentno + blknum ,
18521859 dest_stop_lsn , & page_st ,
18531860 checksum_version );
18541861
1862+ /* we care only about valid pages */
18551863 if (rc == PAGE_IS_VALID )
18561864 {
1857- if (checksum_version )
1858- checksum_map [blknum ].checksum = ((PageHeader ) read_buffer )-> pd_checksum ;
1859- else
1860- checksum_map [blknum ].checksum = page_st .checksum ;
1865+ // if (checksum_version)
1866+ // checksum_map[blknum].checksum = ((PageHeader) read_buffer)->pd_checksum;
1867+ // else
1868+ // checksum_map[blknum].checksum = page_st.checksum;
18611869
1870+ checksum_map [blknum ].checksum = page_st .checksum ;
18621871 checksum_map [blknum ].lsn = page_st .lsn ;
18631872 }
18641873
18651874 blknum ++ ;
18661875 }
1867- else
1868- elog (WARNING , "Odd size read len %lu for blknum %u in file \"%s\"" , read_len , blknum , fullpath );
1869-
1870- if (interrupted )
1871- elog (ERROR , "Interrupted during page reading" );
18721876 }
18731877
18741878 if (in )
18751879 fclose (in );
18761880
1881+ pg_free (read_buffer );
1882+
18771883 return checksum_map ;
18781884}
18791885
@@ -1893,7 +1899,7 @@ get_lsn_map(const char *fullpath, uint32 checksum_version,
18931899 /* open file */
18941900 in = fopen (fullpath , "r+" );
18951901 if (!in )
1896- elog (ERROR , "Cannot open source file \"%s\": %s" , fullpath , strerror (errno ));
1902+ elog (ERROR , "Cannot open file \"%s\": %s" , fullpath , strerror (errno ));
18971903
18981904 /* truncate up to blocks */
18991905 if (ftruncate (fileno (in ), n_blocks * BLCKSZ ) != 0 )
0 commit comments