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

Failed to get mtime attribute (-61) #9

Closed
ghtech opened this issue Jun 24, 2020 · 6 comments
Closed

Failed to get mtime attribute (-61) #9

ghtech opened this issue Jun 24, 2020 · 6 comments

Comments

@ghtech
Copy link

ghtech commented Jun 24, 2020

Hi I am using littleFs component in my esp project and getting
ERROR esp_littlefs: Failed to get mtime attribute (-61)
at time of read and write to file

in config CONFIG_LITTLEFS_USE_MTIME is enabled

test esp idf examples/storage/spiffs with littleFs but no error.
please guide me do I need some changes in code to fix error

@BrianPugh
Copy link
Member

Hi @ghtech !

Are you saying that you tested examples/storage/spiffs and that worked without errors, but you get errors in your own project? If so can you share some code? What version of esp-idf are you using? @lorol just notified me about some possible time attribute incompatibilities with earlier versions of esp-idf.

I'll see if I can add some version checks and stuff later today (will probably get around to it in about 6 hours)

@ghtech
Copy link
Author

ghtech commented Jun 24, 2020

Thanks for quick reply

I am using ESP-IDF v4.2-dev.
yes I am getting error in my own project
but figure out problem
In my code for fopen I am using w+ or rb as mode which is causing problem
FILE *f = fopen("/spiffs/hello.txt", "w+");

If I replace it with w or r which is used in esp spiffs example solve the problem.

@BrianPugh
Copy link
Member

I haven't tested littlefs with the "+" forms of mode. I think the upstream code handles it, so I just have to also handle it properly. I'll investigate and add some tests this evening. Thanks!

@BrianPugh
Copy link
Member

I just added unit tests for "r+" and "w+" modes and i was unable to replicate the mtime attribute issue. Any suggestions or snippets for replicating? Glad you were able to otherwise get it working.

@ghtech
Copy link
Author

ghtech commented Jun 25, 2020

Hi Brain,
Please find following code I have just changed in ESP IDF SPIFFS example with mode to w+

ESP IDF version

C:\esp-idf\examples\storage\spiffs>idf.py --version
ESP-IDF v4.2-dev-1126-gd85d3d969-dirty

CODE ...

/* SPIFFS filesystem example.
   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/

#include <stdio.h>
#include <string.h>
#include <sys/unistd.h>
#include <sys/stat.h>
#include "esp_err.h"
#include "esp_log.h"

//#include "esp_spiffs.h"
#include "esp_littlefs.h"

static const char *TAG = "example";

void app_main(void)
{
    ESP_LOGI(TAG, "Initializing SPIFFS");

    // esp_vfs_spiffs_conf_t conf = {
    //     .base_path = "/spiffs",
    //     .partition_label = NULL,
    //     .max_files = 5,
    //     .format_if_mount_failed = true};

    const esp_vfs_littlefs_conf_t conf = {
        .base_path = "/spiffs",
        .partition_label = "storage",
        .format_if_mount_failed = true};
    //storage, data, spiffs, , 0xF0000,

    // Use settings defined above to initialize and mount SPIFFS filesystem.
    // Note: esp_vfs_spiffs_register is an all-in-one convenience function.
    // esp_err_t ret = esp_vfs_spiffs_register(&conf);
    esp_err_t ret = esp_vfs_littlefs_register(&conf);

    if (ret != ESP_OK)
    {
        if (ret == ESP_FAIL)
        {
            ESP_LOGE(TAG, "Failed to mount or format filesystem");
        }
        else if (ret == ESP_ERR_NOT_FOUND)
        {
            ESP_LOGE(TAG, "Failed to find SPIFFS partition");
        }
        else
        {
            ESP_LOGE(TAG, "Failed to initialize SPIFFS (%s)", esp_err_to_name(ret));
        }
        return;
    }

    size_t total = 0, used = 0;
    ret = esp_littlefs_info(conf.partition_label, &total, &used);
    //ret = esp_spiffs_info(conf.partition_label, &total, &used);
    if (ret != ESP_OK)
    {
        ESP_LOGE(TAG, "Failed to get SPIFFS partition information (%s)", esp_err_to_name(ret));
    }
    else
    {
        ESP_LOGI(TAG, "Partition size: total: %d, used: %d", total, used);
    }

    // Use POSIX and C standard library functions to work with files.
    // First create a file.
    ESP_LOGI(TAG, "Opening file");
    FILE *f = fopen("/spiffs/hello.txt", "w+");
    if (f == NULL)
    {
        ESP_LOGE(TAG, "Failed to open file for writing");
        return;
    }
    fprintf(f, "Hello World!\n");
    fclose(f);
    ESP_LOGI(TAG, "File written");

    // Check if destination file exists before renaming
    struct stat st;
    if (stat("/spiffs/foo.txt", &st) == 0)
    {
        // Delete it if it exists
        unlink("/spiffs/foo.txt");
    }

    // Rename original file
    ESP_LOGI(TAG, "Renaming file");
    if (rename("/spiffs/hello.txt", "/spiffs/foo.txt") != 0)
    {
        ESP_LOGE(TAG, "Rename failed");
        return;
    }

    // Open renamed file for reading
    ESP_LOGI(TAG, "Reading file");
    //char *line;
    //line = xr3_comm_read_file("/spiffs/foo.txt");
    f = fopen("/spiffs/foo.txt", "rb");
    if (f == NULL)
    {
        ESP_LOGE(TAG, "Failed to open file for reading");
        return;
    }
    char line[64];
    fgets(line, sizeof(line), f);
    fclose(f);
    // strip newline
    char *pos = strchr(line, '\n');
    if (pos)
    {
        *pos = '\0';
    }
    ESP_LOGI(TAG, "Read from file: '%s'", line);

    // All done, unmount partition and disable SPIFFS
    //esp_vfs_spiffs_unregister(conf.partition_label);
    esp_vfs_littlefs_unregister(conf.partition_label);
    ESP_LOGI(TAG, "SPIFFS unmounted");
}


console log output

I (0) cpu_start: Starting scheduler on APP CPU.
I (327) example: Initializing SPIFFS
I (357) example: Partition size: total: 983040, used: 8192
I (357) example: Opening file
I (377) esp_littlefs: Failed to get mtime attribute  (-61)
I (377) example: File written
I (387) esp_littlefs: Failed to get mtime attribute  (-61)
I (407) example: Renaming file
I (437) example: Reading file
I (457) esp_littlefs: Failed to get mtime attribute  (-61)
I (457) example: Read from file: 'Hello World!'
I (457) example: SPIFFS unmounted

image

@BrianPugh
Copy link
Member

Thanks for the code snippet!

Should be fixed in 7e0fdde

Basically the issue is that when opening to read/write, the RDONLY and WRONLY flags are both set (they're a bit of a misnomer, they really just give permissions to read or write, respectively). When opening the file, any other flag being set besides RDONLY could modify the contents, so mtime should be updated. So, instead of checking if the RDONLY flag is set, I should be checking if only the RDONLY flag is set.

If this doesn't solve your problem, we can re-open this issue. Thanks!

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