rafalh / rust-fatfs

A FAT filesystem library implemented in Rust.
MIT License
292 stars 53 forks source link

Cannot create directories with `lfn` feature. #64

Open reitermarkus opened 2 years ago

reitermarkus commented 2 years ago

When using the lfn feature, using Dir::create_dir creates empty files instead of directories.

rafalh commented 2 years ago

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.

reitermarkus commented 2 years ago

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.

reitermarkus commented 2 years ago

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?

rafalh commented 2 years ago

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.

reitermarkus commented 2 years ago

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.

reitermarkus commented 2 years ago

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?

reitermarkus commented 2 years ago

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.

rafalh commented 1 year ago

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

reitermarkus commented 1 year ago

Here's step by step how to reproduce it:

  1. Mount the FAT filesystem on an SD card in a STM32 device on macOS.
  2. Unplug/reset the device without properly unmounting in macOS.
  3. Both the FAT dirty bit and the BPB dirty bit are now set.
  4. Device mounts dirty filesystem without clearing dirty bits.
  5. Device creates a new YYYY-MM-DD directory for logging.
  6. Device unmounts the filesystem.
  7. Mount the filesystem on macOS again.
  8. 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.

aruiz commented 9 months ago

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.

reitermarkus commented 9 months ago

@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.

ost-ing commented 2 months ago

I've recently migrated from short file names to LFN, my application is running on an STM32. I'm getting a similar odd behaviour and the directory is seen as a file on macos.