lorol / LITTLEFS

LittleFS library for arduino-esp32
GNU General Public License v2.0
167 stars 68 forks source link

LITTLEFSFS::begin() unexpected behavior #27

Closed robcazzaro closed 3 years ago

robcazzaro commented 3 years ago

Relatively minor issue. The code behaves as expected, but doesn't return the right value

I used the following code in the setup() part of my project

  // Format SPIFFS if not yet
  if (!FileFS.begin(true))
  {
    Serial.println(F("Init failed! AutoFormatting."));
  }

I expected to see the "Init failed! AutoFormatting." message on my terminal window, instead I get

lib\LittleFS_esp32\lfs.c:998:error: Corrupted dir pair at {0x0, 0x1}
E (230) esp_littlefs: mount failed,  (-84)
E (234) esp_littlefs: Failed to initialize LittleFS

It actually auto-formats the SPIFFS partition, just doesn't return false, so the code doesn't know it's been auto formatted. In some cases, the code needs to know if the SPIFFS area has been auto formatted, so would be nice to fix

lorol commented 3 years ago

@robcazzaro Please try on your example to use !FileFS.begin(false) and post what is returning.

robcazzaro commented 3 years ago

I used the code at the end of this message, inside your LITTLEFS_test() example

In order to get the messages below, I had to add the delay(500), otherwise it looks as if your code was running in a separate thread from the Arduino code, and my Serial.print() were overwritten. That is purely a Serial.print() timing problem: I built a different version where I saved the values and printed those at the end, and that showed 0, 0, 1, 1

I get the following output

Test start
lib\LittleFS_esp32\lfs.c:1076:error: Corrupted dir pair at {0x0, 0x1}
E (2032) esp_littlefs: mount failed,  (-84)
E (2032) esp_littlefs: Failed to initialize LittleFS
[E][LITTLEFS.cpp:90] begin(): Mounting LITTLEFS failed! Error: -1
------------>First pass, false FS2 return value = 0
Appending to file: /hello0.txt
[E][vfs_api.cpp:22] open(): File system is not mounted
[E][vfs_api.cpp:22] open(): File system is not mounted
lib\LittleFS_esp32\lfs.c:1076:error: Corrupted dir pair at {0x0, 0x1}
E (2554) esp_littlefs: mount failed,  (-84)
E (2558) esp_littlefs: Failed to initialize LittleFS
[E][LITTLEFS.cpp:90] begin(): Mounting LITTLEFS failed! Error: -1
------------>First pass, false FS main return value = 0
Appending to file: /hello0.txt
[E][vfs_api.cpp:22] open(): File system is not mounted
[E][vfs_api.cpp:22] open(): File system is not mounted
lib\LittleFS_esp32\lfs.c:1076:error: Corrupted dir pair at {0x0, 0x1}
E (3082) esp_littlefs: mount failed,  (-84)
E (3086) esp_littlefs: Failed to initialize LittleFS
------------> second time true -------> FS2 return value = 1
Appending to file: /hello1.txt
- message appended
Second pass FS2 File: /hello1.txt, size: 9B
Done with pass 2 part2, work with the first lfs partition...
lib\LittleFS_esp32\lfs.c:1076:error: Corrupted dir pair at {0x0, 0x1}
E (4349) esp_littlefs: mount failed,  (-84)
E (4352) esp_littlefs: Failed to initialize LittleFS
------------> second time true -------> FS main return value = 1
Appending to file: /hello1.txt
- message appended
FS File: /hello1.txt, size: 9B
Test complete

As you can see, using begin(false) on a unintialized/invalid SPIFFS it returns 0, as it should, and doesn't initialize the SPIFFS. While the second call with begin(true) returns 1, and formats the SPIFFS.

There were two problems masked by the timing issue. 1) I used someone else's code that assumed a return of false meant it was autoformatted. That is a problem on my side, sorry. Clearly it returns true or false based on the success of the mount operation (as it should, now that I think about it) 2) your code issues a "Corrupted dir pair at {0x0, 0x1} E (4349) esp_littlefs: mount failed, (-84) E (4352) esp_littlefs: Failed to initialize LittleFS" debug message even if it does correctly autoformat the SPIFFS and mounts it. Maybe you could add a "autoformatted" to the debug code, for other clueless users like me

void setup()
{
  Serial.begin(115200);
  delay(2000);
  Serial.println();
  Serial.println();
  Serial.println("Test start");
  Serial.println();
  Serial.println();

  int retval = LITTLEFS.begin(false, "/lfs2", 5, "part2");
  delay(500);
  Serial.print(F("------------>First pass, false FS2 return value = "));
  Serial.println(retval);

  appendFile(LITTLEFS, "/hello0.txt", "World0!\r\n");

  File root = LITTLEFS.open("/");
  File file = root.openNextFile();

  while (file)
  {
    String fileName = file.name();
    size_t fileSize = file.size();
    Serial.printf("First pass FS2 File: %s, size: %s\n", fileName.c_str(), formatBytes(fileSize).c_str());
    file = root.openNextFile();
  }

  LITTLEFS.end();

  Serial.println("Done with part2, work with the first lfs partition...");

  retval = LITTLEFS.begin(false);
  delay(500);
  Serial.print(F("------------>First pass, false FS main return value = "));
  Serial.println(retval);

  appendFile(LITTLEFS, "/hello0.txt", "World0!\r\n");

  root = LITTLEFS.open("/");
  file = root.openNextFile();

  while (file)
  {
    String fileName = file.name();
    size_t fileSize = file.size();
    Serial.printf("First pass FS1 File: %s, size: %s\n", fileName.c_str(), formatBytes(fileSize).c_str());
    file = root.openNextFile();
  }
  LITTLEFS.end();

  Serial.println();
  Serial.println();
  Serial.println("<><><><> Second pass <><><><>");
  Serial.println();

  retval = LITTLEFS.begin(true, "/lfs2", 5, "part2");
  delay(500);
  Serial.print(F("------------> second time true -------> FS2 return value = "));
  Serial.println(retval);

  appendFile(LITTLEFS, "/hello1.txt", "World0!\r\n");

  root = LITTLEFS.open("/");
  file = root.openNextFile();

  while (file)
  {
    String fileName = file.name();
    size_t fileSize = file.size();
    Serial.printf("Second pass FS2 File: %s, size: %s\n", fileName.c_str(), formatBytes(fileSize).c_str());
    file = root.openNextFile();
  }
  LITTLEFS.format();
  LITTLEFS.end();

  Serial.println("Done with pass 2 part2, work with the first lfs partition...");

  retval = LITTLEFS.begin(true);
  delay(500);
  Serial.print(F("------------> second time true -------> FS main return value = "));
  Serial.println(retval);

  appendFile(LITTLEFS, "/hello1.txt", "World0!\r\n");

  root = LITTLEFS.open("/");
  file = root.openNextFile();

  while (file)
  {
    String fileName = file.name();
    size_t fileSize = file.size();
    Serial.printf("FS File: %s, size: %s\n", fileName.c_str(), formatBytes(fileSize).c_str());
    file = root.openNextFile();
  }

  LITTLEFS.format();
  LITTLEFS.end();

  Serial.println();
  Serial.println();
  Serial.println();

  Serial.println("Test complete");
}
lorol commented 3 years ago

Hi, the messages like "Corrupted dir pair at {0x0, 0x1} E (4349)" are from lower level of the driver. The whole thing is still in development. Maybe later these will be cleaned by adjusting the error levels there. The lib is really the highest wrapper, similar to SPIFFS. I didn't test much the format scenarios. For now I will leave it this way, as we are moving it as a part of core V2. The driver will be maintained at IDF side and use pre compiled as other FS

robcazzaro commented 3 years ago

Agreed. This was mostly a misunderstanding on my side, not a real issue in your code. Thanks again for adding the multiple SPIFFS functionality

lorol commented 3 years ago

@robcazzaro See: https://github.com/lorol/LITTLEFS/blob/master/src/lfs.c#L10 if you want to suppress or verbose more the debug messages

robcazzaro commented 3 years ago

Thanks!