@@ -935,7 +935,7 @@ static bool cfs_gc_file(char* map_path, GC_CALL_KIND background)
935935uint32 second_pass_bytes = 0 ;
936936inode_t * * inodes = (inode_t * * )palloc (RELSEG_SIZE * sizeof (inode_t * ));
937937bool remove_backups = true;
938- bool second_pass_whole = false ;
938+ int second_pass_whole = 0 ;
939939int n_pages ,n_pages1 ;
940940TimestampTz startTime ,secondTime ,endTime ;
941941long secs ,secs2 ;
@@ -984,13 +984,16 @@ static bool cfs_gc_file(char* map_path, GC_CALL_KIND background)
984984gotoCleanup ;
985985}
986986
987+ cfs_state -> gc_stat .processedFiles += 1 ;
988+ cfs_gc_processed_segments += 1 ;
989+
987990/* temporary lock file for fetching map snapshot */
988991cfs_gc_lock (lock );
989992
990993/* Reread variables after locking file */
991994virtSize = pg_atomic_read_u32 (& map -> hdr .virtSize );
992995n_pages = virtSize /BLCKSZ ;
993-
996+ retry :
994997for (i = 0 ;i < n_pages ;i ++ )
995998{
996999newMap -> inodes [i ]= map -> inodes [i ];
@@ -1000,9 +1003,6 @@ static bool cfs_gc_file(char* map_path, GC_CALL_KIND background)
10001003/* may unlock until second phase */
10011004cfs_gc_unlock (lock );
10021005
1003- cfs_state -> gc_stat .processedFiles += 1 ;
1004- cfs_gc_processed_segments += 1 ;
1005-
10061006if (!cfs_copy_inodes (inodes ,n_pages ,fd ,fd2 ,& writeback ,& newSize ,
10071007file_path ,file_bck_path ))
10081008gotoCleanup ;
@@ -1028,6 +1028,8 @@ static bool cfs_gc_file(char* map_path, GC_CALL_KIND background)
10281028n_pages1 = n_pages ;
10291029virtSize = pg_atomic_read_u32 (& map -> hdr .virtSize );
10301030n_pages = virtSize /BLCKSZ ;
1031+ second_pass = 0 ;
1032+ second_pass_bytes = 0 ;
10311033
10321034for (i = 0 ;i < n_pages ;i ++ )
10331035{
@@ -1048,16 +1050,13 @@ static bool cfs_gc_file(char* map_path, GC_CALL_KIND background)
10481050second_pass ++ ;
10491051}
10501052
1051- if (n_pages1 > n_pages )
1053+ /* if file were truncated (vacuum???), clean a bit */
1054+ for (i = n_pages ;i < n_pages1 ;i ++ )
10521055{
1053- /* if file were truncated (vacuum???), clean a bit */
1054- for (i = n_pages ;i < n_pages1 ;i ++ )
1055- {
1056- inode_t nnode = newMap -> inodes [i ];
1057- if (CFS_INODE_SIZE (nnode )!= 0 ) {
1058- newUsed -= CFS_INODE_SIZE (nnode );
1059- newMap -> inodes [i ]= CFS_INODE (0 ,0 );
1060- }
1056+ inode_t nnode = newMap -> inodes [i ];
1057+ if (CFS_INODE_SIZE (nnode )!= 0 ) {
1058+ newUsed -= CFS_INODE_SIZE (nnode );
1059+ newMap -> inodes [i ]= CFS_INODE (0 ,0 );
10611060}
10621061}
10631062
@@ -1069,10 +1068,16 @@ static bool cfs_gc_file(char* map_path, GC_CALL_KIND background)
10691068newUsed = 0 ;
10701069newSize = 0 ;
10711070writeback = 0 ;
1072- second_pass_whole = true ;
1071+ second_pass_whole ++ ;
10731072rc = lseek (fd2 ,0 ,SEEK_SET );
10741073Assert (rc == 0 );
10751074memset (newMap -> inodes ,0 ,sizeof (newMap -> inodes ));
1075+ elog (LOG ,"CFS: retry %d whole gc file %s" ,second_pass_whole ,
1076+ file_path );
1077+ if (second_pass_whole == 1 )
1078+ {
1079+ gotoretry ;
1080+ }
10761081for (i = 0 ;i < n_pages ;i ++ )
10771082{
10781083newMap -> inodes [i ]= map -> inodes [i ];
@@ -1089,7 +1094,7 @@ static bool cfs_gc_file(char* map_path, GC_CALL_KIND background)
10891094
10901095pg_flush_data (fd2 ,writeback ,newSize );
10911096
1092- if (second_pass_whole )
1097+ if (second_pass_whole != 0 )
10931098{
10941099/* truncate file to copied size */
10951100if (ftruncate (fd2 ,newSize ))