@@ -89,7 +89,7 @@ do_compress(void* dst, size_t dst_size, void const* src, size_t src_size,
8989 * Decompresses source into dest using algorithm. Returns the number of bytes
9090 * decompressed in the destination buffer, or -1 if decompression fails.
9191 */
92- int32
92+ static int32
9393do_decompress (void * dst ,size_t dst_size ,void const * src ,size_t src_size ,
9494CompressAlg alg ,const char * * errormsg )
9595{
@@ -719,7 +719,6 @@ restore_data_file(const char *to_path, pgFile *file, bool allow_truncate,
719719BlockNumber blknum = 0 ,
720720truncate_from = 0 ;
721721bool need_truncate = false;
722- size_t rc ;
723722
724723/* BYTES_INVALID allowed only in case of restoring file from DELTA backup */
725724if (file -> write_size != BYTES_INVALID )
@@ -751,9 +750,9 @@ restore_data_file(const char *to_path, pgFile *file, bool allow_truncate,
751750{
752751off_t write_pos ;
753752size_t read_len ;
753+ DataPage compressed_page ;/* used as read buffer */
754754DataPage page ;
755- int32 compressed_size ;
756- const char * errormsg = NULL ;
755+ int32 uncompressed_size = 0 ;
757756
758757/* File didn`t changed. Nothig to copy */
759758if (file -> write_size == BYTES_INVALID )
@@ -790,9 +789,7 @@ restore_data_file(const char *to_path, pgFile *file, bool allow_truncate,
790789blknum ,file -> path ,strerror (errno_tmp ));
791790}
792791
793- compressed_size = header .compressed_size ;
794-
795- if (header .block == 0 && compressed_size )
792+ if (header .block == 0 && header .compressed_size == 0 )
796793{
797794elog (VERBOSE ,"Skip empty block of \"%s\"" ,file -> path );
798795continue ;
@@ -804,7 +801,7 @@ restore_data_file(const char *to_path, pgFile *file, bool allow_truncate,
804801
805802blknum = header .block ;
806803
807- if (compressed_size == PageIsTruncated )
804+ if (header . compressed_size == PageIsTruncated )
808805{
809806/*
810807 * Backup contains information that this block was truncated.
@@ -815,14 +812,39 @@ restore_data_file(const char *to_path, pgFile *file, bool allow_truncate,
815812break ;
816813}
817814
818- Assert (compressed_size <=BLCKSZ );
815+ Assert (header . compressed_size <=BLCKSZ );
819816
820817/* read a page from file */
821- read_len = fread (page .data ,1 ,
822- MAXALIGN (compressed_size ),in );
823- if (read_len != MAXALIGN (compressed_size ))
818+ read_len = fread (compressed_page .data ,1 ,
819+ MAXALIGN (header . compressed_size ),in );
820+ if (read_len != MAXALIGN (header . compressed_size ))
824821elog (ERROR ,"Cannot read block %u of \"%s\" read %zu of %d" ,
825- blknum ,file -> path ,read_len ,compressed_size );
822+ blknum ,file -> path ,read_len ,header .compressed_size );
823+
824+ /*
825+ * if page size is smaller than BLCKSZ, decompress the page.
826+ * BUGFIX for versions < 2.0.23: if page size is equal to BLCKSZ.
827+ * we have to check, whether it is compressed or not using
828+ * page_may_be_compressed() function.
829+ */
830+ if (header .compressed_size != BLCKSZ
831+ || page_may_be_compressed (compressed_page .data ,file -> compress_alg ,
832+ backup_version ))
833+ {
834+ const char * errormsg = NULL ;
835+
836+ uncompressed_size = do_decompress (page .data ,BLCKSZ ,
837+ compressed_page .data ,
838+ header .compressed_size ,
839+ file -> compress_alg ,& errormsg );
840+ if (uncompressed_size < 0 && errormsg != NULL )
841+ elog (WARNING ,"An error occured during decompressing block %u of file \"%s\": %s" ,
842+ blknum ,file -> path ,errormsg );
843+
844+ if (uncompressed_size != BLCKSZ )
845+ elog (ERROR ,"Page of file \"%s\" uncompressed to %d bytes. != BLCKSZ" ,
846+ file -> path ,uncompressed_size );
847+ }
826848
827849write_pos = (write_header ) ?blknum * (BLCKSZ + sizeof (header )) :
828850blknum * BLCKSZ ;
@@ -843,24 +865,21 @@ restore_data_file(const char *to_path, pgFile *file, bool allow_truncate,
843865blknum ,file -> path ,strerror (errno ));
844866}
845867
846- /*
847- * if page size is smaller than BLCKSZ, decompress the page.
848- * BUGFIX for versions < 2.0.23: if page size is equal to BLCKSZ.
849- * we have to check, whether it is compressed or not using
850- * page_may_be_compressed() function.
868+ /* if we uncompressed the page - write page.data,
869+ * if page wasn't compressed -
870+ * write what we've read - compressed_page.data
851871 */
852- rc = (compressed_size != BLCKSZ || page_may_be_compressed (page .data ,file -> compress_alg ,backup_version ))
853- ?fio_fwrite_compressed (out ,page .data ,compressed_size ,file -> compress_alg ,& errormsg )
854- :fio_fwrite (out ,page .data ,compressed_size );
855-
856- if (rc != compressed_size )
872+ if (uncompressed_size == BLCKSZ )
857873{
858- if (errormsg != NULL )
859- elog (WARNING ,"An error occured during decompressing block %u of file \"%s\": %s" ,
860- blknum ,file -> path ,errormsg );
861-
862- elog (ERROR ,"Cannot write block %u of \"%s\": %s" ,
863- blknum ,file -> path ,strerror (errno ));
874+ if (fio_fwrite (out ,page .data ,BLCKSZ )!= BLCKSZ )
875+ elog (ERROR ,"Cannot write block %u of \"%s\": %s" ,
876+ blknum ,file -> path ,strerror (errno ));
877+ }
878+ else
879+ {
880+ if (fio_fwrite (out ,compressed_page .data ,BLCKSZ )!= BLCKSZ )
881+ elog (ERROR ,"Cannot write block %u of \"%s\": %s" ,
882+ blknum ,file -> path ,strerror (errno ));
864883}
865884}
866885