@@ -118,7 +118,7 @@ typedef struct TablespaceCreatedList
118
118
119
119
static int BlackListCompare (const void * str1 , const void * str2 );
120
120
121
- static bool dir_check_file (const char * root , pgFile * file );
121
+ static char dir_check_file (const char * root , pgFile * file );
122
122
static void dir_list_file_internal (parray * files , const char * root ,
123
123
pgFile * parent , bool exclude ,
124
124
bool omit_symlink , parray * black_list );
@@ -448,6 +448,10 @@ dir_list_file(parray *files, const char *root, bool exclude, bool omit_symlink,
448
448
pgFileFree (file );
449
449
}
450
450
451
+ #define CHECK_FALSE 0
452
+ #define CHECK_TRUE 1
453
+ #define CHECK_EXCLUDE_FALSE 2
454
+
451
455
/*
452
456
* Check file or directory.
453
457
*
@@ -456,16 +460,21 @@ dir_list_file(parray *files, const char *root, bool exclude, bool omit_symlink,
456
460
* Skip files:
457
461
* - skip temp tables files
458
462
* - skip unlogged tables files
463
+ * Skip recursive tablespace content
459
464
* Set flags for:
460
465
* - database directories
461
466
* - datafiles
462
467
*/
463
- static bool
468
+ static char
464
469
dir_check_file (const char * root , pgFile * file )
465
470
{
466
471
const char * rel_path ;
467
472
int i ;
468
473
int sscanf_res ;
474
+ bool in_tablespace = false;
475
+
476
+ rel_path = GetRelativePath (file -> path , root );
477
+ in_tablespace = path_is_prefix_of_path (PG_TBLSPC_DIR , rel_path );
469
478
470
479
/* Check if we need to exclude file by name */
471
480
if (S_IS
8000
REG (file -> mode ))
@@ -478,7 +487,7 @@ dir_check_file(const char *root, pgFile *file)
478
487
{
479
488
/* Skip */
480
489
elog (VERBOSE , "Excluding file: %s" , file -> name );
481
- return false ;
490
+ return CHECK_FALSE ;
482
491
}
483
492
}
484
493
@@ -487,14 +496,14 @@ dir_check_file(const char *root, pgFile *file)
487
496
{
488
497
/* Skip */
489
498
elog (VERBOSE , "Excluding file: %s" , file -> name );
490
- return false ;
499
+ return CHECK_FALSE ;
491
500
}
492
501
}
493
502
/*
494
503
* If the directory name is in the exclude list, do not list the
495
504
* contents.
496
505
*/
497
- else if (S_ISDIR (file -> mode ))
506
+ else if (S_ISDIR (file -> mode ) && ! in_tablespace )
498
507
{
499
508
/*
500
509
* If the item in the exclude list starts with '/', compare to
@@ -510,20 +519,18 @@ dir_check_file(const char *root, pgFile *file)
510
519
{
511
520
elog (VERBOSE , "Excluding directory content: %s" ,
512
521
file -> name );
513
- return false ;
522
+ return CHECK_EXCLUDE_FALSE ;
514
523
}
515
524
}
516
525
else if (strcmp (file -> name , pgdata_exclude_dir [i ]) == 0 )
517
526
{
518
527
elog (VERBOSE , "Excluding directory content: %s" ,
519
528
file -> name );
520
- return false ;
529
+ return CHECK_EXCLUDE_FALSE ;
521
530
}
522
531
}
523
532
}
524
533
525
- rel_path = GetRelativePath (file -> path , root );
526
-
527
534
/*
528
535
* Do not copy tablespaces twice. It may happen if the tablespace is located
529
536
* inside the PGDATA.
@@ -539,14 +546,33 @@ dir_check_file(const char *root, pgFile *file)
539
546
* pg_tblspc/tblsOid/TABLESPACE_VERSION_DIRECTORY
540
547
*/
541
548
if (!path_is_prefix_of_path (PG_TBLSPC_DIR , rel_path ))
542
- return false ;
549
+ return CHECK_FALSE ;
543
550
sscanf_res = sscanf (rel_path , PG_TBLSPC_DIR "/%u/%s" ,
544
551
& tblspcOid , tmp_rel_path );
545
552
if (sscanf_res == 0 )
546
- return false ;
553
+ return CHECK_FALSE ;
547
554
}
548
555
549
- if (path_is_prefix_of_path ("global" , rel_path ))
556
+ if (in_tablespace )
557
+ {
558
+ char tmp_rel_path [MAXPGPATH ];
559
<
A3E2
/td>+
560
+ sscanf_res = sscanf (rel_path , PG_TBLSPC_DIR "/%u/%[^/]/%u/" ,
561
+ & (file -> tblspcOid ), tmp_rel_path ,
562
+ & (file -> dbOid ));
563
+
564
+ /*
565
+ * We should skip other files and directories rather than
566
+ * TABLESPACE_VERSION_DIRECTORY, if this is recursive tablespace.
567
+ */
568
+ if (sscanf_res == 2 && strcmp (tmp_rel_path , TABLESPACE_VERSION_DIRECTORY ) != 0 )
569
+ return CHECK_FALSE ;
570
+
571
+ if (sscanf_res == 3 && S_ISDIR (file -> mode ) &&
572
+ strcmp (tmp_rel_path , TABLESPACE_VERSION_DIRECTORY ) == 0 )
573
+ file -> is_database = true;
574
+ }
575
+ else if (path_is_prefix_of_path ("global" , rel_path ))
550
576
{
551
577
file -> tblspcOid = GLOBALTABLESPACE_OID ;
552
578
@@ -562,22 +588,10 @@ dir_check_file(const char *root, pgFile *file)
562
588
if (S_ISDIR (file -> mode ) && strcmp (file -> name , "base" ) != 0 )
563
589
file -> is_database = true;
564
590
}
565
- else if (path_is_prefix_of_path (PG_TBLSPC_DIR , rel_path ))
566
- {
567
- char tmp_rel_path [MAXPGPATH ];
568
-
569
- sscanf_res = sscanf (rel_path , PG_TBLSPC_DIR "/%u/%[^/]/%u/" ,
570
- & (file -> tblspcOid ), tmp_rel_path ,
571
- & (file -> dbOid ));
572
-
573
- if (sscanf_res == 3 && S_ISDIR (file -> mode ) &&
574
- strcmp (tmp_rel_path , TABLESPACE_VERSION_DIRECTORY ) == 0 )
575
- file -> is_database = true;
576
- }
577
591
578
592
/* Do not backup ptrack_init files */
579
593
if (S_ISREG (file -> mode ) && strcmp (file -> name , "ptrack_init" ) == 0 )
580
- return false ;
594
+ return CHECK_FALSE ;
581
595
582
596
/*
583
597
* Check files located inside database directories including directory
@@ -587,10 +601,10 @@ dir_check_file(const char *root, pgFile *file)
587
601
file -> name && file -> name [0 ])
588
602
{
589
603
if (strcmp (file -> name , "pg_internal.init" ) == 0 )
590
- return false ;
604
+ return CHECK_FALSE ;
591
605
/* Do not backup temp files */
592
606
else if (file -> name [0 ] == 't' && isdigit (file -> name [1 ]))
593
- return false ;
607
+ return CHECK_FALSE ;
594
608
else if (isdigit (file -> name [0 ]))
595
609
{
596
610
char * fork_name ;
@@ -605,14 +619,14 @@ dir_check_file(const char *root, pgFile *file)
605
619
606
620
/* Do not backup ptrack files */
607
621
if (strcmp (file -> forkName , "ptrack" ) == 0 )
608
- return false ;
622
+ return CHECK_FALSE ;
609
623
}
610
624
else
611
625
{
612
626
len = strlen (file -> name );
613
627
/* reloid.cfm */
614
628
if (len > 3 && strcmp (file -> name + len - 3 , "cfm" ) == 0 )
615
- return true ;
629
+ return CHECK_TRUE ;
616
630
617
631
sscanf_res = sscanf (file -> name , "%u.%d.%s" , & (file -> relOid ),
618
632
& (file -> segno ), suffix );
@@ -624,7 +638,7 @@ dir_check_file(const char *root, pgFile *file)
624
638
}
625
639
}
626
640
627
- return true ;
641
+ return CHECK_TRUE ;
628
642
}
629
643
630
644
/*
@@ -659,6 +673,7 @@ dir_list_file_internal(parray *files, const char *root, pgFile *parent,
659
673
{
660
674
pgFile * file ;
661
675
char child [MAXPGPATH ];
676
+ char check_res ;
662
677
663
678
join_path_components (child , parent -> path , dent -> d_name );
664
679
@@ -694,21 +709,24 @@ dir_list_file_internal(parray *files, const char *root, pgFile *parent,
694
709
continue ;
695
710
}
696
711
697
- /* We add the directory anyway */
698
- if (S_ISDIR (file -> mode ))
699
- parray_append (files , file );
700
-
701
- if (exclude && !dir_check_file (root , file ))
712
+ if (exclude )
702
713
{
703
- if (S_ISREG (file -> mode ))
714
+ check_res = dir_check_file (root , file );
715
+ if (check_res == CHECK_FALSE )
716
+ {
717
+ /* Skip */
704
718
pgFileFree (file );
705
- /* Skip */
706
- continue ;
719
+ continue ;
720
+ }
721
+ else if (check_res == CHECK_EXCLUDE_FALSE )
722
+ {
723
+ /* We add the directory itself which content was excluded */
724
+ parray_append (files , file );
725
+ continue ;
726
+ }
707
727
}
708
728
709
- /* At least add the file */
710
- if (S_ISREG (file -> mode ))
711
- parray_append (files , file );
729
+ parray_append (files , file );
712
730
713
731
/*
714
732
* If the entry is a directory call dir_list_file_internal()
@@ -1219,11 +1237,7 @@ print_file_list(FILE *out, const parray *files, const char *root)
1219
1237
if (file -> is_datafile )
1220
1238
fprintf (out , ",\"segno\":\"%d\"" , file -> segno );
1221
1239
1222
- #ifndef WIN32
1223
- if (S_ISLNK (file -> mode ))
1224
- #else
1225
- if (pgwin32_is_junction (file -> path ))
1226
- #endif
1240
+ if (file -> linked )
1227
1241
fprintf (out , ",\"linked\":\"%s\"" , file -> linked );
1228
1242
1229
1243
if (file -> n_blocks != BLOCKNUM_INVALID )
0 commit comments