-
Notifications
You must be signed in to change notification settings - Fork 75
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
implement FAT table write/read and setting the volume dirty status #132
base: develop
Are you sure you want to change the base?
implement FAT table write/read and setting the volume dirty status #132
Conversation
It appears the tests are failing - possible because the API changed? |
src/volume_mgr.rs
Outdated
pub fn open_raw_volume( | ||
&mut self, | ||
volume_idx: VolumeIdx, | ||
read_only: bool, |
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 think I'd prefer an enum VolumeOpenMode { ReadOnly, ReadWrite }
, otherwise the caller writes:
thing.open_raw_volume(VolumeIdx(0), true)
and it's totally unclear what true
means from the context.
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 thanks!
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.
changed in 2fd18cb
src/volume_mgr.rs
Outdated
/// | ||
/// We do not support GUID Partition Table disks. Nor do we support any | ||
/// concept of drive letters - that is for a higher layer to handle. | ||
fn _open_volume( |
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.
We added an argument to open_raw_volume
, so should we just add an argument to open_volume
, and not have the two extra methods? Not sure.
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 made it like this, so it is downward compatible
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.
Then should we keep open_raw_volume backwards compatible too?
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.
Is there a need for? I though because it will be used mostly internally so the impact is lower?
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's a public API, which I use in my projects.
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 can change also to the same structure as for open_volume or do you prefer the argument way for both?
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 think I prefer it with the argument.
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.
Perfect then I will change it also for the open_volume
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.
fixed in 70a5fdb
src/volume_mgr.rs
Outdated
} | ||
Ok(()) | ||
} | ||
#[cfg(test)] |
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.
Tests go in mod test {}
.
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.
changed in 9d6865a
src/volume_mgr.rs
Outdated
let volume_idx = self.get_volume_by_id(volume)?; | ||
if !self.open_volumes[volume_idx].read_only { | ||
let VolumeType::Fat(volume_type) = &self.open_volumes[volume_idx].volume_type; |
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've tried to write this code on the assumption that a non-FAT filesystem will be added in the future. The irrefutable match here will break when that happens. I think set_volume_status_dirty
doesn't need volume_type
as an argument - it should take volume_idx
instead.
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 changed this
src/volume_mgr.rs
Outdated
/// Sets the volume status dirty to dirty if true, to not dirty if false | ||
fn set_volume_status_dirty( | ||
&self, | ||
volume: &FatVolume, |
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 think this should take volume_idx
and handle the different types of volume internally. It should also skip updating the FAT if the FAT is already marked as dirty.
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.
fixed in 56a07fe
src/volume_mgr.rs
Outdated
if !read_only { | ||
let idx = self.get_volume_by_id(v)?; | ||
let VolumeType::Fat(volume_type) = &self.open_volumes[idx].volume_type; | ||
self.set_volume_status_dirty(volume_type, true)?; |
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 don't think you need to mark it as dirty until the first write occurs?
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.
Ah, I read the comment thread from the kernel. Yeah, I can see the value in marking it dirty on first mount.
Note to self - the Neotron OS will need changing to ensure the volume is unmounted when the last file is closed.
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.
But this flag does not fix my problem haha, I have to update somehow the fat, at least Linux does not check the fat and repairs it if needed. I thought when the bit is cleared (is dirty) during mount it will be "repaired" and the FAT table gets update, but this is not the case
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 don't think Linux will run an fsck
on a block device unless you ask it to. It is Windows that prompts to run Scandisk if it things the volume wasn't cleanly shut down.
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 like the idea - left a few notes.
I will have a look into it next days |
c155268
to
c1c57d3
Compare
So we already have functions for updating the FAT: |
My idea was now with this flag, after a restart of my device I check this flag and if dirty I wanna update somehow the dir entries (I think this is currently my problem I have, if I don't update the dirEntry (maybe the size property?) it will not shown in the file explorer correctly). I have to check if I can get there somehow (Maybe iterating through the complete FAT and setting the new file size?). Sorry right now I am not that deep into the topic to understand your idea. I will think about and doing some research. But reparing the FAT could be done in another MR In my case the sd card never leaves the device but at the end over usb storage access shall be established, so I can easily update the FAT at that point |
…me dirty status Description: The dirty flag will be set when opening the volume to indicate that the FAT table might be out of date. In case of an unexpected close without unmount in the next mount it is visible that the FAT table is outdated and can be reread by the operating system (https://en.wikipedia.org/wiki/Design_of_the_FAT_file_system). Without this, the file must always closed before removing the sd card because otherwise the FAT table is outdated and so the files are not visible when mounting the sd card on a computer. For embedded systems it is quite likely that unexpect end can happen and always closing the file after a single write operation is a performance issue. For readonly this dirty flag is not required and therefore it will not set and reset when opening/closing a volume. https://unix.stackexchange.com/questions/230181/why-does-linux-mark-fat-as-dirty-simply-due-to-mounting-it Linux kernel is doing it during mount, so there is no need to ckeck it every time during a new write
…ond block of the fat table
Reason: makes the funktionality more clear and less error prone
so it can be also used outside of tests
…eady set Reason: the function can determine it self.
2c425a1
to
330f807
Compare
I fixed the tests |
So I like the read-only and read-write changes. If they were isolated I'd happily merge them. But to return to my earlier comment and perhaps clarify - I don't think we need a whole new module for writing a couple of FAT entries to indicate dirty/clean, when we already have functions which write FAT entries for the purposes of tracking cluster allocations for files. Either all the FAT writing code needs to go in to the new module, or the clean/dirty bits need to be set with the existing function. |
I will have a look into it. Thanks! |
The dirty flag will be set when opening the volume to indicate that the FAT table might be out of date. In case of an unexpected close without unmount in the next mount it is visible that the FAT table is outdated and can be reread by the operating system (https://en.wikipedia.org/wiki/Design_of_the_FAT_file_system). Without this, the file must always closed before removing the sd card because otherwise the FAT table is outdated and so the files are not visible when mounting the sd card on a computer. For embedded systems it is quite likely that unexpect end can happen and always closing the file after a single write operation is a performance issue. For readonly this dirty flag is not required and therefore it will not set and reset when opening/closing a volume. This is same as the linux kernel is doing.
https://unix.stackexchange.com/questions/230181/why-does-linux-mark-fat-as-dirty-simply-due-to-mounting-it Linux
kernel is doing it during mount, so there is no need to ckeck it every time during a new write