rust-fatfs
rust-fatfs copied to clipboard
Cannot create directories with `lfn` feature.
When using the lfn
feature, using Dir::create_dir
creates empty files instead of directories.
In which version of the crate you encountered this problem? Is it embedded environment? There are tests that create directories and lfn
feature is enabled by default so it should work.
In which version of the crate you encountered this problem?
Master branch of this repo.
Is it embedded environment?
Yes, on STM32L4 with the implementation I am working on (https://github.com/stm32-rs/stm32l4xx-hal/pull/315), so possibly there is a bug in my implementation.
With SFN, everything is working fine though. With LFN, it works sometimes, but most of the time it just creates a file instead of a directory.
I first assumed it was due to reading/writing from an SD card being too slow, since I also encountered spurious timeouts. I have since implemented reading/writing using DMA and the timeouts are gone but I am still unable to create directories.
I am also getting the following debug output when listing the root directory contents:
failed to fill whole buffer in read_exact
Is this expected when reaching the directory iterator end?
No, I don't think it is normal. It most likely means that your filesystem got corrupted. If this is a problem with my crate it would be best if you could make a small code sample that reproduces the issue and does not require embedded env so I could debug it myself.
No, I don't think it is normal.
Okay, I will have to investigate a bit more and try with a freshly formatted SD card to make sure the filesystem is not corrupted.
Okay, I have now found the reason for this behaviour.
I am mounting the SD card on my computer (macOS) via an STM32 running an application making it a USB MSC device. When I then reset the board (i.e. by rebuilding the application and restarting the debugger), the SD card is not properly ejected. On the next run, files are created instead of directories.
If I then delete these files and eject the SD card properly before resetting the board again, the directories are created successfully on the subsequent run.
Not sure how to debug this further. Maybe creating images of the SD card after ejecting it improperly and properly, respectively?
Okay, I managed to create images of the SD card in both the working and broken states. After some investigation I finally found the culprit: The FAT dirty flag is set. If it is cleared before mounting the card again on my computer, the directories are created as expected.
I don't think I fully understand. You are mounting a fat filesystem on your STM32 filesystem using this crate, then reset the board, then mount again (it should be mounting a dirty filesystem), then you create some directories, unmount, and then when mounting on Windows OS it see directories as files? I am still interested to see what is the reason. Dirty flag alone should not break anything unless filesystem is in corrupted state but I think it would still be weird to see directories as files, because all directory entry data is written at once (directory attribute and its name). Maybe there is some other issue here... Attached image with a detailed list of steps you performed to get it would be helpful
Here's step by step how to reproduce it:
- Mount the FAT filesystem on an SD card in a STM32 device on macOS.
- Unplug/reset the device without properly unmounting in macOS.
- Both the FAT dirty bit and the BPB dirty bit are now set.
- Device mounts dirty filesystem without clearing dirty bits.
- Device creates a new
YYYY-MM-DD
directory for logging. - Device unmounts the filesystem.
- Mount the filesystem on macOS again.
- Directory
YYYY-MM-DD
is a file instead of a directory. (Or at least doesn't appear as a browsable directory.)
When replacing step 2 with a proper unmount, both dirty bits are cleared and everything works as expected.
Also, when clearing the dirty bits as part of step 4 (as is made possible with https://github.com/rafalh/rust-fatfs/pull/66), everything works as expected.
I think it'd be easier if you created a disk.img with the filesystem state and a piece of code that reproduced the issue.
@aruiz, not quite sure it would be easier. I couldn't reproduce it now if I wanted to since I don't have the necessary hardware anymore. Also, there is a an open PR with the solution, including a test which reproduces the state leading to the problem, i.e. step 3 and 4 above.