mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-30 12:32:43 +00:00
Make gamedata installation atomic as real PS3
This commit is contained in:
parent
a9b0d25c01
commit
d7b4753007
@ -907,19 +907,16 @@ struct fs_aio_thread : ppu_thread
|
||||
const auto func = cmd2.arg2<fs_aio_cb_t>();
|
||||
cmd_pop(1);
|
||||
|
||||
s32 error = CELL_OK;
|
||||
s32 error = CELL_EBADF;
|
||||
u64 result = 0;
|
||||
|
||||
const auto file = idm::get<lv2_fs_object, lv2_file>(aio->fd);
|
||||
|
||||
if (!file || (type == 1 && file->flags & CELL_FS_O_WRONLY) || (type == 2 && !(file->flags & CELL_FS_O_ACCMODE)))
|
||||
{
|
||||
error = CELL_EBADF;
|
||||
}
|
||||
else
|
||||
else if (std::lock_guard lock(file->mp->mutex); file->file)
|
||||
{
|
||||
std::lock_guard lock(file->mp->mutex);
|
||||
|
||||
const auto old_pos = file->file.pos(); file->file.seek(aio->offset);
|
||||
|
||||
result = type == 2
|
||||
@ -927,6 +924,7 @@ struct fs_aio_thread : ppu_thread
|
||||
: file->op_read(aio->buf, aio->size);
|
||||
|
||||
file->file.seek(old_pos);
|
||||
error = CELL_OK;
|
||||
}
|
||||
|
||||
func(*this, aio, error, xid, result);
|
||||
|
@ -81,7 +81,7 @@ struct syscache_info
|
||||
{
|
||||
idm::select<lv2_fs_object, lv2_file>([](u32 /*id*/, lv2_file& file)
|
||||
{
|
||||
if (std::memcmp("/dev_hdd1", file.name.data(), 9) == 0)
|
||||
if (file.file && std::memcmp("/dev_hdd1/", file.name.data(), 10) == 0)
|
||||
{
|
||||
file.lock = 2;
|
||||
}
|
||||
|
@ -603,6 +603,11 @@ error_code sys_fs_read(ppu_thread& ppu, u32 fd, vm::ptr<void> buf, u64 nbytes, v
|
||||
|
||||
std::lock_guard lock(file->mp->mutex);
|
||||
|
||||
if (!file->file)
|
||||
{
|
||||
return CELL_EBADF;
|
||||
}
|
||||
|
||||
if (file->lock == 2)
|
||||
{
|
||||
nread.try_write(0);
|
||||
@ -648,6 +653,11 @@ error_code sys_fs_write(ppu_thread& ppu, u32 fd, vm::cptr<void> buf, u64 nbytes,
|
||||
|
||||
std::lock_guard lock(file->mp->mutex);
|
||||
|
||||
if (!file->file)
|
||||
{
|
||||
return CELL_EBADF;
|
||||
}
|
||||
|
||||
if (file->lock)
|
||||
{
|
||||
if (file->lock == 2)
|
||||
@ -677,15 +687,49 @@ error_code sys_fs_close(ppu_thread& ppu, u32 fd)
|
||||
|
||||
sys_fs.trace("sys_fs_close(fd=%d)", fd);
|
||||
|
||||
const auto file = idm::withdraw<lv2_fs_object, lv2_file>(fd, [](lv2_file& file)
|
||||
const auto file = idm::get<lv2_fs_object, lv2_file>(fd);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
if (file.type >= lv2_file_type::sdata)
|
||||
return CELL_EBADF;
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard lock(file->mp->mutex);
|
||||
|
||||
if (!file->file)
|
||||
{
|
||||
return CELL_EBADF;
|
||||
}
|
||||
|
||||
if (std::memcmp(file->name.data(), "/dev_hdd1/", 10) != 0
|
||||
&& !(file->mp->flags & lv2_mp_flag::read_only) && file->flags & CELL_FS_O_ACCMODE)
|
||||
{
|
||||
// Special: Ensure temporary directory for gamedata writes will remain on disk before final gamedata commitment
|
||||
file->file.sync(); // For cellGameContentPermit atomicity
|
||||
}
|
||||
|
||||
// Ensure Host file handle won't be kept open after this syscall
|
||||
file->file.close();
|
||||
}
|
||||
|
||||
const auto ret = idm::withdraw<lv2_fs_object, lv2_file>(fd, [&](lv2_file& _file) -> CellError
|
||||
{
|
||||
if (file.get() != std::addressof(_file))
|
||||
{
|
||||
// Other thread destroyed the object inbetween
|
||||
return CELL_EBADF;
|
||||
}
|
||||
|
||||
if (_file.type >= lv2_file_type::sdata)
|
||||
{
|
||||
g_fxo->get<loaded_npdrm_keys>().npdrm_fds--;
|
||||
}
|
||||
|
||||
return {};
|
||||
});
|
||||
|
||||
if (!file)
|
||||
if (!ret || ret.ret == CELL_EBADF)
|
||||
{
|
||||
return CELL_EBADF;
|
||||
}
|
||||
@ -980,6 +1024,11 @@ error_code sys_fs_fstat(ppu_thread& ppu, u32 fd, vm::ptr<CellFsStat> sb)
|
||||
|
||||
std::lock_guard lock(file->mp->mutex);
|
||||
|
||||
if (!file->file)
|
||||
{
|
||||
return CELL_EBADF;
|
||||
}
|
||||
|
||||
if (file->lock == 2)
|
||||
{
|
||||
return CELL_EIO;
|
||||
@ -1296,6 +1345,11 @@ error_code sys_fs_fcntl(ppu_thread& ppu, u32 fd, u32 op, vm::ptr<void> _arg, u32
|
||||
|
||||
std::lock_guard lock(file->mp->mutex);
|
||||
|
||||
if (!file->file)
|
||||
{
|
||||
return CELL_EBADF;
|
||||
}
|
||||
|
||||
if (file->lock == 2)
|
||||
{
|
||||
return CELL_EIO;
|
||||
@ -1339,6 +1393,11 @@ error_code sys_fs_fcntl(ppu_thread& ppu, u32 fd, u32 op, vm::ptr<void> _arg, u32
|
||||
|
||||
std::lock_guard lock(file->mp->mutex);
|
||||
|
||||
if (!file->file)
|
||||
{
|
||||
return CELL_EBADF;
|
||||
}
|
||||
|
||||
auto sdata_file = std::make_unique<EDATADecrypter>(lv2_file::make_view(file, arg->offset));
|
||||
|
||||
if (!sdata_file->ReadHeader())
|
||||
@ -1668,13 +1727,18 @@ error_code sys_fs_lseek(ppu_thread& ppu, u32 fd, s64 offset, s32 whence, vm::ptr
|
||||
return CELL_EBADF;
|
||||
}
|
||||
|
||||
std::lock_guard lock(file->mp->mutex);
|
||||
|
||||
if (!file->file)
|
||||
{
|
||||
return CELL_EBADF;
|
||||
}
|
||||
|
||||
if (whence + 0u >= 3)
|
||||
{
|
||||
return {CELL_EINVAL, whence};
|
||||
}
|
||||
|
||||
std::lock_guard lock(file->mp->mutex);
|
||||
|
||||
const u64 result = file->file.seek(offset, static_cast<fs::seek_mode>(whence));
|
||||
|
||||
if (result == umax)
|
||||
@ -1707,6 +1771,12 @@ error_code sys_fs_fdatasync(ppu_thread& ppu, u32 fd)
|
||||
}
|
||||
|
||||
std::lock_guard lock(file->mp->mutex);
|
||||
|
||||
if (!file->file)
|
||||
{
|
||||
return CELL_EBADF;
|
||||
}
|
||||
|
||||
file->file.sync();
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -1726,6 +1796,12 @@ error_code sys_fs_fsync(ppu_thread& ppu, u32 fd)
|
||||
}
|
||||
|
||||
std::lock_guard lock(file->mp->mutex);
|
||||
|
||||
if (!file->file)
|
||||
{
|
||||
return CELL_EBADF;
|
||||
}
|
||||
|
||||
file->file.sync();
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -1880,6 +1956,11 @@ error_code sys_fs_ftruncate(ppu_thread& ppu, u32 fd, u64 size)
|
||||
|
||||
std::lock_guard lock(file->mp->mutex);
|
||||
|
||||
if (!file->file)
|
||||
{
|
||||
return CELL_EBADF;
|
||||
}
|
||||
|
||||
if (file->lock == 2)
|
||||
{
|
||||
return CELL_EIO;
|
||||
|
@ -101,6 +101,13 @@ error_code sys_overlay_load_module_by_fd(vm::ptr<u32> ovlmid, u32 fd, u64 offset
|
||||
return CELL_EBADF;
|
||||
}
|
||||
|
||||
std::lock_guard lock(file->mp->mutex);
|
||||
|
||||
if (!file->file)
|
||||
{
|
||||
return CELL_EBADF;
|
||||
}
|
||||
|
||||
return overlay_load_module(ovlmid, fmt::format("%s_x%x", file->name.data(), offset), flags, entry, lv2_file::make_view(file, offset));
|
||||
}
|
||||
|
||||
|
@ -311,6 +311,13 @@ error_code _sys_prx_load_module_by_fd(ppu_thread& ppu, s32 fd, u64 offset, u64 f
|
||||
return CELL_EBADF;
|
||||
}
|
||||
|
||||
std::lock_guard lock(file->mp->mutex);
|
||||
|
||||
if (!file->file)
|
||||
{
|
||||
return CELL_EBADF;
|
||||
}
|
||||
|
||||
return prx_load_module(fmt::format("%s_x%x", file->name.data(), offset), flags, pOpt, lv2_file::make_view(file, offset));
|
||||
}
|
||||
|
||||
|
@ -749,7 +749,21 @@ bool vfs::host::rename(const std::string& from, const std::string& to, const lv2
|
||||
if (check_path(fs::escape_path(file.real_path)))
|
||||
{
|
||||
ensure(file.mp == mp);
|
||||
|
||||
if (!file.file)
|
||||
{
|
||||
file.restore_data.seek_pos = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
file.restore_data.seek_pos = file.file.pos();
|
||||
|
||||
if (std::memcmp(file.name.data(), "/dev_hdd1/", 10) != 0
|
||||
&& !(file.mp->flags & lv2_mp_flag::read_only) && file.flags & CELL_FS_O_ACCMODE)
|
||||
{
|
||||
file.file.sync(); // For cellGameContentPermit atomicity
|
||||
}
|
||||
|
||||
file.file.close(); // Actually close it!
|
||||
}
|
||||
});
|
||||
@ -779,6 +793,11 @@ bool vfs::host::rename(const std::string& from, const std::string& to, const lv2
|
||||
|
||||
if (check_path(escaped_real))
|
||||
{
|
||||
if (file.restore_data.seek_pos == umax)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Update internal path
|
||||
if (res)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user