diff --git a/rpcs3/Emu/Cell/Modules/cellFs.cpp b/rpcs3/Emu/Cell/Modules/cellFs.cpp index 14766ce5fe..d8a3ee6a1b 100644 --- a/rpcs3/Emu/Cell/Modules/cellFs.cpp +++ b/rpcs3/Emu/Cell/Modules/cellFs.cpp @@ -189,7 +189,7 @@ s32 cellFsFGetBlockSize(u32 fd, vm::ptr sector_size, vm::ptr block_siz } // call the syscall - return sys_fs_fget_block_size(fd, sector_size, block_size, vm::var{}, vm::var{}); + return sys_fs_fget_block_size(fd, sector_size, block_size, vm::var{}, vm::var{}); } s32 cellFsFGetBlockSize2() @@ -262,10 +262,10 @@ s32 cellFsGetFreeSize(vm::cptr path, vm::ptr block_size, vm::ptr { cellFs.todo("cellFsGetFreeSize(path=%s, block_size=*0x%x, block_count=*0x%x)", path, block_size, block_count); - // TODO: Get real values. Currently, it always returns 40 GB of free space divided in 4 KB blocks - *block_size = 4096; // ? - *block_count = 10 * 1024 * 1024; // ? - + fs::device_stat info; + fs::statfs(vfs::get(path.get_ptr()), info); + *block_size = 4096; + *block_count = info.avail_free / 4096; return CELL_OK; } diff --git a/rpcs3/Emu/Cell/lv2/sys_fs.cpp b/rpcs3/Emu/Cell/lv2/sys_fs.cpp index e93daf0931..796b76fd11 100644 --- a/rpcs3/Emu/Cell/lv2/sys_fs.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_fs.cpp @@ -718,6 +718,22 @@ error_code sys_fs_fcntl(u32 fd, u32 op, vm::ptr _arg, u32 _size) return CELL_EMFILE; } + case 0xc0000002: // cellFsGetFreeSize (TODO) + { + const auto arg = vm::static_ptr_cast(_arg); + + fs::device_stat info; + if (!fs::statfs(vfs::get(arg->path.get_ptr()), info)) + { + return CELL_EIO; // ??? + } + + arg->out_code = CELL_OK; + arg->out_block_size = 4096; + arg->out_block_count = info.avail_free / 4096; + return CELL_OK; + } + case 0xc0000006: // Unknown { const auto arg = vm::static_ptr_cast(_arg); @@ -850,7 +866,7 @@ error_code sys_fs_fsync(u32 fd) return CELL_OK; } -error_code sys_fs_fget_block_size(u32 fd, vm::ptr sector_size, vm::ptr block_size, vm::ptr arg4, vm::ptr arg5) +error_code sys_fs_fget_block_size(u32 fd, vm::ptr sector_size, vm::ptr block_size, vm::ptr arg4, vm::ptr arg5) { sys_fs.todo("sys_fs_fget_block_size(fd=%d, sector_size=*0x%x, block_size=*0x%x, arg4=*0x%x, arg5=*0x%x)", fd, sector_size, block_size, arg4, arg5); @@ -863,6 +879,8 @@ error_code sys_fs_fget_block_size(u32 fd, vm::ptr sector_size, vm::ptr *sector_size = 4096; // ? *block_size = 4096; // ? + *arg4 = 0; + *arg5 = 0; // Probably file->mode return CELL_OK; } @@ -873,6 +891,7 @@ error_code sys_fs_get_block_size(vm::cptr path, vm::ptr sector_size, *sector_size = 4096; // ? *block_size = 4096; // ? + *arg4 = 0; return CELL_OK; } diff --git a/rpcs3/Emu/Cell/lv2/sys_fs.h b/rpcs3/Emu/Cell/lv2/sys_fs.h index 0f4114e2df..3184cc54a4 100644 --- a/rpcs3/Emu/Cell/lv2/sys_fs.h +++ b/rpcs3/Emu/Cell/lv2/sys_fs.h @@ -292,6 +292,24 @@ struct lv2_file_op_dir : lv2_file_op CHECK_SIZE(lv2_file_op_dir, 0x1c); +// sys_fs_fcntl: cellFsGetFreeSize (for dev_hdd0) +struct lv2_file_c0000002 : lv2_file_op +{ + vm::bptrb _vtable; + + be_t op; + be_t _x8; + vm::ps3::bcptr path; + be_t _x10; // 0 + be_t _x14; + + be_t out_code; // CELL_ENOSYS + be_t out_block_size; + be_t out_block_count; +}; + +CHECK_SIZE(lv2_file_c0000002, 0x28); + // sys_fs_fnctl: unknown (called before cellFsOpen, for example) struct lv2_file_c0000006 : lv2_file_op { @@ -327,7 +345,7 @@ error_code sys_fs_fcntl(u32 fd, u32 op, vm::ps3::ptr arg, u32 size); error_code sys_fs_lseek(u32 fd, s64 offset, s32 whence, vm::ps3::ptr pos); error_code sys_fs_fdatasync(u32 fd); error_code sys_fs_fsync(u32 fd); -error_code sys_fs_fget_block_size(u32 fd, vm::ps3::ptr sector_size, vm::ps3::ptr block_size, vm::ps3::ptr arg4, vm::ps3::ptr arg5); +error_code sys_fs_fget_block_size(u32 fd, vm::ps3::ptr sector_size, vm::ps3::ptr block_size, vm::ps3::ptr arg4, vm::ps3::ptr arg5); error_code sys_fs_get_block_size(vm::ps3::cptr path, vm::ps3::ptr sector_size, vm::ps3::ptr block_size, vm::ps3::ptr arg4); error_code sys_fs_truncate(vm::ps3::cptr path, u64 size); error_code sys_fs_ftruncate(u32 fd, u64 size);