Skip to content
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

Unable to list files in a SPIFFS partition #117

Closed
bugadani opened this issue Apr 22, 2022 · 5 comments
Closed

Unable to list files in a SPIFFS partition #117

bugadani opened this issue Apr 22, 2022 · 5 comments
Assignees

Comments

@bugadani
Copy link

bugadani commented Apr 22, 2022

Given is the following test code, built on a CMake setup (with some details omitted):

# Cargo.toml

...

[dependencies]
c_str_macro = "1"
// main.rs
use std::os::raw::c_char;
use std::ffi::CStr;
use c_str_macro::c_str;

#[repr(C)]
pub struct esp_vfs_spiffs_conf_t {
    pub base_path: *const c_char,
    pub partition_label: *const c_char,
    pub max_files: usize,
    pub format_if_mount_failed: bool,
}

extern "C" {
    pub fn esp_vfs_spiffs_register(conf: *const esp_vfs_spiffs_conf_t) -> i32;
}

fn init_partition(path: &CStr, label: &CStr, max_files: usize) {
    let storage_conf = esp_vfs_spiffs_conf_t {
        base_path: path.as_ptr(),
        partition_label: label.as_ptr(),
        max_files,
        format_if_mount_failed: true,
    };

    unsafe { esp_vfs_spiffs_register(&storage_conf) };
}

fn test() {
    let path = std::path::Path::new("/storage/foobar");

    if let Err(err) = std::fs::File::create(path) {
        println!("Failed to create file: {err}");
        return;
    }

    match std::fs::read_dir("/storage") {
        Ok(dir) => {
            for entry in dir {
                println!("{entry:?}");
            }
        }
        Err(err) => println!("Failed to read root: {err}"),
    }

    if let Err(err) = std::fs::remove_file(path) {
        println!("Failed to remove file: {err}");
    }
}

#[no_mangle]
pub extern "C" fn app_main() {
    init_partition(c_str!("/storage"), c_str!("storage"), 3);

    test();
}

I expect the following output:

Ok(DirEntry("/storage/foobar"))

Instead, the output I get is the following:

Ok(DirEntry("/storage/"))
Err(Os { code: 5, kind: Uncategorized, message: "I/O error" })

The OS error is unrelated (SPIFFS seems to indicate the end of folder iteration by returning a value that gets turned into EIO), but note that the path in the DirEntry has an empty filename.

This issue is present on:

rustc verion esp-idf 4.4.1
Rustc 1.60.0.0 x
Rustc 1.59.0.1 x
Rustc 1.59.0.0 not affected
@MabezDev
Copy link
Member

Hey @bugadani, thanks for your patience! I think I've tracked this down to another mismatch of structs on the C side and rust side.

The files are created, and when you step into the ReadDir Iterator, if you look carefully the entries are being populated; with one problem. A zeroed field not included in the C side happens to overlap with the start of the name field, meaning the name on the Rust side starts with a null pointer... hence why only the root directory is printed!

I need to track down whether this is an issue with rust-lang/libc or the newlib component of esp-idf.

@MabezDev
Copy link
Member

This is an esp-idf issue, specifically this definition.

d_ino should be type ino_t, but its defined as an int. sizeof(int) == 4, sizeof(ino_t) == 2 on the esp-idf platform, hence this failure. I'll submit a fix asap :).

@MabezDev
Copy link
Member

The final part Err(Os { code: 5, kind: Uncategorized, message: "I/O error" }) was yet another issue; this time with spiffs. The spiffs module can emit SPIFFS_VIS_END, even though this is not a publically documented error code. According to the developer it is not an error, and should not be emitted.

I've now submitted the two patches internally. Hopefully, they'll be merged and backported soon :).

@bugadani
Copy link
Author

Awesome, thanks :)

@MabezDev
Copy link
Member

MabezDev commented Jul 4, 2022

Thanks for the report @bugadani. This is now fixed & backported to V4.4, so I'm closing this issue :). You may need to remove .embuild/ and rebuild to pull in the fixes from the v4.4 branch.

@MabezDev MabezDev closed this as completed Jul 4, 2022
espressif-bot pushed a commit to espressif/esp-idf that referenced this issue Jul 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants