@@ -202,12 +202,6 @@ typedef struct _zend_file_cache_metainfo {
202
202
uint32_t checksum ;
203
203
} zend_file_cache_metainfo ;
204
204
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
-
211
205
static int zend_file_cache_mkdir (char * filename , size_t start )
212
206
{
213
207
char * s = filename + start ;
@@ -1831,58 +1825,109 @@ static void zend_file_cache_unserialize(zend_persistent_script *script,
1831
1825
zend_file_cache_unserialize_early_bindings (script , buf );
1832
1826
}
1833
1827
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 )
1835
1831
{
1832
+ zend_string * full_path = file_handle -> opened_path ;
1836
1833
int fd ;
1837
1834
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;
1838
1840
unsigned int actual_checksum ;
1841
+ bool ok ;
1839
1842
1840
- if (!file_handle || ! file_handle -> opened_path ) {
1841
- return FAILURE ;
1843
+ if (!full_path ) {
1844
+ return NULL ;
1842
1845
}
1843
- cache_handle -> full_path = file_handle -> opened_path ;
1846
+ filename = zend_file_cache_get_bin_file_path ( full_path ) ;
1844
1847
1845
- filename = zend_file_cache_get_bin_file_path (cache_handle -> full_path );
1846
1848
fd = zend_file_cache_open (filename , O_RDONLY | O_BINARY );
1847
1849
if (fd < 0 ) {
1848
- goto failure ; // Open failed
1850
+ efree (filename );
1851
+ return NULL ;
1849
1852
}
1850
1853
1851
1854
if (zend_file_cache_flock (fd , LOCK_SH ) != 0 ) {
1852
- goto failure_close ; // Flock failed
1855
+ close (fd );
1856
+ efree (filename );
1857
+ return NULL ;
1853
1858
}
1854
1859
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 )) {
1857
1861
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 ;
1859
1869
}
1860
1870
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 ;
1865
1891
}
1866
1892
1867
- // Verify timestamp if required
1893
+ /* verify timestamp */
1868
1894
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
+ return & file_cache_validate_success_script ;
1871
1910
}
1872
1911
1873
- cache_handle -> checkpoint = zend_arena_checkpoint (CG (arena ));
1912
+ checkpoint = zend_arena_checkpoint (CG (arena ));
1874
1913
#if defined(__AVX__ ) || defined(__SSE2__ )
1875
1914
/* 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 );
1915
+ mem = zend_arena_alloc (& CG (arena ), info .mem_size + info .str_size + 64 );
1916
+ mem = (void * )(((uintptr_t )mem + 63L ) & ~63L );
1878
1917
#else
1879
- cache_handle -> mem = zend_arena_alloc (& CG (arena ), cache_handle -> info .mem_size + cache_handle -> info .str_size );
1918
+ mem = zend_arena_alloc (& CG (arena ), info .mem_size + info .str_size );
1880
1919
#endif
1881
1920
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 )) {
1921
+ if (read (fd , mem , info .mem_size + info .str_size ) != (ssize_t )(info .mem_size + info .str_size )) {
1883
1922
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 ;
1923
+ zend_file_cache_flock (fd , LOCK_UN );
1924
+ close (fd );
1925
+ if (!ZCG (accel_directives ).file_cache_read_only ) {
1926
+ zend_file_cache_unlink (filename );
1927
+ }
1928
+ zend_arena_release (& CG (arena ), checkpoint );
1929
+ efree (filename );
1930
+ return NULL ;
1886
1931
}
1887
1932
if (zend_file_cache_flock (fd , LOCK_UN ) != 0 ) {
1888
1933
zend_accel_error (ACCEL_LOG_WARNING , "opcache cannot unlock file '%s'\n" , filename );
@@ -1891,56 +1936,13 @@ zend_result zend_file_cache_validate_and_open(zend_file_handle *file_handle, zen
1891
1936
1892
1937
/* verify checksum */
1893
1938
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 ) {
1939
+ (actual_checksum = zend_adler32 (ADLER32_INIT , mem , info .mem_size + info .str_size )) != info .checksum ) {
1940
+ zend_accel_error (ACCEL_LOG_WARNING , "corrupted file '%s' excepted checksum: 0x%08x actual checksum: 0x%08x\n" , filename , info .checksum , actual_checksum );
1941
+ if (!ZCG (accel_directives ).file_cache_read_only ) {
1942
+ zend_file_cache_unlink (filename );
1943
+ }
1944
+ zend_arena_release (& CG (arena ), checkpoint );
1945
+ efree (filename );
1944
1946
return NULL ;
1945
1947
}
1946
1948
@@ -1955,12 +1957,13 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl
1955
1957
/* Check if we still need to put the file into the cache (may be it was
1956
1958
* already stored by another process. This final check is done under
1957
1959
* exclusive lock) */
1958
- bucket = zend_accel_hash_find_entry (& ZCSG (hash ), cache_handle . full_path );
1960
+ bucket = zend_accel_hash_find_entry (& ZCSG (hash ), full_path );
1959
1961
if (bucket ) {
1960
1962
script = (zend_persistent_script * )bucket -> data ;
1961
1963
if (!script -> corrupted ) {
1962
1964
zend_shared_alloc_unlock ();
1963
- zend_file_cache_close (& cache_handle );
1965
+ zend_arena_release (& CG (arena ), checkpoint );
1966
+ efree (filename );
1964
1967
return script ;
1965
1968
}
1966
1969
}
@@ -1973,23 +1976,23 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl
1973
1976
goto use_process_mem ;
1974
1977
}
1975
1978
1976
- buf = zend_shared_alloc_aligned (cache_handle . info .mem_size );
1979
+ buf = zend_shared_alloc_aligned (info .mem_size );
1977
1980
1978
1981
if (!buf ) {
1979
1982
zend_accel_schedule_restart_if_necessary (ACCEL_RESTART_OOM );
1980
1983
zend_shared_alloc_unlock ();
1981
1984
goto use_process_mem ;
1982
1985
}
1983
- memcpy (buf , cache_handle . mem , cache_handle . info .mem_size );
1986
+ memcpy (buf , mem , info .mem_size );
1984
1987
zend_map_ptr_extend (ZCSG (map_ptr_last ));
1985
1988
} else {
1986
1989
use_process_mem :
1987
- buf = cache_handle . mem ;
1990
+ buf = mem ;
1988
1991
cache_it = false;
1989
1992
}
1990
1993
1991
- ZCG (mem ) = ((char * )cache_handle . mem + cache_handle . info .mem_size );
1992
- script = (zend_persistent_script * )((char * )buf + cache_handle . info .script_offset );
1994
+ ZCG (mem ) = ((char * )mem + info .mem_size );
1995
+ script = (zend_persistent_script * )((char * )buf + info .script_offset );
1993
1996
script -> corrupted = !cache_it ; /* used to check if script restored to SHM or process memory */
1994
1997
1995
1998
ok = true;
@@ -2003,7 +2006,8 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl
2003
2006
zend_shared_alloc_unlock ();
2004
2007
goto use_process_mem ;
2005
2008
} else {
2006
- zend_file_cache_close (& cache_handle );
2009
+ zend_arena_release (& CG (arena ), checkpoint );
2010
+ efree (filename );
2007
2011
return NULL ;
2008
2012
}
2009
2013
}
@@ -2019,8 +2023,9 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl
2019
2023
zend_shared_alloc_unlock ();
2020
2024
zend_accel_error (ACCEL_LOG_INFO , "File cached script loaded into memory '%s'" , ZSTR_VAL (script -> script .filename ));
2021
2025
2022
- zend_file_cache_close ( & cache_handle );
2026
+ zend_arena_release ( & CG ( arena ), checkpoint );
2023
2027
}
2028
+ efree (filename );
2024
2029
2025
2030
return script ;
2026
2031
}
0 commit comments