VirtualBox

Changeset 66672 in vbox for trunk/src/VBox/Runtime/common


Ignore:
Timestamp:
Apr 25, 2017 1:07:05 PM (8 years ago)
Author:
vboxsync
Message:

fatvfs: trunacting files

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/filesystem/fatvfs.cpp

    r66671 r66672  
    6868
    6969
     70/** The number of entire in a chain part. */
     71#define RTFSFATCHAINPART_ENTRIES (256U - 4U)
     72
    7073/**
    7174 * A part of the cluster chain covering up to 252 clusters.
     
    7679    RTLISTNODE  ListEntry;
    7780    /** Chain entries. */
    78     uint32_t    aEntries[256 - 4];
     81    uint32_t    aEntries[RTFSFATCHAINPART_ENTRIES];
    7982} RTFSFATCHAINPART;
    8083AssertCompile(sizeof(RTFSFATCHAINPART) <= _1K);
    8184typedef RTFSFATCHAINPART *PRTFSFATCHAINPART;
    8285typedef RTFSFATCHAINPART const *PCRTFSFATCHAINPART;
     86
    8387
    8488/**
     
    467471{
    468472    PRTFSFATCHAINPART pPart;
    469     uint32_t idxLast = pChain->cClusters % RT_ELEMENTS(pPart->aEntries);
     473    uint32_t idxLast = pChain->cClusters % RTFSFATCHAINPART_ENTRIES;
    470474    if (idxLast != 0)
    471475        pPart = RTListGetLast(&pChain->ListParts, RTFSFATCHAINPART, ListEntry);
     
    500504    {
    501505        PRTFSFATCHAINPART pPart = RTListGetFirst(&pChain->ListParts, RTFSFATCHAINPART, ListEntry);
    502         while (idxCluster >= RT_ELEMENTS(pPart->aEntries))
     506        while (idxCluster >= RTFSFATCHAINPART_ENTRIES)
    503507        {
    504             idxCluster -= RT_ELEMENTS(pPart->aEntries);
     508            idxCluster -= RTFSFATCHAINPART_ENTRIES;
    505509            pPart = RTListGetNext(&pChain->ListParts, pPart, RTFSFATCHAINPART, ListEntry);
    506510        }
     
    529533    for (;;)
    530534    {
    531         uint32_t const cInPart = RT_MIN(cLeft, RT_ELEMENTS(pPart->aEntries));
     535        uint32_t const cInPart = RT_MIN(cLeft, RTFSFATCHAINPART_ENTRIES);
    532536        for (uint32_t iPart = 0; iPart < cInPart; iPart++)
    533537            if (pPart->aEntries[iPart] == idxNext)
     
    543547
    544548
     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 */
     558static 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 */
     599static 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 */
    545614
    546615/**
     
    9571026{
    9581027    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);
    9601030    switch (pThis->enmFatType)
    9611031    {
     
    12301300static int rtFsFatObj_SetSize(PRTFSFATOBJ pObj, uint32_t cbFile)
    12311301{
    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);
    12331304
    12341305    /*
     
    12421313     * or release clusters.
    12431314     */
    1244     int rc;
     1315    int rc = VINF_SUCCESS;
    12451316    uint32_t const cClustersNew = (cbFile + pObj->Clusters.cbCluster - 1) >> pObj->Clusters.cClusterByteShift;
    12461317    AssertReturn(pObj->pParentDir, VERR_INTERNAL_ERROR_2);
     
    12481319    {
    12491320        pObj->cbObject = cbFile;
    1250         rc = VINF_SUCCESS;
    12511321    }
    12521322    else if (pObj->cbObject < cbFile)
     
    12571327    {
    12581328        /* 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));
    12601331        if (RT_SUCCESS(rc))
    12611332        {
     
    12631334            while (iClusterToFree < pObj->Clusters.cClusters && RT_SUCCESS(rc))
    12641335            {
    1265                 rc = rtFsFatClusterMap_FreeCluster(pObj->pVol, rtFsFatChain_GetCluster(&pObj->Clusters, iClusterToFree));
     1336                rc = rtFsFatClusterMap_FreeCluster(pObj->pVol, rtFsFatChain_GetClusterByIndex(&pObj->Clusters, iClusterToFree));
    12661337                iClusterToFree++;
    12671338            }
    12681339
    12691340            /* 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));
    12701346            pObj->Clusters.cClusters = cClustersNew;
     1347            pObj->Clusters.cbChain   = pObj->Clusters.cClusters << pObj->Clusters.cClusterByteShift;
     1348            Assert(rtFsFatChain_AssertValid(&pObj->Clusters));
    12711349        }
    12721350    }
     
    12821360        {
    12831361            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            }
    12841370            rc = rtFsFatDir_PutEntryAfterUpdate(pObj->pParentDir, pDirEntry, uWriteLock);
    12851371        }
     
    26042690    uint32_t const offJump      = 2 + pBootSector->abJmp[1];
    26052691    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));
    26072693    uint32_t const cbZeroPad    = RT_MIN(offJump - offFirstZero,
    26082694                                         sizeof(pBootSector->Bpb.Bpb20) - (offFirstZero - RT_OFFSETOF(FATBOOTSECTOR, Bpb)));
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette