Skip to content

Commit 6bca50d

Browse files
committed
switch to validate_only method
1 parent cd0177f commit 6bca50d

File tree

4 files changed

+99
-95
lines changed

4 files changed

+99
-95
lines changed

ext/opcache/ZendAccelerator.c

+2-2
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

+2-2
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

+94-89
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,109 @@ 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+
return &file_cache_validate_success_script;
18711910
}
18721911

1873-
cache_handle->checkpoint = zend_arena_checkpoint(CG(arena));
1912+
checkpoint = zend_arena_checkpoint(CG(arena));
18741913
#if defined(__AVX__) || defined(__SSE2__)
18751914
/* 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);
18781917
#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);
18801919
#endif
18811920

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)) {
18831922
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;
18861931
}
18871932
if (zend_file_cache_flock(fd, LOCK_UN) != 0) {
18881933
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
18911936

18921937
/* verify checksum */
18931938
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);
19441946
return NULL;
19451947
}
19461948

@@ -1955,12 +1957,13 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl
19551957
/* Check if we still need to put the file into the cache (may be it was
19561958
* already stored by another process. This final check is done under
19571959
* 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);
19591961
if (bucket) {
19601962
script = (zend_persistent_script *)bucket->data;
19611963
if (!script->corrupted) {
19621964
zend_shared_alloc_unlock();
1963-
zend_file_cache_close(&cache_handle);
1965+
zend_arena_release(&CG(arena), checkpoint);
1966+
efree(filename);
19641967
return script;
19651968
}
19661969
}
@@ -1973,23 +1976,23 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl
19731976
goto use_process_mem;
19741977
}
19751978

1976-
buf = zend_shared_alloc_aligned(cache_handle.info.mem_size);
1979+
buf = zend_shared_alloc_aligned(info.mem_size);
19771980

19781981
if (!buf) {
19791982
zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_OOM);
19801983
zend_shared_alloc_unlock();
19811984
goto use_process_mem;
19821985
}
1983-
memcpy(buf, cache_handle.mem, cache_handle.info.mem_size);
1986+
memcpy(buf, mem, info.mem_size);
19841987
zend_map_ptr_extend(ZCSG(map_ptr_last));
19851988
} else {
19861989
use_process_mem:
1987-
buf = cache_handle.mem;
1990+
buf = mem;
19881991
cache_it = false;
19891992
}
19901993

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);
19931996
script->corrupted = !cache_it; /* used to check if script restored to SHM or process memory */
19941997

19951998
ok = true;
@@ -2003,7 +2006,8 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl
20032006
zend_shared_alloc_unlock();
20042007
goto use_process_mem;
20052008
} else {
2006-
zend_file_cache_close(&cache_handle);
2009+
zend_arena_release(&CG(arena), checkpoint);
2010+
efree(filename);
20072011
return NULL;
20082012
}
20092013
}
@@ -2019,8 +2023,9 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl
20192023
zend_shared_alloc_unlock();
20202024
zend_accel_error(ACCEL_LOG_INFO, "File cached script loaded into memory '%s'", ZSTR_VAL(script->script.filename));
20212025

2022-
zend_file_cache_close(&cache_handle);
2026+
zend_arena_release(&CG(arena), checkpoint);
20232027
}
2028+
efree(filename);
20242029

20252030
return script;
20262031
}

ext/opcache/zend_file_cache.h

+1-2
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)