@@ -688,20 +688,6 @@ dir_check_file(pgFile *file, bool backup_logs)
688688
689689 if (file -> forkName == ptrack ) /* Compatibility with left-overs from ptrack1 */
690690 return CHECK_FALSE ;
691- else if (file -> forkName != none )
692- return CHECK_TRUE ;
693-
694- /* Set is_datafile flag */
695- {
696- char suffix [MAXFNAMELEN ];
697-
698- /* check if file is datafile */
699- sscanf_res = sscanf (file -> name , "%u.%d.%s" , & (file -> relOid ),
700- & (file -> segno ), suffix );
701- Assert (sscanf_res > 0 ); /* since first char is digit */
702- if (sscanf_res == 1 || sscanf_res == 2 )
703- file -> is_datafile = true;
704- }
705691 }
706692 }
707693
@@ -1927,34 +1913,74 @@ pfilearray_clear_locks(parray *file_list)
19271913 }
19281914}
19291915
1916+ static inline bool
1917+ is_forkname (char * name , size_t * pos , const char * forkname )
1918+ {
1919+ size_t fnlen = strlen (forkname );
1920+ if (strncmp (name + * pos , forkname , fnlen ) != 0 )
1921+ return false;
1922+ * pos += fnlen ;
1923+ return true;
1924+ }
1925+
1926+ #define OIDCHARS 10
1927+
19301928/* Set forkName if possible */
1931- void
1929+ bool
19321930set_forkname (pgFile * file )
19331931{
1934- int name_len = strlen (file -> name );
1935-
1936- /* Auxiliary fork of the relfile */
1937- if (name_len > 3 && strcmp (file -> name + name_len - 3 , "_vm" ) == 0 )
1938- file -> forkName = vm ;
1932+ size_t i = 0 ;
1933+ uint64_t oid = 0 ; /* use 64bit to not check for overflow in a loop */
19391934
1940- else if (name_len > 4 && strcmp (file -> name + name_len - 4 , "_fsm" ) == 0 )
1941- file -> forkName = fsm ;
1935+ /* pretend it is not relation file */
1936+ file -> relOid = 0 ;
1937+ file -> forkName = none ;
1938+ file -> is_datafile = false;
19421939
1943- else if (name_len > 4 && strcmp (file -> name + name_len - 4 , ".cfm" ) == 0 )
1944- file -> forkName = cfm ;
1940+ for (i = 0 ; isdigit (file -> name [i ]); i ++ )
1941+ {
1942+ if (i == 0 && file -> name [i ] == '0' )
1943+ return false;
1944+ oid = oid * 10 + file -> name [i ] - '0' ;
1945+ }
1946+ if (i == 0 || i > OIDCHARS || oid > UINT32_MAX )
1947+ return false;
19451948
1946- else if (name_len > 5 && strcmp (file -> name + name_len - 5 , "_init" ) == 0 )
1949+ /* usual fork name */
1950+ /* /^\d+_(vm|fsm|init|ptrack)$/ */
1951+ if (is_forkname (file -> name , & i , "_vm" ))
1952+ file -> forkName = vm ;
1953+ else if (is_forkname (file -> name , & i , "_fsm" ))
1954+ file -> forkName = fsm ;
1955+ else if (is_forkname (file -> name , & i , "_init" ))
19471956 file -> forkName = init ;
1948-
1949- else if (name_len > 7 && strcmp (file -> name + name_len - 7 , "_ptrack" ) == 0 )
1957+ else if (is_forkname (file -> name , & i , "_ptrack" ))
19501958 file -> forkName = ptrack ;
19511959
1952- // extract relOid for certain forks
1960+ /* segment number */
1961+ /* /^\d+(_(vm|fsm|init|ptrack))?\.\d+$/ */
1962+ if (file -> name [i ] == '.' && isdigit (file -> name [i + 1 ]))
1963+ {
1964+ for (i ++ ; isdigit (file -> name [i ]); i ++ )
1965+ ;
1966+ }
1967+
1968+ /* CFS "fork name" */
1969+ if (file -> forkName == none &&
1970+ is_forkname (file -> name , & i , ".cfm" ))
1971+ {
1972+ /* /^\d+(\.\d+)?.cfm$/ */
1973+ file -> forkName = cfm ;
1974+ }
1975+
1976+ /* If there are excess characters, it is not relation file */
1977+ if (file -> name [i ] != 0 )
1978+ {
1979+ file -> forkName = none ;
1980+ return false;
1981+ }
19531982
1954- if ((file -> forkName == vm ||
1955- file -> forkName == fsm ||
1956- file -> forkName == init ||
1957- file -> forkName == cfm ) &&
1958- (sscanf (file -> name , "%u*" , & (file -> relOid )) != 1 ))
1959- file -> relOid = 0 ;
1983+ file -> relOid = oid ;
1984+ file -> is_datafile = file -> forkName == none ;
1985+ return true;
19601986}
0 commit comments