Merge pull request #511 from embeddedt/fix_lseek

Skip flushing file if lfs_file_rawseek() doesn't change position
This commit is contained in:
Christopher Haster
2021-01-18 11:47:56 -06:00
committed by GitHub
2 changed files with 66 additions and 15 deletions

36
lfs.c
View File

@@ -3055,14 +3055,6 @@ relocate:
static lfs_soff_t lfs_file_rawseek(lfs_t *lfs, lfs_file_t *file, static lfs_soff_t lfs_file_rawseek(lfs_t *lfs, lfs_file_t *file,
lfs_soff_t off, int whence) { lfs_soff_t off, int whence) {
#ifndef LFS_READONLY
// write out everything beforehand, may be noop if rdonly
int err = lfs_file_flush(lfs, file);
if (err) {
return err;
}
#endif
// find new pos // find new pos
lfs_off_t npos = file->pos; lfs_off_t npos = file->pos;
if (whence == LFS_SEEK_SET) { if (whence == LFS_SEEK_SET) {
@@ -3070,7 +3062,7 @@ static lfs_soff_t lfs_file_rawseek(lfs_t *lfs, lfs_file_t *file,
} else if (whence == LFS_SEEK_CUR) { } else if (whence == LFS_SEEK_CUR) {
npos = file->pos + off; npos = file->pos + off;
} else if (whence == LFS_SEEK_END) { } else if (whence == LFS_SEEK_END) {
npos = file->ctz.size + off; npos = lfs_file_rawsize(lfs, file) + off;
} }
if (npos > lfs->file_max) { if (npos > lfs->file_max) {
@@ -3078,6 +3070,19 @@ static lfs_soff_t lfs_file_rawseek(lfs_t *lfs, lfs_file_t *file,
return LFS_ERR_INVAL; return LFS_ERR_INVAL;
} }
if (file->pos == npos) {
// noop - position has not changed
return npos;
}
#ifndef LFS_READONLY
// write out everything beforehand, may be noop if rdonly
int err = lfs_file_flush(lfs, file);
if (err) {
return err;
}
#endif
// update pos // update pos
file->pos = npos; file->pos = npos;
return npos; return npos;
@@ -3108,21 +3113,22 @@ static int lfs_file_rawtruncate(lfs_t *lfs, lfs_file_t *file, lfs_off_t size) {
return err; return err;
} }
// need to set pos/block/off consistently so seeking back to
// the old position does not get confused
file->pos = size;
file->ctz.head = file->block; file->ctz.head = file->block;
file->ctz.size = size; file->ctz.size = size;
file->flags |= LFS_F_DIRTY | LFS_F_READING; file->flags |= LFS_F_DIRTY | LFS_F_READING;
} else if (size > oldsize) { } else if (size > oldsize) {
// flush+seek if not already at end // flush+seek if not already at end
if (file->pos != oldsize) { lfs_soff_t res = lfs_file_rawseek(lfs, file, 0, LFS_SEEK_END);
lfs_soff_t res = lfs_file_rawseek(lfs, file, 0, LFS_SEEK_END); if (res < 0) {
if (res < 0) { return (int)res;
return (int)res;
}
} }
// fill with zeros // fill with zeros
while (file->pos < size) { while (file->pos < size) {
lfs_ssize_t res = lfs_file_rawwrite(lfs, file, &(uint8_t){0}, 1); res = lfs_file_rawwrite(lfs, file, &(uint8_t){0}, 1);
if (res < 0) { if (res < 0) {
return (int)res; return (int)res;
} }

View File

@@ -392,3 +392,48 @@ code = '''
lfs_unmount(&lfs) => 0; lfs_unmount(&lfs) => 0;
''' '''
[[case]] # noop truncate
define.MEDIUMSIZE = [32, 2048]
code = '''
lfs_format(&lfs, &cfg) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_file_open(&lfs, &file, "baldynoop",
LFS_O_RDWR | LFS_O_CREAT) => 0;
strcpy((char*)buffer, "hair");
size = strlen((char*)buffer);
for (lfs_off_t j = 0; j < MEDIUMSIZE; j += size) {
lfs_file_write(&lfs, &file, buffer, size) => size;
// this truncate should do nothing
lfs_file_truncate(&lfs, &file, j+size) => 0;
}
lfs_file_size(&lfs, &file) => MEDIUMSIZE;
lfs_file_seek(&lfs, &file, 0, LFS_SEEK_SET) => 0;
// should do nothing again
lfs_file_truncate(&lfs, &file, MEDIUMSIZE) => 0;
lfs_file_size(&lfs, &file) => MEDIUMSIZE;
for (lfs_off_t j = 0; j < MEDIUMSIZE; j += size) {
lfs_file_read(&lfs, &file, buffer, size) => size;
memcmp(buffer, "hair", size) => 0;
}
lfs_file_read(&lfs, &file, buffer, size) => 0;
lfs_file_close(&lfs, &file) => 0;
lfs_unmount(&lfs) => 0;
// still there after reboot?
lfs_mount(&lfs, &cfg) => 0;
lfs_file_open(&lfs, &file, "baldynoop", LFS_O_RDWR) => 0;
lfs_file_size(&lfs, &file) => MEDIUMSIZE;
for (lfs_off_t j = 0; j < MEDIUMSIZE; j += size) {
lfs_file_read(&lfs, &file, buffer, size) => size;
memcmp(buffer, "hair", size) => 0;
}
lfs_file_read(&lfs, &file, buffer, size) => 0;
lfs_file_close(&lfs, &file) => 0;
lfs_unmount(&lfs) => 0;
'''