mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-15 18:40:00 +00:00
fixup hdd1 cache
This commit is contained in:
parent
9c354ee269
commit
e4c9af176b
@ -51,10 +51,15 @@ struct syscache_info
|
||||
const auto lock = init.init();
|
||||
|
||||
// Extract cache id from path
|
||||
cache_id = Emu.hdd1;
|
||||
if (cache_id.back() == '/')
|
||||
cache_id.resize(cache_id.size() - 1);
|
||||
cache_id = cache_id.substr(cache_id.find_last_of('/') + 1);
|
||||
std::string_view id = Emu.hdd1;
|
||||
id = id.substr(0, id.find_last_not_of(fs::delim) + 1);
|
||||
id = id.substr(id.find_last_of(fs::delim) + 1);
|
||||
cache_id = std::string{id};
|
||||
|
||||
if (!Emu.DeserialManager() && !fs::write_file<true>(get_syscache_state_corruption_indicator_file_path(Emu.hdd1), fs::write_new))
|
||||
{
|
||||
fmt::throw_exception("Failed to create HDD1 corruption indicator file! (path='%s', reason='%s')", Emu.hdd1, fs::g_tls_error);
|
||||
}
|
||||
|
||||
cellSysutil.success("Retained cache from parent process: %s", Emu.hdd1);
|
||||
return;
|
||||
@ -67,13 +72,17 @@ struct syscache_info
|
||||
{
|
||||
if (entry.is_directory && entry.name.starts_with(prefix))
|
||||
{
|
||||
if (fs::is_file(get_syscache_state_corruption_indicator_file_path(cache_root + '/' + entry.name)))
|
||||
cache_id = vfs::unescape(entry.name);
|
||||
|
||||
if (fs::is_file(get_syscache_state_corruption_indicator_file_path(cache_root + '/' + cache_id)))
|
||||
{
|
||||
// State is not complete
|
||||
break;
|
||||
clear(true);
|
||||
cache_id.clear();
|
||||
continue;
|
||||
}
|
||||
|
||||
cache_id = std::move(entry.name);
|
||||
cellSysutil.notice("Retained cache from past data: %s", cache_root + '/' + cache_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -172,13 +181,22 @@ error_code cellSysCacheMount(vm::ptr<CellSysCacheParam> param)
|
||||
|
||||
auto& cache = g_fxo->get<syscache_info>();
|
||||
|
||||
if (!param || (param->cacheId[0] && sysutil_check_name_string(param->cacheId, 1, CELL_SYSCACHE_ID_SIZE) != 0))
|
||||
if (!param)
|
||||
{
|
||||
return CELL_SYSCACHE_ERROR_PARAM;
|
||||
}
|
||||
|
||||
std::string cache_name;
|
||||
|
||||
ensure(vm::read_string(param.ptr(&CellSysCacheParam::cacheId).addr(), sizeof(param->cacheId), cache_name), "Access violation");
|
||||
|
||||
if (!cache_name.empty() && sysutil_check_name_string(cache_name.data(), 1, CELL_SYSCACHE_ID_SIZE) != 0)
|
||||
{
|
||||
return CELL_SYSCACHE_ERROR_PARAM;
|
||||
}
|
||||
|
||||
// Full virtualized cache id (with title id included)
|
||||
std::string cache_id = vfs::escape(Emu.GetTitleID() + '_' + param->cacheId);
|
||||
std::string cache_id = vfs::escape(Emu.GetTitleID() + '_' + cache_name);
|
||||
|
||||
// Full path to virtual cache root (/dev_hdd1)
|
||||
std::string new_path = cache.cache_root + cache_id + '/';
|
||||
@ -194,7 +212,7 @@ error_code cellSysCacheMount(vm::ptr<CellSysCacheParam> param)
|
||||
std::lock_guard lock0(g_mp_sys_dev_hdd1.mutex);
|
||||
|
||||
// Check if can reuse existing cache (won't if cache id is an empty string or cache is damaged/incomplete)
|
||||
if (param->cacheId[0] && cache_id == cache.cache_id && !fs::is_file(get_syscache_state_corruption_indicator_file_path(cache.cache_root + cache_id)))
|
||||
if (!cache_name.empty() && cache_id == cache.cache_id)
|
||||
{
|
||||
// Isn't mounted yet on first call to cellSysCacheMount
|
||||
if (vfs::mount("/dev_hdd1", new_path))
|
||||
@ -204,7 +222,7 @@ error_code cellSysCacheMount(vm::ptr<CellSysCacheParam> param)
|
||||
return not_an_error(CELL_SYSCACHE_RET_OK_RELAYED);
|
||||
}
|
||||
|
||||
const bool can_create = cache.cache_id != cache_id;
|
||||
const bool can_create = cache.cache_id != cache_id || !cache.cache_id.empty();
|
||||
|
||||
if (!cache.cache_id.empty())
|
||||
{
|
||||
@ -231,6 +249,11 @@ error_code cellSysCacheMount(vm::ptr<CellSysCacheParam> param)
|
||||
}
|
||||
}
|
||||
|
||||
if (!fs::write_file<true>(get_syscache_state_corruption_indicator_file_path(new_path), fs::write_new))
|
||||
{
|
||||
fmt::throw_exception("Failed to create HDD1 corruption indicator file! (path='%s', reason='%s')", new_path, fs::g_tls_error);
|
||||
}
|
||||
|
||||
if (vfs::mount("/dev_hdd1", new_path))
|
||||
g_fxo->get<lv2_fs_mount_info_map>().add("/dev_hdd1", &g_mp_sys_dev_hdd1);
|
||||
|
||||
|
@ -91,6 +91,8 @@ extern void signal_system_cache_can_stay();
|
||||
|
||||
fs::file make_file_view(const fs::file& file, u64 offset, u64 size);
|
||||
|
||||
extern std::string get_syscache_state_corruption_indicator_file_path(std::string_view dir_path);
|
||||
|
||||
fs::file g_tty;
|
||||
atomic_t<s64> g_tty_size{0};
|
||||
std::array<std::deque<std::string>, 16> g_tty_input;
|
||||
@ -1103,7 +1105,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch,
|
||||
}
|
||||
}
|
||||
|
||||
auto load_tar = [&](const std::string& path)
|
||||
auto load_tar = [&](const std::string& path, const std::string& special_file)
|
||||
{
|
||||
const usz size = m_ar->pop<usz>();
|
||||
const usz max_data_size = m_ar->get_size(utils::add_saturate<usz>(size, m_ar->pos));
|
||||
@ -1115,6 +1117,11 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch,
|
||||
|
||||
fs::remove_all(path, size == 0);
|
||||
|
||||
if (!special_file.empty())
|
||||
{
|
||||
fs::write_file<true>(special_file, fs::write_new);
|
||||
}
|
||||
|
||||
if (size)
|
||||
{
|
||||
m_ar->breathe(true);
|
||||
@ -1134,7 +1141,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch,
|
||||
if (!hdd1.empty())
|
||||
{
|
||||
hdd1 = rpcs3::utils::get_hdd1_dir() + "caches/" + hdd1 + "/";
|
||||
load_tar(hdd1);
|
||||
load_tar(hdd1, get_syscache_state_corruption_indicator_file_path(hdd1));
|
||||
}
|
||||
|
||||
for (const std::string hdd0_game = rpcs3::utils::get_hdd0_dir() + "game/";;)
|
||||
@ -1152,7 +1159,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch,
|
||||
fmt::throw_exception("HDD0 deserialization failed: Invalid directory name: %s, ar=%s", dirname.substr(0, CELL_GAME_DIRNAME_SIZE + 1), *m_ar);
|
||||
}
|
||||
|
||||
load_tar(hdd0_game + game_data);
|
||||
load_tar(hdd0_game + game_data, "");
|
||||
}
|
||||
|
||||
// Reserved area
|
||||
|
@ -232,6 +232,9 @@ bool tar_object::extract(std::string prefix_path, bool is_vfs)
|
||||
const TARHeader& header = iter->second.second;
|
||||
const std::string& name = iter->first;
|
||||
|
||||
// Backwards compatibility measure
|
||||
const bool should_ignore = name.find(reinterpret_cast<const char*>(u8"$")) != umax;
|
||||
|
||||
std::string result = name;
|
||||
|
||||
if (!prefix_path.empty())
|
||||
@ -291,7 +294,16 @@ bool tar_object::extract(std::string prefix_path, bool is_vfs)
|
||||
|
||||
std::unique_ptr<utils::serial> file_data = get_file(name);
|
||||
|
||||
fs::file file(result, fs::rewrite);
|
||||
fs::file file;
|
||||
|
||||
if (should_ignore)
|
||||
{
|
||||
file = fs::make_stream<std::vector<u8>>();
|
||||
}
|
||||
else
|
||||
{
|
||||
file.open(result, fs::rewrite);
|
||||
}
|
||||
|
||||
if (file && file_data)
|
||||
{
|
||||
@ -301,7 +313,7 @@ bool tar_object::extract(std::string prefix_path, bool is_vfs)
|
||||
|
||||
if (unread_size == 0)
|
||||
{
|
||||
file.write(filedata_span.data(), filedata_span.size());
|
||||
file.write(filedata_span.data(), should_ignore ? 0 : filedata_span.size());
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -310,7 +322,7 @@ bool tar_object::extract(std::string prefix_path, bool is_vfs)
|
||||
if (usz read_size = filedata_span.size() - unread_size)
|
||||
{
|
||||
ensure(file_data->try_read(filedata_span.first(read_size)) == 0);
|
||||
file.write(filedata_span.data(), read_size);
|
||||
file.write(filedata_span.data(), should_ignore ? 0 : read_size);
|
||||
}
|
||||
|
||||
break;
|
||||
@ -318,6 +330,7 @@ bool tar_object::extract(std::string prefix_path, bool is_vfs)
|
||||
|
||||
file.close();
|
||||
|
||||
|
||||
file_data->seek_pos(m_ar_tar_start + largest_offset, true);
|
||||
|
||||
if (!m_file)
|
||||
@ -327,6 +340,11 @@ bool tar_object::extract(std::string prefix_path, bool is_vfs)
|
||||
m_ar->m_max_data = restore_limit;
|
||||
}
|
||||
|
||||
if (should_ignore)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (mtime != umax && !fs::utime(result, atime, mtime))
|
||||
{
|
||||
tar_log.error("TAR Loader: fs::utime failed on %s (%s)", result, fs::g_tls_error);
|
||||
@ -351,6 +369,11 @@ bool tar_object::extract(std::string prefix_path, bool is_vfs)
|
||||
|
||||
case '5':
|
||||
{
|
||||
if (should_ignore)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (!fs::create_path(result))
|
||||
{
|
||||
tar_log.error("TAR Loader: failed to create directory %s (%s)", name, fs::g_tls_error);
|
||||
@ -576,7 +599,7 @@ void tar_object::save_directory(const std::string& target_path, utils::serial& a
|
||||
{
|
||||
exists = true;
|
||||
|
||||
if (entry.name.find_first_not_of('.') == umax)
|
||||
if (entry.name.find_first_not_of('.') == umax || entry.name.starts_with(reinterpret_cast<const char*>(u8"$")))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user