MBRBlockDevice: When partitioning, clear the rest of first erase unit

Make sure all the parts of the first erase unit, that are not part of the
partition table are clear.
pull/9384/head
David Saada 2019-01-15 16:26:45 +02:00
parent aff2bee8a4
commit af23e3f489
2 changed files with 72 additions and 2 deletions

View File

@ -21,6 +21,7 @@
#include "HeapBlockDevice.h"
#include "FATFileSystem.h"
#include "MBRBlockDevice.h"
#include "LittleFileSystem.h"
#include <stdlib.h>
#include "mbed_retarget.h"
@ -221,9 +222,66 @@ void test_single_mbr()
TEST_ASSERT_EQUAL(0, err);
delete bd;
bd = 0;
}
void test_with_other_fs()
{
TEST_SKIP_UNLESS_MESSAGE(bd, "Not enough heap memory to run test. Test skipped.");
// Stage 0 - LittleFS
// Stage 1 - FatFS with MBR
// Stage 2 - LittleFS
// Make sure that at no stage we are able to mount the current file system after using the
// previous one
// start from scratch in this test
bd = new (std::nothrow) HeapBlockDevice(BLOCK_COUNT * BLOCK_SIZE, BLOCK_SIZE);
TEST_SKIP_UNLESS_MESSAGE(bd, "Not enough heap memory to run test. Test skipped.");
int err;
for (int stage = 0; stage < 3; stage++) {
BlockDevice *part;
FileSystem *fs;
if (stage == 1) {
printf("Stage %d: FAT FS\n", stage + 1);
err = MBRBlockDevice::partition(bd, 1, 0x83, 0, BLOCK_COUNT * BLOCK_SIZE);
TEST_ASSERT_EQUAL(0, err);
part = new (std::nothrow) MBRBlockDevice(bd, 1);
TEST_SKIP_UNLESS_MESSAGE(part, "Not enough heap memory to run test. Test skipped.");
err = part->init();
TEST_ASSERT_EQUAL(0, err);
fs = new FATFileSystem("fat");
} else {
printf("Stage %d: Little FS\n", stage + 1);
part = bd;
fs = new LittleFileSystem("lfs");
}
TEST_SKIP_UNLESS_MESSAGE(fs, "Not enough heap memory to run test. Test skipped.");
err = fs->mount(part);
TEST_ASSERT_NOT_EQUAL(0, err);
err = fs->reformat(part);
TEST_ASSERT_EQUAL(0, err);
err = fs->unmount();
TEST_ASSERT_EQUAL(0, err);
delete fs;
if (stage == 1) {
delete part;
}
}
delete bd;
bd = 0;
}
// Test setup
utest::v1::status_t test_setup(const size_t number_of_cases)
@ -237,6 +295,7 @@ Case cases[] = {
Case("Testing read write < block", test_read_write < BLOCK_SIZE / 2 >),
Case("Testing read write > block", test_read_write<2 * BLOCK_SIZE>),
Case("Testing for no extra MBRs", test_single_mbr),
Case("Testing with other file system", test_with_other_fs),
};
Specification specification(test_setup, cases);

View File

@ -92,8 +92,9 @@ static int partition_absolute(
return err;
}
uint32_t table_start_offset = buffer_size - sizeof(struct mbr_table);
struct mbr_table *table = reinterpret_cast<struct mbr_table *>(
&buffer[buffer_size - sizeof(struct mbr_table)]);
&buffer[table_start_offset]);
if (table->signature[0] != 0x55 || table->signature[1] != 0xaa) {
// Setup default values for MBR
table->signature[0] = 0x55;
@ -143,6 +144,16 @@ static int partition_absolute(
}
}
// As the erase operation may do nothing, erase remainder of the buffer, to eradicate
// any remaining programmed data (such as previously programmed file systems).
if (table_start_offset > 0) {
memset(buffer, 0xFF, table_start_offset);
}
if (table_start_offset + sizeof(struct mbr_table) < buffer_size) {
memset(buffer + table_start_offset + sizeof(struct mbr_table), 0xFF,
buffer_size - (table_start_offset + sizeof(struct mbr_table)));
}
// Write out MBR
err = bd->erase(0, bd->get_erase_size());
if (err) {