@@ -631,20 +631,6 @@ dir_check_file(pgFile *file, bool backup_logs)
631631
632632 if (file -> forkName == ptrack ) /* Compatibility with left-overs from ptrack1 */
633633 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- }
648634 }
649635 }
650636
@@ -1789,34 +1775,74 @@ pfilearray_clear_locks(parray *file_list)
17891775 }
17901776}
17911777
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+
17921790/* Set forkName if possible */
1793- void
1791+ bool
17941792set_forkname (pgFile * file )
17951793{
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 */
18011796
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;
18041801
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;
18071810
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" ))
18091818 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" ))
18121820 file -> forkName = ptrack ;
18131821
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+ }
18151844
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;
18221848}
0 commit comments