file_sys: Change mount points to be relative to the user path

This commit is contained in:
Vitor Kiguchi 2021-01-08 19:10:03 -03:00
parent 8e3c7674d8
commit 79824e9790
7 changed files with 69 additions and 56 deletions

View file

@ -7,11 +7,14 @@
#include <sstream> #include <sstream>
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/string_util.h" #include "common/string_util.h"
#include "common/file_util.h"
#include "core/file_sys/archive_backend.h" #include "core/file_sys/archive_backend.h"
#include "core/memory.h" #include "core/memory.h"
namespace FileSys { namespace FileSys {
std::string ArchiveBackend::base_path = FileUtil::GetUserPath(FileUtil::UserPath::UserDir);
Path::Path(LowPathType type, std::vector<u8> data) : type(type) { Path::Path(LowPathType type, std::vector<u8> data) : type(type) {
switch (type) { switch (type) {
case LowPathType::Binary: { case LowPathType::Binary: {

View file

@ -197,7 +197,7 @@ public:
protected: protected:
std::unique_ptr<DelayGenerator> delay_generator; std::unique_ptr<DelayGenerator> delay_generator;
static std::string base_path;
private: private:
template <class Archive> template <class Archive>
void serialize(Archive& ar, const unsigned int) { void serialize(Archive& ar, const unsigned int) {

View file

@ -124,11 +124,12 @@ public:
return ERROR_UNSUPPORTED_OPEN_FLAGS; return ERROR_UNSUPPORTED_OPEN_FLAGS;
} }
const auto full_path = path_parser.BuildHostPath(mount_point); const auto full_path = path_parser.BuildHostPath(SaveDataArchive::base_path + mount_point);
switch (path_parser.GetHostStatus(mount_point)) { switch (path_parser.GetHostStatus(SaveDataArchive::base_path + mount_point)) {
case PathParser::InvalidMountPoint: case PathParser::InvalidMountPoint:
LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", mount_point); LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}",
SaveDataArchive::base_path + mount_point);
return ERROR_FILE_NOT_FOUND; return ERROR_FILE_NOT_FOUND;
case PathParser::PathNotFound: case PathParser::PathNotFound:
LOG_ERROR(Service_FS, "Path not found {}", full_path); LOG_ERROR(Service_FS, "Path not found {}", full_path);
@ -248,6 +249,9 @@ Path ArchiveFactory_ExtSaveData::GetCorrectedPath(const Path& path) {
ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_ExtSaveData::Open(const Path& path, ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_ExtSaveData::Open(const Path& path,
u64 program_id) { u64 program_id) {
std::string fullpath = GetExtSaveDataPath(mount_point, GetCorrectedPath(path)) + "user/"; std::string fullpath = GetExtSaveDataPath(mount_point, GetCorrectedPath(path)) + "user/";
std::string relative_path =
GetExtSaveDataPath(GetExtDataContainerPath("nand/", shared), GetCorrectedPath(path)) +
"user/";
if (!FileUtil::Exists(fullpath)) { if (!FileUtil::Exists(fullpath)) {
// TODO(Subv): Verify the archive behavior of SharedExtSaveData compared to ExtSaveData. // TODO(Subv): Verify the archive behavior of SharedExtSaveData compared to ExtSaveData.
// ExtSaveData seems to return FS_NotFound (120) when the archive doesn't exist. // ExtSaveData seems to return FS_NotFound (120) when the archive doesn't exist.
@ -258,7 +262,7 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_ExtSaveData::Open(cons
} }
} }
std::unique_ptr<DelayGenerator> delay_generator = std::make_unique<ExtSaveDataDelayGenerator>(); std::unique_ptr<DelayGenerator> delay_generator = std::make_unique<ExtSaveDataDelayGenerator>();
auto archive = std::make_unique<ExtSaveDataArchive>(fullpath, std::move(delay_generator)); auto archive = std::make_unique<ExtSaveDataArchive>(relative_path, std::move(delay_generator));
return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive));
} }

View file

@ -77,11 +77,11 @@ ResultVal<std::unique_ptr<FileBackend>> SDMCArchive::OpenFileBase(const Path& pa
return ERROR_INVALID_OPEN_FLAGS; return ERROR_INVALID_OPEN_FLAGS;
} }
const auto full_path = path_parser.BuildHostPath(mount_point); const auto full_path = path_parser.BuildHostPath(ArchiveBackend::base_path + mount_point);
switch (path_parser.GetHostStatus(mount_point)) { switch (path_parser.GetHostStatus(ArchiveBackend::base_path + mount_point)) {
case PathParser::InvalidMountPoint: case PathParser::InvalidMountPoint:
LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", mount_point); LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", ArchiveBackend::base_path + mount_point);
return ERROR_NOT_FOUND; return ERROR_NOT_FOUND;
case PathParser::PathNotFound: case PathParser::PathNotFound:
case PathParser::FileInPath: case PathParser::FileInPath:
@ -123,11 +123,11 @@ ResultCode SDMCArchive::DeleteFile(const Path& path) const {
return ERROR_INVALID_PATH; return ERROR_INVALID_PATH;
} }
const auto full_path = path_parser.BuildHostPath(mount_point); const auto full_path = path_parser.BuildHostPath(ArchiveBackend::base_path + mount_point);
switch (path_parser.GetHostStatus(mount_point)) { switch (path_parser.GetHostStatus(ArchiveBackend::base_path + mount_point)) {
case PathParser::InvalidMountPoint: case PathParser::InvalidMountPoint:
LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", mount_point); LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", ArchiveBackend::base_path + mount_point);
return ERROR_NOT_FOUND; return ERROR_NOT_FOUND;
case PathParser::PathNotFound: case PathParser::PathNotFound:
case PathParser::FileInPath: case PathParser::FileInPath:
@ -165,8 +165,8 @@ ResultCode SDMCArchive::RenameFile(const Path& src_path, const Path& dest_path)
return ERROR_INVALID_PATH; return ERROR_INVALID_PATH;
} }
const auto src_path_full = path_parser_src.BuildHostPath(mount_point); const auto src_path_full = path_parser_src.BuildHostPath(ArchiveBackend::base_path + mount_point);
const auto dest_path_full = path_parser_dest.BuildHostPath(mount_point); const auto dest_path_full = path_parser_dest.BuildHostPath(ArchiveBackend::base_path + mount_point);
if (FileUtil::Rename(src_path_full, dest_path_full)) { if (FileUtil::Rename(src_path_full, dest_path_full)) {
return RESULT_SUCCESS; return RESULT_SUCCESS;
@ -218,12 +218,12 @@ static ResultCode DeleteDirectoryHelper(const Path& path, const std::string& mou
} }
ResultCode SDMCArchive::DeleteDirectory(const Path& path) const { ResultCode SDMCArchive::DeleteDirectory(const Path& path) const {
return DeleteDirectoryHelper(path, mount_point, FileUtil::DeleteDir); return DeleteDirectoryHelper(path, ArchiveBackend::base_path + mount_point, FileUtil::DeleteDir);
} }
ResultCode SDMCArchive::DeleteDirectoryRecursively(const Path& path) const { ResultCode SDMCArchive::DeleteDirectoryRecursively(const Path& path) const {
return DeleteDirectoryHelper( return DeleteDirectoryHelper(
path, mount_point, [](const std::string& p) { return FileUtil::DeleteDirRecursively(p); }); path, ArchiveBackend::base_path + mount_point, [](const std::string& p) { return FileUtil::DeleteDirRecursively(p); });
} }
ResultCode SDMCArchive::CreateFile(const FileSys::Path& path, u64 size) const { ResultCode SDMCArchive::CreateFile(const FileSys::Path& path, u64 size) const {
@ -234,11 +234,11 @@ ResultCode SDMCArchive::CreateFile(const FileSys::Path& path, u64 size) const {
return ERROR_INVALID_PATH; return ERROR_INVALID_PATH;
} }
const auto full_path = path_parser.BuildHostPath(mount_point); const auto full_path = path_parser.BuildHostPath(ArchiveBackend::base_path + mount_point);
switch (path_parser.GetHostStatus(mount_point)) { switch (path_parser.GetHostStatus(ArchiveBackend::base_path + mount_point)) {
case PathParser::InvalidMountPoint: case PathParser::InvalidMountPoint:
LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", mount_point); LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", ArchiveBackend::base_path + mount_point);
return ERROR_NOT_FOUND; return ERROR_NOT_FOUND;
case PathParser::PathNotFound: case PathParser::PathNotFound:
case PathParser::FileInPath: case PathParser::FileInPath:
@ -279,11 +279,11 @@ ResultCode SDMCArchive::CreateDirectory(const Path& path) const {
return ERROR_INVALID_PATH; return ERROR_INVALID_PATH;
} }
const auto full_path = path_parser.BuildHostPath(mount_point); const auto full_path = path_parser.BuildHostPath(ArchiveBackend::base_path + mount_point);
switch (path_parser.GetHostStatus(mount_point)) { switch (path_parser.GetHostStatus(ArchiveBackend::base_path + mount_point)) {
case PathParser::InvalidMountPoint: case PathParser::InvalidMountPoint:
LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", mount_point); LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", ArchiveBackend::base_path + mount_point);
return ERROR_NOT_FOUND; return ERROR_NOT_FOUND;
case PathParser::PathNotFound: case PathParser::PathNotFound:
case PathParser::FileInPath: case PathParser::FileInPath:
@ -297,11 +297,11 @@ ResultCode SDMCArchive::CreateDirectory(const Path& path) const {
break; // Expected 'success' case break; // Expected 'success' case
} }
if (FileUtil::CreateDir(mount_point + path.AsString())) { if (FileUtil::CreateDir(ArchiveBackend::base_path + mount_point + path.AsString())) {
return RESULT_SUCCESS; return RESULT_SUCCESS;
} }
LOG_CRITICAL(Service_FS, "(unreachable) Unknown error creating {}", mount_point); LOG_CRITICAL(Service_FS, "(unreachable) Unknown error creating {}", ArchiveBackend::base_path + mount_point);
return ResultCode(ErrorDescription::NoData, ErrorModule::FS, ErrorSummary::Canceled, return ResultCode(ErrorDescription::NoData, ErrorModule::FS, ErrorSummary::Canceled,
ErrorLevel::Status); ErrorLevel::Status);
} }
@ -322,8 +322,8 @@ ResultCode SDMCArchive::RenameDirectory(const Path& src_path, const Path& dest_p
return ERROR_INVALID_PATH; return ERROR_INVALID_PATH;
} }
const auto src_path_full = path_parser_src.BuildHostPath(mount_point); const auto src_path_full = path_parser_src.BuildHostPath(ArchiveBackend::base_path + mount_point);
const auto dest_path_full = path_parser_dest.BuildHostPath(mount_point); const auto dest_path_full = path_parser_dest.BuildHostPath(ArchiveBackend::base_path + mount_point);
if (FileUtil::Rename(src_path_full, dest_path_full)) { if (FileUtil::Rename(src_path_full, dest_path_full)) {
return RESULT_SUCCESS; return RESULT_SUCCESS;
@ -343,11 +343,11 @@ ResultVal<std::unique_ptr<DirectoryBackend>> SDMCArchive::OpenDirectory(const Pa
return ERROR_INVALID_PATH; return ERROR_INVALID_PATH;
} }
const auto full_path = path_parser.BuildHostPath(mount_point); const auto full_path = path_parser.BuildHostPath(ArchiveBackend::base_path + mount_point);
switch (path_parser.GetHostStatus(mount_point)) { switch (path_parser.GetHostStatus(ArchiveBackend::base_path + mount_point)) {
case PathParser::InvalidMountPoint: case PathParser::InvalidMountPoint:
LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", mount_point); LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", ArchiveBackend::base_path + mount_point);
return ERROR_NOT_FOUND; return ERROR_NOT_FOUND;
case PathParser::PathNotFound: case PathParser::PathNotFound:
case PathParser::NotFound: case PathParser::NotFound:

View file

@ -44,7 +44,9 @@ ArchiveSource_SDSaveData::ArchiveSource_SDSaveData(const std::string& sdmc_direc
} }
ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveSource_SDSaveData::Open(u64 program_id) { ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveSource_SDSaveData::Open(u64 program_id) {
std::string concrete_mount_point = GetSaveDataPath(mount_point, program_id); const std::string concrete_mount_point = GetSaveDataPath(mount_point, program_id);
std::string relative_mount_point =
GetSaveDataPath(GetSaveDataContainerPath("sdmc/"), program_id);
if (!FileUtil::Exists(concrete_mount_point)) { if (!FileUtil::Exists(concrete_mount_point)) {
// When a SaveData archive is created for the first time, it is not yet formatted and the // When a SaveData archive is created for the first time, it is not yet formatted and the
// save file/directory structure expected by the game has not yet been initialized. // save file/directory structure expected by the game has not yet been initialized.
@ -53,7 +55,7 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveSource_SDSaveData::Open(u64 pr
return ERR_NOT_FORMATTED; return ERR_NOT_FORMATTED;
} }
auto archive = std::make_unique<SaveDataArchive>(std::move(concrete_mount_point)); auto archive = std::make_unique<SaveDataArchive>(std::move(relative_mount_point));
return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive));
} }

View file

@ -57,12 +57,14 @@ ArchiveFactory_SystemSaveData::ArchiveFactory_SystemSaveData(const std::string&
ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SystemSaveData::Open(const Path& path, ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SystemSaveData::Open(const Path& path,
u64 program_id) { u64 program_id) {
std::string fullpath = GetSystemSaveDataPath(base_path, path); const std::string fullpath = GetSystemSaveDataPath(base_path, path);
std::string relative_path =
GetSystemSaveDataPath(GetSystemSaveDataContainerPath("nand/"), path);
if (!FileUtil::Exists(fullpath)) { if (!FileUtil::Exists(fullpath)) {
// TODO(Subv): Check error code, this one is probably wrong // TODO(Subv): Check error code, this one is probably wrong
return ERR_NOT_FORMATTED; return ERR_NOT_FORMATTED;
} }
auto archive = std::make_unique<SaveDataArchive>(fullpath); auto archive = std::make_unique<SaveDataArchive>(relative_path);
return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive));
} }

View file

@ -59,11 +59,11 @@ ResultVal<std::unique_ptr<FileBackend>> SaveDataArchive::OpenFile(const Path& pa
return ERROR_UNSUPPORTED_OPEN_FLAGS; return ERROR_UNSUPPORTED_OPEN_FLAGS;
} }
const auto full_path = path_parser.BuildHostPath(mount_point); const auto full_path = path_parser.BuildHostPath(ArchiveBackend::base_path + mount_point);
switch (path_parser.GetHostStatus(mount_point)) { switch (path_parser.GetHostStatus(ArchiveBackend::base_path + mount_point)) {
case PathParser::InvalidMountPoint: case PathParser::InvalidMountPoint:
LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", mount_point); LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", ArchiveBackend::base_path + mount_point);
return ERROR_FILE_NOT_FOUND; return ERROR_FILE_NOT_FOUND;
case PathParser::PathNotFound: case PathParser::PathNotFound:
LOG_ERROR(Service_FS, "Path not found {}", full_path); LOG_ERROR(Service_FS, "Path not found {}", full_path);
@ -105,11 +105,11 @@ ResultCode SaveDataArchive::DeleteFile(const Path& path) const {
return ERROR_INVALID_PATH; return ERROR_INVALID_PATH;
} }
const auto full_path = path_parser.BuildHostPath(mount_point); const auto full_path = path_parser.BuildHostPath(ArchiveBackend::base_path + mount_point);
switch (path_parser.GetHostStatus(mount_point)) { switch (path_parser.GetHostStatus(ArchiveBackend::base_path + mount_point)) {
case PathParser::InvalidMountPoint: case PathParser::InvalidMountPoint:
LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", mount_point); LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", ArchiveBackend::base_path + mount_point);
return ERROR_FILE_NOT_FOUND; return ERROR_FILE_NOT_FOUND;
case PathParser::PathNotFound: case PathParser::PathNotFound:
LOG_ERROR(Service_FS, "Path not found {}", full_path); LOG_ERROR(Service_FS, "Path not found {}", full_path);
@ -147,8 +147,8 @@ ResultCode SaveDataArchive::RenameFile(const Path& src_path, const Path& dest_pa
return ERROR_INVALID_PATH; return ERROR_INVALID_PATH;
} }
const auto src_path_full = path_parser_src.BuildHostPath(mount_point); const auto src_path_full = path_parser_src.BuildHostPath(ArchiveBackend::base_path + mount_point);
const auto dest_path_full = path_parser_dest.BuildHostPath(mount_point); const auto dest_path_full = path_parser_dest.BuildHostPath(ArchiveBackend::base_path + mount_point);
if (FileUtil::Rename(src_path_full, dest_path_full)) { if (FileUtil::Rename(src_path_full, dest_path_full)) {
return RESULT_SUCCESS; return RESULT_SUCCESS;
@ -200,12 +200,13 @@ static ResultCode DeleteDirectoryHelper(const Path& path, const std::string& mou
} }
ResultCode SaveDataArchive::DeleteDirectory(const Path& path) const { ResultCode SaveDataArchive::DeleteDirectory(const Path& path) const {
return DeleteDirectoryHelper(path, mount_point, FileUtil::DeleteDir); return DeleteDirectoryHelper(path, ArchiveBackend::base_path + mount_point, FileUtil::DeleteDir);
} }
ResultCode SaveDataArchive::DeleteDirectoryRecursively(const Path& path) const { ResultCode SaveDataArchive::DeleteDirectoryRecursively(const Path& path) const {
return DeleteDirectoryHelper( return DeleteDirectoryHelper(path, ArchiveBackend::base_path + mount_point, [](const std::string& p) {
path, mount_point, [](const std::string& p) { return FileUtil::DeleteDirRecursively(p); }); return FileUtil::DeleteDirRecursively(p);
});
} }
ResultCode SaveDataArchive::CreateFile(const FileSys::Path& path, u64 size) const { ResultCode SaveDataArchive::CreateFile(const FileSys::Path& path, u64 size) const {
@ -216,11 +217,11 @@ ResultCode SaveDataArchive::CreateFile(const FileSys::Path& path, u64 size) cons
return ERROR_INVALID_PATH; return ERROR_INVALID_PATH;
} }
const auto full_path = path_parser.BuildHostPath(mount_point); const auto full_path = path_parser.BuildHostPath(ArchiveBackend::base_path + mount_point);
switch (path_parser.GetHostStatus(mount_point)) { switch (path_parser.GetHostStatus(ArchiveBackend::base_path + mount_point)) {
case PathParser::InvalidMountPoint: case PathParser::InvalidMountPoint:
LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", mount_point); LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", ArchiveBackend::base_path + mount_point);
return ERROR_FILE_NOT_FOUND; return ERROR_FILE_NOT_FOUND;
case PathParser::PathNotFound: case PathParser::PathNotFound:
LOG_ERROR(Service_FS, "Path not found {}", full_path); LOG_ERROR(Service_FS, "Path not found {}", full_path);
@ -261,11 +262,11 @@ ResultCode SaveDataArchive::CreateDirectory(const Path& path) const {
return ERROR_INVALID_PATH; return ERROR_INVALID_PATH;
} }
const auto full_path = path_parser.BuildHostPath(mount_point); const auto full_path = path_parser.BuildHostPath(ArchiveBackend::base_path + mount_point);
switch (path_parser.GetHostStatus(mount_point)) { switch (path_parser.GetHostStatus(ArchiveBackend::base_path + mount_point)) {
case PathParser::InvalidMountPoint: case PathParser::InvalidMountPoint:
LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", mount_point); LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", ArchiveBackend::base_path + mount_point);
return ERROR_FILE_NOT_FOUND; return ERROR_FILE_NOT_FOUND;
case PathParser::PathNotFound: case PathParser::PathNotFound:
LOG_ERROR(Service_FS, "Path not found {}", full_path); LOG_ERROR(Service_FS, "Path not found {}", full_path);
@ -281,11 +282,12 @@ ResultCode SaveDataArchive::CreateDirectory(const Path& path) const {
break; // Expected 'success' case break; // Expected 'success' case
} }
if (FileUtil::CreateDir(mount_point + path.AsString())) { if (FileUtil::CreateDir(ArchiveBackend::base_path + mount_point + path.AsString())) {
return RESULT_SUCCESS; return RESULT_SUCCESS;
} }
LOG_CRITICAL(Service_FS, "(unreachable) Unknown error creating {}", mount_point); LOG_CRITICAL(Service_FS, "(unreachable) Unknown error creating {}",
ArchiveBackend::base_path + mount_point + path.AsString());
return ResultCode(ErrorDescription::NoData, ErrorModule::FS, ErrorSummary::Canceled, return ResultCode(ErrorDescription::NoData, ErrorModule::FS, ErrorSummary::Canceled,
ErrorLevel::Status); ErrorLevel::Status);
} }
@ -306,8 +308,8 @@ ResultCode SaveDataArchive::RenameDirectory(const Path& src_path, const Path& de
return ERROR_INVALID_PATH; return ERROR_INVALID_PATH;
} }
const auto src_path_full = path_parser_src.BuildHostPath(mount_point); const auto src_path_full = path_parser_src.BuildHostPath(ArchiveBackend::base_path + mount_point);
const auto dest_path_full = path_parser_dest.BuildHostPath(mount_point); const auto dest_path_full = path_parser_dest.BuildHostPath(ArchiveBackend::base_path + mount_point);
if (FileUtil::Rename(src_path_full, dest_path_full)) { if (FileUtil::Rename(src_path_full, dest_path_full)) {
return RESULT_SUCCESS; return RESULT_SUCCESS;
@ -328,11 +330,11 @@ ResultVal<std::unique_ptr<DirectoryBackend>> SaveDataArchive::OpenDirectory(
return ERROR_INVALID_PATH; return ERROR_INVALID_PATH;
} }
const auto full_path = path_parser.BuildHostPath(mount_point); const auto full_path = path_parser.BuildHostPath(ArchiveBackend::base_path + mount_point);
switch (path_parser.GetHostStatus(mount_point)) { switch (path_parser.GetHostStatus(ArchiveBackend::base_path + mount_point)) {
case PathParser::InvalidMountPoint: case PathParser::InvalidMountPoint:
LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", mount_point); LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point {}", ArchiveBackend::base_path + mount_point);
return ERROR_FILE_NOT_FOUND; return ERROR_FILE_NOT_FOUND;
case PathParser::PathNotFound: case PathParser::PathNotFound:
case PathParser::NotFound: case PathParser::NotFound: