@@ -631,20 +631,6 @@ dir_check_file(pgFile *file, bool backup_logs)
631
631
632
632
if (file -> forkName == ptrack ) /* Compatibility with left-overs from ptrack1 */
633
633
return CHECK_FALSE ;
634
- else if (file -> forkName != none )
635
- return CHECK_TRUE ;
636
-
637
- /* Set is_datafile flag */
638
- {
639
- char suffix [MAXFNAMELEN ];
640
-
641
- /* check if file is datafile */
642
- sscanf_res = sscanf (file -> name , "%u.%d.%s" , & (file -> relOid ),
643
- & (file -> segno ), suffix );
644
- Assert (sscanf_res > 0 ); /* since first char is digit */
645
- if (sscanf_res == 1 || sscanf_res == 2 )
646
- file -> is_datafile = true;
647
- }
648
634
}
649
635
}
650
636
@@ -1789,34 +1775,74 @@ pfilearray_clear_locks(parray *file_list)
1789
1775
}
1790
1776
}
1791
1777
1778
+ static inline bool
1779
+ is_forkname (char * name , size_t * pos , const char * forkname )
1780
+ {
1781
+ size_t fnlen = strlen (forkname );
1782
+ if (strncmp (name + * pos , forkname , fnlen ) != 0 )
1783
+ return false;
1784
+ * pos += fnlen ;
1785
+ return true;
1786
+ }
1787
+
1788
+ #define OIDCHARS 10
1789
+
1792
1790
/* Set forkName if possible */
1793
- void
1791
+ bool
1794
1792
set_forkname (pgFile * file )
1795
1793
{
1796
- int name_len = strlen (file -> name );
1797
-
1798
- /* Auxiliary fork of the relfile */
1799
- if (name_len > 3 && strcmp (file -> name + name_len - 3 , "_vm" ) == 0 )
1800
- file -> forkName = vm ;
1794
+ size_t i = 0 ;
1795
+ uint64_t oid = 0 ; /* use 64bit to not check for overflow in a loop */
1801
1796
1802
- else if (name_len > 4 && strcmp (file -> name + name_len - 4 , "_fsm" ) == 0 )
1803
- file -> forkName = fsm ;
1797
+ /* pretend it is not relation file */
1798
+ file -> relOid = 0 ;
1799
+ file -> forkName = none ;
1800
+ file -> is_datafile = false;
1804
1801
1805
- else if (name_len > 4 && strcmp (file -> name + name_len - 4 , ".cfm" ) == 0 )
1806
- file -> forkName = cfm ;
1802
+ for (i = 0 ; isdigit (file -> name [i ]); i ++ )
1803
+ {
1804
+ if (i == 0 && file -> name [i ] == '0' )
1805
+ return false;
1806
+ oid = oid * 10 + file -> name [i ] - '0' ;
1807
+ }
1808
+ if (i == 0 || i > OIDCHARS || oid > UINT32_MAX )
1809
+ return false;
1807
1810
1808
- else if (name_len > 5 && strcmp (file -> name + name_len - 5 , "_init" ) == 0 )
1811
+ /* usual fork name */
1812
+ /* /^\d+_(vm|fsm|init|ptrack)$/ */
1813
+ if (is_forkname (file -> name , & i , "_vm" ))
1814
+ file -> forkName = vm ;
1815
+ else if (is_forkname (file -> name , & i , "_fsm" ))
1816
+ file -> forkName = fsm ;
1817
+ else if (is_forkname (file -> name , & i , "_init" ))
1809
1818
file -> forkName = init ;
1810
-
1811
- else if (name_len > 7 && strcmp (file -> name + name_len - 7 , "_ptrack" ) == 0 )
1819
+ else if (is_forkname (file -> name , & i , "_ptrack" ))
1812
1820
file -> forkName = ptrack ;
1813
1821
1814
- // extract relOid for certain forks
1822
+ /* segment number */
1823
+ /* /^\d+(_(vm|fsm|init|ptrack))?\.\d+$/ */
1824
+ if (file -> name [i ] == '.' && isdigit (file -> name [i + 1 ]))
1825
+ {
1826
+ for (i ++ ; isdigit (file -> name [i ]); i ++ )
1827
+ ;
1828
+ }
1829
+
1830
+ /* CFS "fork name" */
1831
+ if (file -> forkName == none &&
1832
+ is_forkname (file -> name , & i , ".cfm" ))
1833
+ {
1834
+ /* /^\d+(\.\d+)?.cfm$/ */
1835
+ file -> forkName = cfm ;
1836
+ }
1837
+
1838
+ /* If there are excess characters, it is not relation file */
1839
+ if (file -> name [i ] != 0 )
1840
+ {
1841
+ file -> forkName = none ;
1842
+ return false;
1843
+ }
1815
1844
1816
- if ((file -> forkName == vm ||
1817
- file -> forkName == fsm ||
1818
- file -> forkName == init ||
1819
- file -> forkName == cfm ) &&
1820
- (sscanf (file -> name , "%u*" , & (file -> relOid )) != 1 ))
1821
- file -> relOid = 0 ;
1845
+ file -> relOid = oid ;
1846
+ file -> is_datafile = file -> forkName == none ;
1847
+ return true;
1822
1848
}
0 commit comments