diff --git a/lfs2.c b/lfs2.c index 81aa81a5..3c0bb6b8 100644 --- a/lfs2.c +++ b/lfs2.c @@ -688,7 +688,7 @@ static int lfs2_alloc(lfs2_t *lfs2, lfs2_block_t *block) { if (lfs2->lookahead.ckpoint <= 0) { LFS2_ERROR("No more free space 0x%"PRIx32, (lfs2->lookahead.start + lfs2->lookahead.next) - % lfs2->cfg->block_count); + % lfs2->block_count); return LFS2_ERR_NOSPC; } diff --git a/lfs2.h b/lfs2.h index 4ff37974..4719e5b6 100644 --- a/lfs2.h +++ b/lfs2.h @@ -59,7 +59,8 @@ typedef uint32_t lfs2_block_t; #endif // Maximum size of custom attributes in bytes, may be redefined, but there is -// no real benefit to using a smaller LFS2_ATTR_MAX. Limited to <= 1022. +// no real benefit to using a smaller LFS2_ATTR_MAX. Limited to <= 1022. Stored +// in superblock and must be respected by other littlefs drivers. #ifndef LFS2_ATTR_MAX #define LFS2_ATTR_MAX 1022 #endif @@ -203,7 +204,8 @@ struct lfs2_config { // program sizes. lfs2_size_t block_size; - // Number of erasable blocks on the device. + // Number of erasable blocks on the device. Defaults to block_count stored + // on disk when zero. lfs2_size_t block_count; // Number of erase cycles before littlefs evicts metadata logs and moves @@ -252,18 +254,18 @@ struct lfs2_config { // Optional upper limit on length of file names in bytes. No downside for // larger names except the size of the info struct which is controlled by - // the LFS2_NAME_MAX define. Defaults to LFS2_NAME_MAX when zero. Stored in - // superblock and must be respected by other littlefs drivers. + // the LFS2_NAME_MAX define. Defaults to LFS2_NAME_MAX or name_max stored on + // disk when zero. lfs2_size_t name_max; // Optional upper limit on files in bytes. No downside for larger files - // but must be <= LFS2_FILE_MAX. Defaults to LFS2_FILE_MAX when zero. Stored - // in superblock and must be respected by other littlefs drivers. + // but must be <= LFS2_FILE_MAX. Defaults to LFS2_FILE_MAX or file_max stored + // on disk when zero. lfs2_size_t file_max; // Optional upper limit on custom attributes in bytes. No downside for // larger attributes size but must be <= LFS2_ATTR_MAX. Defaults to - // LFS2_ATTR_MAX when zero. + // LFS2_ATTR_MAX or attr_max stored on disk when zero. lfs2_size_t attr_max; // Optional upper limit on total space given to metadata pairs in bytes. On diff --git a/tests/test_alloc.toml b/tests/test_alloc.toml index 2c9add4c..f2039620 100644 --- a/tests/test_alloc.toml +++ b/tests/test_alloc.toml @@ -8,17 +8,22 @@ defines.FILES = 3 defines.SIZE = '(((BLOCK_SIZE-8)*(BLOCK_COUNT-6)) / FILES)' defines.GC = [false, true] defines.COMPACT_THRESH = ['-1', '0', 'BLOCK_SIZE/2'] +defines.INFER_BC = [false, true] code = ''' const char *names[] = {"bacon", "eggs", "pancakes"}; lfs2_file_t files[FILES]; lfs2_t lfs2; lfs2_format(&lfs2, cfg) => 0; - lfs2_mount(&lfs2, cfg) => 0; + struct lfs2_config cfg_ = *cfg; + if (INFER_BC) { + cfg_.block_count = 0; + } + lfs2_mount(&lfs2, &cfg_) => 0; lfs2_mkdir(&lfs2, "breakfast") => 0; lfs2_unmount(&lfs2) => 0; - lfs2_mount(&lfs2, cfg) => 0; + lfs2_mount(&lfs2, &cfg_) => 0; for (int n = 0; n < FILES; n++) { char path[1024]; sprintf(path, "breakfast/%s", names[n]); @@ -39,7 +44,7 @@ code = ''' } lfs2_unmount(&lfs2) => 0; - lfs2_mount(&lfs2, cfg) => 0; + lfs2_mount(&lfs2, &cfg_) => 0; for (int n = 0; n < FILES; n++) { char path[1024]; sprintf(path, "breakfast/%s", names[n]); @@ -62,17 +67,22 @@ defines.FILES = 3 defines.SIZE = '(((BLOCK_SIZE-8)*(BLOCK_COUNT-6)) / FILES)' defines.GC = [false, true] defines.COMPACT_THRESH = ['-1', '0', 'BLOCK_SIZE/2'] +defines.INFER_BC = [false, true] code = ''' const char *names[] = {"bacon", "eggs", "pancakes"}; lfs2_t lfs2; lfs2_format(&lfs2, cfg) => 0; - lfs2_mount(&lfs2, cfg) => 0; + struct lfs2_config cfg_ = *cfg; + if (INFER_BC) { + cfg_.block_count = 0; + } + lfs2_mount(&lfs2, &cfg_) => 0; lfs2_mkdir(&lfs2, "breakfast") => 0; lfs2_unmount(&lfs2) => 0; for (int n = 0; n < FILES; n++) { - lfs2_mount(&lfs2, cfg) => 0; + lfs2_mount(&lfs2, &cfg_) => 0; char path[1024]; sprintf(path, "breakfast/%s", names[n]); lfs2_file_t file; @@ -91,7 +101,7 @@ code = ''' lfs2_unmount(&lfs2) => 0; } - lfs2_mount(&lfs2, cfg) => 0; + lfs2_mount(&lfs2, &cfg_) => 0; for (int n = 0; n < FILES; n++) { char path[1024]; sprintf(path, "breakfast/%s", names[n]); @@ -113,19 +123,24 @@ code = ''' defines.FILES = 3 defines.SIZE = '(((BLOCK_SIZE-8)*(BLOCK_COUNT-6)) / FILES)' defines.CYCLES = [1, 10] +defines.INFER_BC = [false, true] code = ''' const char *names[] = {"bacon", "eggs", "pancakes"}; lfs2_file_t files[FILES]; lfs2_t lfs2; lfs2_format(&lfs2, cfg) => 0; + struct lfs2_config cfg_ = *cfg; + if (INFER_BC) { + cfg_.block_count = 0; + } for (int c = 0; c < CYCLES; c++) { - lfs2_mount(&lfs2, cfg) => 0; + lfs2_mount(&lfs2, &cfg_) => 0; lfs2_mkdir(&lfs2, "breakfast") => 0; lfs2_unmount(&lfs2) => 0; - lfs2_mount(&lfs2, cfg) => 0; + lfs2_mount(&lfs2, &cfg_) => 0; for (int n = 0; n < FILES; n++) { char path[1024]; sprintf(path, "breakfast/%s", names[n]); @@ -143,7 +158,7 @@ code = ''' } lfs2_unmount(&lfs2) => 0; - lfs2_mount(&lfs2, cfg) => 0; + lfs2_mount(&lfs2, &cfg_) => 0; for (int n = 0; n < FILES; n++) { char path[1024]; sprintf(path, "breakfast/%s", names[n]); @@ -159,7 +174,7 @@ code = ''' } lfs2_unmount(&lfs2) => 0; - lfs2_mount(&lfs2, cfg) => 0; + lfs2_mount(&lfs2, &cfg_) => 0; for (int n = 0; n < FILES; n++) { char path[1024]; sprintf(path, "breakfast/%s", names[n]); @@ -175,19 +190,24 @@ code = ''' defines.FILES = 3 defines.SIZE = '(((BLOCK_SIZE-8)*(BLOCK_COUNT-6)) / FILES)' defines.CYCLES = [1, 10] +defines.INFER_BC = [false, true] code = ''' const char *names[] = {"bacon", "eggs", "pancakes"}; lfs2_t lfs2; lfs2_format(&lfs2, cfg) => 0; + struct lfs2_config cfg_ = *cfg; + if (INFER_BC) { + cfg_.block_count = 0; + } for (int c = 0; c < CYCLES; c++) { - lfs2_mount(&lfs2, cfg) => 0; + lfs2_mount(&lfs2, &cfg_) => 0; lfs2_mkdir(&lfs2, "breakfast") => 0; lfs2_unmount(&lfs2) => 0; for (int n = 0; n < FILES; n++) { - lfs2_mount(&lfs2, cfg) => 0; + lfs2_mount(&lfs2, &cfg_) => 0; char path[1024]; sprintf(path, "breakfast/%s", names[n]); lfs2_file_t file; @@ -232,10 +252,15 @@ code = ''' # exhaustion test [cases.test_alloc_exhaustion] +defines.INFER_BC = [false, true] code = ''' lfs2_t lfs2; lfs2_format(&lfs2, cfg) => 0; - lfs2_mount(&lfs2, cfg) => 0; + struct lfs2_config cfg_ = *cfg; + if (INFER_BC) { + cfg_.block_count = 0; + } + lfs2_mount(&lfs2, &cfg_) => 0; lfs2_file_t file; lfs2_file_open(&lfs2, &file, "exhaustion", LFS2_O_WRONLY | LFS2_O_CREAT); size_t size = strlen("exhaustion"); @@ -263,7 +288,7 @@ code = ''' lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; - lfs2_mount(&lfs2, cfg) => 0; + lfs2_mount(&lfs2, &cfg_) => 0; lfs2_file_open(&lfs2, &file, "exhaustion", LFS2_O_RDONLY); size = strlen("exhaustion"); lfs2_file_size(&lfs2, &file) => size; @@ -276,10 +301,15 @@ code = ''' # exhaustion wraparound test [cases.test_alloc_exhaustion_wraparound] defines.SIZE = '(((BLOCK_SIZE-8)*(BLOCK_COUNT-4)) / 3)' +defines.INFER_BC = [false, true] code = ''' lfs2_t lfs2; lfs2_format(&lfs2, cfg) => 0; - lfs2_mount(&lfs2, cfg) => 0; + struct lfs2_config cfg_ = *cfg; + if (INFER_BC) { + cfg_.block_count = 0; + } + lfs2_mount(&lfs2, &cfg_) => 0; lfs2_file_t file; lfs2_file_open(&lfs2, &file, "padding", LFS2_O_WRONLY | LFS2_O_CREAT); @@ -317,7 +347,7 @@ code = ''' lfs2_file_close(&lfs2, &file) => 0; lfs2_unmount(&lfs2) => 0; - lfs2_mount(&lfs2, cfg) => 0; + lfs2_mount(&lfs2, &cfg_) => 0; lfs2_file_open(&lfs2, &file, "exhaustion", LFS2_O_RDONLY); size = strlen("exhaustion"); lfs2_file_size(&lfs2, &file) => size; @@ -330,10 +360,15 @@ code = ''' # dir exhaustion test [cases.test_alloc_dir_exhaustion] +defines.INFER_BC = [false, true] code = ''' lfs2_t lfs2; lfs2_format(&lfs2, cfg) => 0; - lfs2_mount(&lfs2, cfg) => 0; + struct lfs2_config cfg_ = *cfg; + if (INFER_BC) { + cfg_.block_count = 0; + } + lfs2_mount(&lfs2, &cfg_) => 0; // find out max file size lfs2_mkdir(&lfs2, "exhaustiondir") => 0;