Changeset 66672 in vbox for trunk/src/VBox/Runtime/common
- Timestamp:
- Apr 25, 2017 1:07:05 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/filesystem/fatvfs.cpp
r66671 r66672 68 68 69 69 70 /** The number of entire in a chain part. */ 71 #define RTFSFATCHAINPART_ENTRIES (256U - 4U) 72 70 73 /** 71 74 * A part of the cluster chain covering up to 252 clusters. … … 76 79 RTLISTNODE ListEntry; 77 80 /** Chain entries. */ 78 uint32_t aEntries[ 256 - 4];81 uint32_t aEntries[RTFSFATCHAINPART_ENTRIES]; 79 82 } RTFSFATCHAINPART; 80 83 AssertCompile(sizeof(RTFSFATCHAINPART) <= _1K); 81 84 typedef RTFSFATCHAINPART *PRTFSFATCHAINPART; 82 85 typedef RTFSFATCHAINPART const *PCRTFSFATCHAINPART; 86 83 87 84 88 /** … … 467 471 { 468 472 PRTFSFATCHAINPART pPart; 469 uint32_t idxLast = pChain->cClusters % RT _ELEMENTS(pPart->aEntries);473 uint32_t idxLast = pChain->cClusters % RTFSFATCHAINPART_ENTRIES; 470 474 if (idxLast != 0) 471 475 pPart = RTListGetLast(&pChain->ListParts, RTFSFATCHAINPART, ListEntry); … … 500 504 { 501 505 PRTFSFATCHAINPART pPart = RTListGetFirst(&pChain->ListParts, RTFSFATCHAINPART, ListEntry); 502 while (idxCluster >= RT _ELEMENTS(pPart->aEntries))506 while (idxCluster >= RTFSFATCHAINPART_ENTRIES) 503 507 { 504 idxCluster -= RT _ELEMENTS(pPart->aEntries);508 idxCluster -= RTFSFATCHAINPART_ENTRIES; 505 509 pPart = RTListGetNext(&pChain->ListParts, pPart, RTFSFATCHAINPART, ListEntry); 506 510 } … … 529 533 for (;;) 530 534 { 531 uint32_t const cInPart = RT_MIN(cLeft, RT _ELEMENTS(pPart->aEntries));535 uint32_t const cInPart = RT_MIN(cLeft, RTFSFATCHAINPART_ENTRIES); 532 536 for (uint32_t iPart = 0; iPart < cInPart; iPart++) 533 537 if (pPart->aEntries[iPart] == idxNext) … … 543 547 544 548 549 /** 550 * Gets a cluster array index. 551 * 552 * This works the chain thing as an indexed array. 553 * 554 * @returns The cluster number, UINT32_MAX if out of bounds. 555 * @param pChain The chain. 556 * @param idx The index. 557 */ 558 static uint32_t rtFsFatChain_GetClusterByIndex(PCRTFSFATCHAIN pChain, uint32_t idx) 559 { 560 if (idx < pChain->cClusters) 561 { 562 /* 563 * In the first part? 564 */ 565 PRTFSFATCHAINPART pPart; 566 if (idx < RTFSFATCHAINPART_ENTRIES) 567 { 568 pPart = RTListGetFirst(&pChain->ListParts, RTFSFATCHAINPART, ListEntry); 569 return pPart->aEntries[idx]; 570 } 571 572 /* 573 * In the last part? 574 */ 575 uint32_t cParts = (pChain->cClusters + RTFSFATCHAINPART_ENTRIES - 1) / RTFSFATCHAINPART_ENTRIES; 576 uint32_t idxPart = idx / RTFSFATCHAINPART_ENTRIES; 577 uint32_t idxInPart = idx % RTFSFATCHAINPART_ENTRIES; 578 if (idxPart + 1 == cParts) 579 pPart = RTListGetLast(&pChain->ListParts, RTFSFATCHAINPART, ListEntry); 580 else 581 { 582 /* 583 * No, do linear search from the start, skipping the first part. 584 */ 585 pPart = RTListGetFirst(&pChain->ListParts, RTFSFATCHAINPART, ListEntry); 586 while (idxPart-- > 1) 587 pPart = RTListGetNext(&pChain->ListParts, pPart, RTFSFATCHAINPART, ListEntry); 588 } 589 590 return pPart->aEntries[idxInPart]; 591 } 592 return UINT32_MAX; 593 } 594 595 #ifdef RT_STRICT 596 /** 597 * Assert chain consistency. 598 */ 599 static bool rtFsFatChain_AssertValid(PCRTFSFATCHAIN pChain) 600 { 601 bool fRc = true; 602 uint32_t cParts = 0; 603 PRTFSFATCHAINPART pPart; 604 RTListForEach(&pChain->ListParts, pPart, RTFSFATCHAINPART, ListEntry) 605 cParts++; 606 607 uint32_t cExpected = (pChain->cClusters + RTFSFATCHAINPART_ENTRIES - 1) / RTFSFATCHAINPART_ENTRIES; 608 AssertMsgStmt(cExpected == cParts, ("cExpected=%#x cParts=%#x\n", cExpected, cParts), fRc = false); 609 AssertMsgStmt(pChain->cbChain == (pChain->cClusters << pChain->cClusterByteShift), 610 ("cExpected=%#x cParts=%#x\n", cExpected, cParts), fRc = false); 611 return fRc; 612 } 613 #endif /* RT_STRICT */ 545 614 546 615 /** … … 957 1026 { 958 1027 AssertReturn(idxCluster >= FAT_FIRST_DATA_CLUSTER, VERR_VFS_BOGUS_OFFSET); 959 AssertReturn(idxCluster < pThis->cClusters, VERR_VFS_BOGUS_OFFSET); 1028 AssertMsgReturn(idxCluster < pThis->cClusters, ("idxCluster=%#x cClusters=%#x\n", idxCluster, pThis->cClusters), 1029 VERR_VFS_BOGUS_OFFSET); 960 1030 switch (pThis->enmFatType) 961 1031 { … … 1230 1300 static int rtFsFatObj_SetSize(PRTFSFATOBJ pObj, uint32_t cbFile) 1231 1301 { 1232 AssertReturn((pObj->cbObject >> pObj->Clusters.cClusterByteShift) == pObj->Clusters.cClusters, VERR_INTERNAL_ERROR_3); 1302 AssertReturn( ((pObj->cbObject + pObj->Clusters.cbCluster - 1) >> pObj->Clusters.cClusterByteShift) 1303 == pObj->Clusters.cClusters, VERR_INTERNAL_ERROR_3); 1233 1304 1234 1305 /* … … 1242 1313 * or release clusters. 1243 1314 */ 1244 int rc ;1315 int rc = VINF_SUCCESS; 1245 1316 uint32_t const cClustersNew = (cbFile + pObj->Clusters.cbCluster - 1) >> pObj->Clusters.cClusterByteShift; 1246 1317 AssertReturn(pObj->pParentDir, VERR_INTERNAL_ERROR_2); … … 1248 1319 { 1249 1320 pObj->cbObject = cbFile; 1250 rc = VINF_SUCCESS;1251 1321 } 1252 1322 else if (pObj->cbObject < cbFile) … … 1257 1327 { 1258 1328 /* Free clusters we don't need any more. */ 1259 rc = rtFsFatClusterMap_SetEndOfChain(pObj->pVol, rtFsFatChain_GetCluster(&pObj->Clusters, cClustersNew - 1)); 1329 if (cClustersNew > 0) 1330 rc = rtFsFatClusterMap_SetEndOfChain(pObj->pVol, rtFsFatChain_GetClusterByIndex(&pObj->Clusters, cClustersNew - 1)); 1260 1331 if (RT_SUCCESS(rc)) 1261 1332 { … … 1263 1334 while (iClusterToFree < pObj->Clusters.cClusters && RT_SUCCESS(rc)) 1264 1335 { 1265 rc = rtFsFatClusterMap_FreeCluster(pObj->pVol, rtFsFatChain_GetCluster (&pObj->Clusters, iClusterToFree));1336 rc = rtFsFatClusterMap_FreeCluster(pObj->pVol, rtFsFatChain_GetClusterByIndex(&pObj->Clusters, iClusterToFree)); 1266 1337 iClusterToFree++; 1267 1338 } 1268 1339 1269 1340 /* Update the chain structure. */ 1341 uint32_t cOldParts = (pObj->Clusters.cClusters + RTFSFATCHAINPART_ENTRIES - 1) / RTFSFATCHAINPART_ENTRIES; 1342 uint32_t cNewParts = (cClustersNew + RTFSFATCHAINPART_ENTRIES - 1) / RTFSFATCHAINPART_ENTRIES; 1343 Assert(cOldParts >= cNewParts); 1344 while (cOldParts-- > cNewParts) 1345 RTMemFree(RTListRemoveLast(&pObj->Clusters.ListParts, RTFSFATCHAINPART, ListEntry)); 1270 1346 pObj->Clusters.cClusters = cClustersNew; 1347 pObj->Clusters.cbChain = pObj->Clusters.cClusters << pObj->Clusters.cClusterByteShift; 1348 Assert(rtFsFatChain_AssertValid(&pObj->Clusters)); 1271 1349 } 1272 1350 } … … 1282 1360 { 1283 1361 pDirEntry->cbFile = cbFile; 1362 /** @todo figure out if setting the cluster to 0 is the right way to deal 1363 * with empty files... */ 1364 if (cClustersNew == 0) 1365 { 1366 pDirEntry->idxCluster = 0; 1367 if (pObj->pVol->enmFatType >= RTFSFATTYPE_FAT32) 1368 pDirEntry->u.idxClusterHigh = 0; 1369 } 1284 1370 rc = rtFsFatDir_PutEntryAfterUpdate(pObj->pParentDir, pDirEntry, uWriteLock); 1285 1371 } … … 2604 2690 uint32_t const offJump = 2 + pBootSector->abJmp[1]; 2605 2691 uint32_t const offFirstZero = 2 /*jmp */ + 3 * 2 /* words */ + 9 /* date string */; 2606 Assert(offFirstZero >= RT_ OFFSETOF(FATBOOTSECTOR, Bpb));2692 Assert(offFirstZero >= RT_UOFFSETOF(FATBOOTSECTOR, Bpb)); 2607 2693 uint32_t const cbZeroPad = RT_MIN(offJump - offFirstZero, 2608 2694 sizeof(pBootSector->Bpb.Bpb20) - (offFirstZero - RT_OFFSETOF(FATBOOTSECTOR, Bpb)));
Note:
See TracChangeset
for help on using the changeset viewer.