@@ -524,6 +524,114 @@ code = '''
524524 lfs_unmount(&lfs) => 0;
525525'''
526526
527+
528+ # mount and grow the filesystem
529+ [cases .test_superblocks_shrink ]
530+ defines.BLOCK_COUNT = ' ERASE_COUNT'
531+ defines.BLOCK_COUNT_2 = [' ERASE_COUNT/2' , ' ERASE_COUNT/4' , ' 2' ]
532+ defines.KNOWN_BLOCK_COUNT = [true , false ]
533+ code = '''
534+ #ifdef LFS_SHRINKNONRELOCATING
535+ lfs_t lfs;
536+ lfs_format(&lfs, cfg) => 0;
537+
538+ if (KNOWN_BLOCK_COUNT) {
539+ cfg->block_count = BLOCK_COUNT;
540+ } else {
541+ cfg->block_count = 0;
542+ }
543+
544+ // mount with block_size < erase_size
545+ lfs_mount(&lfs, cfg) => 0;
546+ struct lfs_fsinfo fsinfo;
547+ lfs_fs_stat(&lfs, &fsinfo) => 0;
548+ assert(fsinfo.block_size == BLOCK_SIZE);
549+ assert(fsinfo.block_count == BLOCK_COUNT);
550+ lfs_unmount(&lfs) => 0;
551+
552+ // same size is a noop
553+ lfs_mount(&lfs, cfg) => 0;
554+ lfs_fs_grow(&lfs, BLOCK_COUNT) => 0;
555+ lfs_fs_stat(&lfs, &fsinfo) => 0;
556+ assert(fsinfo.block_size == BLOCK_SIZE);
557+ assert(fsinfo.block_count == BLOCK_COUNT);
558+ lfs_unmount(&lfs) => 0;
559+
560+ lfs_mount(&lfs, cfg) => 0;
561+ lfs_fs_stat(&lfs, &fsinfo) => 0;
562+ assert(fsinfo.block_size == BLOCK_SIZE);
563+ assert(fsinfo.block_count == BLOCK_COUNT);
564+ lfs_unmount(&lfs) => 0;
565+
566+ // grow to new size
567+ lfs_mount(&lfs, cfg) => 0;
568+ lfs_fs_grow(&lfs, BLOCK_COUNT_2) => 0;
569+ lfs_fs_stat(&lfs, &fsinfo) => 0;
570+ assert(fsinfo.block_size == BLOCK_SIZE);
571+ assert(fsinfo.block_count == BLOCK_COUNT_2);
572+ lfs_unmount(&lfs) => 0;
573+
574+ if (KNOWN_BLOCK_COUNT) {
575+ cfg->block_count = BLOCK_COUNT_2;
576+ } else {
577+ cfg->block_count = 0;
578+ }
579+
580+ lfs_mount(&lfs, cfg) => 0;
581+ lfs_fs_stat(&lfs, &fsinfo) => 0;
582+ assert(fsinfo.block_size == BLOCK_SIZE);
583+ assert(fsinfo.block_count == BLOCK_COUNT_2);
584+ lfs_unmount(&lfs) => 0;
585+
586+ // mounting with the previous size should fail
587+ cfg->block_count = BLOCK_COUNT;
588+ lfs_mount(&lfs, cfg) => LFS_ERR_INVAL;
589+
590+ if (KNOWN_BLOCK_COUNT) {
591+ cfg->block_count = BLOCK_COUNT_2;
592+ } else {
593+ cfg->block_count = 0;
594+ }
595+
596+ // same size is a noop
597+ lfs_mount(&lfs, cfg) => 0;
598+ lfs_fs_grow(&lfs, BLOCK_COUNT_2) => 0;
599+ lfs_fs_stat(&lfs, &fsinfo) => 0;
600+ assert(fsinfo.block_size == BLOCK_SIZE);
601+ assert(fsinfo.block_count == BLOCK_COUNT_2);
602+ lfs_unmount(&lfs) => 0;
603+
604+ lfs_mount(&lfs, cfg) => 0;
605+ lfs_fs_stat(&lfs, &fsinfo) => 0;
606+ assert(fsinfo.block_size == BLOCK_SIZE);
607+ assert(fsinfo.block_count == BLOCK_COUNT_2);
608+ lfs_unmount(&lfs) => 0;
609+
610+ // do some work
611+ lfs_mount(&lfs, cfg) => 0;
612+ lfs_fs_stat(&lfs, &fsinfo) => 0;
613+ assert(fsinfo.block_size == BLOCK_SIZE);
614+ assert(fsinfo.block_count == BLOCK_COUNT_2);
615+ lfs_file_t file;
616+ lfs_file_open(&lfs, &file, "test",
617+ LFS_O_CREAT | LFS_O_EXCL | LFS_O_WRONLY) => 0;
618+ lfs_file_write(&lfs, &file, "hello!", 6) => 6;
619+ lfs_file_close(&lfs, &file) => 0;
620+ lfs_unmount(&lfs) => 0;
621+
622+ lfs_mount(&lfs, cfg) => 0;
623+ lfs_fs_stat(&lfs, &fsinfo) => 0;
624+ assert(fsinfo.block_size == BLOCK_SIZE);
625+ assert(fsinfo.block_count == BLOCK_COUNT_2);
626+ lfs_file_open(&lfs, &file, "test", LFS_O_RDONLY) => 0;
627+ uint8_t buffer[256];
628+ lfs_file_read(&lfs, &file, buffer, sizeof(buffer)) => 6;
629+ lfs_file_close(&lfs, &file) => 0;
630+ assert(memcmp(buffer, "hello!", 6) == 0);
631+ lfs_unmount(&lfs) => 0;
632+ #endif
633+ '''
634+
527635# test that metadata_max does not cause problems for superblock compaction
528636[cases .test_superblocks_metadata_max ]
529637defines.METADATA_MAX = [
0 commit comments