diff --git a/lib/asyncfatfs.c b/lib/asyncfatfs.c index 37002e7..8c31771 100644 --- a/lib/asyncfatfs.c +++ b/lib/asyncfatfs.c @@ -490,6 +490,8 @@ static afatfs_t afatfs; static void afatfs_fileOperationContinue(afatfsFile_t *file); static uint8_t* afatfs_fileLockCursorSectorForWrite(afatfsFilePtr_t file); static uint8_t* afatfs_fileRetainCursorSectorForRead(afatfsFilePtr_t file); +static void afatfs_fileOperationsPoll(); +static void afatfs_poll(); static uint32_t roundUpTo(uint32_t value, uint32_t rounding) { @@ -639,6 +641,7 @@ static void afatfs_sdcardReadComplete(sdcardBlockOperation_e operation, uint32_t break; } } + afatfs_poll(); } /** @@ -670,6 +673,7 @@ static void afatfs_sdcardWriteComplete(sdcardBlockOperation_e operation, uint32_ break; } } + afatfs_poll(); } /** @@ -904,6 +908,7 @@ static afatfsOperationStatus_e afatfs_cacheSector(uint32_t physicalSectorIndex, if (cacheSectorIndex == -1) { // We don't have enough free cache to service this request right now, try again later + afatfs_flush(); return AFATFS_OPERATION_IN_PROGRESS; } @@ -1454,7 +1459,7 @@ static afatfsOperationStatus_e afatfs_saveDirectoryEntry(afatfsFilePtr_t file, a entry->fileSize = file->physicalSize; break; case AFATFS_SAVE_DIRECTORY_DELETED: - entry->filename[0] = FAT_DELETED_FILE_MARKER; + entry->filename[0] = (char)FAT_DELETED_FILE_MARKER; //Fall through case AFATFS_SAVE_DIRECTORY_FOR_CLOSE: @@ -1560,6 +1565,9 @@ static afatfsOperationStatus_e afatfs_appendRegularFreeClusterContinue(afatfsFil file->operation.operation = AFATFS_FILE_OPERATION_NONE; } + // flush any pending writes + afatfs_flush(); + return AFATFS_OPERATION_SUCCESS; break; case AFATFS_APPEND_FREE_CLUSTER_PHASE_FAILURE: @@ -2054,7 +2062,13 @@ static afatfsOperationStatus_e afatfs_fseekInternal(afatfsFilePtr_t file, uint32 opState->callback = callback; opState->seekOffset = offset; - return AFATFS_OPERATION_IN_PROGRESS; + // Do an initial round of processing + if (afatfs_fseekInternalContinue(file)) { + return AFATFS_OPERATION_SUCCESS; + } + else { + return AFATFS_OPERATION_IN_PROGRESS; + } } } @@ -2262,6 +2276,9 @@ static afatfsOperationStatus_e afatfs_extendSubdirectoryContinue(afatfsFile_t *d opState->callback(directory); } + // flush any pending writes + afatfs_flush(); + return AFATFS_OPERATION_SUCCESS; break; case AFATFS_EXTEND_SUBDIRECTORY_PHASE_FAILURE: @@ -2475,6 +2492,9 @@ static afatfsOperationStatus_e afatfs_ftruncateContinue(afatfsFilePtr_t file, bo opState->callback(file); } + // flush any pending writes + afatfs_flush(); + return AFATFS_OPERATION_SUCCESS; break; } @@ -2677,6 +2697,9 @@ static void afatfs_createFileContinue(afatfsFile_t *file) } } + // flush any pending writes + afatfs_flush(); + file->operation.operation = AFATFS_FILE_OPERATION_NONE; opState->callback(file); break; @@ -2742,6 +2765,8 @@ bool afatfs_funlink(afatfsFilePtr_t file, afatfsCallback_t callback) file->operation.operation = AFATFS_FILE_OPERATION_UNLINK; + afatfs_funlinkContinue(file); + return true; } @@ -2795,6 +2820,11 @@ static afatfsFilePtr_t afatfs_createFile(afatfsFilePtr_t file, const char *name, afatfs_createFileContinue(file); + if (file->operation.operation != AFATFS_FILE_OPERATION_CREATE_FILE && file->operation.operation != AFATFS_FILE_OPERATION_NONE) { + // file operation changed - process it + afatfs_fileOperationsPoll(); + } + return file; } @@ -3394,6 +3424,7 @@ static void afatfs_initContinue() afatfs_chdir(NULL); afatfs.initPhase++; + goto doMore; } else { afatfs.lastError = AFATFS_ERROR_BAD_FILESYSTEM_HEADER; afatfs.filesystemState = AFATFS_FILESYSTEM_STATE_FATAL; @@ -3407,9 +3438,19 @@ static void afatfs_initContinue() afatfs_createFile(&afatfs.freeFile, AFATFS_FREESPACE_FILENAME, FAT_FILE_ATTRIBUTE_SYSTEM | FAT_FILE_ATTRIBUTE_READ_ONLY, AFATFS_FILE_MODE_CREATE | AFATFS_FILE_MODE_RETAIN_DIRECTORY, afatfs_freeFileCreated); + if (afatfs.filesystemState != AFATFS_FILESYSTEM_STATE_FATAL + && afatfs.initPhase != AFATFS_INITIALIZATION_FREEFILE_CREATING + ) { + goto doMore; + } break; case AFATFS_INITIALIZATION_FREEFILE_CREATING: afatfs_fileOperationContinue(&afatfs.freeFile); + if (afatfs.filesystemState != AFATFS_FILESYSTEM_STATE_FATAL + && afatfs.initPhase != AFATFS_INITIALIZATION_FREEFILE_CREATING + ) { + goto doMore; + } break; case AFATFS_INITIALIZATION_FREEFILE_FAT_SEARCH: if (afatfs_findLargestContiguousFreeBlockContinue() == AFATFS_OPERATION_SUCCESS) { @@ -3493,14 +3534,12 @@ static void afatfs_initContinue() /** * Check to see if there are any pending operations on the filesystem and perform a little work (without waiting on the - * sdcard). You must call this periodically. + * sdcard). */ -void afatfs_poll() +static void afatfs_poll() { // Only attempt to continue FS operations if the card is present & ready, otherwise we would just be wasting time - if (sdcard_poll()) { - afatfs_flush(); - + if (sdcard_poll() && afatfs_flush()) { switch (afatfs.filesystemState) { case AFATFS_FILESYSTEM_STATE_INITIALIZATION: afatfs_initContinue(); @@ -3577,6 +3616,8 @@ void afatfs_init() #ifdef AFATFS_USE_INTROSPECTIVE_LOGGING sdcard_setProfilerCallback(afatfs_sdcardProfilerCallback); #endif + + afatfs_poll(); } /** diff --git a/lib/asyncfatfs.h b/lib/asyncfatfs.h index 06659c4..c4b643a 100644 --- a/lib/asyncfatfs.h +++ b/lib/asyncfatfs.h @@ -65,7 +65,6 @@ void afatfs_findLast(afatfsFilePtr_t directory); bool afatfs_flush(); void afatfs_init(); bool afatfs_destroy(bool dirty); -void afatfs_poll(); uint32_t afatfs_getFreeBufferSpace(); uint32_t afatfs_getContiguousFreeSpace(); diff --git a/tests/sdcard_sim.c b/tests/sdcard_sim.c index be9d81e..e721cb0 100644 --- a/tests/sdcard_sim.c +++ b/tests/sdcard_sim.c @@ -80,6 +80,8 @@ static void sdcard_continueReadBlock() if (--sdcard.currentOperation.countdownTimer <= 0) { uint64_t byteIndex = (uint64_t) sdcard.currentOperation.blockIndex * SDCARD_SIM_BLOCK_SIZE; + sdcard.state = SDCARD_STATE_READY; + fseeko(simFile, byteIndex, SEEK_SET); if (fread(sdcard.currentOperation.buffer, sizeof(uint8_t), SDCARD_SIM_BLOCK_SIZE, simFile) == SDCARD_SIM_BLOCK_SIZE) { @@ -93,8 +95,6 @@ static void sdcard_continueReadBlock() fprintf(stderr, "SDCardSim: fread failed on underlying file\n"); exit(-1); } - - sdcard.state = SDCARD_STATE_READY; } } diff --git a/tests/test_file_delete.c b/tests/test_file_delete.c index e5fb23d..f7c1ee1 100644 --- a/tests/test_file_delete.c +++ b/tests/test_file_delete.c @@ -182,9 +182,10 @@ bool continueSpaceReclaimTest(bool start) afatfs_fopen("test.txt", "w+", spaceReclaimTestFileCreatedForEmpty); break; case SPACE_RECLAIM_TEST_STAGE_EMPTY_DELETE: - if (afatfs_funlink(testFile, spaceReclaimTestFileEmptyDeleted)) { - // Wait for the unlink to complete - reclaimTestStage = SPACE_RECLAIM_TEST_STAGE_IDLE; + reclaimTestStage = SPACE_RECLAIM_TEST_STAGE_IDLE; + if (!afatfs_funlink(testFile, spaceReclaimTestFileEmptyDeleted)) { + // retry later + reclaimTestStage = SPACE_RECLAIM_TEST_STAGE_EMPTY_DELETE; } break; case SPACE_RECLAIM_TEST_STAGE_SOLID_APPEND_INIT: @@ -204,9 +205,10 @@ bool continueSpaceReclaimTest(bool start) } break; case SPACE_RECLAIM_TEST_STAGE_SOLID_APPEND_DELETE: - if (afatfs_funlink(testFile, spaceReclaimTestFileSolidAppendDeleted)) { - // Wait for the unlink to complete - reclaimTestStage = SPACE_RECLAIM_TEST_STAGE_IDLE; + reclaimTestStage = SPACE_RECLAIM_TEST_STAGE_IDLE; + if (!afatfs_funlink(testFile, spaceReclaimTestFileSolidAppendDeleted)) { + // retry later + reclaimTestStage = SPACE_RECLAIM_TEST_STAGE_SOLID_APPEND_DELETE; } break; case SPACE_RECLAIM_TEST_STAGE_APPEND_INIT: @@ -226,9 +228,10 @@ bool continueSpaceReclaimTest(bool start) } break; case SPACE_RECLAIM_TEST_STAGE_APPEND_DELETE: - if (afatfs_funlink(testFile, spaceReclaimTestFileAppendDeleted)) { - // Wait for the unlink to complete - reclaimTestStage = SPACE_RECLAIM_TEST_STAGE_IDLE; + reclaimTestStage = SPACE_RECLAIM_TEST_STAGE_IDLE; + if (!afatfs_funlink(testFile, spaceReclaimTestFileAppendDeleted)) { + // retry later + reclaimTestStage = SPACE_RECLAIM_TEST_STAGE_APPEND_DELETE; } break; case SPACE_RECLAIM_TEST_STAGE_IDLE: @@ -392,8 +395,11 @@ bool continueSpaceRetainTest(bool start, const char *fileMode) break; case SPACE_RETAIN_TEST_STAGE_UNLINK_B: if (afatfs_funlink(retainTestFileB, retainTestFileBDeleted)) { - retainTestFileB = NULL; - retainTestStage = SPACE_RETAIN_TEST_STAGE_IDLE; + // need to check state again in case callback has already been triggered + if (retainTestStage == SPACE_RETAIN_TEST_STAGE_UNLINK_B) { + retainTestFileB = NULL; + retainTestStage = SPACE_RETAIN_TEST_STAGE_IDLE; + } } break; case SPACE_RETAIN_TEST_STAGE_VERIFY_A_OPEN: @@ -506,7 +512,7 @@ int main(int argc, char **argv) bool keepGoing = true; while (keepGoing) { - afatfs_poll(); + sdcard_poll(); switch (afatfs_getFilesystemState()) { case AFATFS_FILESYSTEM_STATE_READY: diff --git a/tests/test_file_modes.c b/tests/test_file_modes.c index fc5a6a4..2a9ddec 100644 --- a/tests/test_file_modes.c +++ b/tests/test_file_modes.c @@ -217,7 +217,7 @@ int main(int argc, char **argv) bool keepGoing = true; while (keepGoing) { - afatfs_poll(); + sdcard_poll(); switch (afatfs_getFilesystemState()) { case AFATFS_FILESYSTEM_STATE_READY: diff --git a/tests/test_file_size.c b/tests/test_file_size.c index 8e230ff..f9a58b5 100644 --- a/tests/test_file_size.c +++ b/tests/test_file_size.c @@ -57,7 +57,7 @@ static void initFilesystem() afatfs_init(); while (afatfs_getFilesystemState() != AFATFS_FILESYSTEM_STATE_READY) { - afatfs_poll(); + sdcard_poll(); if (afatfs_getFilesystemState() == AFATFS_FILESYSTEM_STATE_FATAL) { fprintf(stderr, "[Fail] Fatal filesystem error during init\n"); @@ -252,7 +252,7 @@ int main(int argc, char **argv) bool keepGoing = true; while (keepGoing) { - afatfs_poll(); + sdcard_poll(); switch (afatfs_getFilesystemState()) { case AFATFS_FILESYSTEM_STATE_READY: diff --git a/tests/test_file_size_powerloss.c b/tests/test_file_size_powerloss.c index 6d1d236..7c25b26 100644 --- a/tests/test_file_size_powerloss.c +++ b/tests/test_file_size_powerloss.c @@ -58,7 +58,7 @@ static void initFilesystem() afatfs_init(); while (afatfs_getFilesystemState() != AFATFS_FILESYSTEM_STATE_READY) { - afatfs_poll(); + sdcard_poll(); if (afatfs_getFilesystemState() == AFATFS_FILESYSTEM_STATE_FATAL) { fprintf(stderr, "[Fail] Fatal filesystem error during init\n"); @@ -248,7 +248,7 @@ int main(int argc, char **argv) bool keepGoing = true; while (keepGoing) { - afatfs_poll(); + sdcard_poll(); switch (afatfs_getFilesystemState()) { case AFATFS_FILESYSTEM_STATE_READY: diff --git a/tests/test_logging_workload.c b/tests/test_logging_workload.c index f28f3dd..12a7484 100644 --- a/tests/test_logging_workload.c +++ b/tests/test_logging_workload.c @@ -207,7 +207,7 @@ int main(int argc, char **argv) bool keepGoing = true; while (keepGoing) { - afatfs_poll(); + sdcard_poll(); switch (afatfs_getFilesystemState()) { case AFATFS_FILESYSTEM_STATE_READY: diff --git a/tests/test_root_fill.c b/tests/test_root_fill.c index 681e348..c2dbbae 100644 --- a/tests/test_root_fill.c +++ b/tests/test_root_fill.c @@ -134,7 +134,7 @@ int main(int argc, char **argv) bool keepGoing = true; while (keepGoing) { - afatfs_poll(); + sdcard_poll(); switch (afatfs_getFilesystemState()) { case AFATFS_FILESYSTEM_STATE_READY: diff --git a/tests/test_subdir_fill.c b/tests/test_subdir_fill.c index 34e5538..02224a0 100644 --- a/tests/test_subdir_fill.c +++ b/tests/test_subdir_fill.c @@ -153,7 +153,7 @@ int main(int argc, char **argv) bool keepGoing = true; while (keepGoing) { - afatfs_poll(); + sdcard_poll(); switch (afatfs_getFilesystemState()) { case AFATFS_FILESYSTEM_STATE_READY: diff --git a/tests/test_volume_fill.c b/tests/test_volume_fill.c index 126b8b8..dc31f7e 100644 --- a/tests/test_volume_fill.c +++ b/tests/test_volume_fill.c @@ -218,7 +218,7 @@ int main(int argc, char **argv) bool keepGoing = true; while (keepGoing) { - afatfs_poll(); + sdcard_poll(); switch (afatfs_getFilesystemState()) { case AFATFS_FILESYSTEM_STATE_READY: