📄 fileapi.c
字号:
/* Bad device handles (stale ones attempted after we've closed/terminated a device) */ /* Provided only API tests have been run since startup, handle 2 has never been opened */ if (ST_NO_ERROR == STAVFS_GetFreeDiskSpace ((void *) 2, &Size)) { STTBX_Print (("STAVFS_GetFreeDiskSpace should fail for a device handle" " that has never been opened (inside the range used)\n")); Result = TEST_FAILED; } if (ST_NO_ERROR == STAVFS_GetFreeDiskSpace ((void *) 10000, &Size)) { STTBX_Print (("STAVFS_GetFreeDiskSpace should fail for out-of-range device handle\n")); Result = TEST_FAILED; } /* open a device */ if (TEST_PASSED != OpenPartition (0, 0, "Dev0", &DiskHandle)) { Result = TEST_FAILED; /* message already displayed */ } else { /* NULL destination */ if (ST_NO_ERROR == STAVFS_GetFreeDiskSpace (DiskHandle, NULL)) { STTBX_Print (("STAVFS_GetFreeDiskSpace should fail for NULL destination\n")); Result = TEST_FAILED; } if (TEST_PASSED != ClosePartition("Dev0", DiskHandle)) { Result = TEST_FAILED; /* message already displayed */ } } return (Result);}/******************************************************************************Function Name : PushLimits Description : push max open files / files per partition, postponed to leave some "not yet used" slots available to other tests Parameters :******************************************************************************/static TestResult_t PushLimits(int TestNo, TestVariant_t Variant){ TestResult_t Result = TEST_PASSED; STAVFS_Handle_t DiskHandle; if (TEST_PASSED != OpenPartition (0, 0, "Dev0", &DiskHandle)) { Result = TEST_FAILED; /* message already displayed */ } else { PushMaxHandles (DiskHandle, &Result); PushMaxPartitionFiles (DiskHandle, &Result); if (TEST_PASSED != ClosePartition("Dev0", DiskHandle)) { Result = TEST_FAILED; /* message already displayed */ } } return (Result);}/******************************************************************************Function Name : PushMaxHandles Description : Helper for FileOpen: Tests behaviour as the maximum number of open file handles is hit Parameters : device handle, place to record test failure******************************************************************************/static void PushMaxHandles(STAVFS_Handle_t DiskHandle, TestResult_t * Result_p){ STAVFS_FileHandle_t FileHandles[PUSH_FILES_LIMIT]; ST_ErrorCode_t Error; U64 FileSize; int i = 0; I64_SetValue (STD_FILE_SIZE, 0, FileSize); assert (Result_p != NULL); /* Open the same file lots of times */ while (1) /* breaks and increment in body */ { Error = STAVFS_OpenFile (DiskHandle, STAVFS_NULL_FILE_HANDLE, "MaxOpenTest", STAVFS_WRITE_MODE, FileSize, FileHandles + i); if (Error != ST_NO_ERROR) { if ((i == 0) || (Error != ST_ERROR_NO_FREE_HANDLES)) { /* this error code can indicate being out of open file handles or directory slots; it is the former interpretation we want here, and I guard against the latter by requiring that we succeed in opening the file at least once before I consider the limit acceptable */ STTBX_Print (("Unexpected error opening file handle #%i in PushMaxOpenFiles\n", i)); *Result_p = TEST_FAILED; } break; } ++i; /* include this file handle in cleanup if we get this far */ if (i == PUSH_FILES_LIMIT) { /* didn't hit a maximum number of file handles, which we interpret as improper checking */ STTBX_Print (("Maximum number of open file handles is not enforced\n", i)); *Result_p = TEST_FAILED; break; } } /* -> i one above index of last sucessfully opened handle (0 for none successfully opened) */ /* Now close them and delete the file */ while (--i >= 0) { if (ST_NO_ERROR != STAVFS_CloseFile(FileHandles[i])) { STTBX_Print (("Error closing file #%i in PushMaxOpenFiles\n", i)); *Result_p = TEST_FAILED; /* but keep going trying to close the others */ } } if (ST_NO_ERROR != STAVFS_DeleteFile (DiskHandle, STAVFS_NULL_FILE_HANDLE, "MaxOpenTest")) { STTBX_Print (("Error deleting file in PushMaxOpenFiles\n", i)); *Result_p = TEST_FAILED; } }/******************************************************************************Function Name : PushMaxPartitionFiles Description : Helper for FileOpen: Tests behaviour as the maximum number of files on a partition is hit Parameters : device handle, place to record test failure******************************************************************************/static void PushMaxPartitionFiles(STAVFS_Handle_t DiskHandle, TestResult_t * Result_p){ STAVFS_FileHandle_t FileHandle; ST_ErrorCode_t Error; char FileName[10]; /* name constructed as string representation of file number */ U64 FileSize; int i = 0; I64_SetValue (STD_FILE_SIZE, 0, FileSize); assert (Result_p != NULL); /* Create lots of files one after the other */ while (1) /* breaks and increment in body */ { sprintf (FileName, "%i", i); Error = STAVFS_OpenFile (DiskHandle, STAVFS_NULL_FILE_HANDLE, FileName, STAVFS_WRITE_MODE, FileSize, &FileHandle); if (Error != ST_NO_ERROR) { if ((i == 0) || (Error != ST_ERROR_NO_FREE_HANDLES)) { /* this error code can indicate being out of open file handles or directory slots; it is the latter interpretation we want here, and I guard against the former by requiring that we succeed in creating at least one file before I consider the limit acceptable */ STTBX_Print (("Unexpected error creating file #%i in PushMaxPartitionFiles\n", i)); *Result_p = TEST_FAILED; } break; } ++i; /* include this file in cleanup if we get this far */ if (ST_NO_ERROR != STAVFS_CloseFile(FileHandle)) { STTBX_Print (("Error closing file #%i in PushMaxPartitionFiles\n", i)); *Result_p = TEST_FAILED; break; } if (i == PUSH_FILES_LIMIT) { /* didn't hit a maximum number of files, which we interpret as improper checking */ STTBX_Print (("Maximum number of files in partition is not enforced\n", i)); *Result_p = TEST_FAILED; break; } } /* -> i one above index of last sucessfully created file (0 for none successfully created) */ /* Now delete them */ while (--i >= 0) { sprintf (FileName, "%i", i); if (ST_NO_ERROR != STAVFS_DeleteFile (DiskHandle, STAVFS_NULL_FILE_HANDLE, FileName)) { STTBX_Print (("Error deleting file #%i in PushMaxPartitionFiles\n", i)); *Result_p = TEST_FAILED; /* but keep going trying to delete the others */ } } }/******************************************************************************Function Name : PushSpace Description : API test for file creation / write > available free space, separated out because of the time requirement and to use partition 3 to make things as quick as we can without formatting Parameters :******************************************************************************/static TestResult_t PushSpace(int TestNo, TestVariant_t Variant){ TestResult_t Result = TEST_PASSED; STAVFS_Handle_t DiskHandle; STAVFS_FileHandle_t FileHandle; ST_ErrorCode_t Error; int i; U64 FileSize; U32 DataWritten; /* number of MBYTES by which FillerFile is smaller than the overall partition size. Currently, the overhead on this partition is ~16MB, so this leaves 14MB that the second two parts of the test fill before running out of space */ U32 ActiveMBytes = 30; if (TEST_PASSED != OpenPartition (0, 3, "Dev3", &DiskHandle)) { Result = TEST_FAILED; /* message already displayed */ } else { /* Sanity check - output GetFreeDiskSpace */ RPT_FREE_SPACE(DiskHandle, TRUE, "at start of PushSpace test"); /* The driver does not perform an up-front check; instead it just keeps allocating clusters until the requested size is reached or there are no free clusters left. So do most of that cluster-grabbing work just once in the following allocation: */ I64_SetValue (TestPartitionDefs[3].Size * DISK_SECTOR_SIZE - ActiveMBytes * M_BYTES, 0, FileSize); if (ST_NO_ERROR != STAVFS_OpenFile (DiskHandle, STAVFS_NULL_FILE_HANDLE, "FillerFile", STAVFS_WRITE_MODE, FileSize, &FileHandle)) { STTBX_Print (("Error creating FillerFile %iMB smaller than the partition\n", ActiveMBytes)); Result = TEST_FAILED; } else { if (ST_NO_ERROR != STAVFS_CloseFile (FileHandle)) { STTBX_Print (("Error closing file FillerFile\n")); Result = TEST_FAILED; /* but keep going ... */ } RPT_FREE_SPACE(DiskHandle, FALSE, "after creating FillerFile"); /* File creation test exceeds partition size (1GB) directly. 3GB chosen to exercise the top bit of the low-order Word, and so confirm that the driver uses _unsigned_ integer arithmetic */ I64_SetValue (3 * (U32) G_BYTES, 0, FileSize); TryBadFileOpen (DiskHandle, STAVFS_NULL_FILE_HANDLE, "SizePushFile", STAVFS_WRITE_MODE, FileSize, "creating a new 3GB file on a 1GB partition", &Result); RPT_FREE_SPACE(DiskHandle, FALSE, "after trying to create a file larger than the partition"); /* File write test has to work in blocks because the data has to be valid */ I64_SetValue (0, 0, FileSize); if (ST_NO_ERROR != STAVFS_OpenFile (DiskHandle, STAVFS_NULL_FILE_HANDLE, "SizePushFile", STAVFS_WRITE_MODE, FileSize, &FileHandle)) { STTBX_Print (("Error opening SizePushFile\n")); Result = TEST_FAILED; } else { /* rather than rely on GetFreeDiskSpace, shoot over where we know the boundary must be, and assert that at some point STAVFS_WriteFail fails with STAVFS_ERROR_DISK_FULL */ for (i = 0; i <= ActiveMBytes * (M_BYTES/sizeof(Buffer)); ++i) { /* that's about 30000 iterations, so provide a debugger hook every 5000 */ if (i % 5000 == 0) { i=i; /* put breakpoint here */ } /* Buffer is uninitialised, but what we write is immaterial, so long as it's valid memory */ Error = STAVFS_WriteFile (FileHandle, Buffer, sizeof(Buffer), &DataWritten); if (Error != ST_NO_ERROR) { if (Error == STAVFS_ERROR_DISK_FULL) { /* sanity check on DataWritten: we should have written a whole number of sectors */ if ( (i*sizeof(Buffer) + DataWritten) % DISK_SECTOR_SIZE != 0 ) { STTBX_Print (("DataWritten returned when we ran out of disk space does not" " imply a whole number of sectors written in total\n")); Result = TEST_FAILED; } } else { STTBX_Print (("Unexpected error %i returned whilst trying to write past" " available disk space\n", Error)); Result = TEST_FAILED; } break; } } if (i > ActiveMBytes * (M_BYTES/sizeof(Buffer))) { STTBX_Print (("No error encountered despite writing past available partition space\n")); Result = TEST_FAILED; } if (ST_NO_ERROR != STAVFS_CloseFile (FileHandle)) { STTBX_Print (("Error closing SizePushFile\n")); Result = TEST_FAILED; } RPT_FREE_SPACE(DiskHandle, FALSE, "after trying to write past available disk space"); if (ST_NO_ERROR != STAVFS_DeleteFile (DiskHandle, STAVFS_NULL_FILE_HANDLE, "SizePushFile")) { STTBX_Print (("Error deleting SizePushFile\n")); Result = TEST_FAILED; } } if (ST_NO_ERROR != STAVFS_DeleteFile (DiskHandle, STAVFS_NULL_FILE_HANDLE, "FillerFile")) { STTBX_Print (("Error deleting FillerFile\n")); Result = TEST_FAILED; } } RPT_FREE_SPACE(DiskHandle, FALSE, "at end of PushSpace test (after deleting FillerFile)"); if (TEST_PASSED != ClosePartition("Dev3", DiskHandle)) { Result = TEST_FAILED; /* message already displayed */ } } return (Result);}/******************************************************************************Function Name : RptFreeSpace Description : Prints the return value of GetFreeDiskSpace Parameters : disk handle, whether to display comparison values too******************************************************************************/static TestResult_t RptFreeSpace(STAVFS_Handle_t DiskHandle, BOOL Extras, char * Descr){ TestResult_t Result = TEST_PASSED; ST_ErrorCode_t Error; U64 Space; if (ST_NO_ERROR != (Error = STAVFS_GetFreeDiskSpace (DiskHandle, &Space))) { STTBX_Print (("Error %i running STAVFS_GetFreeDiskSpace %s\n", Error, Descr)); Result = TEST_FAILED; } else { STTBX_Print (("STAVFS_GetFreeDiskSpace returns 0x%012X %012X %s\n", I64_GetUpper(Space), I64_GetLower(Space), Descr)); if (Extras) { STTBX_Print ((" (cf 1GB 0x%012X, 1GB - 30MB 0x%012X)\n", G_BYTES, G_BYTES - 30 * M_BYTES )); } } return (Result);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -