Skip to content

WIP - Add time to SPIFFS for 3.0.0 #6315

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

Closed
wants to merge 8 commits into from

Conversation

earlephilhower
Copy link
Collaborator

@earlephilhower earlephilhower commented Jul 18, 2019

Support the ESP32 File::getLastWrite() call and setting the time on
all filesystems automatically (assuming the system clock has
been set properly and time(NULL) returns the proper time!).

Adds Dir::fileTime() to get the time of a file being listed, similar to
Dir::fileName() and Dir::fileSize().

Adds ::setTimeCallback(time_t (*cb)()) to File, Dir, and FS, allowing
users to override the default timestamp on a per-file, directory, or
filesystem basis. By default, a simple callback returning time(nullptr)
is implemented.

LittleFS uses the 't' attribute and should be backwards compatible.

SD/SDFS work and include wrappers for obsolete SdFat timestamp callbacks
using the MSDOS time.

SPIFFS has been updated to support either the existing on-flash format
without any timestamps, or a new on-flash format with a flag area and a
timestamp metadata element added.

SPIFFS will try and mount any existing filesystem as non-timestamp, and
continue to write them in the old format.

New filesystems may be formatted to include timestamps (default) or in
the old format, configurable via the SPIFFS.setConfig call.

The SPIFFS work took as starting point all of work of @luc-github in #3730
and extended it into a backwards compatible mode by doing much surgery
on the SPIFFS library itself and the on-flash format.

Includes an updated SD/listfiles and SPIFFS_time example.

@earlephilhower earlephilhower changed the title WIP - Add time to filesystems, new API calls Add time to filesystems, add metadata to SPIFFS (compatibly), add new API calls Jul 19, 2019
@earlephilhower earlephilhower changed the title Add time to filesystems, add metadata to SPIFFS (compatibly), add new API calls WIP - Add time to filesystems, add metadata to SPIFFS (compatibly), add new API calls Jul 19, 2019
@earlephilhower earlephilhower force-pushed the fstime branch 3 times, most recently from e315d0a to 04c9ff9 Compare July 20, 2019 01:03
@earlephilhower earlephilhower changed the title WIP - Add time to filesystems, add metadata to SPIFFS (compatibly), add new API calls Add time to filesystems, add metadata to SPIFFS (compatibly), add new API calls Jul 20, 2019
Support the ESP32 File::getLastWrite() call and setting the time on
all filesystems automatically (assuming the system clock has
been set properly and time(NULL) returns the proper time!).

Adds Dir::fileTime() to get the time of a file being listed, similar to
Dir::fileName() and Dir::fileSize().

Adds ::setTimeCallback(time_t (*cb)()) to File, Dir, and FS, allowing
users to override the default timestamp on a per-file, directory, or
filesystem basis.  By default, a simple callback returning time(nullptr)
is implemented.

LittleFS uses the 't' attribute and should be backwards compatible.

SD/SDFS work and include wrappers for obsolete SdFat timestamp callbacks
using the MSDOS time.

SPIFFS has been updated to support either the existing on-flash format
without any timestamps, or a new on-flash format with a flag area and a
timestamp metadata element added.

SPIFFS will try and mount any existing filesystem as non-timestamp, and
continue to write them in the old format.

New filesystems may be formatted to include timestamps (default) or in
the old format, configurable via the SPIFFS.setConfig call.

The SPIFFS work took as starting point all of work of @luc-github in esp8266#3730
and extended it into a backwards compatible mode by doing much surgery
on the SPIFFS library itself and the on-flash format.

Includes an updated SD/listfiles and SPIFFS_time example.
It seems more appropriate to use the config struct tio hold the meta-len
and not the spiffs fs object itself.  Cleans up the higher layewr code a
bit, too.
Allow user overrides of SDFat configuration settings in platform.txt by
bracketing the config.h file defines with ifndefs.
@earlephilhower
Copy link
Collaborator Author

mkspiffs and mklittlefs need to be updated to match the new format. Will look at that after we get some approval on the changes here. Using the old mkspiffs will run fine, but it won't include timestamps on the generated filesystem.

@earlephilhower earlephilhower requested a review from devyte July 24, 2019 19:11
@earlephilhower
Copy link
Collaborator Author

@luc-github, can you give this a look-see? I've got a way to make your SPIFFS change #3730 compatible with the existing flash layout, so that we don't have to wait until 3.0 or make people wipe their existing FSes.

As you found out, SPIFFS unfortunately doesn't have anything like a FSInfo block describing the filesystem config options and it will happily mount a metadata=4 filesystem with a metadata=0 application (resulting in silent data corruption on reads and writes). The way I handled it was to add a poison page to the beginning of the FS flash space. At runtime I now check and see if the poison is there, and if so we know it's a new md=4 FS and mount(flashstart+4K). If it's not, then it's mounted as a md=0 FS. The poison also makes sure that old code can't mount and read/write corrupted data to a md=4 FS.

@luc-github
Copy link
Contributor

Ho looks good - the trick is clever - thank you ^_^
Will do my best to try ASAP

earlephilhower added a commit to earlephilhower/mklittlefs that referenced this pull request Sep 3, 2019
Add time to filesystem and mkfs utility

Fixes #3. Adds a 't' metadata attribute to all files added, and when listing or extracting restore according to the 't' attribute, if present.

Compatible w/o an w/ esp8266/Arduino#6315 since LittleFS always has metadata support (and can silently ignore them if present but not used).
@earlephilhower earlephilhower changed the title Add time to filesystems, add metadata to SPIFFS (compatibly), add new API calls WIP - Add time to filesystems, add metadata to SPIFFS (compatibly), add new API calls Sep 11, 2019
@earlephilhower earlephilhower removed this from the 2.6.0 milestone Sep 11, 2019
@earlephilhower
Copy link
Collaborator Author

Functionality is there, but moving to WIP because I want to include a data protection test to either host tests or device tests that will verify the correct behavior (i.e. guarantee no corruption of a non-time, older FS, and that it preserves existing older FS w/o metadata when run with the new code; and guarantee that the new FS can not be mounted by the old code (which would also cause corruption since the old code cannot handle metadata).

@luc-github
Copy link
Contributor

@earlephilhower postpone affect LittleFS also ?

@earlephilhower
Copy link
Collaborator Author

@luc-github ,For LittleFS there is 0 risk in adding this (attributes are part and parcel of the FS and don't affect any layout considerations), but unfortunately with this PR I've upgraded everything. So if SPIFFS doesn't go in, neither does SD or LittleFS.

I will try to get a host test this weekend with a pre-built old-format and new-format FS. If that doesn't happen I can probably split this PR into one for LittleFS+SD and one for SPIFFS. The LittleFS can go in the next rev, no question, and the SPIFFS will be a matter of if it gets enough testing.

I've worked at data storage companies for a long time, and the two worst words I can hear are "data corruption," so I want to make sure SPIFFS is solid.

@luc-github
Copy link
Contributor

Thank you for your great contribution. I have implemented LittleFS support in my project. I was just checking if I can enable time support, and saw the postpone comment.
I will wait the pr, no problem.
Thank you again

earlephilhower added a commit to earlephilhower/Arduino that referenced this pull request Sep 21, 2019
Support the ESP32 File::getLastWrite() call and setting the time on
all filesystems automatically (assuming the system clock has
been set properly and time(NULL) returns the proper time!).

Adds Dir::fileTime() to get the time of a file being listed, similar to
Dir::fileName() and Dir::fileSize().

Adds ::setTimeCallback(time_t (*cb)()) to File, Dir, and FS, allowing
users to override the default timestamp on a per-file, directory, or
filesystem basis. By default, a simple callback returning time(nullptr)
is implemented.

LittleFS uses the 't' attribute and should be backwards compatible.

SD/SDFS work and include wrappers for obsolete SdFat timestamp callbacks
using the MSDOS time.

This PR does not update SPIFFS, due to compatability concerns and a
possible massive rewrite which would make it possible to determine if an
old-style ot metadata enabled FS is present at mount time.

Includes an updated SD/listfiles and LittleFS_time example.

Replaces esp8266#6315
@d-a-v
Copy link
Collaborator

d-a-v commented Sep 26, 2019

Replaced by #6544

@d-a-v d-a-v closed this Sep 26, 2019
@earlephilhower earlephilhower changed the title WIP - Add time to filesystems, add metadata to SPIFFS (compatibly), add new API calls WIP - Add time to SPIFFS for 3.0.0 Sep 26, 2019
@earlephilhower earlephilhower added this to the 3.0.0 milestone Sep 26, 2019
@earlephilhower
Copy link
Collaborator Author

Reopening just because, once #6544 is done, this PR will end up just being the changes to SPIFFS to make it support the metadata size as a variable.

It's lots of little things, and will be used if/when we go to a partition setup with embedded FS info blocks to avoid the poison page added.

So, not for 2.x, but I don't want to lose the SPIFFS changes which will still be needed (I think).

d-a-v pushed a commit that referenced this pull request Oct 31, 2019
* Add time to filesystem API

Support the ESP32 File::getLastWrite() call and setting the time on
all filesystems automatically (assuming the system clock has
been set properly and time(NULL) returns the proper time!).

Adds Dir::fileTime() to get the time of a file being listed, similar to
Dir::fileName() and Dir::fileSize().

Adds ::setTimeCallback(time_t (*cb)()) to File, Dir, and FS, allowing
users to override the default timestamp on a per-file, directory, or
filesystem basis. By default, a simple callback returning time(nullptr)
is implemented.

LittleFS uses the 't' attribute and should be backwards compatible.

SD/SDFS work and include wrappers for obsolete SdFat timestamp callbacks
using the MSDOS time.

This PR does not update SPIFFS, due to compatability concerns and a
possible massive rewrite which would make it possible to determine if an
old-style ot metadata enabled FS is present at mount time.

Includes an updated SD/listfiles and LittleFS_time example.

Replaces #6315

* Add links to new mklittlefs w/timestamp support

Include the update mklittlefs which generated 't' metadata on imported
files.
	../tools/sdk/lwip2/include/netif/lowpan6_opts.h

* Add explicit note about timestamp being local time

* Address review concerns

Clean up some awkward object instantiations.

Remove the _enableTime flag/setter from SPIFFS.

Clean up the FSConfig constructors using C++ style init lists.
@NicoZuid
Copy link

According to the documentation of the file system
{url} https://arduino-esp8266.readthedocs.io/en/latest/filesystem.html {url]
there is a (date) time of the last Write available per file.
After reading the above discussion I wonder if the documentation of ESP SDK version 2.6.3 is correct.
It says: "The SD, SDFS, and LittleFS filesystems support a file timestamp, updated when the file is opened for writing." Do I not have to wait for version 3.0.0?
(I have been trying to make a PIFFS and SD version of my program for several hours :))

@earlephilhower
Copy link
Collaborator Author

@NicoZuid if you use LittleFS and SD, you'll be all set with a file write time. I updated SPIFFS to support it, too, but because it is a massive change and relies on a hack to determine which FS version is in use, you'll have to wait for V3.0 for SPIFFs.

@NicoZuid
Copy link

@earlephilhower, Thanks for your answer.
I am trying to create an SDFS version of my program.
Unfortunately, the SD card suddenly became completely unusable.
The card is no longer even recognized as an SD card on a PC.
Cause? Hardware card reader, SD card or software.

@earlephilhower
Copy link
Collaborator Author

That really sounds like a hardware issue. You need to be very careful with the voltages applied and pinout on the card/adapter. A SW issue could only scramble the data, at worst, and the card itself would still be recognized (but your OS would probably ask you to reformat).

This really isn't the right spot for this, though. You'll be able to get more help on https://gitter.im/esp8266/Arduino .

@NicoZuid
Copy link

As mentioned above, the SD card was suddenly no longer usable on both the esp hardware and on a Windows PC. I have just been able to view the SD card with a PC with Ubuntu.
The volume header and / or the directory header is probably currupt.
Both give: Free space: 2.0 GB from 2.0 GB (0% used).
I am sure the information was previously correct ALSO through my program on the ESP8266 hardware. In reality there were around 120 files with a total of around 5.5 MB.
If I can reproduce the problem in due course I will return to it in a separate issue.

@earlephilhower
Copy link
Collaborator Author

Closing due to SPIFFS deprecation. I think the code's pretty solid, but I don't think it's appropriate to do such a massive change to a dead-end codebase.

@earlephilhower earlephilhower deleted the fstime branch November 18, 2020 00:17
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

Successfully merging this pull request may close these issues.

4 participants