@@ -202,12 +202,6 @@ typedef struct _zend_file_cache_metainfo {
202202 uint32_t checksum ;
203203} zend_file_cache_metainfo ;
204204
205- typedef struct _zend_file_cache_handle {
206- zend_string * full_path ;
207- zend_file_cache_metainfo info ;
208- void * mem , * checkpoint ;
209- } zend_file_cache_handle ;
210-
211205static int zend_file_cache_mkdir (char * filename , size_t start )
212206{
213207 char * s = filename + start ;
@@ -1831,58 +1825,114 @@ static void zend_file_cache_unserialize(zend_persistent_script *script,
18311825 zend_file_cache_unserialize_early_bindings (script , buf );
18321826}
18331827
1834- zend_result zend_file_cache_validate_and_open (zend_file_handle * file_handle , zend_file_cache_handle * cache_handle )
1828+ static zend_persistent_script file_cache_validate_success_script ;
1829+
1830+ zend_persistent_script * zend_file_cache_script_load (zend_file_handle * file_handle , bool validate_only )
18351831{
1832+ zend_string * full_path = file_handle -> opened_path ;
18361833 int fd ;
18371834 char * filename ;
1835+ zend_persistent_script * script ;
1836+ zend_file_cache_metainfo info ;
1837+ zend_accel_hash_entry * bucket ;
1838+ void * mem , * checkpoint , * buf ;
1839+ bool cache_it = true;
18381840 unsigned int actual_checksum ;
1841+ bool ok ;
18391842
1840- if (!file_handle || ! file_handle -> opened_path ) {
1841- return FAILURE ;
1843+ if (!full_path ) {
1844+ return NULL ;
18421845 }
1843- cache_handle -> full_path = file_handle -> opened_path ;
1846+ filename = zend_file_cache_get_bin_file_path ( full_path ) ;
18441847
1845- filename = zend_file_cache_get_bin_file_path (cache_handle -> full_path );
18461848 fd = zend_file_cache_open (filename , O_RDONLY | O_BINARY );
18471849 if (fd < 0 ) {
1848- goto failure ; // Open failed
1850+ efree (filename );
1851+ return NULL ;
18491852 }
18501853
18511854 if (zend_file_cache_flock (fd , LOCK_SH ) != 0 ) {
1852- goto failure_close ; // Flock failed
1855+ close (fd );
1856+ efree (filename );
1857+ return NULL ;
18531858 }
18541859
1855-
1856- if (read (fd , & cache_handle -> info , sizeof (cache_handle -> info )) != sizeof (cache_handle -> info )) {
1860+ if (read (fd , & info , sizeof (info )) != sizeof (info )) {
18571861 zend_accel_error (ACCEL_LOG_WARNING , "opcache cannot read from file '%s' (info)\n" , filename );
1858- goto failure_unlock_close ;
1862+ zend_file_cache_flock (fd , LOCK_UN );
1863+ close (fd );
1864+ if (!ZCG (accel_directives ).file_cache_read_only ) {
1865+ zend_file_cache_unlink (filename );
1866+ }
1867+ efree (filename );
1868+ return NULL ;
18591869 }
18601870
1861- // Verify header
1862- if (memcmp (cache_handle -> info .magic , "OPCACHE" , 8 ) != 0 || memcmp (cache_handle -> info .system_id , zend_system_id , 32 ) != 0 ) {
1863- zend_accel_error (ACCEL_LOG_WARNING , "opcache invalid header in file '%s'\n" , filename );
1864- goto failure_unlock_close ;
1871+ /* verify header */
1872+ if (memcmp (info .magic , "OPCACHE" , 8 ) != 0 ) {
1873+ zend_accel_error (ACCEL_LOG_WARNING , "opcache cannot read from file '%s' (wrong header)\n" , filename );
1874+ zend_file_cache_flock (fd , LOCK_UN );
1875+ close (fd );
1876+ if (!ZCG (accel_directives ).file_cache_read_only ) {
1877+ zend_file_cache_unlink (filename );
1878+ }
1879+ efree (filename );
1880+ return NULL ;
1881+ }
1882+ if (memcmp (info .system_id , zend_system_id , 32 ) != 0 ) {
1883+ zend_accel_error (ACCEL_LOG_WARNING , "opcache cannot read from file '%s' (wrong \"system_id\")\n" , filename );
1884+ zend_file_cache_flock (fd , LOCK_UN );
1885+ close (fd );
1886+ if (!ZCG (accel_directives ).file_cache_read_only ) {
1887+ zend_file_cache_unlink (filename );
1888+ }
1889+ efree (filename );
1890+ return NULL ;
18651891 }
18661892
1867- // Verify timestamp if required
1893+ /* verify timestamp */
18681894 if (ZCG (accel_directives ).validate_timestamps &&
1869- zend_get_file_handle_timestamp (file_handle , NULL ) != cache_handle -> info .timestamp ) {
1870- goto failure_unlock_close ;
1895+ zend_get_file_handle_timestamp (file_handle , NULL ) != info .timestamp ) {
1896+ if (zend_file_cache_flock (fd , LOCK_UN ) != 0 ) {
1897+ zend_accel_error (ACCEL_LOG_WARNING , "opcache cannot unlock file '%s'\n" , filename );
1898+ }
1899+ close (fd );
1900+ if (!ZCG (accel_directives ).file_cache_read_only ) {
1901+ zend_file_cache_unlink (filename );
1902+ }
1903+ efree (filename );
1904+ return NULL ;
1905+ }
1906+
1907+ /* return here if validating */
1908+ if (validate_only ) {
1909+ if (zend_file_cache_flock (fd , LOCK_UN ) != 0 ) {
1910+ zend_accel_error (ACCEL_LOG_WARNING , "opcache cannot unlock file '%s'\n" , filename );
1911+ }
1912+ close (fd );
1913+ efree (filename );
1914+ return & file_cache_validate_success_script ;
18711915 }
18721916
1873- cache_handle -> checkpoint = zend_arena_checkpoint (CG (arena ));
1917+ checkpoint = zend_arena_checkpoint (CG (arena ));
18741918#if defined(__AVX__ ) || defined(__SSE2__ )
18751919 /* Align to 64-byte boundary */
1876- cache_handle -> mem = zend_arena_alloc (& CG (arena ), cache_handle -> info .mem_size + cache_handle -> info .str_size + 64 );
1877- cache_handle -> mem = (void * )(((uintptr_t )cache_handle -> mem + 63L ) & ~63L );
1920+ mem = zend_arena_alloc (& CG (arena ), info .mem_size + info .str_size + 64 );
1921+ mem = (void * )(((uintptr_t )mem + 63L ) & ~63L );
18781922#else
1879- cache_handle -> mem = zend_arena_alloc (& CG (arena ), cache_handle -> info .mem_size + cache_handle -> info .str_size );
1923+ mem = zend_arena_alloc (& CG (arena ), info .mem_size + info .str_size );
18801924#endif
18811925
1882- if (read (fd , cache_handle -> mem , cache_handle -> info .mem_size + cache_handle -> info .str_size ) != (ssize_t )(cache_handle -> info .mem_size + cache_handle -> info .str_size )) {
1926+ if (read (fd , mem , info .mem_size + info .str_size ) != (ssize_t )(info .mem_size + info .str_size )) {
18831927 zend_accel_error (ACCEL_LOG_WARNING , "opcache cannot read from file '%s' (mem)\n" , filename );
1884- zend_arena_release (& CG (arena ), cache_handle -> checkpoint );
1885- goto failure_unlock_close ;
1928+ zend_file_cache_flock (fd , LOCK_UN );
1929+ close (fd );
1930+ if (!ZCG (accel_directives ).file_cache_read_only ) {
1931+ zend_file_cache_unlink (filename );
1932+ }
1933+ zend_arena_release (& CG (arena ), checkpoint );
1934+ efree (filename );
1935+ return NULL ;
18861936 }
18871937 if (zend_file_cache_flock (fd , LOCK_UN ) != 0 ) {
18881938 zend_accel_error (ACCEL_LOG_WARNING , "opcache cannot unlock file '%s'\n" , filename );
@@ -1891,56 +1941,13 @@ zend_result zend_file_cache_validate_and_open(zend_file_handle *file_handle, zen
18911941
18921942 /* verify checksum */
18931943 if (ZCG (accel_directives ).file_cache_consistency_checks &&
1894- (actual_checksum = zend_adler32 (ADLER32_INIT , cache_handle -> mem , cache_handle -> info .mem_size + cache_handle -> info .str_size )) != cache_handle -> info .checksum ) {
1895- zend_accel_error (ACCEL_LOG_WARNING , "corrupted file '%s' excepted checksum: 0x%08x actual checksum: 0x%08x\n" , filename , cache_handle -> info .checksum , actual_checksum );
1896- zend_arena_release (& CG (arena ), cache_handle -> checkpoint );
1897- goto failure ;
1898- }
1899-
1900- efree (filename );
1901- return SUCCESS ;
1902-
1903- failure_unlock_close :
1904- zend_file_cache_flock (fd , LOCK_UN );
1905- failure_close :
1906- close (fd );
1907- failure :
1908- if (!ZCG (accel_directives ).file_cache_read_only ) {
1909- zend_file_cache_unlink (filename );
1910- }
1911- efree (filename );
1912-
1913- return FAILURE ;
1914- }
1915-
1916- void zend_file_cache_close (zend_file_cache_handle * cache_handle )
1917- {
1918- zend_arena_release (& CG (arena ), cache_handle -> checkpoint );
1919- }
1920-
1921- zend_result zend_file_cache_validate (zend_file_handle * file_handle )
1922- {
1923- zend_file_cache_handle cache_handle ;
1924-
1925- zend_result ret = zend_file_cache_validate_and_open (file_handle , & cache_handle );
1926-
1927- if (ret == SUCCESS ) {
1928- zend_file_cache_close (& cache_handle );
1929- }
1930-
1931- return ret ;
1932- }
1933-
1934- zend_persistent_script * zend_file_cache_script_load (zend_file_handle * file_handle )
1935- {
1936- zend_file_cache_handle cache_handle ;
1937- zend_persistent_script * script ;
1938- zend_accel_hash_entry * bucket ;
1939- void * buf ;
1940- bool cache_it = true;
1941- bool ok ;
1942-
1943- if (zend_file_cache_validate_and_open (file_handle , & cache_handle ) == FAILURE ) {
1944+ (actual_checksum = zend_adler32 (ADLER32_INIT , mem , info .mem_size + info .str_size )) != info .checksum ) {
1945+ zend_accel_error (ACCEL_LOG_WARNING , "corrupted file '%s' excepted checksum: 0x%08x actual checksum: 0x%08x\n" , filename , info .checksum , actual_checksum );
1946+ if (!ZCG (accel_directives ).file_cache_read_only ) {
1947+ zend_file_cache_unlink (filename );
1948+ }
1949+ zend_arena_release (& CG (arena ), checkpoint );
1950+ efree (filename );
19441951 return NULL ;
19451952 }
19461953
@@ -1955,12 +1962,13 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl
19551962 /* Check if we still need to put the file into the cache (may be it was
19561963 * already stored by another process. This final check is done under
19571964 * exclusive lock) */
1958- bucket = zend_accel_hash_find_entry (& ZCSG (hash ), cache_handle . full_path );
1965+ bucket = zend_accel_hash_find_entry (& ZCSG (hash ), full_path );
19591966 if (bucket ) {
19601967 script = (zend_persistent_script * )bucket -> data ;
19611968 if (!script -> corrupted ) {
19621969 zend_shared_alloc_unlock ();
1963- zend_file_cache_close (& cache_handle );
1970+ zend_arena_release (& CG (arena ), checkpoint );
1971+ efree (filename );
19641972 return script ;
19651973 }
19661974 }
@@ -1973,23 +1981,23 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl
19731981 goto use_process_mem ;
19741982 }
19751983
1976- buf = zend_shared_alloc_aligned (cache_handle . info .mem_size );
1984+ buf = zend_shared_alloc_aligned (info .mem_size );
19771985
19781986 if (!buf ) {
19791987 zend_accel_schedule_restart_if_necessary (ACCEL_RESTART_OOM );
19801988 zend_shared_alloc_unlock ();
19811989 goto use_process_mem ;
19821990 }
1983- memcpy (buf , cache_handle . mem , cache_handle . info .mem_size );
1991+ memcpy (buf , mem , info .mem_size );
19841992 zend_map_ptr_extend (ZCSG (map_ptr_last ));
19851993 } else {
19861994use_process_mem :
1987- buf = cache_handle . mem ;
1995+ buf = mem ;
19881996 cache_it = false;
19891997 }
19901998
1991- ZCG (mem ) = ((char * )cache_handle . mem + cache_handle . info .mem_size );
1992- script = (zend_persistent_script * )((char * )buf + cache_handle . info .script_offset );
1999+ ZCG (mem ) = ((char * )mem + info .mem_size );
2000+ script = (zend_persistent_script * )((char * )buf + info .script_offset );
19932001 script -> corrupted = !cache_it ; /* used to check if script restored to SHM or process memory */
19942002
19952003 ok = true;
@@ -2003,7 +2011,8 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl
20032011 zend_shared_alloc_unlock ();
20042012 goto use_process_mem ;
20052013 } else {
2006- zend_file_cache_close (& cache_handle );
2014+ zend_arena_release (& CG (arena ), checkpoint );
2015+ efree (filename );
20072016 return NULL ;
20082017 }
20092018 }
@@ -2019,8 +2028,9 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl
20192028 zend_shared_alloc_unlock ();
20202029 zend_accel_error (ACCEL_LOG_INFO , "File cached script loaded into memory '%s'" , ZSTR_VAL (script -> script .filename ));
20212030
2022- zend_file_cache_close ( & cache_handle );
2031+ zend_arena_release ( & CG ( arena ), checkpoint );
20232032 }
2033+ efree (filename );
20242034
20252035 return script ;
20262036}
0 commit comments