-
Notifications
You must be signed in to change notification settings - Fork 3k
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
Conversation
There was a problem hiding this 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()); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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()) { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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()); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point 👍
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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
8619c20
to
b567ce4
Compare
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.
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good
/morph build |
Build : SUCCESSBuild number : 2015 Triggering tests/morph test |
Exporter Build : SUCCESSBuild number : 1667 |
@davidsaada Could you re-review? |
There was a problem hiding this 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.
As requested, this should get more approvals |
@dannybenor, @deepikabhavnani, @kegilbert, @cmonr, @moranpeker, @karsev Could we please have your reviews on this asap? |
Looks good to me |
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
Pull request type