Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/littlefs-project/littlefs.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/emubd
diff options
context:
space:
mode:
authorChristopher Haster <chaster@utexas.edu>2017-04-01 20:23:15 +0300
committerChristopher Haster <chaster@utexas.edu>2017-04-18 09:44:01 +0300
commita3734eeb34e09b85b59b53944f88b0325b968488 (patch)
tree0948d3a02e8ba5b4a98832a33425a8b76f149e35 /emubd
parent8a674524fcec8db761bc7c3818df58609a28623c (diff)
Added proper handling of orphans
Unfortunately, threading all dir blocks in a linked-list did not come without problems. While it's possible to atomically add a dir to the linked list (by adding the new dir into the linked-list position immediately after it's parent, requiring only one atomic update to the parent block), it is not easy to make sure the linked-list is in a state that always allows atomic removal of dirs. The simple solution is to allow this non-atomic removal, with an additional step to remove any orphans that could have been created by a power-loss. This deorphan step is only run if the normal allocator has failed.
Diffstat (limited to 'emubd')
-rw-r--r--emubd/lfs_emubd.c32
1 files changed, 14 insertions, 18 deletions
diff --git a/emubd/lfs_emubd.c b/emubd/lfs_emubd.c
index b24cb0a..7acd8f7 100644
--- a/emubd/lfs_emubd.c
+++ b/emubd/lfs_emubd.c
@@ -14,6 +14,8 @@
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <assert.h>
+#include <stdbool.h>
// Block device emulated on existing filesystem
@@ -76,12 +78,10 @@ int lfs_emubd_read(lfs_emubd_t *emu, lfs_block_t block,
uint8_t *data = buffer;
// Check if read is valid
- if (!(off % emu->info.read_size == 0 &&
- size % emu->info.read_size == 0 &&
- ((uint64_t)block*emu->info.erase_size + off + size
- < emu->info.total_size))) {
- return -EINVAL;
- }
+ assert(off % emu->info.read_size == 0);
+ assert(size % emu->info.read_size == 0);
+ assert((uint64_t)block*emu->info.erase_size + off + size
+ < emu->info.total_size);
// Zero out buffer for debugging
memset(data, 0, size);
@@ -128,12 +128,10 @@ int lfs_emubd_prog(lfs_emubd_t *emu, lfs_block_t block,
const uint8_t *data = buffer;
// Check if write is valid
- if (!(off % emu->info.prog_size == 0 &&
- size % emu->info.prog_size == 0 &&
- ((uint64_t)block*emu->info.erase_size + off + size
- < emu->info.total_size))) {
- return -EINVAL;
- }
+ assert(off % emu->info.prog_size == 0);
+ assert(size % emu->info.prog_size == 0);
+ assert((uint64_t)block*emu->info.erase_size + off + size
+ < emu->info.total_size);
// Iterate over blocks until enough data is read
while (size > 0) {
@@ -177,12 +175,10 @@ int lfs_emubd_erase(lfs_emubd_t *emu, lfs_block_t block,
lfs_off_t off, lfs_size_t size) {
// Check if erase is valid
- if (!(off % emu->info.erase_size == 0 &&
- size % emu->info.erase_size == 0 &&
- ((uint64_t)block*emu->info.erase_size + off + size
- < emu->info.total_size))) {
- return -EINVAL;
- }
+ assert(off % emu->info.erase_size == 0);
+ assert(size % emu->info.erase_size == 0);
+ assert((uint64_t)block*emu->info.erase_size + off + size
+ < emu->info.total_size);
// Iterate and erase blocks
while (size > 0) {