Skip to content

Commit 603c4f9

Browse files
authored
Merge pull request #7851 from geky/fix-littlefs-mount-cleanup
littlefs: Fixed issue with cleanup in mount function on error
2 parents f5fb3c1 + 475cc6b commit 603c4f9

File tree

2 files changed

+216
-12
lines changed

2 files changed

+216
-12
lines changed

features/filesystem/littlefs/LittleFileSystem.cpp

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ int LittleFileSystem::mount(BlockDevice *bd)
134134
_bd = bd;
135135
int err = _bd->init();
136136
if (err) {
137+
_bd = NULL;
137138
LFS_INFO("mount -> %d", err);
138139
_mutex.unlock();
139140
return err;
@@ -164,36 +165,40 @@ int LittleFileSystem::mount(BlockDevice *bd)
164165
}
165166

166167
err = lfs_mount(&_lfs, &_config);
167-
LFS_INFO("mount -> %d", lfs_toerror(err));
168+
if (err) {
169+
_bd = NULL;
170+
LFS_INFO("mount -> %d", lfs_toerror(err));
171+
_mutex.unlock();
172+
return lfs_toerror(err);
173+
}
174+
168175
_mutex.unlock();
169-
return lfs_toerror(err);
176+
LFS_INFO("mount -> %d", 0);
177+
return 0;
170178
}
171179

172180
int LittleFileSystem::unmount()
173181
{
174182
_mutex.lock();
175183
LFS_INFO("unmount(%s)", "");
184+
int res = 0;
176185
if (_bd) {
177186
int err = lfs_unmount(&_lfs);
178-
if (err) {
179-
LFS_INFO("unmount -> %d", lfs_toerror(err));
180-
_mutex.unlock();
181-
return lfs_toerror(err);
187+
if (err && !res) {
188+
res = lfs_toerror(err);
182189
}
183190

184191
err = _bd->deinit();
185-
if (err) {
186-
LFS_INFO("unmount -> %d", err);
187-
_mutex.unlock();
188-
return err;
192+
if (err && !res) {
193+
res = err;
189194
}
190195

191196
_bd = NULL;
192197
}
193198

194-
LFS_INFO("unmount -> %d", 0);
199+
LFS_INFO("unmount -> %d", res);
195200
_mutex.unlock();
196-
return 0;
201+
return res;
197202
}
198203

199204
int LittleFileSystem::format(BlockDevice *bd,
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2017 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
#include "mbed.h"
17+
#include "greentea-client/test_env.h"
18+
#include "unity.h"
19+
#include "utest.h"
20+
#include <stdlib.h>
21+
#include <errno.h>
22+
23+
using namespace utest::v1;
24+
25+
// test configuration
26+
#ifndef MBED_TEST_FILESYSTEM
27+
#define MBED_TEST_FILESYSTEM LittleFileSystem
28+
#endif
29+
30+
#ifndef MBED_TEST_FILESYSTEM_DECL
31+
#define MBED_TEST_FILESYSTEM_DECL MBED_TEST_FILESYSTEM fs("fs")
32+
#endif
33+
34+
#ifndef MBED_TEST_BLOCKDEVICE
35+
#error [NOT_SUPPORTED] Non-volatile block device required
36+
#endif
37+
38+
#ifndef MBED_TEST_BLOCKDEVICE_DECL
39+
#define MBED_TEST_BLOCKDEVICE_DECL MBED_TEST_BLOCKDEVICE bd
40+
#endif
41+
42+
#ifndef MBED_TEST_FILES
43+
#define MBED_TEST_FILES 4
44+
#endif
45+
46+
#ifndef MBED_TEST_DIRS
47+
#define MBED_TEST_DIRS 4
48+
#endif
49+
50+
#ifndef MBED_TEST_BUFFER
51+
#define MBED_TEST_BUFFER 8192
52+
#endif
53+
54+
#ifndef MBED_TEST_TIMEOUT
55+
#define MBED_TEST_TIMEOUT 480
56+
#endif
57+
58+
59+
// declarations
60+
#define STRINGIZE(x) STRINGIZE2(x)
61+
#define STRINGIZE2(x) #x
62+
#define INCLUDE(x) STRINGIZE(x.h)
63+
64+
#include INCLUDE(MBED_TEST_FILESYSTEM)
65+
#include INCLUDE(MBED_TEST_BLOCKDEVICE)
66+
67+
MBED_TEST_FILESYSTEM_DECL;
68+
MBED_TEST_BLOCKDEVICE_DECL;
69+
70+
Dir dir[MBED_TEST_DIRS];
71+
File file[MBED_TEST_FILES];
72+
DIR *dd[MBED_TEST_DIRS];
73+
FILE *fd[MBED_TEST_FILES];
74+
struct dirent ent;
75+
struct dirent *ed;
76+
size_t size;
77+
uint8_t buffer[MBED_TEST_BUFFER];
78+
uint8_t rbuffer[MBED_TEST_BUFFER];
79+
uint8_t wbuffer[MBED_TEST_BUFFER];
80+
81+
82+
// tests for integration level format operations
83+
84+
void test_format()
85+
{
86+
int res = bd.init();
87+
TEST_ASSERT_EQUAL(0, res);
88+
89+
{
90+
res = MBED_TEST_FILESYSTEM::format(&bd);
91+
TEST_ASSERT_EQUAL(0, res);
92+
}
93+
94+
res = bd.deinit();
95+
TEST_ASSERT_EQUAL(0, res);
96+
}
97+
98+
void test_mount()
99+
{
100+
int res = bd.init();
101+
TEST_ASSERT_EQUAL(0, res);
102+
103+
{
104+
res = fs.mount(&bd);
105+
TEST_ASSERT_EQUAL(0, res);
106+
res = fs.unmount();
107+
TEST_ASSERT_EQUAL(0, res);
108+
}
109+
110+
res = bd.deinit();
111+
TEST_ASSERT_EQUAL(0, res);
112+
}
113+
114+
void test_bad_mount()
115+
{
116+
int res = bd.init();
117+
TEST_ASSERT_EQUAL(0, res);
118+
119+
{
120+
res = bd.erase(0, 2*bd.get_erase_size());
121+
TEST_ASSERT_EQUAL(0, res);
122+
memset(buffer, 0, bd.get_program_size());
123+
for (int i = 0; i < 2*bd.get_erase_size(); i += bd.get_program_size()) {
124+
res = bd.program(buffer, i, bd.get_program_size());
125+
TEST_ASSERT_EQUAL(0, res);
126+
}
127+
}
128+
129+
{
130+
res = fs.mount(&bd);
131+
TEST_ASSERT_NOT_EQUAL(0, res);
132+
}
133+
134+
res = bd.deinit();
135+
TEST_ASSERT_EQUAL(0, res);
136+
}
137+
138+
void test_bad_mount_then_reformat()
139+
{
140+
int res = bd.init();
141+
TEST_ASSERT_EQUAL(0, res);
142+
143+
{
144+
res = fs.mount(&bd);
145+
TEST_ASSERT_NOT_EQUAL(0, res);
146+
147+
res = fs.reformat(&bd);
148+
TEST_ASSERT_EQUAL(0, res);
149+
150+
res = fs.unmount();
151+
TEST_ASSERT_EQUAL(0, res);
152+
}
153+
154+
res = bd.deinit();
155+
TEST_ASSERT_EQUAL(0, res);
156+
}
157+
158+
void test_good_mount_then_reformat()
159+
{
160+
int res = bd.init();
161+
TEST_ASSERT_EQUAL(0, res);
162+
163+
{
164+
res = fs.mount(&bd);
165+
TEST_ASSERT_EQUAL(0, res);
166+
167+
res = fs.reformat(&bd);
168+
TEST_ASSERT_EQUAL(0, res);
169+
170+
res = fs.unmount();
171+
TEST_ASSERT_EQUAL(0, res);
172+
}
173+
174+
res = bd.deinit();
175+
TEST_ASSERT_EQUAL(0, res);
176+
}
177+
178+
179+
// test setup
180+
utest::v1::status_t test_setup(const size_t number_of_cases)
181+
{
182+
GREENTEA_SETUP(MBED_TEST_TIMEOUT, "default_auto");
183+
return verbose_test_setup_handler(number_of_cases);
184+
}
185+
186+
Case cases[] = {
187+
Case("Test format", test_format),
188+
Case("Test mount", test_mount),
189+
Case("Test bad mount", test_bad_mount),
190+
Case("Test bad mount than reformat", test_bad_mount_then_reformat),
191+
Case("Test good mount than reformat", test_good_mount_then_reformat),
192+
};
193+
194+
Specification specification(test_setup, cases);
195+
196+
int main()
197+
{
198+
return !Harness::run(specification);
199+
}

0 commit comments

Comments
 (0)