VirtualBox

Changeset 32882 in vbox


Ignore:
Timestamp:
Oct 4, 2010 9:19:15 AM (14 years ago)
Author:
vboxsync
Message:

Storage/VMDK: reorganize the compression/decompression code so that it reads/writes the file in less chunks and also strictly sequentially

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/VmdkHDDCore.cpp

    r32642 r32882  
    314314    /** Starting sector of the decompressed grain buffer. */
    315315    uint32_t    uGrainSector;
     316    /** Size of compressed grain buffer for streamOptimized extents. */
     317    size_t      cbCompGrain;
     318    /** Compressed grain buffer for streamOptimized extents, with marker. */
     319    void        *pvCompGrain;
    316320    /** Decompressed grain buffer for streamOptimized extents. */
    317321    void        *pvGrain;
     
    474478    /* Image this operation relates to. */
    475479    PVMDKIMAGE pImage;
    476     /* File where the data is stored. */
    477     PVMDKFILE pFile;
    478     /* Total size of the data to read. */
    479     size_t cbSize;
    480     /* Offset in the file to read. */
    481     uint64_t uFileOffset;
    482480    /* Current read position. */
    483481    ssize_t iOffset;
     482    /* Size of the compressed grain buffer (available data). */
     483    size_t cbCompGrain;
     484    /* Pointer to the compressed grain buffer. */
     485    void *pvCompGrain;
    484486} VMDKINFLATESTATE;
    485487
     
    489491    /* Image this operation relates to. */
    490492    PVMDKIMAGE pImage;
    491     /* File where the data is to be stored. */
    492     PVMDKFILE pFile;
    493     /* Offset in the file to write at. */
    494     uint64_t uFileOffset;
    495493    /* Current write position. */
    496494    ssize_t iOffset;
     495    /* Size of the compressed grain buffer. */
     496    size_t cbCompGrain;
     497    /* Pointer to the compressed grain buffer. */
     498    void *pvCompGrain;
    497499} VMDKDEFLATESTATE;
    498500
     
    851853{
    852854    VMDKINFLATESTATE *pInflateState = (VMDKINFLATESTATE *)pvUser;
     855    size_t cbInjected = 0;
    853856
    854857    Assert(cbBuf);
     
    856859    {
    857860        *(uint8_t *)pvBuf = RTZIPTYPE_ZLIB;
     861        pvBuf = (uint8_t *)pvBuf + 1;
     862        cbBuf--;
     863        cbInjected = 1;
     864        pInflateState->iOffset = RT_OFFSETOF(VMDKMARKER, uType);
     865    }
     866    if (!cbBuf)
     867    {
    858868        if (pcbBuf)
    859             *pcbBuf = 1;
    860         pInflateState->iOffset = 0;
     869            *pcbBuf = cbInjected;
    861870        return VINF_SUCCESS;
    862871    }
    863     cbBuf = RT_MIN(cbBuf, pInflateState->cbSize);
    864     int rc = vmdkFileReadSync(pInflateState->pImage, pInflateState->pFile,
    865                               pInflateState->uFileOffset, pvBuf, cbBuf, NULL);
    866     if (RT_FAILURE(rc))
    867         return rc;
    868     pInflateState->uFileOffset += cbBuf;
     872    cbBuf = RT_MIN(cbBuf, pInflateState->cbCompGrain - pInflateState->iOffset);
     873    memcpy(pvBuf,
     874           (uint8_t *)pInflateState->pvCompGrain + pInflateState->iOffset,
     875           cbBuf);
    869876    pInflateState->iOffset += cbBuf;
    870     pInflateState->cbSize -= cbBuf;
    871877    Assert(pcbBuf);
    872     *pcbBuf = cbBuf;
     878    *pcbBuf = cbBuf + cbInjected;
    873879    return VINF_SUCCESS;
    874880}
     
    878884 * distinguishing between async and normal operation
    879885 */
    880 DECLINLINE(int) vmdkFileInflateSync(PVMDKIMAGE pImage, PVMDKFILE pVmdkFile,
     886DECLINLINE(int) vmdkFileInflateSync(PVMDKIMAGE pImage, PVMDKEXTENT pExtent,
    881887                                    uint64_t uOffset, void *pvBuf,
    882                                     size_t cbToRead, unsigned uMarker,
    883                                     uint64_t *puLBA, uint32_t *pcbMarkerData)
    884 {
    885     if (pVmdkFile->fAsyncIO)
     888                                    size_t cbToRead, uint64_t *puLBA,
     889                                    uint32_t *pcbMarkerData)
     890{
     891    if (pExtent->pFile->fAsyncIO)
    886892    {
    887893        AssertMsgFailed(("TODO\n"));
     
    892898        int rc;
    893899        PRTZIPDECOMP pZip = NULL;
    894         VMDKMARKER Marker;
    895         uint64_t uCompOffset, cbComp;
    896         VMDKINFLATESTATE InflateState;
    897         size_t cbActuallyRead;
    898         size_t cbMarker = sizeof(Marker);
    899 
    900         if (uMarker == VMDK_MARKER_IGNORE)
    901             cbMarker -= sizeof(Marker.uType);
    902         rc = vmdkFileReadSync(pImage, pVmdkFile, uOffset, &Marker, cbMarker, NULL);
     900        VMDKMARKER *pMarker = (VMDKMARKER *)pExtent->pvCompGrain;
     901        size_t cbCompSize, cbActuallyRead;
     902
     903        rc = vmdkFileReadSync(pImage, pExtent->pFile, uOffset, pMarker,
     904                              RT_OFFSETOF(VMDKMARKER, uType), NULL);
    903905        if (RT_FAILURE(rc))
    904906            return rc;
    905         Marker.uSector = RT_LE2H_U64(Marker.uSector);
    906         Marker.cbSize = RT_LE2H_U32(Marker.cbSize);
    907         if (    uMarker != VMDK_MARKER_IGNORE
    908             &&  (   RT_LE2H_U32(Marker.uType) != uMarker
    909                  || Marker.cbSize != 0))
     907        cbCompSize = RT_LE2H_U32(pMarker->cbSize);
     908        if (cbCompSize == 0)
     909        {
     910            AssertMsgFailed(("VMDK: corrupted marker\n"));
    910911            return VERR_VD_VMDK_INVALID_FORMAT;
    911         if (Marker.cbSize != 0)
    912         {
    913             /* Compressed grain marker. Data follows immediately. */
    914             uCompOffset = uOffset + 12;
    915             cbComp = Marker.cbSize;
    916             if (puLBA)
    917                 *puLBA = Marker.uSector;
    918             if (pcbMarkerData)
    919                 *pcbMarkerData = cbComp + 12;
    920         }
    921         else
    922         {
    923             Marker.uType = RT_LE2H_U32(Marker.uType);
    924             AssertMsgFailed(("VMDK: unexpected marker type %u\n", Marker.uType));
     912        }
     913
     914        /* Sanity check - the expansion ratio should be much less than 2. */
     915        Assert(cbCompSize < 2 * cbToRead);
     916        if (cbCompSize >= 2 * cbToRead)
    925917            return VERR_VD_VMDK_INVALID_FORMAT;
    926         }
     918
     919        /* Compressed grain marker. Data follows immediately. */
     920        rc = vmdkFileReadSync(pImage, pExtent->pFile,
     921                              uOffset + RT_OFFSETOF(VMDKMARKER, uType),
     922                                (uint8_t *)pExtent->pvCompGrain
     923                              + RT_OFFSETOF(VMDKMARKER, uType),
     924                                RT_ALIGN_Z(  cbCompSize
     925                                           + RT_OFFSETOF(VMDKMARKER, uType),
     926                                           512)
     927                              - RT_OFFSETOF(VMDKMARKER, uType), NULL);
     928
     929        if (puLBA)
     930            *puLBA = RT_LE2H_U64(pMarker->uSector);
     931        if (pcbMarkerData)
     932            *pcbMarkerData = RT_ALIGN(  cbCompSize
     933                                      + RT_OFFSETOF(VMDKMARKER, uType),
     934                                      512);
     935
     936        VMDKINFLATESTATE InflateState;
    927937        InflateState.pImage = pImage;
    928         InflateState.pFile = pVmdkFile;
    929         InflateState.cbSize = cbComp;
    930         InflateState.uFileOffset = uCompOffset;
    931938        InflateState.iOffset = -1;
    932         /* Sanity check - the expansion ratio should be much less than 2. */
    933         Assert(cbComp < 2 * cbToRead);
    934         if (cbComp >= 2 * cbToRead)
    935             return VERR_VD_VMDK_INVALID_FORMAT;
     939        InflateState.cbCompGrain = cbCompSize + RT_OFFSETOF(VMDKMARKER, uType);
     940        InflateState.pvCompGrain = pExtent->pvCompGrain;
    936941
    937942        rc = RTZipDecompCreate(&pZip, &InflateState, vmdkFileInflateHelper);
     
    957962        pvBuf = (const uint8_t *)pvBuf + 1;
    958963        cbBuf--;
    959         pDeflateState->iOffset = 0;
     964        pDeflateState->iOffset = RT_OFFSETOF(VMDKMARKER, uType);
    960965    }
    961966    if (!cbBuf)
    962967        return VINF_SUCCESS;
    963     int rc = vmdkFileWriteSync(pDeflateState->pImage, pDeflateState->pFile,
    964                                pDeflateState->uFileOffset, pvBuf, cbBuf, NULL);
    965     if (RT_FAILURE(rc))
    966         return rc;
    967     pDeflateState->uFileOffset += cbBuf;
     968    if (pDeflateState->iOffset + cbBuf > pDeflateState->cbCompGrain)
     969        return VERR_BUFFER_OVERFLOW;
     970    memcpy((uint8_t *)pDeflateState->pvCompGrain + pDeflateState->iOffset,
     971           pvBuf, cbBuf);
    968972    pDeflateState->iOffset += cbBuf;
    969973    return VINF_SUCCESS;
     
    974978 * distinguishing between async and normal operation
    975979 */
    976 DECLINLINE(int) vmdkFileDeflateSync(PVMDKIMAGE pImage, PVMDKFILE pVmdkFile,
     980DECLINLINE(int) vmdkFileDeflateSync(PVMDKIMAGE pImage, PVMDKEXTENT pExtent,
    977981                                    uint64_t uOffset, const void *pvBuf,
    978                                     size_t cbToWrite, unsigned uMarker,
    979                                     uint64_t uLBA, uint32_t *pcbMarkerData)
    980 {
    981     if (pVmdkFile->fAsyncIO)
     982                                    size_t cbToWrite, uint64_t uLBA,
     983                                    uint32_t *pcbMarkerData)
     984{
     985    if (pExtent->pFile->fAsyncIO)
    982986    {
    983987        AssertMsgFailed(("TODO\n"));
     
    988992        int rc;
    989993        PRTZIPCOMP pZip = NULL;
    990         VMDKMARKER Marker;
    991         uint64_t uCompOffset, cbDecomp;
    992994        VMDKDEFLATESTATE DeflateState;
    993995
    994         Marker.uSector = RT_H2LE_U64(uLBA);
    995         Marker.cbSize = RT_H2LE_U32((uint32_t)cbToWrite);
    996         if (uMarker == VMDK_MARKER_IGNORE)
    997         {
    998             /* Compressed grain marker. Data follows immediately. */
    999             uCompOffset = uOffset + 12;
    1000             cbDecomp = cbToWrite;
    1001         }
    1002         else
    1003         {
    1004             /* The other markers don't contain compressed data. */
    1005             return VERR_NOT_IMPLEMENTED;
    1006         }
    1007996        DeflateState.pImage = pImage;
    1008         DeflateState.pFile = pVmdkFile;
    1009         DeflateState.uFileOffset = uCompOffset;
    1010997        DeflateState.iOffset = -1;
     998        DeflateState.cbCompGrain = pExtent->cbCompGrain;
     999        DeflateState.pvCompGrain = pExtent->pvCompGrain;
    10111000
    10121001        rc = RTZipCompCreate(&pZip, &DeflateState, vmdkFileDeflateHelper, RTZIPTYPE_ZLIB, RTZIPLEVEL_DEFAULT);
    10131002        if (RT_FAILURE(rc))
    10141003            return rc;
    1015         rc = RTZipCompress(pZip, pvBuf, cbDecomp);
     1004        rc = RTZipCompress(pZip, pvBuf, cbToWrite);
    10161005        if (RT_SUCCESS(rc))
    10171006            rc = RTZipCompFinish(pZip);
     
    10191008        if (RT_SUCCESS(rc))
    10201009        {
     1010            Assert(   DeflateState.iOffset > 0
     1011                   && (size_t)DeflateState.iOffset <= DeflateState.cbCompGrain);
     1012
     1013            /* pad with zeroes to get to a full sector size */
     1014            uint32_t uSize = DeflateState.iOffset;
     1015            if (uSize % 512)
     1016            {
     1017                uint32_t uSizeAlign = RT_ALIGN(uSize, 512);
     1018                memset((uint8_t *)pExtent->pvCompGrain + uSize, '\0',
     1019                       uSizeAlign - uSize);
     1020                uSize = uSizeAlign;
     1021            }
     1022
    10211023            if (pcbMarkerData)
    1022                 *pcbMarkerData = 12 + DeflateState.iOffset;
     1024                *pcbMarkerData = uSize;
     1025
     1026            /* Compressed grain marker. Data follows immediately. */
     1027            VMDKMARKER *pMarker = (VMDKMARKER *)pExtent->pvCompGrain;
     1028            pMarker->uSector = RT_H2LE_U64(uLBA);
     1029            pMarker->cbSize = RT_H2LE_U32(  DeflateState.iOffset
     1030                                          - RT_OFFSETOF(VMDKMARKER, uType));
     1031            rc = vmdkFileWriteSync(pImage, pExtent->pFile, uOffset, pMarker,
     1032                                   uSize, NULL);
     1033            if (RT_FAILURE(rc))
     1034                return rc;
     1035
    10231036            /* Set the file size to remove old garbage in case the block is
    10241037             * rewritten. Cannot cause data loss as the code calling this
    1025              * guarantees that data gets only appended. */
    1026             Assert(DeflateState.uFileOffset > uCompOffset);
    1027 
    1028             /*
    1029              * Change the file size only if the size really changed,
    1030              * because this is very expensive on some filesystems
    1031              * like XFS.
    1032              */
     1038             * guarantees that data gets only appended. Change the file size
     1039             * only if the size really changed, because this is very expensive
     1040             * on some filesystems such as XFS. */
    10331041            uint64_t cbOld;
    1034             rc = vmdkFileGetSize(pImage, pVmdkFile, &cbOld);
     1042            rc = vmdkFileGetSize(pImage, pExtent->pFile, &cbOld);
    10351043            if (RT_FAILURE(rc))
    10361044                return rc;
    10371045
    1038             if (cbOld != DeflateState.uFileOffset)
    1039                 rc = vmdkFileSetSize(pImage, pVmdkFile, DeflateState.uFileOffset);
    1040 
    1041             if (uMarker == VMDK_MARKER_IGNORE)
    1042             {
    1043                 /* Compressed grain marker. */
    1044                 Marker.cbSize = RT_H2LE_U32(DeflateState.iOffset);
    1045                 rc = vmdkFileWriteSync(pImage, pVmdkFile, uOffset, &Marker, 12, NULL);
    1046                 if (RT_FAILURE(rc))
    1047                     return rc;
    1048             }
    1049             else
    1050             {
    1051                 /* The other markers don't contain compressed data. */
    1052                 return VERR_NOT_IMPLEMENTED;
    1053             }
     1046            if (cbOld != uOffset + uSize)
     1047                rc = vmdkFileSetSize(pImage, pExtent->pFile, uOffset + uSize);
    10541048        }
    10551049        return rc;
     
    13491343        RTMemTmpFree(pTmpGT);
    13501344
    1351         /* streamOptimized extents need a grain decompress buffer. */
     1345        /* streamOptimized extents need a compressed grain buffer, which must
     1346         * be big enough to hold uncompressible data (which needs ~8 bytes
     1347         * more than the uncompressed data), the marker and padding. */
     1348        pExtent->cbCompGrain = RT_ALIGN_Z(  VMDK_SECTOR2BYTE(pExtent->cSectorsPerGrain)
     1349                                          + 8 + sizeof(VMDKMARKER), 512);
     1350        pExtent->pvCompGrain = RTMemAlloc(pExtent->cbCompGrain);
     1351        if (!pExtent->pvCompGrain)
     1352        {
     1353            rc = VERR_NO_MEMORY;
     1354            goto out;
     1355        }
     1356
     1357        /* streamOptimized extents need a decompressed grain buffer. */
    13521358        pExtent->pvGrain = RTMemAlloc(VMDK_SECTOR2BYTE(pExtent->cSectorsPerGrain));
    13531359        if (!pExtent->pvGrain)
     
    13611367            uint64_t uLBA = 0;
    13621368            uint32_t cbMarker = 0;
    1363             rc = vmdkFileInflateSync(pImage, pExtent->pFile, VMDK_SECTOR2BYTE(uLastGrainSector),
    1364                                      pExtent->pvGrain, VMDK_SECTOR2BYTE(pExtent->cSectorsPerGrain), VMDK_MARKER_IGNORE, &uLBA, &cbMarker);
     1369            rc = vmdkFileInflateSync(pImage, pExtent,
     1370                                     VMDK_SECTOR2BYTE(uLastGrainSector),
     1371                                     pExtent->pvGrain,
     1372                                     VMDK_SECTOR2BYTE(pExtent->cSectorsPerGrain),
     1373                                     &uLBA, &cbMarker);
    13651374            if (RT_FAILURE(rc))
    13661375                goto out;
     
    13681377            Assert(uLBA == uLastGrainWritten * pExtent->cSectorsPerGrain);
    13691378            pExtent->uGrainSector = uLastGrainSector;
    1370             pExtent->cbLastGrainWritten = RT_ALIGN(cbMarker, 512);
     1379            pExtent->cbLastGrainWritten = cbMarker;
    13711380        }
    13721381        pExtent->uLastGrainWritten = uLastGrainWritten;
     
    14251434            cbOverhead = RT_ALIGN_64(cbOverhead,
    14261435                                     VMDK_SECTOR2BYTE(pExtent->cSectorsPerGrain));
    1427             if (pExtent->fFooter)
    1428                 rc = vmdkFileSetSize(pImage, pExtent->pFile, cbOverhead);
    1429             else
     1436            if (!pExtent->fFooter)
    14301437                rc = vmdkFileSetSize(pImage, pExtent->pFile, cbOverhead + 512);
    14311438        }
     
    14991506    }
    15001507    pExtent->cOverheadSectors = VMDK_BYTE2SECTOR(cbOverhead);
     1508
     1509    /* streamOptimized extents need a compressed grain buffer, which must
     1510     * be big enough to hold uncompressible data (which needs ~8 bytes
     1511     * more than the uncompressed data), the marker and padding. */
     1512    pExtent->cbCompGrain = RT_ALIGN_Z(  VMDK_SECTOR2BYTE(pExtent->cSectorsPerGrain)
     1513                                      + 8 + sizeof(VMDKMARKER), 512);
     1514    pExtent->pvCompGrain = RTMemAlloc(pExtent->cbCompGrain);
     1515    if (!pExtent->pvCompGrain)
     1516    {
     1517        rc = VERR_NO_MEMORY;
     1518        goto out;
     1519    }
    15011520
    15021521    /* streamOptimized extents need a grain decompress buffer. */
     
    45004519    }
    45014520
     4521    /* Skip over the overhead area. */
     4522    rc = vmdkFileSetSize(pImage, pExtent->pFile,
     4523                         VMDK_SECTOR2BYTE(pExtent->cOverheadSectors));
     4524
    45024525    if (pfnProgress)
    45034526        pfnProgress(pvUser, uPercentStart + uPercentSpan * 70 / 100);
     
    52365259        Assert(cbWrite == VMDK_SECTOR2BYTE(pExtent->cSectorsPerGrain));
    52375260        uint32_t cbGrain = 0;
    5238         rc = vmdkFileDeflateSync(pImage, pExtent->pFile, cbExtentSize,
    5239                                  pvBuf, cbWrite, VMDK_MARKER_IGNORE, uSector, &cbGrain);
     5261        rc = vmdkFileDeflateSync(pImage, pExtent, cbExtentSize,
     5262                                 pvBuf, cbWrite, uSector, &cbGrain);
    52405263        if (RT_FAILURE(rc))
    52415264        {
     
    52455268            return vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: cannot write allocated compressed data block in '%s'"), pExtent->pszFullname);
    52465269        }
    5247         cbGrain = RT_ALIGN(cbGrain, 512);
    52485270        pExtent->uLastGrainSector = VMDK_BYTE2SECTOR(cbExtentSize);
    52495271        pExtent->uLastGrainWritten = uSector / pExtent->cSectorsPerGrain;
     
    59545976        pData = pExtent->pvGrain;
    59555977    }
    5956     rc = vmdkFileDeflateSync(pImage, pExtent->pFile, uFileOffset,
    5957                              pData, VMDK_SECTOR2BYTE(pExtent->cSectorsPerGrain),
    5958                              VMDK_MARKER_IGNORE, uSector, &cbGrain);
     5978    rc = vmdkFileDeflateSync(pImage, pExtent, uFileOffset, pData,
     5979                             VMDK_SECTOR2BYTE(pExtent->cSectorsPerGrain),
     5980                             uSector, &cbGrain);
    59595981    if (RT_FAILURE(rc))
    59605982    {
     
    59645986        return vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: cannot write compressed data block in '%s'"), pExtent->pszFullname);
    59655987    }
    5966     cbGrain = RT_ALIGN(cbGrain, 512);
    59675988    pExtent->uLastGrainSector = VMDK_BYTE2SECTOR(uFileOffset);
    59685989    pExtent->uLastGrainWritten = uGrain;
     
    67036724                    if (pExtent->uGrainSector != uSectorExtentAbs)
    67046725                    {
    6705                         rc = vmdkFileInflateSync(pImage, pExtent->pFile, VMDK_SECTOR2BYTE(uSectorExtentAbs),
    6706                                                  pExtent->pvGrain, VMDK_SECTOR2BYTE(pExtent->cSectorsPerGrain), VMDK_MARKER_IGNORE, &uLBA, NULL);
     6726                        rc = vmdkFileInflateSync(pImage, pExtent,
     6727                                                 VMDK_SECTOR2BYTE(uSectorExtentAbs),
     6728                                                 pExtent->pvGrain,
     6729                                                 VMDK_SECTOR2BYTE(pExtent->cSectorsPerGrain),
     6730                                                 &uLBA, NULL);
    67076731                        if (RT_FAILURE(rc))
    67086732                        {
     
    68446868                        ||  pExtent->uGrainSector != pExtent->uLastGrainSector)
    68456869                    {
    6846                         rc = vmdkFileInflateSync(pImage, pExtent->pFile, VMDK_SECTOR2BYTE(uSectorExtentAbs),
    6847                                                  pExtent->pvGrain, VMDK_SECTOR2BYTE(pExtent->cSectorsPerGrain), VMDK_MARKER_IGNORE, &uLBA, NULL);
     6870                        rc = vmdkFileInflateSync(pImage, pExtent,
     6871                                                 VMDK_SECTOR2BYTE(uSectorExtentAbs),
     6872                                                 pExtent->pvGrain,
     6873                                                 VMDK_SECTOR2BYTE(pExtent->cSectorsPerGrain),
     6874                                                 &uLBA, NULL);
    68486875                        if (RT_FAILURE(rc))
    68496876                        {
     
    68596886                    memcpy((uint8_t *)pExtent->pvGrain + VMDK_SECTOR2BYTE(uSectorInGrain), pvBuf, cbToWrite);
    68606887                    uint32_t cbGrain = 0;
    6861                     rc = vmdkFileDeflateSync(pImage, pExtent->pFile,
     6888                    rc = vmdkFileDeflateSync(pImage, pExtent,
    68626889                                             VMDK_SECTOR2BYTE(uSectorExtentAbs),
    6863                                              pExtent->pvGrain, VMDK_SECTOR2BYTE(pExtent->cSectorsPerGrain),
    6864                                              VMDK_MARKER_IGNORE, uLBA, &cbGrain);
     6890                                             pExtent->pvGrain,
     6891                                             VMDK_SECTOR2BYTE(pExtent->cSectorsPerGrain),
     6892                                             uLBA, &cbGrain);
    68656893                    if (RT_FAILURE(rc))
    68666894                    {
     
    68706898                        return vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: cannot write compressed data block in '%s'"), pExtent->pszFullname);
    68716899                    }
    6872                     cbGrain = RT_ALIGN(cbGrain, 512);
    68736900                    pExtent->uLastGrainSector = uSectorExtentAbs;
    68746901                    pExtent->uLastGrainWritten = uSectorExtentRel / pExtent->cSectorsPerGrain;
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