diff --git a/lfs2.c b/lfs2.c index 0ea658f..4d17bd7 100644 --- a/lfs2.c +++ b/lfs2.c @@ -84,9 +84,12 @@ static int lfs2_bd_read(lfs2_t *lfs2, LFS2_ASSERT(block < lfs2->cfg->block_count); rcache->block = block; rcache->off = lfs2_aligndown(off, lfs2->cfg->read_size); - rcache->size = lfs2_min(lfs2_alignup(off+hint, lfs2->cfg->read_size), - lfs2_min(lfs2->cfg->block_size - rcache->off, - lfs2->cfg->cache_size)); + rcache->size = lfs2_min( + lfs2_min( + lfs2_alignup(off+hint, lfs2->cfg->read_size), + lfs2->cfg->block_size) + - rcache->off, + lfs2->cfg->cache_size); int err = lfs2->cfg->read(lfs2->cfg, rcache->block, rcache->off, rcache->buffer, rcache->size); if (err) { @@ -2734,7 +2737,7 @@ lfs2_ssize_t lfs2_file_write(lfs2_t *lfs2, lfs2_file_t *file, if ((file->flags & LFS2_F_INLINE) && lfs2_max(file->pos+nsize, file->ctz.size) > - lfs2_min(LFS2_ATTR_MAX, lfs2_min( + lfs2_min(0x3fe, lfs2_min( lfs2->cfg->cache_size, lfs2->cfg->block_size/8))) { // inline file doesn't fit anymore file->off = file->pos; @@ -2864,13 +2867,14 @@ int lfs2_file_truncate(lfs2_t *lfs2, lfs2_file_t *file, lfs2_off_t size) { // lookup new head in ctz skip list err = lfs2_ctz_find(lfs2, NULL, &file->cache, file->ctz.head, file->ctz.size, - size, &file->ctz.head, &(lfs2_off_t){0}); + size, &file->block, &file->off); if (err) { return err; } + file->ctz.head = file->block; file->ctz.size = size; - file->flags |= LFS2_F_DIRTY; + file->flags |= LFS2_F_DIRTY | LFS2_F_READING; } else if (size > oldsize) { lfs2_off_t pos = file->pos; @@ -3900,7 +3904,7 @@ typedef struct lfs21_superblock { /// Low-level wrappers v1->v2 /// -void lfs21_crc(uint32_t *crc, const void *buffer, size_t size) { +static void lfs21_crc(uint32_t *crc, const void *buffer, size_t size) { *crc = lfs2_crc(*crc, buffer, size); } diff --git a/lfs2_util.h b/lfs2_util.h index c8cc316..8e68210 100644 --- a/lfs2_util.h +++ b/lfs2_util.h @@ -143,14 +143,14 @@ static inline int lfs2_scmp(uint32_t a, uint32_t b) { // Convert between 32-bit little-endian and native order static inline uint32_t lfs2_fromle32(uint32_t a) { #if !defined(LFS2_NO_INTRINSICS) && ( \ - (defined( BYTE_ORDER ) && BYTE_ORDER == ORDER_LITTLE_ENDIAN ) || \ - (defined(__BYTE_ORDER ) && __BYTE_ORDER == __ORDER_LITTLE_ENDIAN ) || \ - (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) + (defined( BYTE_ORDER ) && defined( ORDER_LITTLE_ENDIAN ) && BYTE_ORDER == ORDER_LITTLE_ENDIAN ) || \ + (defined(__BYTE_ORDER ) && defined(__ORDER_LITTLE_ENDIAN ) && __BYTE_ORDER == __ORDER_LITTLE_ENDIAN ) || \ + (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) return a; #elif !defined(LFS2_NO_INTRINSICS) && ( \ - (defined( BYTE_ORDER ) && BYTE_ORDER == ORDER_BIG_ENDIAN ) || \ - (defined(__BYTE_ORDER ) && __BYTE_ORDER == __ORDER_BIG_ENDIAN ) || \ - (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) + (defined( BYTE_ORDER ) && defined( ORDER_BIG_ENDIAN ) && BYTE_ORDER == ORDER_BIG_ENDIAN ) || \ + (defined(__BYTE_ORDER ) && defined(__ORDER_BIG_ENDIAN ) && __BYTE_ORDER == __ORDER_BIG_ENDIAN ) || \ + (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) return __builtin_bswap32(a); #else return (((uint8_t*)&a)[0] << 0) | @@ -167,14 +167,14 @@ static inline uint32_t lfs2_tole32(uint32_t a) { // Convert between 32-bit big-endian and native order static inline uint32_t lfs2_frombe32(uint32_t a) { #if !defined(LFS2_NO_INTRINSICS) && ( \ - (defined( BYTE_ORDER ) && BYTE_ORDER == ORDER_LITTLE_ENDIAN ) || \ - (defined(__BYTE_ORDER ) && __BYTE_ORDER == __ORDER_LITTLE_ENDIAN ) || \ - (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) + (defined( BYTE_ORDER ) && defined( ORDER_LITTLE_ENDIAN ) && BYTE_ORDER == ORDER_LITTLE_ENDIAN ) || \ + (defined(__BYTE_ORDER ) && defined(__ORDER_LITTLE_ENDIAN ) && __BYTE_ORDER == __ORDER_LITTLE_ENDIAN ) || \ + (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) return __builtin_bswap32(a); #elif !defined(LFS2_NO_INTRINSICS) && ( \ - (defined( BYTE_ORDER ) && BYTE_ORDER == ORDER_BIG_ENDIAN ) || \ - (defined(__BYTE_ORDER ) && __BYTE_ORDER == __ORDER_BIG_ENDIAN ) || \ - (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) + (defined( BYTE_ORDER ) && defined( ORDER_BIG_ENDIAN ) && BYTE_ORDER == ORDER_BIG_ENDIAN ) || \ + (defined(__BYTE_ORDER ) && defined(__ORDER_BIG_ENDIAN ) && __BYTE_ORDER == __ORDER_BIG_ENDIAN ) || \ + (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) return a; #else return (((uint8_t*)&a)[0] << 24) | diff --git a/tests/test_truncate.sh b/tests/test_truncate.sh index 28381a3..73fd41e 100755 --- a/tests/test_truncate.sh +++ b/tests/test_truncate.sh @@ -11,6 +11,150 @@ tests/test.py << TEST lfs2_format(&lfs2, &cfg) => 0; TEST +echo "--- Simple truncate ---" +tests/test.py << TEST + lfs2_mount(&lfs2, &cfg) => 0; + lfs2_file_open(&lfs2, &file[0], "baldynoop", + LFS2_O_WRONLY | LFS2_O_CREAT) => 0; + + strcpy((char*)buffer, "hair"); + size = strlen((char*)buffer); + for (lfs2_off_t j = 0; j < $LARGESIZE; j += size) { + lfs2_file_write(&lfs2, &file[0], buffer, size) => size; + } + lfs2_file_size(&lfs2, &file[0]) => $LARGESIZE; + + lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_unmount(&lfs2) => 0; +TEST +tests/test.py << TEST + lfs2_mount(&lfs2, &cfg) => 0; + lfs2_file_open(&lfs2, &file[0], "baldynoop", LFS2_O_RDWR) => 0; + lfs2_file_size(&lfs2, &file[0]) => $LARGESIZE; + + lfs2_file_truncate(&lfs2, &file[0], $MEDIUMSIZE) => 0; + lfs2_file_size(&lfs2, &file[0]) => $MEDIUMSIZE; + + lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_unmount(&lfs2) => 0; +TEST +tests/test.py << TEST + lfs2_mount(&lfs2, &cfg) => 0; + lfs2_file_open(&lfs2, &file[0], "baldynoop", LFS2_O_RDONLY) => 0; + lfs2_file_size(&lfs2, &file[0]) => $MEDIUMSIZE; + + size = strlen("hair"); + for (lfs2_off_t j = 0; j < $MEDIUMSIZE; j += size) { + lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + memcmp(buffer, "hair", size) => 0; + } + lfs2_file_read(&lfs2, &file[0], buffer, size) => 0; + + lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_unmount(&lfs2) => 0; +TEST + +echo "--- Truncate and read ---" +tests/test.py << TEST + lfs2_mount(&lfs2, &cfg) => 0; + lfs2_file_open(&lfs2, &file[0], "baldyread", + LFS2_O_WRONLY | LFS2_O_CREAT) => 0; + + strcpy((char*)buffer, "hair"); + size = strlen((char*)buffer); + for (lfs2_off_t j = 0; j < $LARGESIZE; j += size) { + lfs2_file_write(&lfs2, &file[0], buffer, size) => size; + } + lfs2_file_size(&lfs2, &file[0]) => $LARGESIZE; + + lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_unmount(&lfs2) => 0; +TEST +tests/test.py << TEST + lfs2_mount(&lfs2, &cfg) => 0; + lfs2_file_open(&lfs2, &file[0], "baldyread", LFS2_O_RDWR) => 0; + lfs2_file_size(&lfs2, &file[0]) => $LARGESIZE; + + lfs2_file_truncate(&lfs2, &file[0], $MEDIUMSIZE) => 0; + lfs2_file_size(&lfs2, &file[0]) => $MEDIUMSIZE; + + size = strlen("hair"); + for (lfs2_off_t j = 0; j < $MEDIUMSIZE; j += size) { + lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + memcmp(buffer, "hair", size) => 0; + } + lfs2_file_read(&lfs2, &file[0], buffer, size) => 0; + + lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_unmount(&lfs2) => 0; +TEST +tests/test.py << TEST + lfs2_mount(&lfs2, &cfg) => 0; + lfs2_file_open(&lfs2, &file[0], "baldyread", LFS2_O_RDONLY) => 0; + lfs2_file_size(&lfs2, &file[0]) => $MEDIUMSIZE; + + size = strlen("hair"); + for (lfs2_off_t j = 0; j < $MEDIUMSIZE; j += size) { + lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + memcmp(buffer, "hair", size) => 0; + } + lfs2_file_read(&lfs2, &file[0], buffer, size) => 0; + + lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_unmount(&lfs2) => 0; +TEST + +echo "--- Truncate and write ---" +tests/test.py << TEST + lfs2_mount(&lfs2, &cfg) => 0; + lfs2_file_open(&lfs2, &file[0], "baldywrite", + LFS2_O_WRONLY | LFS2_O_CREAT) => 0; + + strcpy((char*)buffer, "hair"); + size = strlen((char*)buffer); + for (lfs2_off_t j = 0; j < $LARGESIZE; j += size) { + lfs2_file_write(&lfs2, &file[0], buffer, size) => size; + } + lfs2_file_size(&lfs2, &file[0]) => $LARGESIZE; + + lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_unmount(&lfs2) => 0; +TEST +tests/test.py << TEST + lfs2_mount(&lfs2, &cfg) => 0; + lfs2_file_open(&lfs2, &file[0], "baldywrite", LFS2_O_RDWR) => 0; + lfs2_file_size(&lfs2, &file[0]) => $LARGESIZE; + + lfs2_file_truncate(&lfs2, &file[0], $MEDIUMSIZE) => 0; + lfs2_file_size(&lfs2, &file[0]) => $MEDIUMSIZE; + + strcpy((char*)buffer, "bald"); + size = strlen((char*)buffer); + for (lfs2_off_t j = 0; j < $MEDIUMSIZE; j += size) { + lfs2_file_write(&lfs2, &file[0], buffer, size) => size; + } + lfs2_file_size(&lfs2, &file[0]) => $MEDIUMSIZE; + + lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_unmount(&lfs2) => 0; +TEST +tests/test.py << TEST + lfs2_mount(&lfs2, &cfg) => 0; + lfs2_file_open(&lfs2, &file[0], "baldywrite", LFS2_O_RDONLY) => 0; + lfs2_file_size(&lfs2, &file[0]) => $MEDIUMSIZE; + + size = strlen("bald"); + for (lfs2_off_t j = 0; j < $MEDIUMSIZE; j += size) { + lfs2_file_read(&lfs2, &file[0], buffer, size) => size; + memcmp(buffer, "bald", size) => 0; + } + lfs2_file_read(&lfs2, &file[0], buffer, size) => 0; + + lfs2_file_close(&lfs2, &file[0]) => 0; + lfs2_unmount(&lfs2) => 0; +TEST + +# More aggressive general truncation tests truncate_test() { STARTSIZES="$1" STARTSEEKS="$2"