Skip to content

fatfs: Add erase disk to format #6866

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
May 21, 2018
Merged

fatfs: Add erase disk to format #6866

merged 1 commit into from
May 21, 2018

Conversation

geky
Copy link
Contributor

@geky geky commented May 10, 2018

Description

Right now, many users are trying out many different filesystems. Unfortunately, this can leave partially written filesystems on disk in various states.

A common pattern for using embedded filesystems is to attempt a mount, and on failure, format the storage with the filesystem.

Unfortunately, this simply doesn't work if you try to change the filesystem being used on a piece of storage. Filesystems don't always use the same regions of storage, and can leave enough metadata lying
around from old filesystems to trick a different mount into thinking a valid filesystem exists on disk. The filesystems we have were never designed to check for malicious modification and can't protect against
arbitrary changes.


That being said, it's caused enough problems for users, so as a workaround, this patch adds a disk erase to the FAT filesystem format. The most common error happens when you use LittleFS, followed by FAT,
followed again by LittleFS.

No other combination of filesystem usage has shown a similar failure, but it is possible after extensive filesystem use, so I would still heavily suggest that you force a format of the storage when changing filesystems.

Note

This needs significant review before merging, but I believe it is a welcomed fix:
needs testing
cc @dannybenor, @davidsaada, @deepikabhavnani, @kegilbert, @cmonr, @moranpeker, @karsev
related #5871, ARMmbed/mbed-os-example-filesystem#21

TODO

  • Test

Pull request type

[ ] Fix
[ ] Refactor
[ ] New target
[x] Feature
[ ] Breaking change

Copy link
Contributor

@davidsaada davidsaada left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. Just a few small artifacts.


if (bd->get_erase_value() < 0) {
// erase is unknown, need to write 1s
void *buf = malloc(bd->get_program_size());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we're on a C++ module, guess it would make more sense to use new[] and delete[] rather than malloc and free.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still use malloc when I want a blob of raw memory. new[] and delete[] are important for staying within the type system, but here the memory allocated is intentionally without type.


memset(buf, 0xff, bd->get_program_size());

for (bd_addr_t i = 0; i < bd->size(); i += bd->get_program_size()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest to store the program size in a local variable. Getting it from the bd each time (certainly inside the loop) is a bit inefficient.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was surprised, I expected the compiler to optimize this call out, but it didn't at all!

}

// erase disk
err = bd->erase(0, bd->size());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this solution work for all block devices? In case of SD we do not implement erase, erase is done as part of trim.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It checks erase_value below. If erase_value is negative (default), erase isn't trusted and 1s are written out.

err = bd->erase(0, bd->size());
if (err) {
fs.unlock();
return err;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case of error deinit operation should be performed before unlock and return.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should be updated

for (bd_addr_t i = 0; i < bd->size(); i += bd->get_program_size()) {
err = bd->program(buf, i, bd->get_program_size());
if (err) {
free(buf);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

deinit?

if (res != FR_OK) {
fs.unlock();
return fat_error_remap(res);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can return old error, but don't return without un-mount operation

@geky geky force-pushed the fat-erase-disk branch 2 times, most recently from 8619c20 to b567ce4 Compare May 14, 2018 15:29
Right now, many users are trying out many different filesystems.
Unfortunately, this can leave partially written filesystems on disk
in various states.

A very common pattern for using embedded filesystems is to attempt
a mount, and on failure, format the storage with the filesystem.

Unfortunately, this simply doesn't work if you try to change the
filesystem being used on a piece of storage. Filesystems don't always
use the same regions of storage, and can leave enough metadata lying
around from old filesystems to trick a different mount into thinking a
valid filesystem exists on disk. The filesystems we have were never
designed to check for malicious modification and can't protect against
arbitrary changes.

That being said, it's caused enough problems for users, so as a
workaround this patch adds a disk erase to the FAT filesystem format.
The most common error happens when you use LittleFS, followed by FAT,
followed again by LittleFS.

No other combination of filesystem usage has shown a similar failure,
but it is possible after extensive filesystem use, so it is still
suggested to force a format of the storage when changing filesystems.
@geky
Copy link
Contributor Author

geky commented May 14, 2018

Discussion with @deepikabhavnani: For runtime we should only erase first couple of blocks and trim remaining storage. The erase is required, where the trim is a suggestion to the block device.

Copy link

@deepikabhavnani deepikabhavnani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good

@cmonr
Copy link
Contributor

cmonr commented May 14, 2018

/morph build

@mbed-ci
Copy link

mbed-ci commented May 14, 2018

Build : SUCCESS

Build number : 2015
Build artifacts/logs : http://mbed-os.s3-website-eu-west-1.amazonaws.com/?prefix=builds/6866/

Triggering tests

/morph test
/morph uvisor-test
/morph export-build
/morph mbed2-build

@mbed-ci
Copy link

mbed-ci commented May 15, 2018

@mbed-ci
Copy link

mbed-ci commented May 15, 2018

@cmonr
Copy link
Contributor

cmonr commented May 15, 2018

@davidsaada Could you re-review?

Copy link
Contributor

@davidsaada davidsaada left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.

@0xc0170
Copy link
Contributor

0xc0170 commented May 16, 2018

This needs significant review before merging, but I believe it is a welcomed fix:
needs testing
cc @dannybenor, @davidsaada, @deepikabhavnani, @kegilbert, @cmonr, @moranpeker, @karsev

As requested, this should get more approvals

@0xc0170 0xc0170 requested a review from bulislaw May 18, 2018 11:14
@adbridge
Copy link
Contributor

@dannybenor, @deepikabhavnani, @kegilbert, @cmonr, @moranpeker, @karsev Could we please have your reviews on this asap?

@dannybenor
Copy link

Looks good to me

@cmonr cmonr merged commit cd1ff94 into ARMmbed:master May 21, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants