From 44bda41cf665f4e5bc1ee0162b84380e51b0f63c Mon Sep 17 00:00:00 2001 From: "Earle F. Philhower, III" Date: Thu, 30 May 2019 10:51:55 -0700 Subject: [PATCH] Add FS::info64 call for filesystems > 4GB (#6154) 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 | 2 ++ cores/esp8266/spiffs_api.h | 15 ++++++++++++++- libraries/LittleFS/src/LittleFS.h | 14 ++++++++++++++ libraries/SDFS/src/SDFS.h | 28 ++++++++++++++++++++++++---- 6 files changed, 74 insertions(+), 5 deletions(-) diff --git a/cores/esp8266/FS.cpp b/cores/esp8266/FS.cpp index 9461d9fdd..b5ca008f1 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 f30483d90..2d33f4808 100644 --- a/cores/esp8266/FS.h +++ b/cores/esp8266/FS.h @@ -137,6 +137,7 @@ protected: 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 @@ public: 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 a668f2887..6caea9ca2 100644 --- a/cores/esp8266/FSImpl.h +++ b/cores/esp8266/FSImpl.h @@ -22,6 +22,7 @@ #include #include +#include namespace fs { @@ -75,6 +76,7 @@ public: virtual void end() = 0; virtual bool format() = 0; virtual bool info(FSInfo& info) = 0; + 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 7312fa086..0491508f4 100644 --- a/cores/esp8266/spiffs_api.h +++ b/cores/esp8266/spiffs_api.h @@ -85,7 +85,6 @@ public: bool info(FSInfo& info) override { - info.maxOpenFiles = _maxOpenFds; info.blockSize = _blockSize; info.pageSize = _pageSize; info.maxOpenFiles = _maxOpenFds; @@ -101,6 +100,20 @@ public: 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 f81541557..6e6cae160 100644 --- a/libraries/LittleFS/src/LittleFS.h +++ b/libraries/LittleFS/src/LittleFS.h @@ -126,6 +126,20 @@ public: 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 ecae30732..db55fe547 100644 --- a/libraries/SDFS/src/SDFS.h +++ b/libraries/SDFS/src/SDFS.h @@ -94,7 +94,7 @@ public: 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 @@ public: 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,28 @@ public: 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; +#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; }