@@ -31,6 +31,11 @@ typedef struct DataPage
3131char 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 ,
3540pg_crc32 * crc ,bool use_crc32c );
3641
@@ -1792,51 +1797,49 @@ validate_file_pages(pgFile *file, const char *fullpath, XLogRecPtr stop_lsn,
17921797return 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{
18001808PageState * checksum_map = NULL ;
18011809FILE * in = NULL ;
18021810BlockNumber 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 */
18081815in = fopen (fullpath ,"r+" );
18091816if (!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 */
18131822if (ftruncate (fileno (in ),n_blocks * BLCKSZ )!= 0 )
18141823elog (ERROR ,"Cannot truncate file to blknum %u \"%s\": %s" ,
18151824n_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 */
18201829checksum_map = pgut_malloc (n_blocks * sizeof (PageState ));
18211830memset (checksum_map ,0 ,n_blocks * sizeof (PageState ));
18221831
18231832for (;;)
18241833{
1834+ int rc ;
1835+ int block ;
18251836PageState 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 */
18421845if (ferror (in ))
@@ -1846,34 +1849,37 @@ get_checksum_map(const char *fullpath, uint32 checksum_version,
18461849if (read_len == 0 && feof (in ))
18471850break ;
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 ,
18521859dest_stop_lsn ,& page_st ,
18531860checksum_version );
18541861
1862+ /* we care only about valid pages */
18551863if (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 ;
18621871checksum_map [blknum ].lsn = page_st .lsn ;
18631872}
18641873
18651874blknum ++ ;
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
18741878if (in )
18751879fclose (in );
18761880
1881+ pg_free (read_buffer );
1882+
18771883return checksum_map ;
18781884}
18791885
@@ -1893,7 +1899,7 @@ get_lsn_map(const char *fullpath, uint32 checksum_version,
18931899/* open file */
18941900in = fopen (fullpath ,"r+" );
18951901if (!in )
1896- elog (ERROR ,"Cannot opensource file \"%s\": %s" ,fullpath ,strerror (errno ));
1902+ elog (ERROR ,"Cannot open file \"%s\": %s" ,fullpath ,strerror (errno ));
18971903
18981904/* truncate up to blocks */
18991905if (ftruncate (fileno (in ),n_blocks * BLCKSZ )!= 0 )