Skip to content

Commit 7cff70a

Browse files
committed
switch to validate_only method
1 parent cd0177f commit 7cff70a

File tree

4 files changed

+104
-95
lines changed

4 files changed

+104
-95
lines changed

ext/opcache/ZendAccelerator.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1917,7 +1917,7 @@ static zend_op_array *file_cache_compile_file(zend_file_handle *file_handle, int
19171917

19181918
HANDLE_BLOCK_INTERRUPTIONS();
19191919
SHM_UNPROTECT();
1920-
persistent_script = zend_file_cache_script_load(file_handle);
1920+
persistent_script = zend_file_cache_script_load(file_handle, false);
19211921
SHM_PROTECT();
19221922
HANDLE_UNBLOCK_INTERRUPTIONS();
19231923
if (persistent_script) {
@@ -2134,7 +2134,7 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type)
21342134

21352135
/* Check the second level cache */
21362136
if (!persistent_script && ZCG(accel_directives).file_cache) {
2137-
persistent_script = zend_file_cache_script_load(file_handle);
2137+
persistent_script = zend_file_cache_script_load(file_handle, false);
21382138
}
21392139

21402140
/* If script was not found or invalidated by validate_timestamps */

ext/opcache/zend_accelerator_module.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -380,11 +380,11 @@ static int filename_is_in_file_cache(zend_string *filename)
380380
zend_stream_init_filename_ex(&handle, filename);
381381
handle.opened_path = realpath;
382382

383-
zend_result result = zend_file_cache_validate(&handle);
383+
zend_persistent_script *result = zend_file_cache_script_load(&handle, true);
384384

385385
zend_destroy_file_handle(&handle);
386386

387-
return result == SUCCESS;
387+
return result != NULL;
388388
}
389389

390390

ext/opcache/zend_file_cache.c

Lines changed: 99 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -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-
211205
static 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 {
19861994
use_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
}

ext/opcache/zend_file_cache.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@
2020
#define ZEND_FILE_CACHE_H
2121

2222
int zend_file_cache_script_store(zend_persistent_script *script, bool in_shm);
23-
zend_result zend_file_cache_validate(zend_file_handle *file_handle);
24-
zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handle);
23+
zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handle, bool validate_only);
2524
void zend_file_cache_invalidate(zend_string *full_path);
2625

2726
#endif /* ZEND_FILE_CACHE_H */

0 commit comments

Comments
 (0)