Skip to content

Commit 906b92d

Browse files
committed
zend_file_cache_open with struct
1 parent 7e23285 commit 906b92d

File tree

3 files changed

+94
-175
lines changed

3 files changed

+94
-175
lines changed

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-
bool result = zend_file_cache_script_validate(&handle);
383+
zend_result result = zend_file_cache_script_validate(&handle);
384384

385385
zend_destroy_file_handle(&handle);
386386

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

390390

ext/opcache/zend_file_cache.c

+83-172
Original file line numberDiff line numberDiff line change
@@ -1813,187 +1813,58 @@ static void zend_file_cache_unserialize(zend_persistent_script *script,
18131813
zend_file_cache_unserialize_early_bindings(script, buf);
18141814
}
18151815

1816-
// Function to validate the file cache and return a boolean result
1817-
bool zend_file_cache_script_validate(zend_file_handle *file_handle)
1816+
zend_always_inline zend_result zend_file_cache_open(zend_file_handle *file_handle, zend_file_cache_handle *cache_handle)
18181817
{
1819-
int fd;
1820-
char *filename;
1821-
zend_file_cache_metainfo info;
1822-
unsigned int actual_checksum;
1823-
void *mem, *checkpoint;
1824-
1825-
if (!file_handle || !file_handle->opened_path) {
1826-
return false;
1827-
}
1828-
1829-
filename = zend_file_cache_get_bin_file_path(file_handle->opened_path);
1830-
fd = zend_file_cache_open(filename, O_RDONLY | O_BINARY);
1831-
if (fd < 0) {
1832-
goto failure; // Open failed
1833-
}
1834-
1835-
if (zend_file_cache_flock(fd, LOCK_SH) != 0) {
1836-
goto failure_close; // Flock failed
1837-
}
1838-
1839-
1840-
if (read(fd, &info, sizeof(info)) != sizeof(info)) {
1841-
zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot read from file '%s' (info)\n", filename);
1842-
goto failure_unlock_close;
1843-
}
1844-
1845-
// Verify header
1846-
if (memcmp(info.magic, "OPCACHE", 8) != 0 || memcmp(info.system_id, zend_system_id, 32) != 0) {
1847-
zend_accel_error(ACCEL_LOG_WARNING, "opcache invalid header in file '%s'\n", filename);
1848-
goto failure_unlock_close;
1849-
}
1850-
1851-
// Verify timestamp if required
1852-
if (ZCG(accel_directives).validate_timestamps &&
1853-
zend_get_file_handle_timestamp(file_handle, NULL) != info.timestamp) {
1854-
goto failure_unlock_close;
1855-
}
1856-
1857-
checkpoint = zend_arena_checkpoint(CG(arena));
1858-
#if defined(__AVX__) || defined(__SSE2__)
1859-
/* Align to 64-byte boundary */
1860-
mem = zend_arena_alloc(&CG(arena), info.mem_size + info.str_size + 64);
1861-
mem = (void*)(((uintptr_t)mem + 63L) & ~63L);
1862-
#else
1863-
mem = zend_arena_alloc(&CG(arena), info.mem_size + info.str_size);
1864-
#endif
1865-
1866-
if (read(fd, mem, info.mem_size + info.str_size) != (ssize_t)(info.mem_size + info.str_size)) {
1867-
zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot read from file '%s' (mem)\n", filename);
1868-
zend_arena_release(&CG(arena), checkpoint);
1869-
goto failure_unlock_close;
1870-
}
1871-
if (zend_file_cache_flock(fd, LOCK_UN) != 0) {
1872-
zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot unlock file '%s'\n", filename);
1873-
}
1874-
close(fd);
1875-
1876-
/* verify checksum */
1877-
if (ZCG(accel_directives).file_cache_consistency_checks &&
1878-
(actual_checksum = zend_adler32(ADLER32_INIT, mem, info.mem_size + info.str_size)) != info.checksum) {
1879-
zend_accel_error(ACCEL_LOG_WARNING, "corrupted file '%s' excepted checksum: 0x%08x actual checksum: 0x%08x\n", filename, info.checksum, actual_checksum);
1880-
zend_arena_release(&CG(arena), checkpoint);
1881-
goto failure;
1882-
}
1883-
1884-
zend_arena_release(&CG(arena), checkpoint);
1885-
efree(filename);
1886-
return true; // Validation successful
1887-
1888-
failure_unlock_close:
1889-
zend_file_cache_flock(fd, LOCK_UN);
1890-
failure_close:
1891-
close(fd);
1892-
failure:
1893-
if (!ZCG(accel_directives).file_cache_read_only) {
1894-
zend_file_cache_unlink(filename);
1895-
}
1896-
efree(filename);
1897-
1898-
return false; // Validation failed
1899-
}
1900-
1901-
zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handle)
1902-
{
1903-
zend_string *full_path = file_handle->opened_path;
19041818
int fd;
19051819
char *filename;
1906-
zend_persistent_script *script;
1907-
zend_file_cache_metainfo info;
1908-
zend_accel_hash_entry *bucket;
1909-
void *mem, *checkpoint, *buf;
1910-
bool cache_it = true;
19111820
unsigned int actual_checksum;
1912-
bool ok;
19131821

1914-
if (!full_path) {
1915-
return NULL;
1822+
if (!file_handle || !file_handle->opened_path) {
1823+
return FAILURE;
19161824
}
1917-
filename = zend_file_cache_get_bin_file_path(full_path);
1825+
zend_file_cache_handle->full_path = file_handle->opened_path
19181826

1827+
filename = zend_file_cache_get_bin_file_path(zend_file_cache_handle->full_path);
19191828
fd = zend_file_cache_open(filename, O_RDONLY | O_BINARY);
19201829
if (fd < 0) {
1921-
efree(filename);
1922-
return NULL;
1830+
goto failure; // Open failed
19231831
}
19241832

19251833
if (zend_file_cache_flock(fd, LOCK_SH) != 0) {
1926-
close(fd);
1927-
efree(filename);
1928-
return NULL;
1834+
goto failure_close; // Flock failed
19291835
}
19301836

1931-
if (read(fd, &info, sizeof(info)) != sizeof(info)) {
1837+
1838+
if (read(fd, &zend_file_cache_handle->info, sizeof(zend_file_cache_handle->info)) != sizeof(zend_file_cache_handle->info)) {
19321839
zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot read from file '%s' (info)\n", filename);
1933-
zend_file_cache_flock(fd, LOCK_UN);
1934-
close(fd);
1935-
if (!ZCG(accel_directives).file_cache_read_only) {
1936-
zend_file_cache_unlink(filename);
1937-
}
1938-
efree(filename);
1939-
return NULL;
1840+
goto failure_unlock_close;
19401841
}
19411842

1942-
/* verify header */
1943-
if (memcmp(info.magic, "OPCACHE", 8) != 0) {
1944-
zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot read from file '%s' (wrong header)\n", filename);
1945-
zend_file_cache_flock(fd, LOCK_UN);
1946-
close(fd);
1947-
if (!ZCG(accel_directives).file_cache_read_only) {
1948-
zend_file_cache_unlink(filename);
1949-
}
1950-
efree(filename);
1951-
return NULL;
1952-
}
1953-
if (memcmp(info.system_id, zend_system_id, 32) != 0) {
1954-
zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot read from file '%s' (wrong \"system_id\")\n", filename);
1955-
zend_file_cache_flock(fd, LOCK_UN);
1956-
close(fd);
1957-
if (!ZCG(accel_directives).file_cache_read_only) {
1958-
zend_file_cache_unlink(filename);
1959-
}
1960-
efree(filename);
1961-
return NULL;
1843+
// Verify header
1844+
if (memcmp(zend_file_cache_handle->info.magic, "OPCACHE", 8) != 0 || memcmp(zend_file_cache_handle->info.system_id, zend_system_id, 32) != 0) {
1845+
zend_accel_error(ACCEL_LOG_WARNING, "opcache invalid header in file '%s'\n", filename);
1846+
goto failure_unlock_close;
19621847
}
19631848

1964-
/* verify timestamp */
1849+
// Verify timestamp if required
19651850
if (ZCG(accel_directives).validate_timestamps &&
1966-
zend_get_file_handle_timestamp(file_handle, NULL) != info.timestamp) {
1967-
if (zend_file_cache_flock(fd, LOCK_UN) != 0) {
1968-
zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot unlock file '%s'\n", filename);
1969-
}
1970-
close(fd);
1971-
if (!ZCG(accel_directives).file_cache_read_only) {
1972-
zend_file_cache_unlink(filename);
1973-
}
1974-
efree(filename);
1975-
return NULL;
1851+
zend_get_file_handle_timestamp(file_handle, NULL) != zend_file_cache_handle->info.timestamp) {
1852+
goto failure_unlock_close;
19761853
}
19771854

1978-
checkpoint = zend_arena_checkpoint(CG(arena));
1855+
zend_file_cache_handle->checkpoint = zend_arena_checkpoint(CG(arena));
19791856
#if defined(__AVX__) || defined(__SSE2__)
19801857
/* Align to 64-byte boundary */
1981-
mem = zend_arena_alloc(&CG(arena), info.mem_size + info.str_size + 64);
1982-
mem = (void*)(((uintptr_t)mem + 63L) & ~63L);
1858+
zend_file_cache_handle->mem = zend_arena_alloc(&CG(arena), zend_file_cache_handle->info.mem_size + zend_file_cache_handle->info.str_size + 64);
1859+
zend_file_cache_handle->mem = (void*)(((uintptr_t)zend_file_cache_handle->mem + 63L) & ~63L);
19831860
#else
1984-
mem = zend_arena_alloc(&CG(arena), info.mem_size + info.str_size);
1861+
zend_file_cache_handle->mem = zend_arena_alloc(&CG(arena), zend_file_cache_handle->info.mem_size + zend_file_cache_handle->info.str_size);
19851862
#endif
19861863

1987-
if (read(fd, mem, info.mem_size + info.str_size) != (ssize_t)(info.mem_size + info.str_size)) {
1864+
if (read(fd, zend_file_cache_handle->mem, zend_file_cache_handle->info.mem_size + zend_file_cache_handle->info.str_size) != (ssize_t)(zend_file_cache_handle->info.mem_size + zend_file_cache_handle->info.str_size)) {
19881865
zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot read from file '%s' (mem)\n", filename);
1989-
zend_file_cache_flock(fd, LOCK_UN);
1990-
close(fd);
1991-
if (!ZCG(accel_directives).file_cache_read_only) {
1992-
zend_file_cache_unlink(filename);
1993-
}
1994-
zend_arena_release(&CG(arena), checkpoint);
1995-
efree(filename);
1996-
return NULL;
1866+
zend_arena_release(&CG(arena), zend_file_cache_handle->checkpoint);
1867+
goto failure_unlock_close;
19971868
}
19981869
if (zend_file_cache_flock(fd, LOCK_UN) != 0) {
19991870
zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot unlock file '%s'\n", filename);
@@ -2002,13 +1873,56 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl
20021873

20031874
/* verify checksum */
20041875
if (ZCG(accel_directives).file_cache_consistency_checks &&
2005-
(actual_checksum = zend_adler32(ADLER32_INIT, mem, info.mem_size + info.str_size)) != info.checksum) {
2006-
zend_accel_error(ACCEL_LOG_WARNING, "corrupted file '%s' excepted checksum: 0x%08x actual checksum: 0x%08x\n", filename, info.checksum, actual_checksum);
2007-
if (!ZCG(accel_directives).file_cache_read_only) {
2008-
zend_file_cache_unlink(filename);
2009-
}
2010-
zend_arena_release(&CG(arena), checkpoint);
2011-
efree(filename);
1876+
(actual_checksum = zend_adler32(ADLER32_INIT, zend_file_cache_handle->mem, zend_file_cache_handle->info.mem_size + zend_file_cache_handle->info.str_size)) != zend_file_cache_handle->info.checksum) {
1877+
zend_accel_error(ACCEL_LOG_WARNING, "corrupted file '%s' excepted checksum: 0x%08x actual checksum: 0x%08x\n", filename, zend_file_cache_handle->info.checksum, actual_checksum);
1878+
zend_arena_release(&CG(arena), zend_file_cache_handle->checkpoint);
1879+
goto failure;
1880+
}
1881+
1882+
efree(filename);
1883+
return SUCCESS;
1884+
1885+
failure_unlock_close:
1886+
zend_file_cache_flock(fd, LOCK_UN);
1887+
failure_close:
1888+
close(fd);
1889+
failure:
1890+
if (!ZCG(accel_directives).file_cache_read_only) {
1891+
zend_file_cache_unlink(filename);
1892+
}
1893+
efree(filename);
1894+
1895+
return FAILURE;
1896+
}
1897+
1898+
zend_always_inline void zend_file_cache_close(zend_file_cache_handle *cache_handle)
1899+
{
1900+
zend_arena_release(&CG(arena), zend_file_cache_handle->checkpoint);
1901+
}
1902+
1903+
zend_result zend_file_cache_validate(zend_file_handle *file_handle)
1904+
{
1905+
zend_file_cache_handle cache_handle;
1906+
1907+
zend_result ret = zend_file_cache_open(file_handle, &cache_handle);
1908+
1909+
if (res == SUCCESS) {
1910+
zend_file_cache_close(&cache_handle);
1911+
}
1912+
1913+
return ret;
1914+
}
1915+
1916+
zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handle)
1917+
{
1918+
zend_file_cache_handle cache_handle;
1919+
zend_persistent_script *script;
1920+
zend_accel_hash_entry *bucket;
1921+
void *buf;
1922+
bool cache_it = true;
1923+
bool ok;
1924+
1925+
if (zend_file_cache_open(file_handle, &cache_handle) == FAILURE) {
20121926
return NULL;
20131927
}
20141928

@@ -2023,13 +1937,12 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl
20231937
/* Check if we still need to put the file into the cache (may be it was
20241938
* already stored by another process. This final check is done under
20251939
* exclusive lock) */
2026-
bucket = zend_accel_hash_find_entry(&ZCSG(hash), full_path);
1940+
bucket = zend_accel_hash_find_entry(&ZCSG(hash), cache_handle->full_path);
20271941
if (bucket) {
20281942
script = (zend_persistent_script *)bucket->data;
20291943
if (!script->corrupted) {
20301944
zend_shared_alloc_unlock();
2031-
zend_arena_release(&CG(arena), checkpoint);
2032-
efree(filename);
1945+
zend_file_cache_close(&cache_handle);
20331946
return script;
20341947
}
20351948
}
@@ -2042,23 +1955,23 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl
20421955
goto use_process_mem;
20431956
}
20441957

2045-
buf = zend_shared_alloc_aligned(info.mem_size);
1958+
buf = zend_shared_alloc_aligned(cache_handle->info.mem_size);
20461959

20471960
if (!buf) {
20481961
zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_OOM);
20491962
zend_shared_alloc_unlock();
20501963
goto use_process_mem;
20511964
}
2052-
memcpy(buf, mem, info.mem_size);
1965+
memcpy(buf, cache_handle->mem, cache_handle->info.mem_size);
20531966
zend_map_ptr_extend(ZCSG(map_ptr_last));
20541967
} else {
20551968
use_process_mem:
2056-
buf = mem;
1969+
buf = cache_handle->mem;
20571970
cache_it = false;
20581971
}
20591972

2060-
ZCG(mem) = ((char*)mem + info.mem_size);
2061-
script = (zend_persistent_script*)((char*)buf + info.script_offset);
1973+
ZCG(cache_handle->mem) = ((char*)cache_handle->mem + cache_handle->info.mem_size);
1974+
script = (zend_persistent_script*)((char*)buf + cache_handle->info.script_offset);
20621975
script->corrupted = !cache_it; /* used to check if script restored to SHM or process memory */
20631976

20641977
ok = true;
@@ -2072,8 +1985,7 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl
20721985
zend_shared_alloc_unlock();
20731986
goto use_process_mem;
20741987
} else {
2075-
zend_arena_release(&CG(arena), checkpoint);
2076-
efree(filename);
1988+
zend_file_cache_close(&cache_handle);
20771989
return NULL;
20781990
}
20791991
}
@@ -2089,9 +2001,8 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl
20892001
zend_shared_alloc_unlock();
20902002
zend_accel_error(ACCEL_LOG_INFO, "File cached script loaded into memory '%s'", ZSTR_VAL(script->script.filename));
20912003

2092-
zend_arena_release(&CG(arena), checkpoint);
2004+
zend_file_cache_close(&cache_handle);
20932005
}
2094-
efree(filename);
20952006

20962007
return script;
20972008
}

ext/opcache/zend_file_cache.h

+9-1
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,16 @@
1919
#ifndef ZEND_FILE_CACHE_H
2020
#define ZEND_FILE_CACHE_H
2121

22+
typedef struct _zend_file_cache_handle {
23+
zend_string *full_path;
24+
zend_file_cache_metainfo info;
25+
void *mem, *checkpoint;
26+
} zend_file_cache_handle;
27+
2228
int zend_file_cache_script_store(zend_persistent_script *script, bool in_shm);
23-
bool zend_file_cache_script_validate(zend_file_handle *file_handle);
29+
zend_always_inline zend_result zend_file_cache_open(zend_file_handle *file_handle, zend_file_cache_handle *cache_handle);
30+
zend_always_inline void zend_file_cache_close(zend_file_cache_handle *cache_handle);
31+
zend_result zend_file_cache_validate(zend_file_handle *file_handle);
2432
zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handle);
2533
void zend_file_cache_invalidate(zend_string *full_path);
2634

0 commit comments

Comments
 (0)