@@ -630,24 +630,104 @@ write_backup(pgBackup *backup)
630630 */
631631void
632632write_backup_filelist (pgBackup * backup , parray * files , const char * root ,
633- const char * external_prefix , parray * external_list )
633+ parray * external_list )
634634{
635- FILE * fp ;
635+ FILE * out ;
636636 char path [MAXPGPATH ];
637637 char path_temp [MAXPGPATH ];
638638 int errno_temp ;
639+ size_t i = 0 ;
640+ #define BUFFERSZ BLCKSZ*500
641+ char buf [BUFFERSZ ];
642+ size_t write_len = 0 ;
643+ int64 backup_size_on_disk = 0 ;
639644
640645 pgBackupGetPath (backup , path , lengthof (path ), DATABASE_FILE_LIST );
641646 snprintf (path_temp , sizeof (path_temp ), "%s.tmp" , path );
642647
643- fp = fio_fopen (path_temp , PG_BINARY_W , FIO_BACKUP_HOST );
644- if (fp == NULL )
648+ out = fio_fopen (path_temp , PG_BINARY_W , FIO_BACKUP_HOST );
649+ if (out == NULL )
645650 elog (ERROR , "Cannot open file list \"%s\": %s" , path_temp ,
646651 strerror (errno ));
647652
648- print_file_list (fp , files , root , external_prefix , external_list );
653+ /* print each file in the list */
654+ while (i < parray_num (files ))
655+ {
656+ pgFile * file = (pgFile * ) parray_get (files , i );
657+ char * path = file -> path ; /* for streamed WAL files */
658+ char line [BLCKSZ ];
659+ int len = 0 ;
649660
650- if (fio_fflush (fp ) || fio_fclose (fp ))
661+ i ++ ;
662+
663+ if (S_ISDIR (file -> mode ))
664+ backup_size_on_disk += 4096 ;
665+
666+ /* Count the amount of the data actually copied */
667+ if (S_ISREG (file -> mode ) && file -> write_size > 0 )
668+ backup_size_on_disk += file -> write_size ;
669+
670+ /* for files from PGDATA and external files use rel_path
671+ * streamed WAL files has rel_path relative not to "database/"
672+ * but to "database/pg_wal", so for them use path.
673+ */
674+ if ((root && strstr (path , root ) == path ) ||
675+ (file -> external_dir_num && external_list ))
676+ path = file -> rel_path ;
677+
678+ len = sprintf (line , "{\"path\":\"%s\", \"size\":\"" INT64_FORMAT "\", "
679+ "\"mode\":\"%u\", \"is_datafile\":\"%u\", "
680+ "\"is_cfs\":\"%u\", \"crc\":\"%u\", "
681+ "\"compress_alg\":\"%s\", \"external_dir_num\":\"%d\"" ,
682+ path , file -> write_size , file -> mode ,
683+ file -> is_datafile ? 1 : 0 ,
684+ file -> is_cfs ? 1 : 0 ,
685+ file -> crc ,
686+ deparse_compress_alg (file -> compress_alg ),
687+ file -> external_dir_num );
688+
689+ if (file -> is_datafile )
690+ len += sprintf (line + len , ",\"segno\":\"%d\"" , file -> segno );
691+
692+ if (file -> linked )
693+ len += sprintf (line + len , ",\"linked\":\"%s\"" , file -> linked );
694+
695+ if (file -> n_blocks != BLOCKNUM_INVALID )
696+ len += sprintf (line + len , ",\"n_blocks\":\"%i\"" , file -> n_blocks );
697+
698+ len += sprintf (line + len , "}\n" );
699+
700+ if (write_len + len <= BUFFERSZ )
701+ {
702+ memcpy (buf + write_len , line , len );
703+ write_len += len ;
704+ }
705+ else
706+ {
707+ /* write buffer to file */
708+ if (fio_fwrite (out , buf , write_len ) != write_len )
709+ {
710+ errno_temp = errno ;
711+ fio_unlink (path_temp , FIO_BACKUP_HOST );
712+ elog (ERROR , "Cannot write file list \"%s\": %s" ,
713+ path_temp , strerror (errno ));
714+ }
715+ /* reset write_len */
716+ write_len = 0 ;
717+ }
718+ }
719+
720+ /* write what is left in the buffer to file */
721+ if (write_len > 0 )
722+ if (fio_fwrite (out , buf , write_len ) != write_len )
723+ {
724+ errno_temp = errno ;
725+ fio_unlink (path_temp , FIO_BACKUP_HOST );
726+ elog (ERROR , "Cannot write file list \"%s\": %s" ,
727+ path_temp , strerror (errno ));
728+ }
729+
730+ if (fio_fflush (out ) || fio_fclose (out ))
651731 {
652732 errno_temp = errno ;
653733 fio_unlink (path_temp , FIO_BACKUP_HOST );
@@ -662,6 +742,9 @@ write_backup_filelist(pgBackup *backup, parray *files, const char *root,
662742 elog (ERROR , "Cannot rename configuration file \"%s\" to \"%s\": %s" ,
663743 path_temp , path , strerror (errno_temp ));
664744 }
745+
746+ /* use extra variable to avoid reset of previous data_bytes value in case of error */
747+ backup -> data_bytes = backup_size_on_disk ;
665748}
666749
667750/*
0 commit comments