From 8a3a2bf058973e01ab332bf58e1173927f4f38f8 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 19 Aug 2020 18:34:02 -0700 Subject: [PATCH] VFS: Change semantics of VFile.sync on mapped files (fixes #1730) --- CHANGES | 1 + include/mgba-util/vfs.h | 2 +- src/platform/3ds/3ds-vfs.c | 8 +++----- src/platform/psp2/sce-vfs.c | 9 +++++---- src/platform/python/mgba/vfs.py | 3 ++- src/platform/python/vfs-py.h | 2 +- src/util/vfs/vfs-fd.c | 8 ++++---- src/util/vfs/vfs-fifo.c | 4 ++-- src/util/vfs/vfs-file.c | 7 ++++--- src/util/vfs/vfs-lzma.c | 4 ++-- src/util/vfs/vfs-mem.c | 4 ++-- src/util/vfs/vfs-zip.c | 6 +++--- 12 files changed, 30 insertions(+), 28 deletions(-) diff --git a/CHANGES b/CHANGES index 71f5f4fa8..bf28a6b04 100644 --- a/CHANGES +++ b/CHANGES @@ -70,6 +70,7 @@ Misc: - Qt: Add transformation matrix info to sprite view - Qt: Memory viewer now supports editing decimal values directly (closes mgba.io/i/1705) - Util: Reset vector size on deinit + - VFS: Change semantics of VFile.sync on mapped files (fixes mgba.io/i/1730) 0.8.3: (2020-08-03) Emulation fixes: diff --git a/include/mgba-util/vfs.h b/include/mgba-util/vfs.h index 0ac676d5f..8100541e0 100644 --- a/include/mgba-util/vfs.h +++ b/include/mgba-util/vfs.h @@ -47,7 +47,7 @@ struct VFile { void (*unmap)(struct VFile* vf, void* memory, size_t size); void (*truncate)(struct VFile* vf, size_t size); ssize_t (*size)(struct VFile* vf); - bool (*sync)(struct VFile* vf, const void* buffer, size_t size); + bool (*sync)(struct VFile* vf, void* buffer, size_t size); }; struct VDirEntry { diff --git a/src/platform/3ds/3ds-vfs.c b/src/platform/3ds/3ds-vfs.c index 8f5864745..508b9fac3 100644 --- a/src/platform/3ds/3ds-vfs.c +++ b/src/platform/3ds/3ds-vfs.c @@ -38,7 +38,7 @@ static void* _vf3dMap(struct VFile* vf, size_t size, int flags); static void _vf3dUnmap(struct VFile* vf, void* memory, size_t size); static void _vf3dTruncate(struct VFile* vf, size_t size); static ssize_t _vf3dSize(struct VFile* vf); -static bool _vf3dSync(struct VFile* vf, const void* buffer, size_t size); +static bool _vf3dSync(struct VFile* vf, void* buffer, size_t size); static bool _vd3dClose(struct VDir* vd); static void _vd3dRewind(struct VDir* vd); @@ -160,14 +160,12 @@ ssize_t _vf3dSize(struct VFile* vf) { return size; } -static bool _vf3dSync(struct VFile* vf, const void* buffer, size_t size) { +static bool _vf3dSync(struct VFile* vf, void* buffer, size_t size) { struct VFile3DS* vf3d = (struct VFile3DS*) vf; if (buffer) { u32 sizeWritten; Result res = FSFILE_Write(vf3d->handle, &sizeWritten, 0, buffer, size, FS_WRITE_FLUSH); - if (res) { - return false; - } + return R_SUCCEEDED(res); } FSFILE_Flush(vf3d->handle); return true; diff --git a/src/platform/psp2/sce-vfs.c b/src/platform/psp2/sce-vfs.c index c200d8903..22b05950f 100644 --- a/src/platform/psp2/sce-vfs.c +++ b/src/platform/psp2/sce-vfs.c @@ -40,7 +40,7 @@ static void* _vfsceMap(struct VFile* vf, size_t size, int flags); static void _vfsceUnmap(struct VFile* vf, void* memory, size_t size); static void _vfsceTruncate(struct VFile* vf, size_t size); static ssize_t _vfsceSize(struct VFile* vf); -static bool _vfsceSync(struct VFile* vf, const void* memory, size_t size); +static bool _vfsceSync(struct VFile* vf, void* memory, size_t size); static bool _vdsceClose(struct VDir* vd); static void _vdsceRewind(struct VDir* vd); @@ -146,13 +146,14 @@ ssize_t _vfsceSize(struct VFile* vf) { return end; } -bool _vfsceSync(struct VFile* vf, const void* buffer, size_t size) { +bool _vfsceSync(struct VFile* vf, void* buffer, size_t size) { struct VFileSce* vfsce = (struct VFileSce*) vf; if (buffer && size) { SceOff cur = sceIoLseek(vfsce->fd, 0, SEEK_CUR); sceIoLseek(vfsce->fd, 0, SEEK_SET); - sceIoWrite(vfsce->fd, buffer, size); + int res = sceIoWrite(vfsce->fd, buffer, size); sceIoLseek(vfsce->fd, cur, SEEK_SET); + return res == size; } return sceIoSyncByFd(vfsce->fd) >= 0; } @@ -362,4 +363,4 @@ bool VDirCreate(const char* path) { // TODO: Verify vitasdk explanation of return values sceIoMkdir(path, 0777); return true; -} \ No newline at end of file +} diff --git a/src/platform/python/mgba/vfs.py b/src/platform/python/mgba/vfs.py index bab78c799..80c7a658b 100644 --- a/src/platform/python/mgba/vfs.py +++ b/src/platform/python/mgba/vfs.py @@ -73,8 +73,9 @@ def _vfpSync(vf, buffer, size): if buffer and size: pos = f.tell() f.seek(0, os.SEEK_SET) - _vfpWrite(vf, buffer, size) + res = _vfpWrite(vf, buffer, size) f.seek(pos, os.SEEK_SET) + return res == size f.flush() os.fsync() return True diff --git a/src/platform/python/vfs-py.h b/src/platform/python/vfs-py.h index 2f913a741..377474a8a 100644 --- a/src/platform/python/vfs-py.h +++ b/src/platform/python/vfs-py.h @@ -22,4 +22,4 @@ PYEXPORT void* _vfpMap(struct VFile* vf, size_t size, int flags); PYEXPORT void _vfpUnmap(struct VFile* vf, void* memory, size_t size); PYEXPORT void _vfpTruncate(struct VFile* vf, size_t size); PYEXPORT ssize_t _vfpSize(struct VFile* vf); -PYEXPORT bool _vfpSync(struct VFile* vf, const void* buffer, size_t size); +PYEXPORT bool _vfpSync(struct VFile* vf, void* buffer, size_t size); diff --git a/src/util/vfs/vfs-fd.c b/src/util/vfs/vfs-fd.c index 8460a0253..c15ab5ca1 100644 --- a/src/util/vfs/vfs-fd.c +++ b/src/util/vfs/vfs-fd.c @@ -42,7 +42,7 @@ static void* _vfdMap(struct VFile* vf, size_t size, int flags); static void _vfdUnmap(struct VFile* vf, void* memory, size_t size); static void _vfdTruncate(struct VFile* vf, size_t size); static ssize_t _vfdSize(struct VFile* vf); -static bool _vfdSync(struct VFile* vf, const void* buffer, size_t size); +static bool _vfdSync(struct VFile* vf, void* buffer, size_t size); struct VFile* VFileOpenFD(const char* path, int flags) { if (!path) { @@ -195,7 +195,7 @@ static ssize_t _vfdSize(struct VFile* vf) { return stat.st_size; } -static bool _vfdSync(struct VFile* vf, const void* buffer, size_t size) { +static bool _vfdSync(struct VFile* vf, void* buffer, size_t size) { UNUSED(buffer); UNUSED(size); struct VFileFD* vfd = (struct VFileFD*) vf; @@ -206,7 +206,7 @@ static bool _vfdSync(struct VFile* vf, const void* buffer, size_t size) { futimes(vfd->fd, NULL); #endif if (buffer && size) { - return msync(buffer, size, MS_SYNC) == 0; + return msync(buffer, size, MS_ASYNC) == 0; } return fsync(vfd->fd) == 0; #else @@ -217,7 +217,7 @@ static bool _vfdSync(struct VFile* vf, const void* buffer, size_t size) { SystemTimeToFileTime(&st, &ft); SetFileTime(h, NULL, &ft, &ft); if (buffer && size) { - FlushViewOfFile(buffer, size); + return FlushViewOfFile(buffer, size); } return FlushFileBuffers(h); #endif diff --git a/src/util/vfs/vfs-fifo.c b/src/util/vfs/vfs-fifo.c index efff7bdab..5b6af5760 100644 --- a/src/util/vfs/vfs-fifo.c +++ b/src/util/vfs/vfs-fifo.c @@ -19,7 +19,7 @@ static void* _vffMap(struct VFile* vf, size_t size, int flags); static void _vffUnmap(struct VFile* vf, void* memory, size_t size); static void _vffTruncate(struct VFile* vf, size_t size); static ssize_t _vffSize(struct VFile* vf); -static bool _vffSync(struct VFile* vf, const void* buffer, size_t size); +static bool _vffSync(struct VFile* vf, void* buffer, size_t size); struct VFile* VFileFIFO(struct CircleBuffer* backing) { if (!backing) { @@ -94,7 +94,7 @@ static ssize_t _vffSize(struct VFile* vf) { return CircleBufferSize(vff->backing); } -static bool _vffSync(struct VFile* vf, const void* buffer, size_t size) { +static bool _vffSync(struct VFile* vf, void* buffer, size_t size) { UNUSED(vf); UNUSED(buffer); UNUSED(size); diff --git a/src/util/vfs/vfs-file.c b/src/util/vfs/vfs-file.c index bfde30e93..d3adc3177 100644 --- a/src/util/vfs/vfs-file.c +++ b/src/util/vfs/vfs-file.c @@ -24,7 +24,7 @@ static void* _vffMap(struct VFile* vf, size_t size, int flags); static void _vffUnmap(struct VFile* vf, void* memory, size_t size); static void _vffTruncate(struct VFile* vf, size_t size); static ssize_t _vffSize(struct VFile* vf); -static bool _vffSync(struct VFile* vf, const void* buffer, size_t size); +static bool _vffSync(struct VFile* vf, void* buffer, size_t size); struct VFile* VFileFOpen(const char* path, const char* mode) { if (!path && !mode) { @@ -144,13 +144,14 @@ static ssize_t _vffSize(struct VFile* vf) { return size; } -static bool _vffSync(struct VFile* vf, const void* buffer, size_t size) { +static bool _vffSync(struct VFile* vf, void* buffer, size_t size) { struct VFileFILE* vff = (struct VFileFILE*) vf; if (buffer && size) { long pos = ftell(vff->file); fseek(vff->file, 0, SEEK_SET); - fwrite(buffer, size, 1, vff->file); + size_t res = fwrite(buffer, size, 1, vff->file); fseek(vff->file, pos, SEEK_SET); + return res == 1; } return fflush(vff->file) == 0; } diff --git a/src/util/vfs/vfs-lzma.c b/src/util/vfs/vfs-lzma.c index a1c259ee4..a094c187a 100644 --- a/src/util/vfs/vfs-lzma.c +++ b/src/util/vfs/vfs-lzma.c @@ -58,7 +58,7 @@ static void* _vf7zMap(struct VFile* vf, size_t size, int flags); static void _vf7zUnmap(struct VFile* vf, void* memory, size_t size); static void _vf7zTruncate(struct VFile* vf, size_t size); static ssize_t _vf7zSize(struct VFile* vf); -static bool _vf7zSync(struct VFile* vf, const void* buffer, size_t size); +static bool _vf7zSync(struct VFile* vf, void* buffer, size_t size); static bool _vd7zClose(struct VDir* vd); static void _vd7zRewind(struct VDir* vd); @@ -327,7 +327,7 @@ bool _vd7zDeleteFile(struct VDir* vd, const char* path) { return false; } -bool _vf7zSync(struct VFile* vf, const void* memory, size_t size) { +bool _vf7zSync(struct VFile* vf, void* memory, size_t size) { UNUSED(vf); UNUSED(memory); UNUSED(size); diff --git a/src/util/vfs/vfs-mem.c b/src/util/vfs/vfs-mem.c index 2ccdc339c..05d5a599f 100644 --- a/src/util/vfs/vfs-mem.c +++ b/src/util/vfs/vfs-mem.c @@ -28,7 +28,7 @@ static void _vfmUnmap(struct VFile* vf, void* memory, size_t size); static void _vfmTruncate(struct VFile* vf, size_t size); static void _vfmTruncateNoop(struct VFile* vf, size_t size); static ssize_t _vfmSize(struct VFile* vf); -static bool _vfmSync(struct VFile* vf, const void* buffer, size_t size); +static bool _vfmSync(struct VFile* vf, void* buffer, size_t size); struct VFile* VFileFromMemory(void* mem, size_t size) { if (!mem || !size) { @@ -297,7 +297,7 @@ ssize_t _vfmSize(struct VFile* vf) { return vfm->size; } -bool _vfmSync(struct VFile* vf, const void* buffer, size_t size) { +bool _vfmSync(struct VFile* vf, void* buffer, size_t size) { UNUSED(vf); UNUSED(buffer); UNUSED(size); diff --git a/src/util/vfs/vfs-zip.c b/src/util/vfs/vfs-zip.c index c3849d8e7..912b048d3 100644 --- a/src/util/vfs/vfs-zip.c +++ b/src/util/vfs/vfs-zip.c @@ -74,7 +74,7 @@ static void* _vfzMap(struct VFile* vf, size_t size, int flags); static void _vfzUnmap(struct VFile* vf, void* memory, size_t size); static void _vfzTruncate(struct VFile* vf, size_t size); static ssize_t _vfzSize(struct VFile* vf); -static bool _vfzSync(struct VFile* vf, const void* buffer, size_t size); +static bool _vfzSync(struct VFile* vf, void* buffer, size_t size); static bool _vdzClose(struct VDir* vd); static void _vdzRewind(struct VDir* vd); @@ -426,7 +426,7 @@ bool _vdzDeleteFile(struct VDir* vd, const char* path) { return false; } -bool _vfzSync(struct VFile* vf, const void* memory, size_t size) { +bool _vfzSync(struct VFile* vf, void* memory, size_t size) { UNUSED(vf); UNUSED(memory); UNUSED(size); @@ -654,7 +654,7 @@ bool _vdzDeleteFile(struct VDir* vd, const char* path) { return false; } -bool _vfzSync(struct VFile* vf, const void* memory, size_t size) { +bool _vfzSync(struct VFile* vf, void* memory, size_t size) { UNUSED(vf); UNUSED(memory); UNUSED(size);