mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2025-01-18 11:16:10 +00:00
Refactor placeholder cacheing
This commit is contained in:
parent
e528269b53
commit
1aa4c12e5e
3 changed files with 142 additions and 149 deletions
|
@ -24,6 +24,87 @@
|
||||||
|
|
||||||
namespace sts::ncm::impl {
|
namespace sts::ncm::impl {
|
||||||
|
|
||||||
|
Result PlaceHolderAccessor::Open(FILE** out_handle, PlaceHolderId placeholder_id) {
|
||||||
|
if (this->LoadFromCache(out_handle, placeholder_id)) {
|
||||||
|
return ResultSuccess;
|
||||||
|
}
|
||||||
|
char placeholder_path[FS_MAX_PATH] = {0};
|
||||||
|
this->MakePath(placeholder_path, placeholder_id);
|
||||||
|
|
||||||
|
FILE* f = nullptr;
|
||||||
|
R_TRY(OpenFile(&f, placeholder_path, FS_OPEN_WRITE));
|
||||||
|
|
||||||
|
*out_handle = f;
|
||||||
|
return ResultSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PlaceHolderAccessor::LoadFromCache(FILE** out_handle, PlaceHolderId placeholder_id) {
|
||||||
|
std::scoped_lock lk(this->cache_mutex);
|
||||||
|
CacheEntry *entry = this->FindInCache(placeholder_id);
|
||||||
|
if (!entry) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*out_handle = entry->handle;
|
||||||
|
entry->id = InvalidUuid;
|
||||||
|
entry->handle = nullptr;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
PlaceHolderAccessor::CacheEntry *PlaceHolderAccessor::FindInCache(PlaceHolderId placeholder_id) {
|
||||||
|
for (size_t i = 0; i < MaxCaches; i++) {
|
||||||
|
if (placeholder_id == this->caches[i].id) {
|
||||||
|
return &this->caches[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
PlaceHolderAccessor::CacheEntry *PlaceHolderAccessor::GetFreeEntry() {
|
||||||
|
/* Try to find an already free entry. */
|
||||||
|
CacheEntry* entry = this->FindInCache(InvalidUuid);
|
||||||
|
|
||||||
|
if (entry) {
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the oldest entry. */
|
||||||
|
{
|
||||||
|
entry = &this->caches[0];
|
||||||
|
for (size_t i = 1; i < MaxCaches; i++) {
|
||||||
|
if (entry->counter > this->caches[i].counter) {
|
||||||
|
entry = &this->caches[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->Invalidate(entry);
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlaceHolderAccessor::StoreToCache(FILE* handle, PlaceHolderId placeholder_id) {
|
||||||
|
std::scoped_lock lk(this->cache_mutex);
|
||||||
|
CacheEntry *entry = this->GetFreeEntry();
|
||||||
|
entry->id = placeholder_id;
|
||||||
|
entry->handle = handle;
|
||||||
|
entry->counter = this->cur_counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlaceHolderAccessor::Invalidate(CacheEntry *entry) {
|
||||||
|
if (entry != nullptr) {
|
||||||
|
if (entry->handle != nullptr) {
|
||||||
|
fflush(entry->handle);
|
||||||
|
fclose(entry->handle);
|
||||||
|
entry->handle = nullptr;
|
||||||
|
}
|
||||||
|
entry->id = InvalidUuid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlaceHolderAccessor::Initialize(char* root, MakePlaceHolderPathFunc path_func, bool delay_flush) {
|
||||||
|
this->root_path = root;
|
||||||
|
this->make_placeholder_path_func = path_func;
|
||||||
|
this->delay_flush = delay_flush;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int PlaceHolderAccessor::GetDirectoryDepth() {
|
unsigned int PlaceHolderAccessor::GetDirectoryDepth() {
|
||||||
if (this->make_placeholder_path_func == static_cast<MakePlaceHolderPathFunc>(path::MakePlaceHolderPathFlat)) {
|
if (this->make_placeholder_path_func == static_cast<MakePlaceHolderPathFunc>(path::MakePlaceHolderPathFlat)) {
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -34,37 +115,18 @@ namespace sts::ncm::impl {
|
||||||
std::abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlaceHolderAccessor::GetPlaceHolderPathUncached(char* placeholder_path_out, PlaceHolderId placeholder_id) {
|
void PlaceHolderAccessor::GetPath(char* placeholder_path_out, PlaceHolderId placeholder_id) {
|
||||||
std::scoped_lock<HosMutex> lock(this->cache_mutex);
|
std::scoped_lock lock(this->cache_mutex);
|
||||||
|
CacheEntry* entry = this->FindInCache(placeholder_id);
|
||||||
if (placeholder_id != InvalidUuid) {
|
this->Invalidate(entry);
|
||||||
CacheEntry* found_cache = NULL;
|
this->MakePath(placeholder_path_out, placeholder_id);
|
||||||
|
|
||||||
for (size_t i = 0; i < PlaceHolderAccessor::MaxCaches; i++) {
|
|
||||||
CacheEntry* cache = &this->caches[i];
|
|
||||||
|
|
||||||
if (placeholder_id == cache->id) {
|
|
||||||
found_cache = cache;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found_cache) {
|
|
||||||
/* Flush and close */
|
|
||||||
fflush(found_cache->handle);
|
|
||||||
fclose(found_cache->handle);
|
|
||||||
std::fill(found_cache->id.uuid, found_cache->id.uuid + sizeof(PlaceHolderId), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->GetPlaceHolderPath(placeholder_path_out, placeholder_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result PlaceHolderAccessor::Create(PlaceHolderId placeholder_id, size_t size) {
|
Result PlaceHolderAccessor::Create(PlaceHolderId placeholder_id, size_t size) {
|
||||||
char placeholder_path[FS_MAX_PATH] = {0};
|
char placeholder_path[FS_MAX_PATH] = {0};
|
||||||
|
|
||||||
this->EnsureRecursively(placeholder_id);
|
this->EnsureRecursively(placeholder_id);
|
||||||
this->GetPlaceHolderPathUncached(placeholder_path, placeholder_id);
|
this->GetPath(placeholder_path, placeholder_id);
|
||||||
|
|
||||||
debug::DebugLog("Creating %s\n", placeholder_path);
|
debug::DebugLog("Creating %s\n", placeholder_path);
|
||||||
R_TRY_CATCH(fsdevCreateFile(placeholder_path, size, FS_CREATE_BIG_FILE)) {
|
R_TRY_CATCH(fsdevCreateFile(placeholder_path, size, FS_CREATE_BIG_FILE)) {
|
||||||
|
@ -79,7 +141,7 @@ namespace sts::ncm::impl {
|
||||||
Result PlaceHolderAccessor::Delete(PlaceHolderId placeholder_id) {
|
Result PlaceHolderAccessor::Delete(PlaceHolderId placeholder_id) {
|
||||||
char placeholder_path[FS_MAX_PATH] = {0};
|
char placeholder_path[FS_MAX_PATH] = {0};
|
||||||
|
|
||||||
this->GetPlaceHolderPathUncached(placeholder_path, placeholder_id);
|
this->GetPath(placeholder_path, placeholder_id);
|
||||||
|
|
||||||
debug::DebugLog("Deleting %s\n", placeholder_path);
|
debug::DebugLog("Deleting %s\n", placeholder_path);
|
||||||
if (std::remove(placeholder_path) != 0) {
|
if (std::remove(placeholder_path) != 0) {
|
||||||
|
@ -93,24 +155,26 @@ namespace sts::ncm::impl {
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result PlaceHolderAccessor::Open(FILE** out_handle, PlaceHolderId placeholder_id) {
|
Result PlaceHolderAccessor::Write(PlaceHolderId placeholder_id, size_t offset, const void* buffer, size_t size) {
|
||||||
if (this->LoadFromCache(out_handle, placeholder_id)) {
|
|
||||||
return ResultSuccess;
|
|
||||||
}
|
|
||||||
char placeholder_path[FS_MAX_PATH] = {0};
|
|
||||||
|
|
||||||
this->GetPlaceHolderPath(placeholder_path, placeholder_id);
|
|
||||||
|
|
||||||
FILE* f = nullptr;
|
FILE* f = nullptr;
|
||||||
R_TRY(OpenFile(&f, placeholder_path, FS_OPEN_WRITE));
|
|
||||||
|
|
||||||
*out_handle = f;
|
R_TRY_CATCH(this->Open(&f, placeholder_id)) {
|
||||||
|
R_CATCH(ResultFsPathNotFound) {
|
||||||
|
return ResultNcmPlaceHolderNotFound;
|
||||||
|
}
|
||||||
|
} R_END_TRY_CATCH;
|
||||||
|
|
||||||
|
ON_SCOPE_EXIT {
|
||||||
|
this->StoreToCache(f, placeholder_id);
|
||||||
|
};
|
||||||
|
|
||||||
|
R_TRY(WriteFile(f, offset, buffer, size, !this->delay_flush));
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result PlaceHolderAccessor::SetSize(PlaceHolderId placeholder_id, size_t size) {
|
Result PlaceHolderAccessor::SetSize(PlaceHolderId placeholder_id, size_t size) {
|
||||||
char placeholder_path[FS_MAX_PATH] = {0};
|
char placeholder_path[FS_MAX_PATH] = {0};
|
||||||
this->GetPlaceHolderPath(placeholder_path, placeholder_id);
|
this->MakePath(placeholder_path, placeholder_id);
|
||||||
if (truncate(placeholder_path, size) == -1) {
|
if (truncate(placeholder_path, size) == -1) {
|
||||||
R_TRY_CATCH(fsdevGetLastResult()) {
|
R_TRY_CATCH(fsdevGetLastResult()) {
|
||||||
R_CATCH(ResultFsPathNotFound) {
|
R_CATCH(ResultFsPathNotFound) {
|
||||||
|
@ -127,7 +191,7 @@ namespace sts::ncm::impl {
|
||||||
|
|
||||||
/* Set the scope for the scoped_lock. */
|
/* Set the scope for the scoped_lock. */
|
||||||
{
|
{
|
||||||
std::scoped_lock<HosMutex> lock(this->cache_mutex);
|
std::scoped_lock lock(this->cache_mutex);
|
||||||
|
|
||||||
if (placeholder_id == InvalidUuid) {
|
if (placeholder_id == InvalidUuid) {
|
||||||
*found_in_cache = false;
|
*found_in_cache = false;
|
||||||
|
@ -162,73 +226,15 @@ namespace sts::ncm::impl {
|
||||||
|
|
||||||
Result PlaceHolderAccessor::EnsureRecursively(PlaceHolderId placeholder_id) {
|
Result PlaceHolderAccessor::EnsureRecursively(PlaceHolderId placeholder_id) {
|
||||||
char placeholder_path[FS_MAX_PATH] = {0};
|
char placeholder_path[FS_MAX_PATH] = {0};
|
||||||
this->GetPlaceHolderPath(placeholder_path, placeholder_id);
|
this->MakePath(placeholder_path, placeholder_id);
|
||||||
R_TRY(EnsureParentDirectoryRecursively(placeholder_path));
|
R_TRY(EnsureParentDirectoryRecursively(placeholder_path));
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PlaceHolderAccessor::LoadFromCache(FILE** out_handle, PlaceHolderId placeholder_id) {
|
void PlaceHolderAccessor::InvalidateAll() {
|
||||||
std::scoped_lock<HosMutex> lk(this->cache_mutex);
|
for (auto &entry : this->caches) {
|
||||||
CacheEntry *entry = this->FindInCache(placeholder_id);
|
if (entry.id != InvalidUuid) {
|
||||||
if (entry == nullptr) {
|
this->Invalidate(&entry);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
entry->id = InvalidUuid;
|
|
||||||
*out_handle = entry->handle;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
PlaceHolderAccessor::CacheEntry *PlaceHolderAccessor::FindInCache(PlaceHolderId placeholder_id) {
|
|
||||||
if (placeholder_id == InvalidUuid) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
for (size_t i = 0; i < MaxCaches; i++) {
|
|
||||||
if (placeholder_id == this->caches[i].id) {
|
|
||||||
return &this->caches[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlaceHolderAccessor::StoreToCache(FILE* handle, PlaceHolderId placeholder_id) {
|
|
||||||
std::scoped_lock<HosMutex> lk(this->cache_mutex);
|
|
||||||
CacheEntry* cache = nullptr;
|
|
||||||
|
|
||||||
/* Find an empty cache */
|
|
||||||
for (size_t i = 0; i < MaxCaches; i++) {
|
|
||||||
if (placeholder_id == InvalidUuid) {
|
|
||||||
cache = &this->caches[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* No empty caches found. Let's clear cache 0. */
|
|
||||||
if (cache == nullptr) {
|
|
||||||
cache = &this->caches[0];
|
|
||||||
|
|
||||||
/* Flush and close any handles. */
|
|
||||||
if (cache->handle) {
|
|
||||||
fflush(cache->handle);
|
|
||||||
fclose(cache->handle);
|
|
||||||
}
|
|
||||||
cache->id = InvalidUuid;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Cache the new placeholder id and its file handle. */
|
|
||||||
cache->id = placeholder_id;
|
|
||||||
cache->handle = handle;
|
|
||||||
cache->counter = this->cur_counter;
|
|
||||||
this->cur_counter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlaceHolderAccessor::ClearAllCaches() {
|
|
||||||
for (size_t i = 0; i < MaxCaches; i++) {
|
|
||||||
CacheEntry* cache = &this->caches[i];
|
|
||||||
|
|
||||||
if (cache->id != InvalidUuid) {
|
|
||||||
fflush(cache->handle);
|
|
||||||
fclose(cache->handle);
|
|
||||||
cache->id = InvalidUuid;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,53 +24,56 @@
|
||||||
namespace sts::ncm::impl {
|
namespace sts::ncm::impl {
|
||||||
|
|
||||||
class PlaceHolderAccessor {
|
class PlaceHolderAccessor {
|
||||||
public:
|
private:
|
||||||
class CacheEntry {
|
class CacheEntry {
|
||||||
public:
|
public:
|
||||||
PlaceHolderId id;
|
PlaceHolderId id;
|
||||||
FILE* handle;
|
FILE* handle;
|
||||||
u64 counter;
|
u64 counter;
|
||||||
};
|
};
|
||||||
|
private:
|
||||||
public:
|
|
||||||
static constexpr size_t MaxCaches = 0x2;
|
static constexpr size_t MaxCaches = 0x2;
|
||||||
|
|
||||||
CacheEntry caches[MaxCaches];
|
std::array<CacheEntry, MaxCaches> caches;
|
||||||
char* root_path;
|
char* root_path;
|
||||||
u64 cur_counter;
|
u64 cur_counter;
|
||||||
HosMutex cache_mutex;
|
HosMutex cache_mutex;
|
||||||
MakePlaceHolderPathFunc make_placeholder_path_func;
|
MakePlaceHolderPathFunc make_placeholder_path_func;
|
||||||
bool delay_flush;
|
bool delay_flush;
|
||||||
|
private:
|
||||||
|
Result Open(FILE** out_handle, PlaceHolderId placeholder_id);
|
||||||
|
CacheEntry *FindInCache(PlaceHolderId placeholder_id);
|
||||||
|
bool LoadFromCache(FILE** out_handle, PlaceHolderId placeholder_id);
|
||||||
|
CacheEntry *GetFreeEntry();
|
||||||
|
void StoreToCache(FILE* handle, PlaceHolderId placeholder_id);
|
||||||
|
void Invalidate(CacheEntry *entry);
|
||||||
|
public:
|
||||||
PlaceHolderAccessor() : cur_counter(0), delay_flush(false) {
|
PlaceHolderAccessor() : cur_counter(0), delay_flush(false) {
|
||||||
for (size_t i = 0; i < MaxCaches; i++) {
|
for (size_t i = 0; i < MaxCaches; i++) {
|
||||||
caches[i].id = InvalidUuid;
|
caches[i].id = InvalidUuid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void GetPlaceHolderRootPath(char* out_placeholder_root) {
|
inline void MakeRootPath(char* out_placeholder_root) {
|
||||||
path::GetPlaceHolderRootPath(out_placeholder_root, this->root_path);
|
path::GetPlaceHolderRootPath(out_placeholder_root, this->root_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void GetPlaceHolderPath(char* out_placeholder_path, PlaceHolderId placeholder_id) {
|
inline void MakePath(char* out_placeholder_path, PlaceHolderId placeholder_id) {
|
||||||
char placeholder_root_path[FS_MAX_PATH] = {0};
|
char placeholder_root_path[FS_MAX_PATH] = {0};
|
||||||
this->GetPlaceHolderRootPath(placeholder_root_path);
|
this->MakeRootPath(placeholder_root_path);
|
||||||
this->make_placeholder_path_func(out_placeholder_path, placeholder_id, placeholder_root_path);
|
this->make_placeholder_path_func(out_placeholder_path, placeholder_id, placeholder_root_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Initialize(char* root, MakePlaceHolderPathFunc path_func, bool delay_flush);
|
||||||
unsigned int GetDirectoryDepth();
|
unsigned int GetDirectoryDepth();
|
||||||
void GetPlaceHolderPathUncached(char* out_placeholder_path, PlaceHolderId placeholder_id);
|
void GetPath(char* out_placeholder_path, PlaceHolderId placeholder_id);
|
||||||
Result Create(PlaceHolderId placeholder_id, size_t size);
|
Result Create(PlaceHolderId placeholder_id, size_t size);
|
||||||
Result Delete(PlaceHolderId placeholder_id);
|
Result Delete(PlaceHolderId placeholder_id);
|
||||||
Result Open(FILE** out_handle, PlaceHolderId placeholder_id);
|
Result Write(PlaceHolderId placeholder_id, size_t offset, const void* buffer, size_t size);
|
||||||
Result SetSize(PlaceHolderId placeholder_id, size_t size);
|
Result SetSize(PlaceHolderId placeholder_id, size_t size);
|
||||||
Result GetSize(bool* found_in_cache, size_t* out_size, PlaceHolderId placeholder_id);
|
Result GetSize(bool* found_in_cache, size_t* out_size, PlaceHolderId placeholder_id);
|
||||||
Result EnsureRecursively(PlaceHolderId placeholder_id);
|
Result EnsureRecursively(PlaceHolderId placeholder_id);
|
||||||
|
void InvalidateAll();
|
||||||
CacheEntry *FindInCache(PlaceHolderId placeholder_id);
|
|
||||||
bool LoadFromCache(FILE** out_handle, PlaceHolderId placeholder_id);
|
|
||||||
void StoreToCache(FILE* handle, PlaceHolderId placeholder_id);
|
|
||||||
void ClearAllCaches();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -39,15 +39,13 @@ namespace sts::ncm {
|
||||||
|
|
||||||
strncpy(this->root_path, root_path, FS_MAX_PATH-2);
|
strncpy(this->root_path, root_path, FS_MAX_PATH-2);
|
||||||
this->make_content_path_func = *content_path_func;
|
this->make_content_path_func = *content_path_func;
|
||||||
this->placeholder_accessor.root_path = this->root_path;
|
this->placeholder_accessor.Initialize(this->root_path, *placeholder_path_func, delay_flush);
|
||||||
this->placeholder_accessor.make_placeholder_path_func = *placeholder_path_func;
|
|
||||||
this->placeholder_accessor.delay_flush = delay_flush;
|
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentStorageInterface::Finalize() {
|
void ContentStorageInterface::Finalize() {
|
||||||
this->ClearContentCache();
|
this->ClearContentCache();
|
||||||
this->placeholder_accessor.ClearAllCaches();
|
this->placeholder_accessor.InvalidateAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentStorageInterface::ClearContentCache() {
|
void ContentStorageInterface::ClearContentCache() {
|
||||||
|
@ -126,7 +124,7 @@ namespace sts::ncm {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
char placeholder_path[FS_MAX_PATH] = {0};
|
char placeholder_path[FS_MAX_PATH] = {0};
|
||||||
this->placeholder_accessor.GetPlaceHolderPath(placeholder_path, placeholder_id);
|
this->placeholder_accessor.MakePath(placeholder_path, placeholder_id);
|
||||||
|
|
||||||
bool has = false;
|
bool has = false;
|
||||||
R_TRY(HasFile(&has, placeholder_path));
|
R_TRY(HasFile(&has, placeholder_path));
|
||||||
|
@ -144,21 +142,7 @@ namespace sts::ncm {
|
||||||
}
|
}
|
||||||
|
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
R_TRY(this->placeholder_accessor.Write(placeholder_id, offset, data.buffer, data.num_elements));
|
||||||
FILE* f = nullptr;
|
|
||||||
|
|
||||||
R_TRY_CATCH(this->placeholder_accessor.Open(&f, placeholder_id)) {
|
|
||||||
R_CATCH(ResultFsPathNotFound) {
|
|
||||||
return ResultNcmPlaceHolderNotFound;
|
|
||||||
}
|
|
||||||
} R_END_TRY_CATCH;
|
|
||||||
|
|
||||||
ON_SCOPE_EXIT {
|
|
||||||
this->placeholder_accessor.StoreToCache(f, placeholder_id);
|
|
||||||
};
|
|
||||||
|
|
||||||
R_TRY(WriteFile(f, offset, data.buffer, data.num_elements, !this->placeholder_accessor.delay_flush));
|
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
R_DEBUG_END
|
R_DEBUG_END
|
||||||
}
|
}
|
||||||
|
@ -171,7 +155,7 @@ namespace sts::ncm {
|
||||||
char placeholder_path[FS_MAX_PATH] = {0};
|
char placeholder_path[FS_MAX_PATH] = {0};
|
||||||
char content_path[FS_MAX_PATH] = {0};
|
char content_path[FS_MAX_PATH] = {0};
|
||||||
|
|
||||||
this->placeholder_accessor.GetPlaceHolderPathUncached(placeholder_path, placeholder_id);
|
this->placeholder_accessor.GetPath(placeholder_path, placeholder_id);
|
||||||
this->GetContentPath(content_path, content_id);
|
this->GetContentPath(content_path, content_id);
|
||||||
|
|
||||||
if (rename(placeholder_path, content_path) != 0) {
|
if (rename(placeholder_path, content_path) != 0) {
|
||||||
|
@ -244,7 +228,7 @@ namespace sts::ncm {
|
||||||
|
|
||||||
char placeholder_path[FS_MAX_PATH] = {0};
|
char placeholder_path[FS_MAX_PATH] = {0};
|
||||||
char common_path[FS_MAX_PATH] = {0};
|
char common_path[FS_MAX_PATH] = {0};
|
||||||
this->placeholder_accessor.GetPlaceHolderPathUncached(placeholder_path, placeholder_id);
|
this->placeholder_accessor.GetPath(placeholder_path, placeholder_id);
|
||||||
R_TRY(ConvertToFsCommonPath(common_path, FS_MAX_PATH-1, placeholder_path));
|
R_TRY(ConvertToFsCommonPath(common_path, FS_MAX_PATH-1, placeholder_path));
|
||||||
*out.pointer = common_path;
|
*out.pointer = common_path;
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
|
@ -256,8 +240,8 @@ namespace sts::ncm {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
char placeholder_root_path[FS_MAX_PATH] = {0};
|
char placeholder_root_path[FS_MAX_PATH] = {0};
|
||||||
this->placeholder_accessor.ClearAllCaches();
|
this->placeholder_accessor.InvalidateAll();
|
||||||
this->placeholder_accessor.GetPlaceHolderRootPath(placeholder_root_path);
|
this->placeholder_accessor.MakeRootPath(placeholder_root_path);
|
||||||
|
|
||||||
/* Nintendo uses CleanDirectoryRecursively which is 3.0.0+.
|
/* Nintendo uses CleanDirectoryRecursively which is 3.0.0+.
|
||||||
We'll just delete the directory and recreate it to support all firmwares. */
|
We'll just delete the directory and recreate it to support all firmwares. */
|
||||||
|
@ -276,7 +260,7 @@ namespace sts::ncm {
|
||||||
R_TRY(this->EnsureEnabled());
|
R_TRY(this->EnsureEnabled());
|
||||||
|
|
||||||
char placeholder_root_path[FS_MAX_PATH] = {0};
|
char placeholder_root_path[FS_MAX_PATH] = {0};
|
||||||
this->placeholder_accessor.GetPlaceHolderRootPath(placeholder_root_path);
|
this->placeholder_accessor.MakeRootPath(placeholder_root_path);
|
||||||
const unsigned int dir_depth = this->placeholder_accessor.GetDirectoryDepth();
|
const unsigned int dir_depth = this->placeholder_accessor.GetDirectoryDepth();
|
||||||
size_t entry_count = 0;
|
size_t entry_count = 0;
|
||||||
|
|
||||||
|
@ -403,7 +387,7 @@ namespace sts::ncm {
|
||||||
R_DEBUG_START
|
R_DEBUG_START
|
||||||
this->disabled = true;
|
this->disabled = true;
|
||||||
this->ClearContentCache();
|
this->ClearContentCache();
|
||||||
this->placeholder_accessor.ClearAllCaches();
|
this->placeholder_accessor.InvalidateAll();
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
R_DEBUG_END
|
R_DEBUG_END
|
||||||
}
|
}
|
||||||
|
@ -423,7 +407,7 @@ namespace sts::ncm {
|
||||||
R_TRY(EnsureParentDirectoryRecursively(new_content_path));
|
R_TRY(EnsureParentDirectoryRecursively(new_content_path));
|
||||||
|
|
||||||
R_TRY(this->placeholder_accessor.EnsureRecursively(placeholder_id));
|
R_TRY(this->placeholder_accessor.EnsureRecursively(placeholder_id));
|
||||||
this->placeholder_accessor.GetPlaceHolderPathUncached(placeholder_path, placeholder_id);
|
this->placeholder_accessor.GetPath(placeholder_path, placeholder_id);
|
||||||
if (rename(old_content_path, placeholder_path) != 0) {
|
if (rename(old_content_path, placeholder_path) != 0) {
|
||||||
R_TRY_CATCH(fsdevGetLastResult()) {
|
R_TRY_CATCH(fsdevGetLastResult()) {
|
||||||
R_CATCH(ResultFsPathNotFound) {
|
R_CATCH(ResultFsPathNotFound) {
|
||||||
|
@ -474,7 +458,7 @@ namespace sts::ncm {
|
||||||
|
|
||||||
char placeholder_path[FS_MAX_PATH] = {0};
|
char placeholder_path[FS_MAX_PATH] = {0};
|
||||||
char common_path[FS_MAX_PATH] = {0};
|
char common_path[FS_MAX_PATH] = {0};
|
||||||
this->placeholder_accessor.GetPlaceHolderPathUncached(placeholder_path, placeholder_id);
|
this->placeholder_accessor.GetPath(placeholder_path, placeholder_id);
|
||||||
R_TRY(ConvertToFsCommonPath(common_path, FS_MAX_PATH-1, placeholder_path));
|
R_TRY(ConvertToFsCommonPath(common_path, FS_MAX_PATH-1, placeholder_path));
|
||||||
R_TRY(fsGetRightsIdAndKeyGenerationByPath(common_path, &key_generation, &rights_id));
|
R_TRY(fsGetRightsIdAndKeyGenerationByPath(common_path, &key_generation, &rights_id));
|
||||||
|
|
||||||
|
@ -607,7 +591,7 @@ namespace sts::ncm {
|
||||||
|
|
||||||
Result ContentStorageInterface::FlushPlaceHolder() {
|
Result ContentStorageInterface::FlushPlaceHolder() {
|
||||||
R_DEBUG_START
|
R_DEBUG_START
|
||||||
this->placeholder_accessor.ClearAllCaches();
|
this->placeholder_accessor.InvalidateAll();
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
R_DEBUG_END
|
R_DEBUG_END
|
||||||
}
|
}
|
||||||
|
@ -629,7 +613,7 @@ namespace sts::ncm {
|
||||||
char placeholder_path[FS_MAX_PATH] = {0};
|
char placeholder_path[FS_MAX_PATH] = {0};
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
this->placeholder_accessor.GetPlaceHolderPathUncached(placeholder_path, placeholder_id);
|
this->placeholder_accessor.GetPath(placeholder_path, placeholder_id);
|
||||||
if (stat(placeholder_path, &st) == -1) {
|
if (stat(placeholder_path, &st) == -1) {
|
||||||
return fsdevGetLastResult();
|
return fsdevGetLastResult();
|
||||||
}
|
}
|
||||||
|
@ -662,8 +646,8 @@ namespace sts::ncm {
|
||||||
R_TRY(TraverseDirectory(content_root_path, dir_depth, fix_file_attributes));
|
R_TRY(TraverseDirectory(content_root_path, dir_depth, fix_file_attributes));
|
||||||
|
|
||||||
char placeholder_root_path[FS_MAX_PATH] = {0};
|
char placeholder_root_path[FS_MAX_PATH] = {0};
|
||||||
this->placeholder_accessor.ClearAllCaches();
|
this->placeholder_accessor.InvalidateAll();
|
||||||
this->placeholder_accessor.GetPlaceHolderRootPath(placeholder_root_path);
|
this->placeholder_accessor.MakeRootPath(placeholder_root_path);
|
||||||
dir_depth = this->placeholder_accessor.GetDirectoryDepth();
|
dir_depth = this->placeholder_accessor.GetDirectoryDepth();
|
||||||
|
|
||||||
R_TRY(TraverseDirectory(placeholder_root_path, dir_depth, fix_file_attributes));
|
R_TRY(TraverseDirectory(placeholder_root_path, dir_depth, fix_file_attributes));
|
||||||
|
@ -699,7 +683,7 @@ namespace sts::ncm {
|
||||||
u8 key_generation = 0;
|
u8 key_generation = 0;
|
||||||
char placeholder_path[FS_MAX_PATH] = {0};
|
char placeholder_path[FS_MAX_PATH] = {0};
|
||||||
char common_path[FS_MAX_PATH] = {0};
|
char common_path[FS_MAX_PATH] = {0};
|
||||||
this->placeholder_accessor.GetPlaceHolderPathUncached(placeholder_path, placeholder_id);
|
this->placeholder_accessor.GetPath(placeholder_path, placeholder_id);
|
||||||
R_TRY(ConvertToFsCommonPath(common_path, FS_MAX_PATH-1, placeholder_path));
|
R_TRY(ConvertToFsCommonPath(common_path, FS_MAX_PATH-1, placeholder_path));
|
||||||
R_TRY(fsGetRightsIdAndKeyGenerationByPath(common_path, &key_generation, &rights_id));
|
R_TRY(fsGetRightsIdAndKeyGenerationByPath(common_path, &key_generation, &rights_id));
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue