From 970850cedd887d47afbe6e4cb0120314d72ecc26 Mon Sep 17 00:00:00 2001 From: "Earle F. Philhower, III" Date: Mon, 27 May 2019 13:26:39 -0700 Subject: [PATCH 1/2] Add FS::info64 call for fielsystems > 4GB Fixes #6082 Add an info64() call which returns used and total sizes as 64 bit quantities. A default wrapper that just copies the 32-bit values is included for LittleFS/SPIFFS which can't hit those capacities. --- cores/esp8266/FS.cpp | 7 +++++++ cores/esp8266/FS.h | 13 +++++++++++++ cores/esp8266/FSImpl.h | 15 +++++++++++++++ cores/esp8266/spiffs_api.h | 1 - libraries/SDFS/src/SDFS.h | 22 ++++++++++++++++++---- 5 files changed, 53 insertions(+), 5 deletions(-) diff --git a/cores/esp8266/FS.cpp b/cores/esp8266/FS.cpp index 9461d9fddc..b5ca008f1c 100644 --- a/cores/esp8266/FS.cpp +++ b/cores/esp8266/FS.cpp @@ -283,6 +283,13 @@ bool FS::info(FSInfo& info){ return _impl->info(info); } +bool FS::info64(FSInfo64& info){ + if (!_impl) { + return false; + } + return _impl->info64(info); +} + File FS::open(const String& path, const char* mode) { return open(path.c_str(), mode); } diff --git a/cores/esp8266/FS.h b/cores/esp8266/FS.h index f30483d901..2d33f48084 100644 --- a/cores/esp8266/FS.h +++ b/cores/esp8266/FS.h @@ -137,6 +137,7 @@ class Dir { FS *_baseFS; }; +// Backwards compatible, <4GB filesystem usage struct FSInfo { size_t totalBytes; size_t usedBytes; @@ -146,6 +147,17 @@ struct FSInfo { size_t maxPathLength; }; +// Support > 4GB filesystems (SD, etc.) +struct FSInfo64 { + uint64_t totalBytes; + uint64_t usedBytes; + size_t blockSize; + size_t pageSize; + size_t maxOpenFiles; + size_t maxPathLength; +}; + + class FSConfig { public: @@ -186,6 +198,7 @@ class FS bool format(); bool info(FSInfo& info); + bool info64(FSInfo64& info); File open(const char* path, const char* mode); File open(const String& path, const char* mode); diff --git a/cores/esp8266/FSImpl.h b/cores/esp8266/FSImpl.h index a668f2887d..90ad18d0ce 100644 --- a/cores/esp8266/FSImpl.h +++ b/cores/esp8266/FSImpl.h @@ -22,6 +22,7 @@ #include #include +#include namespace fs { @@ -75,6 +76,20 @@ class FSImpl { virtual void end() = 0; virtual bool format() = 0; virtual bool info(FSInfo& info) = 0; + // For seamless backward compatibilty, supply default which just copies form the 32bit version + virtual bool info64(FSInfo64& info64) { + FSInfo i; + if (!info(i)) { + return false; + } + info64.blockSize = i.blockSize; + info64.pageSize = i.pageSize; + info64.maxOpenFiles = i.maxOpenFiles; + info64.maxPathLength = i.maxPathLength; + info64.totalBytes = i.totalBytes; + info64.usedBytes = i.usedBytes; + return true; + } virtual FileImplPtr open(const char* path, OpenMode openMode, AccessMode accessMode) = 0; virtual bool exists(const char* path) = 0; virtual DirImplPtr openDir(const char* path) = 0; diff --git a/cores/esp8266/spiffs_api.h b/cores/esp8266/spiffs_api.h index 7312fa0867..7c818fc486 100644 --- a/cores/esp8266/spiffs_api.h +++ b/cores/esp8266/spiffs_api.h @@ -85,7 +85,6 @@ class SPIFFSImpl : public FSImpl bool info(FSInfo& info) override { - info.maxOpenFiles = _maxOpenFds; info.blockSize = _blockSize; info.pageSize = _pageSize; info.maxOpenFiles = _maxOpenFds; diff --git a/libraries/SDFS/src/SDFS.h b/libraries/SDFS/src/SDFS.h index ecae30732f..624b8d5764 100644 --- a/libraries/SDFS/src/SDFS.h +++ b/libraries/SDFS/src/SDFS.h @@ -94,7 +94,7 @@ class SDFSImpl : public FSImpl FileImplPtr open(const char* path, OpenMode openMode, AccessMode accessMode) override; - bool exists(const char* path) { + bool exists(const char* path) override { return _mounted ? _fs.exists(path) : false; } @@ -104,7 +104,7 @@ class SDFSImpl : public FSImpl return _mounted ? _fs.rename(pathFrom, pathTo) : false; } - bool info(FSInfo& info) override { + bool info64(FSInfo64& info) override { if (!_mounted) { DEBUGV("SDFS::info: FS not mounted\n"); return false; @@ -113,8 +113,22 @@ class SDFSImpl : public FSImpl info.blockSize = _fs.vol()->blocksPerCluster() * 512; info.pageSize = 0; // TODO ? info.maxPathLength = 255; // TODO ? - info.totalBytes =_fs.vol()->volumeBlockCount() * 512; - info.usedBytes = info.totalBytes - (_fs.vol()->freeClusterCount() * _fs.vol()->blocksPerCluster() * 512); + info.totalBytes =_fs.vol()->volumeBlockCount() * 512LL; + info.usedBytes = info.totalBytes - (_fs.vol()->freeClusterCount() * _fs.vol()->blocksPerCluster() * 512LL); + return true; + } + + bool info(FSInfo& info) override { + FSInfo64 i; + if (!info64(i)) { + return false; + } + info.blockSize = i.blockSize; + info.pageSize = i.pageSize; + info.maxOpenFiles = i.maxOpenFiles; + info.maxPathLength = i.maxPathLength; + info.totalBytes = (size_t)i.totalBytes; + info.usedBytes = (size_t)i.usedBytes; return true; } From f43f840573e3d59be6c74bffa5aade5c51ce46e3 Mon Sep 17 00:00:00 2001 From: "Earle F. Philhower, III" Date: Tue, 28 May 2019 07:08:44 -0700 Subject: [PATCH 2/2] Remove info64 default impl, add 4G overflow warn --- cores/esp8266/FSImpl.h | 15 +-------------- cores/esp8266/spiffs_api.h | 14 ++++++++++++++ libraries/LittleFS/src/LittleFS.h | 14 ++++++++++++++ libraries/SDFS/src/SDFS.h | 6 ++++++ 4 files changed, 35 insertions(+), 14 deletions(-) diff --git a/cores/esp8266/FSImpl.h b/cores/esp8266/FSImpl.h index 90ad18d0ce..6caea9ca2f 100644 --- a/cores/esp8266/FSImpl.h +++ b/cores/esp8266/FSImpl.h @@ -76,20 +76,7 @@ class FSImpl { virtual void end() = 0; virtual bool format() = 0; virtual bool info(FSInfo& info) = 0; - // For seamless backward compatibilty, supply default which just copies form the 32bit version - virtual bool info64(FSInfo64& info64) { - FSInfo i; - if (!info(i)) { - return false; - } - info64.blockSize = i.blockSize; - info64.pageSize = i.pageSize; - info64.maxOpenFiles = i.maxOpenFiles; - info64.maxPathLength = i.maxPathLength; - info64.totalBytes = i.totalBytes; - info64.usedBytes = i.usedBytes; - return true; - } + virtual bool info64(FSInfo64& info) = 0; virtual FileImplPtr open(const char* path, OpenMode openMode, AccessMode accessMode) = 0; virtual bool exists(const char* path) = 0; virtual DirImplPtr openDir(const char* path) = 0; diff --git a/cores/esp8266/spiffs_api.h b/cores/esp8266/spiffs_api.h index 7c818fc486..0491508f4d 100644 --- a/cores/esp8266/spiffs_api.h +++ b/cores/esp8266/spiffs_api.h @@ -100,6 +100,20 @@ class SPIFFSImpl : public FSImpl return true; } + virtual bool info64(FSInfo64& info64) { + FSInfo i; + if (!info(i)) { + return false; + } + info64.blockSize = i.blockSize; + info64.pageSize = i.pageSize; + info64.maxOpenFiles = i.maxOpenFiles; + info64.maxPathLength = i.maxPathLength; + info64.totalBytes = i.totalBytes; + info64.usedBytes = i.usedBytes; + return true; + } + bool remove(const char* path) override { if (!isSpiffsFilenameValid(path)) { diff --git a/libraries/LittleFS/src/LittleFS.h b/libraries/LittleFS/src/LittleFS.h index f81541557c..6e6cae160d 100644 --- a/libraries/LittleFS/src/LittleFS.h +++ b/libraries/LittleFS/src/LittleFS.h @@ -126,6 +126,20 @@ class LittleFSImpl : public FSImpl return true; } + virtual bool info64(FSInfo64& info64) { + FSInfo i; + if (!info(i)) { + return false; + } + info64.blockSize = i.blockSize; + info64.pageSize = i.pageSize; + info64.maxOpenFiles = i.maxOpenFiles; + info64.maxPathLength = i.maxPathLength; + info64.totalBytes = i.totalBytes; + info64.usedBytes = i.usedBytes; + return true; + } + bool remove(const char* path) override { if (!_mounted || !path || !path[0]) { return false; diff --git a/libraries/SDFS/src/SDFS.h b/libraries/SDFS/src/SDFS.h index 624b8d5764..db55fe547a 100644 --- a/libraries/SDFS/src/SDFS.h +++ b/libraries/SDFS/src/SDFS.h @@ -127,6 +127,12 @@ class SDFSImpl : public FSImpl info.pageSize = i.pageSize; info.maxOpenFiles = i.maxOpenFiles; info.maxPathLength = i.maxPathLength; +#ifdef DEBUG_ESP_PORT + if (i.totalBytes > (uint64_t)SIZE_MAX) { + // This catches both total and used cases, since used must always be < total. + DEBUG_ESP_PORT.printf_P(PSTR("WARNING: SD card size overflow (%lld>= 4GB). Please update source to use info64().\n"), i.totalBytes); + } +#endif info.totalBytes = (size_t)i.totalBytes; info.usedBytes = (size_t)i.usedBytes; return true;