mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Add a bit more error detection to the disk cache.
This commit is contained in:
parent
475964133c
commit
0264422b8d
2 changed files with 58 additions and 12 deletions
|
@ -165,6 +165,10 @@ void DiskCachingFileLoaderCache::ShutdownCache() {
|
||||||
size_t DiskCachingFileLoaderCache::ReadFromCache(s64 pos, size_t bytes, void *data) {
|
size_t DiskCachingFileLoaderCache::ReadFromCache(s64 pos, size_t bytes, void *data) {
|
||||||
lock_guard guard(lock_);
|
lock_guard guard(lock_);
|
||||||
|
|
||||||
|
if (!f_) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
s64 cacheStartPos = pos / blockSize_;
|
s64 cacheStartPos = pos / blockSize_;
|
||||||
s64 cacheEndPos = (pos + bytes - 1) / blockSize_;
|
s64 cacheEndPos = (pos + bytes - 1) / blockSize_;
|
||||||
size_t readSize = 0;
|
size_t readSize = 0;
|
||||||
|
@ -182,7 +186,9 @@ size_t DiskCachingFileLoaderCache::ReadFromCache(s64 pos, size_t bytes, void *da
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t toRead = std::min(bytes - readSize, (size_t)blockSize_ - offset);
|
size_t toRead = std::min(bytes - readSize, (size_t)blockSize_ - offset);
|
||||||
ReadBlockData(p + readSize, info, offset, toRead);
|
if (!ReadBlockData(p + readSize, info, offset, toRead)) {
|
||||||
|
return readSize;
|
||||||
|
}
|
||||||
readSize += toRead;
|
readSize += toRead;
|
||||||
|
|
||||||
// Don't need an offset after the first read.
|
// Don't need an offset after the first read.
|
||||||
|
@ -194,6 +200,11 @@ size_t DiskCachingFileLoaderCache::ReadFromCache(s64 pos, size_t bytes, void *da
|
||||||
size_t DiskCachingFileLoaderCache::SaveIntoCache(FileLoader *backend, s64 pos, size_t bytes, void *data) {
|
size_t DiskCachingFileLoaderCache::SaveIntoCache(FileLoader *backend, s64 pos, size_t bytes, void *data) {
|
||||||
lock_guard guard(lock_);
|
lock_guard guard(lock_);
|
||||||
|
|
||||||
|
if (!f_) {
|
||||||
|
// Just to keep things working.
|
||||||
|
return backend->ReadAt(pos, bytes, data);
|
||||||
|
}
|
||||||
|
|
||||||
s64 cacheStartPos = pos / blockSize_;
|
s64 cacheStartPos = pos / blockSize_;
|
||||||
s64 cacheEndPos = (pos + bytes - 1) / blockSize_;
|
s64 cacheEndPos = (pos + bytes - 1) / blockSize_;
|
||||||
size_t readSize = 0;
|
size_t readSize = 0;
|
||||||
|
@ -374,49 +385,84 @@ s64 DiskCachingFileLoaderCache::GetBlockOffset(u32 block) {
|
||||||
return blockOffset + (s64)block * (s64)blockSize_;
|
return blockOffset + (s64)block * (s64)blockSize_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiskCachingFileLoaderCache::ReadBlockData(u8 *dest, BlockInfo &info, size_t offset, size_t size) {
|
bool DiskCachingFileLoaderCache::ReadBlockData(u8 *dest, BlockInfo &info, size_t offset, size_t size) {
|
||||||
|
if (!f_) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
s64 blockOffset = GetBlockOffset(info.block);
|
s64 blockOffset = GetBlockOffset(info.block);
|
||||||
|
|
||||||
|
bool failed = false;
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
if (lseek64(fd_, blockOffset, SEEK_SET) != blockOffset) {
|
if (lseek64(fd_, blockOffset, SEEK_SET) != blockOffset) {
|
||||||
ERROR_LOG(LOADER, "Unable to read disk cache data entry.");
|
failed = true;
|
||||||
} else if (read(fd_, dest + offset, size) != (ssize_t)size) {
|
} else if (read(fd_, dest + offset, size) != (ssize_t)size) {
|
||||||
ERROR_LOG(LOADER, "Unable to read disk cache data entry.");
|
failed = true;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (fseeko(f_, blockOffset, SEEK_SET) != 0) {
|
if (fseeko(f_, blockOffset, SEEK_SET) != 0) {
|
||||||
ERROR_LOG(LOADER, "Unable to read disk cache data entry.");
|
failed = true;
|
||||||
} else if (fread(dest + offset, size, 1, f_) != 1) {
|
} else if (fread(dest + offset, size, 1, f_) != 1) {
|
||||||
ERROR_LOG(LOADER, "Unable to read disk cache data entry.");
|
failed = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (failed) {
|
||||||
|
ERROR_LOG(LOADER, "Unable to read disk cache data entry.");
|
||||||
|
fclose(f_);
|
||||||
|
f_ = nullptr;
|
||||||
|
fd_ = 0;
|
||||||
|
}
|
||||||
|
return !failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiskCachingFileLoaderCache::WriteBlockData(BlockInfo &info, u8 *src) {
|
void DiskCachingFileLoaderCache::WriteBlockData(BlockInfo &info, u8 *src) {
|
||||||
|
if (!f_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
s64 blockOffset = GetBlockOffset(info.block);
|
s64 blockOffset = GetBlockOffset(info.block);
|
||||||
|
|
||||||
|
bool failed = false;
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
if (lseek64(fd_, blockOffset, SEEK_SET) != blockOffset) {
|
if (lseek64(fd_, blockOffset, SEEK_SET) != blockOffset) {
|
||||||
ERROR_LOG(LOADER, "Unable to write disk cache data entry.");
|
failed = true;
|
||||||
} else if (write(fd_, src, blockSize_) != (ssize_t)blockSize_) {
|
} else if (write(fd_, src, blockSize_) != (ssize_t)blockSize_) {
|
||||||
ERROR_LOG(LOADER, "Unable to write disk cache data entry.");
|
failed = true;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (fseeko(f_, blockOffset, SEEK_SET) != 0) {
|
if (fseeko(f_, blockOffset, SEEK_SET) != 0) {
|
||||||
ERROR_LOG(LOADER, "Unable to write disk cache data entry.");
|
failed = true;
|
||||||
} else if (fwrite(src, blockSize_, 1, f_) != 1) {
|
} else if (fwrite(src, blockSize_, 1, f_) != 1) {
|
||||||
ERROR_LOG(LOADER, "Unable to write disk cache data entry.");
|
failed = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (failed) {
|
||||||
|
ERROR_LOG(LOADER, "Unable to write disk cache data entry.");
|
||||||
|
fclose(f_);
|
||||||
|
f_ = nullptr;
|
||||||
|
fd_ = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiskCachingFileLoaderCache::WriteIndexData(u32 indexPos, BlockInfo &info) {
|
void DiskCachingFileLoaderCache::WriteIndexData(u32 indexPos, BlockInfo &info) {
|
||||||
|
if (!f_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
u32 offset = (u32)sizeof(FileHeader) + indexPos * (u32)sizeof(BlockInfo);
|
u32 offset = (u32)sizeof(FileHeader) + indexPos * (u32)sizeof(BlockInfo);
|
||||||
|
|
||||||
|
bool failed = false;
|
||||||
if (fseek(f_, offset, SEEK_SET) != 0) {
|
if (fseek(f_, offset, SEEK_SET) != 0) {
|
||||||
ERROR_LOG(LOADER, "Unable to write disk cache index entry.");
|
failed = true;
|
||||||
} else if (fwrite(&info, sizeof(BlockInfo), 1, f_) != 1) {
|
} else if (fwrite(&info, sizeof(BlockInfo), 1, f_) != 1) {
|
||||||
|
failed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failed) {
|
||||||
ERROR_LOG(LOADER, "Unable to write disk cache index entry.");
|
ERROR_LOG(LOADER, "Unable to write disk cache index entry.");
|
||||||
|
fclose(f_);
|
||||||
|
f_ = nullptr;
|
||||||
|
fd_ = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -96,7 +96,7 @@ private:
|
||||||
u32 AllocateBlock(u32 indexPos);
|
u32 AllocateBlock(u32 indexPos);
|
||||||
|
|
||||||
struct BlockInfo;
|
struct BlockInfo;
|
||||||
void ReadBlockData(u8 *dest, BlockInfo &info, size_t offset, size_t size);
|
bool ReadBlockData(u8 *dest, BlockInfo &info, size_t offset, size_t size);
|
||||||
void WriteBlockData(BlockInfo &info, u8 *src);
|
void WriteBlockData(BlockInfo &info, u8 *src);
|
||||||
void WriteIndexData(u32 indexPos, BlockInfo &info);
|
void WriteIndexData(u32 indexPos, BlockInfo &info);
|
||||||
s64 GetBlockOffset(u32 block);
|
s64 GetBlockOffset(u32 block);
|
||||||
|
|
Loading…
Add table
Reference in a new issue