diff --git a/Sming/Components/IFS b/Sming/Components/IFS index 7054533606..0b3588a4db 160000 --- a/Sming/Components/IFS +++ b/Sming/Components/IFS @@ -1 +1 @@ -Subproject commit 70545336066e93e11bd5e6a70555c8a04d2e1b03 +Subproject commit 0b3588a4db2f0650bc9f57cf0edcfb0cb12272fc diff --git a/Sming/Libraries/LittleFS b/Sming/Libraries/LittleFS index 4b3ecd8ba8..5d41c9e136 160000 --- a/Sming/Libraries/LittleFS +++ b/Sming/Libraries/LittleFS @@ -1 +1 @@ -Subproject commit 4b3ecd8ba82bb9121ac4faa64f3bf4845b5d9d8c +Subproject commit 5d41c9e136dc5d0a15118de6ed1c6a1fc9c84c5f diff --git a/Sming/Libraries/Spiffs/src/FileSystem.cpp b/Sming/Libraries/Spiffs/src/FileSystem.cpp index d779f4f5c7..a698b4468a 100644 --- a/Sming/Libraries/Spiffs/src/FileSystem.cpp +++ b/Sming/Libraries/Spiffs/src/FileSystem.cpp @@ -27,6 +27,11 @@ namespace IFS { namespace SPIFFS { +#define CHECK_MOUNTED() \ + if(!SPIFFS_mounted(handle())) { \ + return Error::NotMounted; \ + } + struct FileDir { char path[SPIFFS_OBJ_NAME_LEN]; ///< Filter for readdir() unsigned pathlen; @@ -34,12 +39,6 @@ struct FileDir { spiffs_DIR d; }; -#define GET_FILEDIR() \ - if(dir == nullptr) { \ - return Error::InvalidHandle; \ - } \ - auto d = reinterpret_cast(dir); - constexpr uint32_t logicalBlockSize{4096 * 2}; namespace @@ -210,6 +209,7 @@ int FileSystem::getinfo(Info& info) info.type = Type::SPIFFS; info.maxNameLength = SPIFFS_OBJ_NAME_LEN - 1; info.maxPathLength = info.maxNameLength; + if(SPIFFS_mounted(handle())) { info.volumeID = fs.config_magic; info.attr |= Attribute::Mounted; @@ -247,8 +247,7 @@ String FileSystem::getErrorString(int err) FileHandle FileSystem::open(const char* path, OpenFlags flags) { - FS_CHECK_PATH(path); - if(path == nullptr) { + if(isRootPath(path)) { return Error::BadParam; } @@ -295,6 +294,8 @@ FileHandle FileSystem::open(const char* path, OpenFlags flags) int FileSystem::close(FileHandle file) { + CHECK_MOUNTED() + if(file < 0) { return Error::FileNotOpen; } @@ -327,6 +328,8 @@ int FileSystem::ftruncate(FileHandle file, size_t new_size) int FileSystem::flush(FileHandle file) { + CHECK_MOUNTED() + int res = flushMeta(file); int err = SPIFFS_fflush(handle(), file); if(err < 0) { @@ -431,6 +434,17 @@ int FileSystem::flushMeta(FileHandle file) int FileSystem::stat(const char* path, Stat* stat) { + CHECK_MOUNTED() + + if(isRootPath(path)) { + if(stat != nullptr) { + *stat = Stat{}; + stat->fs = this; + stat->attr += FileAttribute::Directory; + } + return FS_OK; + } + spiffs_stat ss; int err = SPIFFS_stat(handle(), path ?: "", &ss); if(err < 0) { @@ -486,6 +500,8 @@ int FileSystem::fstat(FileHandle file, Stat* stat) int FileSystem::fsetxattr(FileHandle file, AttributeTag tag, const void* data, size_t size) { + CHECK_MOUNTED() + auto smb = getMetaBuffer(file); if(smb == nullptr) { return Error::InvalidHandle; @@ -495,6 +511,8 @@ int FileSystem::fsetxattr(FileHandle file, AttributeTag tag, const void* data, s int FileSystem::fgetxattr(FileHandle file, AttributeTag tag, void* buffer, size_t size) { + CHECK_MOUNTED() + auto smb = getMetaBuffer(file); if(smb == nullptr) { return Error::InvalidHandle; @@ -505,7 +523,7 @@ int FileSystem::fgetxattr(FileHandle file, AttributeTag tag, void* buffer, size_ int FileSystem::setxattr(const char* path, AttributeTag tag, const void* data, size_t size) { #ifdef SPIFFS_STORE_META - FS_CHECK_PATH(path); + FS_CHECK_PATH(path) spiffs_stat ss; int err = SPIFFS_stat(handle(), path ?: "", &ss); if(err < 0) { @@ -530,7 +548,7 @@ int FileSystem::setxattr(const char* path, AttributeTag tag, const void* data, s int FileSystem::getxattr(const char* path, AttributeTag tag, void* buffer, size_t size) { #ifdef SPIFFS_STORE_META - FS_CHECK_PATH(path); + FS_CHECK_PATH(path) spiffs_stat ss; int err = SPIFFS_stat(handle(), path, &ss); if(err < 0) { @@ -546,7 +564,9 @@ int FileSystem::getxattr(const char* path, AttributeTag tag, void* buffer, size_ int FileSystem::opendir(const char* path, DirHandle& dir) { - FS_CHECK_PATH(path); + CHECK_MOUNTED() + + isRootPath(path); unsigned pathlen = 0; if(path != nullptr) { pathlen = strlen(path); @@ -696,9 +716,7 @@ int FileSystem::mkdir(const char* path) int FileSystem::rename(const char* oldpath, const char* newpath) { - FS_CHECK_PATH(oldpath); - FS_CHECK_PATH(newpath); - if(oldpath == nullptr || newpath == nullptr) { + if(isRootPath(oldpath) || isRootPath(newpath)) { return Error::BadParam; } @@ -708,8 +726,7 @@ int FileSystem::rename(const char* oldpath, const char* newpath) int FileSystem::remove(const char* path) { - FS_CHECK_PATH(path); - if(path == nullptr) { + if(isRootPath(path)) { return Error::BadParam; } @@ -733,6 +750,8 @@ int FileSystem::remove(const char* path) int FileSystem::fremove(FileHandle file) { + CHECK_MOUNTED() + // If file is marked read-only, fail request auto smb = getMetaBuffer(file); if(smb == nullptr) { diff --git a/samples/Basic_IFS/app/application.cpp b/samples/Basic_IFS/app/application.cpp index a721a7907f..e1a9223c1c 100644 --- a/samples/Basic_IFS/app/application.cpp +++ b/samples/Basic_IFS/app/application.cpp @@ -110,10 +110,8 @@ bool initFileSystem() { fileFreeFileSystem(); -#if DEBUG_BUILD - auto freeheap = system_get_free_heap_size(); -#endif - debug_i("1: heap = %u", freeheap); + auto initialFreeheap = system_get_free_heap_size(); + debug_i("Initial freeheap = %u", initialFreeheap); #ifdef ENABLE_FLASHSTRING_IMAGE // Create a partition wrapping some flashstring data @@ -124,25 +122,53 @@ bool initFileSystem() // Read-only auto fs = IFS::createFirmwareFilesystem(part); - debug_i("2: heap = -%u", freeheap - system_get_free_heap_size()); if(fs == nullptr) { debug_e("Failed to created filesystem object"); return false; } - int res = fs->mount(); - debug_i("3: heap = -%u", freeheap - system_get_free_heap_size()); - - debug_i("mount() returned %d (%s)", res, fs->getErrorString(res).c_str()); + auto mount = [&](IFS::FileSystem* fs) { + int res = fs->mount(); + debug_i("heap used: %u, mount() returned %d (%s)", initialFreeheap - system_get_free_heap_size(), res, + fs->getErrorString(res).c_str()); + return res == FS_OK; + }; - if(res < 0) { + if(!mount(fs)) { delete fs; return false; } + // Make this the default filesystem fileSetFileSystem(fs); + // Let's mount an LFS volume as well + initialFreeheap = system_get_free_heap_size(); + part = Storage::findDefaultPartition(Storage::Partition::SubType::Data::littlefs); + auto lfs = IFS::createLfsFilesystem(part); + if(lfs == nullptr) { + debug_e("Failed to create LFS filesystem"); + } else if(mount(lfs)) { + // Place the root of this volume at index #0 (the corresponding directory is given in `fwimage.fwfs`) + fs->setVolume(0, lfs); + } else { + delete lfs; + } + + // And we'll mount a SPIFFS volume too + initialFreeheap = system_get_free_heap_size(); + part = Storage::findDefaultPartition(Storage::Partition::SubType::Data::spiffs); + auto spiffs = IFS::createSpiffsFilesystem(part); + if(spiffs == nullptr) { + debug_e("Failed to create SPIFFS filesystem"); + } else if(mount(spiffs)) { + // Place the root of this volume at index #1 + fs->setVolume(1, spiffs); + } else { + delete spiffs; + } + debug_i("File system initialised"); return true; } diff --git a/samples/Basic_IFS/fsimage.fwfs b/samples/Basic_IFS/fsimage.fwfs index b8e7cbe19a..8e63a810cd 100644 --- a/samples/Basic_IFS/fsimage.fwfs +++ b/samples/Basic_IFS/fsimage.fwfs @@ -15,7 +15,8 @@ }, // Directories to mount other object stores "mountpoints": { - "config": 1 + "littlefs": 0, + "spiffs": 1 }, // Rules for file metadata. All rules are evaluated in sequence for every file "rules": [