|
@@ -323,6 +323,90 @@ code = '''
|
|
|
lfs_unmount(&lfs) => 0;
|
|
lfs_unmount(&lfs) => 0;
|
|
|
'''
|
|
'''
|
|
|
|
|
|
|
|
|
|
+[[case]] # what if we have a bad block during an allocation scan?
|
|
|
|
|
+in = "lfs.c"
|
|
|
|
|
+define.LFS_ERASE_CYCLES = 0xffffffff
|
|
|
|
|
+define.LFS_BADBLOCK_BEHAVIOR = 'LFS_TESTBD_BADBLOCK_READERROR'
|
|
|
|
|
+code = '''
|
|
|
|
|
+ lfs_format(&lfs, &cfg) => 0;
|
|
|
|
|
+ lfs_mount(&lfs, &cfg) => 0;
|
|
|
|
|
+ // first fill to exhaustion to find available space
|
|
|
|
|
+ lfs_file_open(&lfs, &file, "pacman", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
|
|
|
+ strcpy((char*)buffer, "waka");
|
|
|
|
|
+ size = strlen("waka");
|
|
|
|
|
+ lfs_size_t filesize = 0;
|
|
|
|
|
+ while (true) {
|
|
|
|
|
+ lfs_ssize_t res = lfs_file_write(&lfs, &file, buffer, size);
|
|
|
|
|
+ assert(res == (lfs_ssize_t)size || res == LFS_ERR_NOSPC);
|
|
|
|
|
+ if (res == LFS_ERR_NOSPC) {
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ filesize += size;
|
|
|
|
|
+ }
|
|
|
|
|
+ lfs_file_close(&lfs, &file) => 0;
|
|
|
|
|
+ // now fill all but a couple of blocks of the filesystem with data
|
|
|
|
|
+ filesize -= 3*LFS_BLOCK_SIZE;
|
|
|
|
|
+ lfs_file_open(&lfs, &file, "pacman", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
|
|
|
+ strcpy((char*)buffer, "waka");
|
|
|
|
|
+ size = strlen("waka");
|
|
|
|
|
+ for (lfs_size_t i = 0; i < filesize/size; i++) {
|
|
|
|
|
+ lfs_file_write(&lfs, &file, buffer, size) => size;
|
|
|
|
|
+ }
|
|
|
|
|
+ lfs_file_close(&lfs, &file) => 0;
|
|
|
|
|
+ // also save head of file so we can error during lookahead scan
|
|
|
|
|
+ lfs_block_t fileblock = file.ctz.head;
|
|
|
|
|
+ lfs_unmount(&lfs) => 0;
|
|
|
|
|
+
|
|
|
|
|
+ // remount to force an alloc scan
|
|
|
|
|
+ lfs_mount(&lfs, &cfg) => 0;
|
|
|
|
|
+
|
|
|
|
|
+ // but mark the head of our file as a "bad block", this is force our
|
|
|
|
|
+ // scan to bail early
|
|
|
|
|
+ lfs_testbd_setwear(&cfg, fileblock, 0xffffffff) => 0;
|
|
|
|
|
+ lfs_file_open(&lfs, &file, "ghost", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
|
|
|
+ strcpy((char*)buffer, "chomp");
|
|
|
|
|
+ size = strlen("chomp");
|
|
|
|
|
+ while (true) {
|
|
|
|
|
+ lfs_ssize_t res = lfs_file_write(&lfs, &file, buffer, size);
|
|
|
|
|
+ assert(res == (lfs_ssize_t)size || res == LFS_ERR_CORRUPT);
|
|
|
|
|
+ if (res == LFS_ERR_CORRUPT) {
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ lfs_file_close(&lfs, &file) => 0;
|
|
|
|
|
+
|
|
|
|
|
+ // now reverse the "bad block" and try to write the file again until we
|
|
|
|
|
+ // run out of space
|
|
|
|
|
+ lfs_testbd_setwear(&cfg, fileblock, 0) => 0;
|
|
|
|
|
+ lfs_file_open(&lfs, &file, "ghost", LFS_O_WRONLY | LFS_O_CREAT) => 0;
|
|
|
|
|
+ strcpy((char*)buffer, "chomp");
|
|
|
|
|
+ size = strlen("chomp");
|
|
|
|
|
+ while (true) {
|
|
|
|
|
+ lfs_ssize_t res = lfs_file_write(&lfs, &file, buffer, size);
|
|
|
|
|
+ assert(res == (lfs_ssize_t)size || res == LFS_ERR_NOSPC);
|
|
|
|
|
+ if (res == LFS_ERR_NOSPC) {
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ lfs_file_close(&lfs, &file) => 0;
|
|
|
|
|
+
|
|
|
|
|
+ lfs_unmount(&lfs) => 0;
|
|
|
|
|
+
|
|
|
|
|
+ // check that the disk isn't hurt
|
|
|
|
|
+ lfs_mount(&lfs, &cfg) => 0;
|
|
|
|
|
+ lfs_file_open(&lfs, &file, "pacman", LFS_O_RDONLY) => 0;
|
|
|
|
|
+ strcpy((char*)buffer, "waka");
|
|
|
|
|
+ size = strlen("waka");
|
|
|
|
|
+ for (lfs_size_t i = 0; i < filesize/size; i++) {
|
|
|
|
|
+ uint8_t rbuffer[4];
|
|
|
|
|
+ lfs_file_read(&lfs, &file, rbuffer, size) => size;
|
|
|
|
|
+ assert(memcmp(rbuffer, buffer, size) == 0);
|
|
|
|
|
+ }
|
|
|
|
|
+ lfs_file_close(&lfs, &file) => 0;
|
|
|
|
|
+ lfs_unmount(&lfs) => 0;
|
|
|
|
|
+'''
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
# Below, I don't like these tests. They're fragile and depend _heavily_
|
|
# Below, I don't like these tests. They're fragile and depend _heavily_
|
|
|
# on the geometry of the block device. But they are valuable. Eventually they
|
|
# on the geometry of the block device. But they are valuable. Eventually they
|
|
|
# should be removed and replaced with generalized tests.
|
|
# should be removed and replaced with generalized tests.
|