From cc1bad90a7a4fea53e894c5eb208109afdd88ebe Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Tue, 21 Aug 2018 17:23:32 -0500 Subject: [PATCH] littlefs: Fixed issue with cleanup in mount function on error As a part of the v1.6 update, littlefs added proper handling for cleaning up memory in the case of an error during mount. This took care of a memory leak users were seeing. Ironically, it turns out the implementation and user patterns in mbed-os was _relying_ on this memory leak to avoid a double free in the same case of an error during mount. The issue was that a failed mount would leave the LittleFileSystem class in a state where it thought it was mounted, and later it would attempt to unmount the filesystem. With the previous memory leak this would be "ok", and the leaked memory would be freed. But with the fix in v1.6, no memory is leaked, and the incorrect free triggers a hard fault. Fixed to clean up state properly on failed mounts. --- .../filesystem/littlefs/LittleFileSystem.cpp | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/features/filesystem/littlefs/LittleFileSystem.cpp b/features/filesystem/littlefs/LittleFileSystem.cpp index 269dafab39..74f52f3278 100644 --- a/features/filesystem/littlefs/LittleFileSystem.cpp +++ b/features/filesystem/littlefs/LittleFileSystem.cpp @@ -134,6 +134,7 @@ int LittleFileSystem::mount(BlockDevice *bd) _bd = bd; int err = _bd->init(); if (err) { + _bd = NULL; LFS_INFO("mount -> %d", err); _mutex.unlock(); return err; @@ -164,36 +165,40 @@ int LittleFileSystem::mount(BlockDevice *bd) } err = lfs_mount(&_lfs, &_config); - LFS_INFO("mount -> %d", lfs_toerror(err)); + if (err) { + _bd = NULL; + LFS_INFO("mount -> %d", lfs_toerror(err)); + _mutex.unlock(); + return lfs_toerror(err); + } + _mutex.unlock(); - return lfs_toerror(err); + LFS_INFO("mount -> %d", 0); + return 0; } int LittleFileSystem::unmount() { _mutex.lock(); LFS_INFO("unmount(%s)", ""); + int res = 0; if (_bd) { int err = lfs_unmount(&_lfs); - if (err) { - LFS_INFO("unmount -> %d", lfs_toerror(err)); - _mutex.unlock(); - return lfs_toerror(err); + if (err && !res) { + res = lfs_toerror(err); } err = _bd->deinit(); - if (err) { - LFS_INFO("unmount -> %d", err); - _mutex.unlock(); - return err; + if (err && !res) { + res = err; } _bd = NULL; } - LFS_INFO("unmount -> %d", 0); + LFS_INFO("unmount -> %d", res); _mutex.unlock(); - return 0; + return res; } int LittleFileSystem::format(BlockDevice *bd,