VirtualBox

vbox的更動 41767 路徑 trunk


忽略:
時間撮記:
2012-6-15 下午06:40:36 (12 年 以前)
作者:
vboxsync
訊息:

Storage/VMDK: Coalesce reads when checking for inconsistencies between grain table and backup grain table while opening the image. Should decrease time required to open the image in async I/O mode if the image is stored on a slow network share or filesystem

檔案:
修改 1 筆資料

圖例:

未更動
新增
刪除
  • trunk/src/VBox/Storage/VMDK.cpp

    r40843 r41767  
    10991099        /* Check grain table and redundant grain table for consistency. */
    11001100        size_t cbGT = pExtent->cGTEntries * sizeof(uint32_t);
    1101         uint32_t *pTmpGT1 = (uint32_t *)RTMemTmpAlloc(cbGT);
    1102         if (!pTmpGT1)
    1103         {
     1101        size_t cbGTBuffers = cbGT; /* Start with space for one GT. */
     1102        size_t cbGTBuffersMax = _1M;
     1103
     1104        uint32_t *pTmpGT1 = (uint32_t *)RTMemAlloc(cbGTBuffers);
     1105        uint32_t *pTmpGT2 = (uint32_t *)RTMemAlloc(cbGTBuffers);
     1106
     1107        if (   !pTmpGT1
     1108            || !pTmpGT2)
    11041109            rc = VERR_NO_MEMORY;
    1105             goto out;
    1106         }
    1107         uint32_t *pTmpGT2 = (uint32_t *)RTMemTmpAlloc(cbGT);
    1108         if (!pTmpGT2)
    1109         {
    1110             RTMemTmpFree(pTmpGT1);
    1111             rc = VERR_NO_MEMORY;
    1112             goto out;
    1113         }
    1114 
    1115         for (i = 0, pGDTmp = pExtent->pGD, pRGDTmp = pExtent->pRGD;
    1116              i < pExtent->cGDEntries;
    1117              i++, pGDTmp++, pRGDTmp++)
    1118         {
     1110
     1111        i = 0;
     1112        pGDTmp = pExtent->pGD;
     1113        pRGDTmp = pExtent->pRGD;
     1114
     1115        /* Loop through all entries. */
     1116        while (i < pExtent->cGDEntries)
     1117        {
     1118            uint32_t uGTStart = *pGDTmp;
     1119            uint32_t uRGTStart = *pRGDTmp;
     1120            uint32_t cbGTRead = cbGT;
     1121
    11191122            /* If no grain table is allocated skip the entry. */
    11201123            if (*pGDTmp == 0 && *pRGDTmp == 0)
     1124            {
     1125                i++;
    11211126                continue;
     1127            }
    11221128
    11231129            if (*pGDTmp == 0 || *pRGDTmp == 0 || *pGDTmp == *pRGDTmp)
     
    11261132                 * grain table or both grain directory copies refer to the same
    11271133                 * grain table. Not allowed. */
    1128                 RTMemTmpFree(pTmpGT1);
    1129                 RTMemTmpFree(pTmpGT2);
    11301134                rc = vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: inconsistent references to grain directory in '%s'"), pExtent->pszFullname);
    1131                 goto out;
     1135                break;
    11321136            }
    1133             /* The VMDK 1.1 spec seems to talk about compressed grain tables,
    1134              * but in reality they are not compressed. */
    1135             rc = vdIfIoIntFileReadSync(pImage->pIfIo, pExtent->pFile->pStorage,
    1136                                        VMDK_SECTOR2BYTE(*pGDTmp),
    1137                                        pTmpGT1, cbGT, NULL);
    1138             if (RT_FAILURE(rc))
     1137
     1138            i++;
     1139            pGDTmp++;
     1140            pRGDTmp++;
     1141
     1142            /*
     1143             * Read a few tables at once if adjacent to decrease the number
     1144             * of I/O requests. Read at maximum 1MB at once.
     1145             */
     1146            while (   i < pExtent->cGDEntries
     1147                   && cbGTRead < cbGTBuffersMax)
    11391148            {
    1140                 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error reading grain table in '%s'"), pExtent->pszFullname);
    1141                 RTMemTmpFree(pTmpGT1);
    1142                 RTMemTmpFree(pTmpGT2);
    1143                 goto out;
     1149                /* If no grain table is allocated skip the entry. */
     1150                if (*pGDTmp == 0 && *pRGDTmp == 0)
     1151                    continue;
     1152
     1153                if (*pGDTmp == 0 || *pRGDTmp == 0 || *pGDTmp == *pRGDTmp)
     1154                {
     1155                    /* Just one grain directory entry refers to a not yet allocated
     1156                     * grain table or both grain directory copies refer to the same
     1157                     * grain table. Not allowed. */
     1158                    rc = vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: inconsistent references to grain directory in '%s'"), pExtent->pszFullname);
     1159                    break;
     1160                }
     1161
     1162                /* Check that the start offsets are adjacent.*/
     1163                if (   VMDK_SECTOR2BYTE(uGTStart) + cbGTRead != VMDK_SECTOR2BYTE(*pGDTmp)
     1164                    || VMDK_SECTOR2BYTE(uRGTStart) + cbGTRead != VMDK_SECTOR2BYTE(*pRGDTmp))
     1165                    break;
     1166
     1167                i++;
     1168                pGDTmp++;
     1169                pRGDTmp++;
     1170                cbGTRead += cbGT;
    11441171            }
    1145             /* The VMDK 1.1 spec seems to talk about compressed grain tables,
    1146              * but in reality they are not compressed. */
    1147             rc = vdIfIoIntFileReadSync(pImage->pIfIo, pExtent->pFile->pStorage,
    1148                                        VMDK_SECTOR2BYTE(*pRGDTmp),
    1149                                        pTmpGT2, cbGT, NULL);
    1150             if (RT_FAILURE(rc))
     1172
     1173            /* Increase buffers if required. */
     1174            if (   RT_SUCCESS(rc)
     1175                && cbGTBuffers < cbGTRead)
    11511176            {
    1152                 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error reading backup grain table in '%s'"), pExtent->pszFullname);
    1153                 RTMemTmpFree(pTmpGT1);
    1154                 RTMemTmpFree(pTmpGT2);
    1155                 goto out;
     1177                uint32_t *pTmp;
     1178                pTmp = (uint32_t *)RTMemRealloc(pTmpGT1, cbGTRead);
     1179                if (pTmp)
     1180                {
     1181                    pTmpGT1 = pTmp;
     1182                    pTmp = (uint32_t *)RTMemRealloc(pTmpGT2, cbGTRead);
     1183                    if (pTmp)
     1184                        pTmpGT2 = pTmp;
     1185                    else
     1186                        rc = VERR_NO_MEMORY;
     1187                }
     1188                else
     1189                    rc = VERR_NO_MEMORY;
     1190
     1191                if (rc == VERR_NO_MEMORY)
     1192                {
     1193                    /* Reset to the old values. */
     1194                    rc = VINF_SUCCESS;
     1195                    i -= cbGTRead / cbGT;
     1196                    cbGTRead = cbGT;
     1197
     1198                    /* Don't try to increase the buffer again in the next run. */
     1199                    cbGTBuffersMax = cbGTBuffers;
     1200                }
    11561201            }
    1157             if (memcmp(pTmpGT1, pTmpGT2, cbGT))
     1202
     1203            if (RT_SUCCESS(rc))
    11581204            {
    1159                 RTMemTmpFree(pTmpGT1);
    1160                 RTMemTmpFree(pTmpGT2);
    1161                 rc = vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: inconsistency between grain table and backup grain table in '%s'"), pExtent->pszFullname);
    1162                 goto out;
     1205               /* The VMDK 1.1 spec seems to talk about compressed grain tables,
     1206                 * but in reality they are not compressed. */
     1207                rc = vdIfIoIntFileReadSync(pImage->pIfIo, pExtent->pFile->pStorage,
     1208                                           VMDK_SECTOR2BYTE(uGTStart),
     1209                                           pTmpGT1, cbGTRead, NULL);
     1210                if (RT_FAILURE(rc))
     1211                {
     1212                    rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS,
     1213                                   N_("VMDK: error reading grain table in '%s'"), pExtent->pszFullname);
     1214                    break;
     1215                }
     1216                /* The VMDK 1.1 spec seems to talk about compressed grain tables,
     1217                 * but in reality they are not compressed. */
     1218                rc = vdIfIoIntFileReadSync(pImage->pIfIo, pExtent->pFile->pStorage,
     1219                                           VMDK_SECTOR2BYTE(uRGTStart),
     1220                                           pTmpGT2, cbGTRead, NULL);
     1221                if (RT_FAILURE(rc))
     1222                {
     1223                    rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS,
     1224                                   N_("VMDK: error reading backup grain table in '%s'"), pExtent->pszFullname);
     1225                    break;
     1226                }
     1227                if (memcmp(pTmpGT1, pTmpGT2, cbGTRead))
     1228                {
     1229                    rc = vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS,
     1230                                   N_("VMDK: inconsistency between grain table and backup grain table in '%s'"), pExtent->pszFullname);
     1231                    break;
     1232                }
    11631233            }
    1164         }
     1234        } /* while (i < pExtent->cGDEntries) */
    11651235
    11661236        /** @todo figure out what to do for unclean VMDKs. */
    1167         RTMemTmpFree(pTmpGT1);
    1168         RTMemTmpFree(pTmpGT2);
     1237        if (pTmpGT1)
     1238            RTMemFree(pTmpGT1);
     1239        if (pTmpGT2)
     1240            RTMemFree(pTmpGT2);
    11691241    }
    11701242
     
    11811253    unsigned i;
    11821254    size_t cbGD = pExtent->cGDEntries * sizeof(uint32_t);
    1183     size_t cbGDRounded = RT_ALIGN_64(pExtent->cGDEntries * sizeof(uint32_t), 512);
     1255    size_t cbGDRounded = RT_ALIGN_64(cbGD, 512);
    11841256    size_t cbGTRounded;
    11851257    uint64_t cbOverhead;
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

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