Added lfsr_file_resync
lfsr_file_resync discards the current working state of a file and
reverts it to the contents on disk. It also clears the desynced flag
from files, so provides an alternative to lfsr_file_sync for when you
don't want to write to the filesystem:
disk=A file=A disk=A file=A
| write B | write B
v v
disk=A file=B disk=A file=B
| sync | resync
v v
disk=B file=B disk=A file=A
The main motivation for this is to provide a way to mark desynced
readonly files as in-sync, without putting them into a weird state where
they are "in-sync" but don't match disk.
It's also a bit safer if the file is desynced due to an error, since
errors aren't currently guaranteed to leave file data in a defined
state. Needed to resync to recover from errors avoids accidentally
syncing partial writes.
This exact behavior can also be accomplished by closing+opening the
file, but lfsr_file_resync makes it much easier without _that_ much
extra code. It may even pay for itself if you consider what code it
saves on the user's side of things.
I considered naming this lfsr_file_discard because I think it sounds
cooler, but I figured including sync in the name provides a stronger
hint that it affects the file's desync status.
---
You may think it's not possible for a readonly file to become
out-of-sync from disk, since it's, well, readonly. But it is possible
thanks to desynced files ignoring other sync broadcasts.
Consider what happens if you open a file readonly, and write+sync the
file with another file handle at the same time:
disk=A f1=A f2=A
| desync f2
v
disk=A f1=A f2=A
| write f1=B
v
disk=A f1=B f2=A
| sync f1
v
disk=B f1=B f2=A <-- f2 is out-of-sync without any writes
---
This commit also changes lfsr_file_sync/flush to assert if the file is
readonly. Previously we allowed lfsr_file_sync to be called on readonly
files if it would be a noop, but lfsr_file_resync makes this
unnecessary.
More code means more code, but I think it is well worth it for the
additional flexibility:
code stack
before: 36412 2616
after: 36748 (+0.9%) 2616 (+0.0%)
This commit is contained in:
@@ -988,6 +988,15 @@ int lfsr_file_close(lfs_t *lfs, lfsr_file_t *file);
|
||||
//int lfs_file_sync(lfs_t *lfs, lfs_file_t *file);
|
||||
int lfsr_file_sync(lfs_t *lfs, lfsr_file_t *file);
|
||||
|
||||
// Flush any buffered data
|
||||
//
|
||||
// This does not update metadata and is called implicitly by lfsr_file_sync.
|
||||
// Calling this explicitly may be useful for preventing write errors in
|
||||
// read operations.
|
||||
//
|
||||
// Returns a negative error code on failure.
|
||||
int lfsr_file_flush(lfs_t *lfs, lfsr_file_t *file);
|
||||
|
||||
// Mark a file as desynchronized
|
||||
//
|
||||
// Desynchronized files do not recieve file updates and do not sync on close.
|
||||
@@ -997,20 +1006,19 @@ int lfsr_file_sync(lfs_t *lfs, lfsr_file_t *file);
|
||||
// If an error occurs during a write operation, the file is implicitly marked
|
||||
// as desynchronized.
|
||||
//
|
||||
// An explicit and successful call to lfsr_file_sync reverses this, marking
|
||||
// the file as synchronized again.
|
||||
// An explicit and successful call to either lfsr_file_sync or
|
||||
// lfsr_file_resync reverses this, marking the file as synchronized again.
|
||||
//
|
||||
// Returns a negative error code on failure.
|
||||
int lfsr_file_desync(lfs_t *lfs, lfsr_file_t *file);
|
||||
|
||||
// Flush any buffered data
|
||||
// Discard unsynchronized changes and mark a file as synchronized
|
||||
//
|
||||
// This does not update metadata and is called implicitly by lfsr_file_sync.
|
||||
// Calling this explicitly may be useful for preventing write errors in
|
||||
// read operations.
|
||||
// This is effectively the same as closing and reopening the file, and
|
||||
// may read from disk to figure out file state.
|
||||
//
|
||||
// Returns a negative error code on failure.
|
||||
int lfsr_file_flush(lfs_t *lfs, lfsr_file_t *file);
|
||||
int lfsr_file_resync(lfs_t *lfs, lfsr_file_t *file);
|
||||
|
||||
// Read data from file
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user