diff options
author | Christopher Haster <chaster@utexas.edu> | 2017-04-01 20:23:15 +0300 |
---|---|---|
committer | Christopher Haster <chaster@utexas.edu> | 2017-04-18 09:44:01 +0300 |
commit | a3734eeb34e09b85b59b53944f88b0325b968488 (patch) | |
tree | 0948d3a02e8ba5b4a98832a33425a8b76f149e35 /emubd | |
parent | 8a674524fcec8db761bc7c3818df58609a28623c (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.c | 32 |
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) { |