Skip to content
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

[issue 551] Optimized lfs_bd_cmp() and lfs_file_relocate() for bad block reloction. #686

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
20 changes: 14 additions & 6 deletions lfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
#define LFS_BLOCK_NULL ((lfs_block_t)-1)
#define LFS_BLOCK_INLINE ((lfs_block_t)-2)

#define LFS_BULK_RELOC_SIZE 32
#define LFS_BULK_CMP_SIZE 8

enum {
LFS_OK_RELOCATED = 1,
LFS_OK_DROPPED = 2,
Expand Down Expand Up @@ -132,7 +135,7 @@ static int lfs_bd_cmp(lfs_t *lfs,
lfs_size_t diff = 0;

for (lfs_off_t i = 0; i < size; i += diff) {
uint8_t dat[8];
uint8_t dat[LFS_BULK_CMP_SIZE];

diff = lfs_min(size-i, sizeof(dat));
int res = lfs_bd_read(lfs,
Expand Down Expand Up @@ -3026,6 +3029,8 @@ static int lfs_file_rawclose(lfs_t *lfs, lfs_file_t *file) {

#ifndef LFS_READONLY
static int lfs_file_relocate(lfs_t *lfs, lfs_file_t *file) {
lfs_size_t diff = 0;

while (true) {
// just relocate what exists into new block
lfs_block_t nblock;
Expand All @@ -3043,30 +3048,33 @@ static int lfs_file_relocate(lfs_t *lfs, lfs_file_t *file) {
}

// either read from dirty cache or disk
for (lfs_off_t i = 0; i < file->off; i++) {
uint8_t data;
for (lfs_off_t i = 0; i < file->off; i += diff) {
uint8_t dat[LFS_BULK_RELOC_SIZE];

if (file->flags & LFS_F_INLINE) {
diff = 1;
err = lfs_dir_getread(lfs, &file->m,
// note we evict inline files before they can be dirty
NULL, &file->cache, file->off-i,
LFS_MKTAG(0xfff, 0x1ff, 0),
LFS_MKTAG(LFS_TYPE_INLINESTRUCT, file->id, 0),
i, &data, 1);
i, &dat, diff);
if (err) {
return err;
}
} else {
diff = lfs_min(sizeof(dat), file->off-i);
err = lfs_bd_read(lfs,
&file->cache, &lfs->rcache, file->off-i,
file->block, i, &data, 1);
file->block, i, &dat, diff);
if (err) {
return err;
}
}

err = lfs_bd_prog(lfs,
&lfs->pcache, &lfs->rcache, true,
nblock, i, &data, 1);
nblock, i, dat, diff);
if (err) {
if (err == LFS_ERR_CORRUPT) {
goto relocate;
Expand Down