Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "HeapBlockDevice.h"
#include "FATFileSystem.h"
#include "MBRBlockDevice.h"
#include "LittleFileSystem.h"
#include <stdlib.h>
#include "mbed_retarget.h"

Expand Down Expand Up @@ -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)
Expand All @@ -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);
Expand Down
13 changes: 12 additions & 1 deletion features/storage/blockdevice/MBRBlockDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down