VirtualBox

Changeset 63793 in vbox for trunk


Ignore:
Timestamp:
Sep 12, 2016 10:13:44 AM (8 years ago)
Author:
vboxsync
Message:

Storage/QCOW: Cleanup, get rid of goto...

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Storage/QCOW.cpp

    r63785 r63793  
    452452}
    453453
    454 #if 0 /* unused */
    455 /**
    456  * Convert refcount table entries from little endian to host endianess.
    457  *
    458  * @returns nothing.
    459  * @param   paTbl       Pointer to the table.
    460  * @param   cEntries    Number of entries in the table.
    461  */
    462 static void qcowRefcountTableConvertToHostEndianess(uint16_t *paTbl, uint32_t cEntries)
    463 {
    464     while(cEntries-- > 0)
    465     {
    466         *paTbl = RT_BE2H_U16(*paTbl);
    467         paTbl++;
    468     }
    469 }
    470 #endif
    471 
    472 #if 0 /* unused */
    473 /**
    474  * Convert table entries from host to little endian format.
    475  *
    476  * @returns nothing.
    477  * @param   paTblImg    Pointer to the table which will store the little endian table.
    478  * @param   paTbl       The source table to convert.
    479  * @param   cEntries    Number of entries in the table.
    480  */
    481 static void qcowRefcountTableConvertFromHostEndianess(uint16_t *paTblImg, uint16_t *paTbl,
    482                                                       uint32_t cEntries)
    483 {
    484     while(cEntries-- > 0)
    485     {
    486         *paTblImg = RT_H2BE_U16(*paTbl);
    487         paTbl++;
    488         paTblImg++;
    489     }
    490 }
    491 #endif
    492 
    493454/**
    494455 * Creates the L2 table cache.
     
    975936
    976937/**
    977  * Flush image data to disk - version for async I/O.
    978  *
    979  * @returns VBox status code.
    980  * @param   pImage    The image instance data.
    981  * @param   pIoCtx    The I/o context
    982  */
    983 static int qcowFlushImageAsync(PQCOWIMAGE pImage, PVDIOCTX pIoCtx)
    984 {
    985     int rc = VINF_SUCCESS;
    986 
    987     if (   pImage->pStorage
    988         && !(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
    989     {
    990         QCowHeader Header;
    991 
    992         rc = qcowTblWrite(pImage, pIoCtx, pImage->offL1Table, pImage->paL1Table,
    993                           pImage->cbL1Table, pImage->cL1TableEntries, NULL, NULL);
    994         if (RT_SUCCESS(rc) || rc == VERR_VD_ASYNC_IO_IN_PROGRESS)
    995         {
    996             /* Write header. */
    997             size_t cbHeader = 0;
    998             qcowHdrConvertFromHostEndianess(pImage, &Header, &cbHeader);
    999             rc = vdIfIoIntFileWriteMeta(pImage->pIfIo, pImage->pStorage,
    1000                                         0, &Header, cbHeader,
    1001                                         pIoCtx, NULL, NULL);
    1002             if (RT_SUCCESS(rc) || rc == VERR_VD_ASYNC_IO_IN_PROGRESS)
    1003                 rc = vdIfIoIntFileFlush(pImage->pIfIo, pImage->pStorage,
    1004                                         pIoCtx, NULL, NULL);
    1005         }
    1006     }
    1007 
    1008     return rc;
    1009 }
    1010 
    1011 /**
    1012938 * Internal. Free all allocated space for representing an image except pImage,
    1013939 * and optionally delete the image from disk.
     
    11121038static int qcowOpenImage(PQCOWIMAGE pImage, unsigned uOpenFlags)
    11131039{
    1114     int rc;
    1115 
    11161040    pImage->uOpenFlags = uOpenFlags;
    11171041
     
    11201044    AssertPtrReturn(pImage->pIfIo, VERR_INVALID_PARAMETER);
    11211045
    1122     rc = qcowL2TblCacheCreate(pImage);
    1123     AssertRC(rc);
    1124 
    1125     /*
    1126      * Open the image.
    1127      */
    1128     rc = vdIfIoIntFileOpen(pImage->pIfIo, pImage->pszFilename,
    1129                            VDOpenFlagsToFileOpenFlags(uOpenFlags,
    1130                                                       false /* fCreate */),
    1131                            &pImage->pStorage);
    1132     if (RT_FAILURE(rc))
    1133     {
    1134         /* Do NOT signal an appropriate error here, as the VD layer has the
    1135          * choice of retrying the open if it failed. */
    1136         goto out;
    1137     }
    1138 
    1139     uint64_t cbFile;
    1140     QCowHeader Header;
    1141     rc = vdIfIoIntFileGetSize(pImage->pIfIo, pImage->pStorage, &cbFile);
    1142     if (RT_FAILURE(rc))
    1143         goto out;
    1144     if (cbFile > sizeof(Header))
    1145     {
    1146         rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, 0, &Header, sizeof(Header));
    1147         if (   RT_SUCCESS(rc)
    1148             && qcowHdrConvertToHostEndianess(&Header))
    1149         {
    1150             pImage->offNextCluster = RT_ALIGN_64(cbFile, 512); /* Align image to sector boundary. */
    1151             Assert(pImage->offNextCluster >= cbFile);
    1152 
    1153             rc = qcowHdrValidate(pImage, &Header, cbFile);
    1154             if (RT_SUCCESS(rc))
     1046    int rc = qcowL2TblCacheCreate(pImage);
     1047    if (RT_SUCCESS(rc))
     1048    {
     1049        /* Open the image. */
     1050        rc = vdIfIoIntFileOpen(pImage->pIfIo, pImage->pszFilename,
     1051                               VDOpenFlagsToFileOpenFlags(uOpenFlags,
     1052                                                          false /* fCreate */),
     1053                               &pImage->pStorage);
     1054        if (RT_SUCCESS(rc))
     1055        {
     1056            uint64_t cbFile;
     1057            rc = vdIfIoIntFileGetSize(pImage->pIfIo, pImage->pStorage, &cbFile);
     1058            if (   RT_SUCCESS(rc)
     1059                && cbFile > sizeof(QCowHeader))
    11551060            {
    1156                 if (Header.u32Version == 1)
     1061                QCowHeader Header;
     1062
     1063                rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, 0, &Header, sizeof(Header));
     1064                if (   RT_SUCCESS(rc)
     1065                    && qcowHdrConvertToHostEndianess(&Header))
    11571066                {
    1158                     if (!Header.Version.v1.u32CryptMethod)
     1067                    pImage->offNextCluster = RT_ALIGN_64(cbFile, 512); /* Align image to sector boundary. */
     1068                    Assert(pImage->offNextCluster >= cbFile);
     1069
     1070                    rc = qcowHdrValidate(pImage, &Header, cbFile);
     1071                    if (RT_SUCCESS(rc))
    11591072                    {
    1160                         pImage->uVersion           = 1;
    1161                         pImage->offBackingFilename = Header.Version.v1.u64BackingFileOffset;
    1162                         pImage->cbBackingFilename  = Header.Version.v1.u32BackingFileSize;
    1163                         pImage->MTime              = Header.Version.v1.u32MTime;
    1164                         pImage->cbSize             = Header.Version.v1.u64Size;
    1165                         pImage->cbCluster          = RT_BIT_32(Header.Version.v1.u8ClusterBits);
    1166                         pImage->cL2TableEntries    = RT_BIT_32(Header.Version.v1.u8L2Bits);
    1167                         pImage->cbL2Table          = RT_ALIGN_64(pImage->cL2TableEntries * sizeof(uint64_t), pImage->cbCluster);
    1168                         pImage->offL1Table         = Header.Version.v1.u64L1TableOffset;
    1169                         pImage->cL1TableEntries    = pImage->cbSize / (pImage->cbCluster * pImage->cL2TableEntries);
    1170                         if (pImage->cbSize % (pImage->cbCluster * pImage->cL2TableEntries))
    1171                             pImage->cL1TableEntries++;
     1073                        if (Header.u32Version == 1)
     1074                        {
     1075                            if (!Header.Version.v1.u32CryptMethod)
     1076                            {
     1077                                pImage->uVersion           = 1;
     1078                                pImage->offBackingFilename = Header.Version.v1.u64BackingFileOffset;
     1079                                pImage->cbBackingFilename  = Header.Version.v1.u32BackingFileSize;
     1080                                pImage->MTime              = Header.Version.v1.u32MTime;
     1081                                pImage->cbSize             = Header.Version.v1.u64Size;
     1082                                pImage->cbCluster          = RT_BIT_32(Header.Version.v1.u8ClusterBits);
     1083                                pImage->cL2TableEntries    = RT_BIT_32(Header.Version.v1.u8L2Bits);
     1084                                pImage->cbL2Table          = RT_ALIGN_64(pImage->cL2TableEntries * sizeof(uint64_t), pImage->cbCluster);
     1085                                pImage->offL1Table         = Header.Version.v1.u64L1TableOffset;
     1086                                pImage->cL1TableEntries    = pImage->cbSize / (pImage->cbCluster * pImage->cL2TableEntries);
     1087                                if (pImage->cbSize % (pImage->cbCluster * pImage->cL2TableEntries))
     1088                                    pImage->cL1TableEntries++;
     1089                            }
     1090                            else
     1091                                rc = vdIfError(pImage->pIfError, VERR_NOT_SUPPORTED, RT_SRC_POS,
     1092                                               N_("QCow: Encrypted image '%s' is not supported"),
     1093                                               pImage->pszFilename);
     1094                        }
     1095                        else if (Header.u32Version == 2)
     1096                        {
     1097                            if (Header.Version.v2.u32CryptMethod)
     1098                                rc = vdIfError(pImage->pIfError, VERR_NOT_SUPPORTED, RT_SRC_POS,
     1099                                               N_("QCow: Encrypted image '%s' is not supported"),
     1100                                               pImage->pszFilename);
     1101                            else if (Header.Version.v2.u32NbSnapshots)
     1102                                rc = vdIfError(pImage->pIfError, VERR_NOT_SUPPORTED, RT_SRC_POS,
     1103                                               N_("QCow: Image '%s' contains snapshots which is not supported"),
     1104                                               pImage->pszFilename);
     1105                            else
     1106                            {
     1107                                pImage->uVersion              = 2;
     1108                                pImage->offBackingFilename    = Header.Version.v2.u64BackingFileOffset;
     1109                                pImage->cbBackingFilename     = Header.Version.v2.u32BackingFileSize;
     1110                                pImage->cbSize                = Header.Version.v2.u64Size;
     1111                                pImage->cbCluster             = RT_BIT_32(Header.Version.v2.u32ClusterBits);
     1112                                pImage->cL2TableEntries       = pImage->cbCluster / sizeof(uint64_t);
     1113                                pImage->cbL2Table             = pImage->cbCluster;
     1114                                pImage->offL1Table            = Header.Version.v2.u64L1TableOffset;
     1115                                pImage->cL1TableEntries       = Header.Version.v2.u32L1Size;
     1116                                pImage->offRefcountTable      = Header.Version.v2.u64RefcountTableOffset;
     1117                                pImage->cbRefcountTable       = qcowCluster2Byte(pImage, Header.Version.v2.u32RefcountTableClusters);
     1118                                pImage->cRefcountTableEntries = pImage->cbRefcountTable / sizeof(uint64_t);
     1119                            }
     1120                        }
     1121                        else
     1122                            rc = vdIfError(pImage->pIfError, VERR_NOT_SUPPORTED, RT_SRC_POS,
     1123                                           N_("QCow: Image '%s' uses version %u which is not supported"),
     1124                                           pImage->pszFilename, Header.u32Version);
     1125
     1126                        pImage->cbL1Table = RT_ALIGN_64(pImage->cL1TableEntries * sizeof(uint64_t), pImage->cbCluster);
     1127                        if ((uint64_t)pImage->cbL1Table != RT_ALIGN_64(pImage->cL1TableEntries * sizeof(uint64_t), pImage->cbCluster))
     1128                            rc = vdIfError(pImage->pIfError, VERR_INVALID_STATE, RT_SRC_POS,
     1129                                           N_("QCOW: L1 table size overflow in image '%s'"),
     1130                                           pImage->pszFilename);
    11721131                    }
    1173                     else
    1174                         rc = vdIfError(pImage->pIfError, VERR_NOT_SUPPORTED, RT_SRC_POS,
    1175                                        N_("QCow: Encrypted image '%s' is not supported"),
    1176                                        pImage->pszFilename);
    1177                 }
    1178                 else if (Header.u32Version == 2)
    1179                 {
    1180                     if (Header.Version.v2.u32CryptMethod)
    1181                         rc = vdIfError(pImage->pIfError, VERR_NOT_SUPPORTED, RT_SRC_POS,
    1182                                        N_("QCow: Encrypted image '%s' is not supported"),
    1183                                        pImage->pszFilename);
    1184                     else if (Header.Version.v2.u32NbSnapshots)
    1185                         rc = vdIfError(pImage->pIfError, VERR_NOT_SUPPORTED, RT_SRC_POS,
    1186                                        N_("QCow: Image '%s' contains snapshots which is not supported"),
    1187                                        pImage->pszFilename);
    1188                     else
     1132
     1133                    /** @todo Check that there are no compressed clusters in the image
     1134                     *  (by traversing the L2 tables and checking each offset).
     1135                     *  Refuse to open such images.
     1136                     */
     1137
     1138                    if (   RT_SUCCESS(rc)
     1139                        && pImage->cbBackingFilename
     1140                        && pImage->offBackingFilename)
    11891141                    {
    1190                         pImage->uVersion              = 2;
    1191                         pImage->offBackingFilename    = Header.Version.v2.u64BackingFileOffset;
    1192                         pImage->cbBackingFilename     = Header.Version.v2.u32BackingFileSize;
    1193                         pImage->cbSize                = Header.Version.v2.u64Size;
    1194                         pImage->cbCluster             = RT_BIT_32(Header.Version.v2.u32ClusterBits);
    1195                         pImage->cL2TableEntries       = pImage->cbCluster / sizeof(uint64_t);
    1196                         pImage->cbL2Table             = pImage->cbCluster;
    1197                         pImage->offL1Table            = Header.Version.v2.u64L1TableOffset;
    1198                         pImage->cL1TableEntries       = Header.Version.v2.u32L1Size;
    1199                         pImage->offRefcountTable      = Header.Version.v2.u64RefcountTableOffset;
    1200                         pImage->cbRefcountTable       = qcowCluster2Byte(pImage, Header.Version.v2.u32RefcountTableClusters);
    1201                         pImage->cRefcountTableEntries = pImage->cbRefcountTable / sizeof(uint64_t);
     1142                        /* Load backing filename from image. */
     1143                        pImage->pszBackingFilename = (char *)RTMemAllocZ(pImage->cbBackingFilename + 1); /* +1 for \0 terminator. */
     1144                        if (pImage->pszBackingFilename)
     1145                        {
     1146                            rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage,
     1147                                                       pImage->offBackingFilename, pImage->pszBackingFilename,
     1148                                                       pImage->cbBackingFilename);
     1149                        }
     1150                        else
     1151                            rc = VERR_NO_MEMORY;
     1152                    }
     1153
     1154                    if (   RT_SUCCESS(rc)
     1155                        && pImage->cbRefcountTable
     1156                        && pImage->offRefcountTable)
     1157                    {
     1158                        /* Load refcount table. */
     1159                        Assert(pImage->cRefcountTableEntries);
     1160                        pImage->paRefcountTable = (uint64_t *)RTMemAllocZ(pImage->cbRefcountTable);
     1161                        if (RT_LIKELY(pImage->paRefcountTable))
     1162                        {
     1163                            rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage,
     1164                                                       pImage->offRefcountTable, pImage->paRefcountTable,
     1165                                                       pImage->cbRefcountTable);
     1166                            if (RT_SUCCESS(rc))
     1167                                qcowTableConvertToHostEndianess(pImage->paRefcountTable,
     1168                                                                pImage->cRefcountTableEntries);
     1169                            else
     1170                                rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS,
     1171                                               N_("QCow: Reading refcount table of image '%s' failed"),
     1172                                               pImage->pszFilename);
     1173                        }
     1174                        else
     1175                            rc = vdIfError(pImage->pIfError, VERR_NO_MEMORY, RT_SRC_POS,
     1176                                           N_("QCow: Allocating memory for refcount table of image '%s' failed"),
     1177                                           pImage->pszFilename);
     1178                    }
     1179
     1180                    if (RT_SUCCESS(rc))
     1181                    {
     1182                        qcowTableMasksInit(pImage);
     1183
     1184                        /* Allocate L1 table. */
     1185                        pImage->paL1Table = (uint64_t *)RTMemAllocZ(pImage->cbL1Table);
     1186                        if (pImage->paL1Table)
     1187                        {
     1188                            /* Read from the image. */
     1189                            rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage,
     1190                                                       pImage->offL1Table, pImage->paL1Table,
     1191                                                       pImage->cbL1Table);
     1192                            if (RT_SUCCESS(rc))
     1193                                qcowTableConvertToHostEndianess(pImage->paL1Table, pImage->cL1TableEntries);
     1194                            else
     1195                                rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS,
     1196                                               N_("QCow: Reading the L1 table for image '%s' failed"),
     1197                                               pImage->pszFilename);
     1198                        }
     1199                        else
     1200                            rc = vdIfError(pImage->pIfError, VERR_NO_MEMORY, RT_SRC_POS,
     1201                                           N_("QCow: Out of memory allocating L1 table for image '%s'"),
     1202                                           pImage->pszFilename);
    12021203                    }
    12031204                }
    1204                 else
    1205                     rc = vdIfError(pImage->pIfError, VERR_NOT_SUPPORTED, RT_SRC_POS,
    1206                                    N_("QCow: Image '%s' uses version %u which is not supported"),
    1207                                    pImage->pszFilename, Header.u32Version);
    1208 
    1209                 pImage->cbL1Table = RT_ALIGN_64(pImage->cL1TableEntries * sizeof(uint64_t), pImage->cbCluster);
    1210                 if ((uint64_t)pImage->cbL1Table != RT_ALIGN_64(pImage->cL1TableEntries * sizeof(uint64_t), pImage->cbCluster))
    1211                     rc = vdIfError(pImage->pIfError, VERR_INVALID_STATE, RT_SRC_POS,
    1212                                    N_("QCOW: L1 table size overflow in image '%s'"),
    1213                                    pImage->pszFilename);
     1205                else if (RT_SUCCESS(rc))
     1206                    rc = VERR_VD_GEN_INVALID_HEADER;
    12141207            }
    1215 
    1216             /** @todo Check that there are no compressed clusters in the image
    1217              *  (by traversing the L2 tables and checking each offset).
    1218              *  Refuse to open such images.
    1219              */
    1220 
    1221             if (   RT_SUCCESS(rc)
    1222                 && pImage->cbBackingFilename
    1223                 && pImage->offBackingFilename)
    1224             {
    1225                 /* Load backing filename from image. */
    1226                 pImage->pszBackingFilename = (char *)RTMemAllocZ(pImage->cbBackingFilename + 1); /* +1 for \0 terminator. */
    1227                 if (pImage->pszBackingFilename)
    1228                 {
    1229                     rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage,
    1230                                                pImage->offBackingFilename, pImage->pszBackingFilename,
    1231                                                pImage->cbBackingFilename);
    1232                 }
    1233                 else
    1234                     rc = VERR_NO_MEMORY;
    1235             }
    1236 
    1237             if (   RT_SUCCESS(rc)
    1238                 && pImage->cbRefcountTable
    1239                 && pImage->offRefcountTable)
    1240             {
    1241                 /* Load refcount table. */
    1242                 Assert(pImage->cRefcountTableEntries);
    1243                 pImage->paRefcountTable = (uint64_t *)RTMemAllocZ(pImage->cbRefcountTable);
    1244                 if (RT_LIKELY(pImage->paRefcountTable))
    1245                 {
    1246                     rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage,
    1247                                                pImage->offRefcountTable, pImage->paRefcountTable,
    1248                                                pImage->cbRefcountTable);
    1249                     if (RT_SUCCESS(rc))
    1250                         qcowTableConvertToHostEndianess(pImage->paRefcountTable,
    1251                                                         pImage->cRefcountTableEntries);
    1252                     else
    1253                         rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS,
    1254                                        N_("QCow: Reading refcount table of image '%s' failed"),
    1255                                        pImage->pszFilename);
    1256                 }
    1257                 else
    1258                     rc = vdIfError(pImage->pIfError, VERR_NO_MEMORY, RT_SRC_POS,
    1259                                    N_("QCow: Allocating memory for refcount table of image '%s' failed"),
    1260                                    pImage->pszFilename);
    1261             }
    1262 
    1263             if (RT_SUCCESS(rc))
    1264             {
    1265                 qcowTableMasksInit(pImage);
    1266 
    1267                 /* Allocate L1 table. */
    1268                 pImage->paL1Table = (uint64_t *)RTMemAllocZ(pImage->cbL1Table);
    1269                 if (pImage->paL1Table)
    1270                 {
    1271                     /* Read from the image. */
    1272                     rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage,
    1273                                                pImage->offL1Table, pImage->paL1Table,
    1274                                                pImage->cbL1Table);
    1275                     if (RT_SUCCESS(rc))
    1276                         qcowTableConvertToHostEndianess(pImage->paL1Table, pImage->cL1TableEntries);
    1277                     else
    1278                         rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS,
    1279                                        N_("QCow: Reading the L1 table for image '%s' failed"),
    1280                                        pImage->pszFilename);
    1281                 }
    1282                 else
    1283                     rc = vdIfError(pImage->pIfError, VERR_NO_MEMORY, RT_SRC_POS,
    1284                                    N_("QCow: Out of memory allocating L1 table for image '%s'"),
    1285                                    pImage->pszFilename);
    1286             }
     1208            else if (RT_SUCCESS(rc))
     1209                rc = VERR_VD_GEN_INVALID_HEADER;
    12871210        }
    1288         else if (RT_SUCCESS(rc))
    1289             rc = VERR_VD_GEN_INVALID_HEADER;
     1211        /* else: Do NOT signal an appropriate error here, as the VD layer has the
     1212         *       choice of retrying the open if it failed. */
    12901213    }
    12911214    else
    1292         rc = VERR_VD_GEN_INVALID_HEADER;
    1293 
    1294 out:
     1215        rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS,
     1216                       N_("Qcow: Creating the L2 table cache for image '%s' failed"),
     1217                       pImage->pszFilename);
     1218
    12951219    if (RT_FAILURE(rc))
    12961220        qcowFreeImage(pImage, false);
     
    13051229                           PCVDGEOMETRY pPCHSGeometry,
    13061230                           PCVDGEOMETRY pLCHSGeometry, unsigned uOpenFlags,
    1307                            PFNVDPROGRESS pfnProgress, void *pvUser,
     1231                           PVDINTERFACEPROGRESS pIfProgress,
    13081232                           unsigned uPercentStart, unsigned uPercentSpan)
    13091233{
     
    13121236    int32_t fOpen;
    13131237
    1314     if (uImageFlags & VD_IMAGE_FLAGS_FIXED)
    1315     {
     1238    if (!(uImageFlags & VD_IMAGE_FLAGS_FIXED))
     1239    {
     1240        rc = qcowL2TblCacheCreate(pImage);
     1241        if (RT_SUCCESS(rc))
     1242        {
     1243            pImage->uOpenFlags   = uOpenFlags & ~VD_OPEN_FLAGS_READONLY;
     1244            pImage->uImageFlags  = uImageFlags;
     1245            pImage->PCHSGeometry = *pPCHSGeometry;
     1246            pImage->LCHSGeometry = *pLCHSGeometry;
     1247            pImage->pIfError = VDIfErrorGet(pImage->pVDIfsDisk);
     1248            pImage->pIfIo = VDIfIoIntGet(pImage->pVDIfsImage);
     1249            AssertPtrReturn(pImage->pIfIo, VERR_INVALID_PARAMETER);
     1250
     1251            /* Create image file. */
     1252            fOpen = VDOpenFlagsToFileOpenFlags(pImage->uOpenFlags, true /* fCreate */);
     1253            rc = vdIfIoIntFileOpen(pImage->pIfIo, pImage->pszFilename, fOpen, &pImage->pStorage);
     1254            if (RT_SUCCESS(rc))
     1255            {
     1256                /* Init image state. */
     1257                pImage->uVersion           = 1; /* We create only version 1 images at the moment. */
     1258                pImage->cbSize             = cbSize;
     1259                pImage->cbCluster          = QCOW_CLUSTER_SIZE_DEFAULT;
     1260                pImage->cbL2Table          = qcowCluster2Byte(pImage, QCOW_L2_CLUSTERS_DEFAULT);
     1261                pImage->cL2TableEntries    = pImage->cbL2Table / sizeof(uint64_t);
     1262                pImage->cL1TableEntries    = cbSize / (pImage->cbCluster * pImage->cL2TableEntries);
     1263                if (cbSize % (pImage->cbCluster * pImage->cL2TableEntries))
     1264                    pImage->cL1TableEntries++;
     1265                pImage->cbL1Table          = pImage->cL1TableEntries * sizeof(uint64_t);
     1266                pImage->offL1Table         = QCOW_V1_HDR_SIZE;
     1267                pImage->cbBackingFilename  = 0;
     1268                pImage->offBackingFilename = 0;
     1269                pImage->offNextCluster     = RT_ALIGN_64(QCOW_V1_HDR_SIZE + pImage->cbL1Table, pImage->cbCluster);
     1270                qcowTableMasksInit(pImage);
     1271
     1272                /* Init L1 table. */
     1273                pImage->paL1Table = (uint64_t *)RTMemAllocZ(pImage->cbL1Table);
     1274                if (RT_LIKELY(pImage->paL1Table))
     1275                {
     1276                    if (RT_SUCCESS(rc))
     1277                        vdIfProgress(pIfProgress, uPercentStart + uPercentSpan * 98 / 100);
     1278
     1279                    rc = qcowFlushImage(pImage);
     1280                    if (RT_SUCCESS(rc))
     1281                        rc = vdIfIoIntFileSetSize(pImage->pIfIo, pImage->pStorage, pImage->offNextCluster);
     1282                }
     1283                else
     1284                    rc = vdIfError(pImage->pIfError, VERR_NO_MEMORY, RT_SRC_POS, N_("QCow: cannot allocate memory for L1 table of image '%s'"),
     1285                                   pImage->pszFilename);
     1286            }
     1287            else
     1288                rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("QCow: cannot create image '%s'"), pImage->pszFilename);
     1289        }
     1290        else
     1291            rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("QCow: Failed to create L2 cache for image '%s'"),
     1292                           pImage->pszFilename);
     1293    }
     1294    else
    13161295        rc = vdIfError(pImage->pIfError, VERR_VD_INVALID_TYPE, RT_SRC_POS, N_("QCow: cannot create fixed image '%s'"), pImage->pszFilename);
    1317         goto out;
    1318     }
    1319 
    1320     pImage->uOpenFlags   = uOpenFlags & ~VD_OPEN_FLAGS_READONLY;
    1321     pImage->uImageFlags  = uImageFlags;
    1322     pImage->PCHSGeometry = *pPCHSGeometry;
    1323     pImage->LCHSGeometry = *pLCHSGeometry;
    1324 
    1325     pImage->pIfError = VDIfErrorGet(pImage->pVDIfsDisk);
    1326     pImage->pIfIo = VDIfIoIntGet(pImage->pVDIfsImage);
    1327     AssertPtrReturn(pImage->pIfIo, VERR_INVALID_PARAMETER);
    1328 
    1329     /* Create image file. */
    1330     fOpen = VDOpenFlagsToFileOpenFlags(pImage->uOpenFlags, true /* fCreate */);
    1331     rc = vdIfIoIntFileOpen(pImage->pIfIo, pImage->pszFilename, fOpen, &pImage->pStorage);
    1332     if (RT_FAILURE(rc))
    1333     {
    1334         rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("QCow: cannot create image '%s'"), pImage->pszFilename);
    1335         goto out;
    1336     }
    1337 
    1338     /* Init image state. */
    1339     pImage->uVersion           = 1; /* We create only version 1 images at the moment. */
    1340     pImage->cbSize             = cbSize;
    1341     pImage->cbCluster          = QCOW_CLUSTER_SIZE_DEFAULT;
    1342     pImage->cbL2Table          = qcowCluster2Byte(pImage, QCOW_L2_CLUSTERS_DEFAULT);
    1343     pImage->cL2TableEntries    = pImage->cbL2Table / sizeof(uint64_t);
    1344     pImage->cL1TableEntries    = cbSize / (pImage->cbCluster * pImage->cL2TableEntries);
    1345     if (cbSize % (pImage->cbCluster * pImage->cL2TableEntries))
    1346         pImage->cL1TableEntries++;
    1347     pImage->cbL1Table          = pImage->cL1TableEntries * sizeof(uint64_t);
    1348     pImage->offL1Table         = QCOW_V1_HDR_SIZE;
    1349     pImage->cbBackingFilename  = 0;
    1350     pImage->offBackingFilename = 0;
    1351     pImage->offNextCluster     = RT_ALIGN_64(QCOW_V1_HDR_SIZE + pImage->cbL1Table, pImage->cbCluster);
    1352     qcowTableMasksInit(pImage);
    1353 
    1354     /* Init L1 table. */
    1355     pImage->paL1Table = (uint64_t *)RTMemAllocZ(pImage->cbL1Table);
    1356     if (!pImage->paL1Table)
    1357     {
    1358         rc = vdIfError(pImage->pIfError, VERR_NO_MEMORY, RT_SRC_POS, N_("QCow: cannot allocate memory for L1 table of image '%s'"),
    1359                        pImage->pszFilename);
    1360         goto out;
    1361     }
    1362 
    1363     rc = qcowL2TblCacheCreate(pImage);
    1364     if (RT_FAILURE(rc))
    1365     {
    1366         rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("QCow: Failed to create L2 cache for image '%s'"),
    1367                        pImage->pszFilename);
    1368         goto out;
    1369     }
    1370 
    1371     if (RT_SUCCESS(rc) && pfnProgress)
    1372         pfnProgress(pvUser, uPercentStart + uPercentSpan * 98 / 100);
    1373 
    1374     rc = qcowFlushImage(pImage);
     1296
    13751297    if (RT_SUCCESS(rc))
    1376         rc = vdIfIoIntFileSetSize(pImage->pIfIo, pImage->pStorage, pImage->offNextCluster);
    1377 
    1378 out:
    1379     if (RT_SUCCESS(rc) && pfnProgress)
    1380         pfnProgress(pvUser, uPercentStart + uPercentSpan);
     1298        vdIfProgress(pIfProgress, uPercentStart + uPercentSpan);
    13811299
    13821300    if (RT_FAILURE(rc))
     
    15441462    PVDINTERFACEIOINT pIfIo = VDIfIoIntGet(pVDIfsImage);
    15451463    AssertPtrReturn(pIfIo, VERR_INVALID_PARAMETER);
    1546 
    1547     if (   !VALID_PTR(pszFilename)
    1548         || !*pszFilename)
    1549     {
    1550         rc = VERR_INVALID_PARAMETER;
    1551         goto out;
    1552     }
     1464    AssertReturn((VALID_PTR(pszFilename) && *pszFilename), VERR_INVALID_PARAMETER);
    15531465
    15541466    /*
     
    15701482            if (   RT_SUCCESS(rc)
    15711483                && qcowHdrConvertToHostEndianess(&Header))
    1572             {
    15731484                *penmType = VDTYPE_HDD;
    1574                 rc = VINF_SUCCESS;
    1575             }
    15761485            else
    15771486                rc = VERR_VD_GEN_INVALID_HEADER;
     
    15841493        vdIfIoIntFileClose(pIfIo, pStorage);
    15851494
    1586 out:
    15871495    LogFlowFunc(("returns %Rrc\n", rc));
    15881496    return rc;
     
    15941502                                  VDTYPE enmType, void **ppBackendData)
    15951503{
    1596     LogFlowFunc(("pszFilename=\"%s\" uOpenFlags=%#x pVDIfsDisk=%#p pVDIfsImage=%#p enmType=%u ppBackendData=%#p\n", pszFilename, uOpenFlags, pVDIfsDisk, pVDIfsImage, enmType, ppBackendData));
     1504    RT_NOREF1(enmType); /**< @todo r=klaus make use of the type info. */
     1505
     1506    LogFlowFunc(("pszFilename=\"%s\" uOpenFlags=%#x pVDIfsDisk=%#p pVDIfsImage=%#p enmType=%u ppBackendData=%#p\n",
     1507                 pszFilename, uOpenFlags, pVDIfsDisk, pVDIfsImage, enmType, ppBackendData));
    15971508    int rc;
    1598     PQCOWIMAGE pImage;
    1599 
    1600     NOREF(enmType); /**< @todo r=klaus make use of the type info. */
    16011509
    16021510    /* Check open flags. All valid flags are supported. */
    1603     if (uOpenFlags & ~VD_OPEN_FLAGS_MASK)
    1604     {
    1605         rc = VERR_INVALID_PARAMETER;
    1606         goto out;
    1607     }
    1608 
    1609     /* Check remaining arguments. */
    1610     if (   !VALID_PTR(pszFilename)
    1611         || !*pszFilename)
    1612     {
    1613         rc = VERR_INVALID_PARAMETER;
    1614         goto out;
    1615     }
    1616 
    1617 
    1618     pImage = (PQCOWIMAGE)RTMemAllocZ(sizeof(QCOWIMAGE));
    1619     if (!pImage)
    1620     {
     1511    AssertReturn(!(uOpenFlags & ~VD_OPEN_FLAGS_MASK), VERR_INVALID_PARAMETER);
     1512    AssertReturn((VALID_PTR(pszFilename) && *pszFilename), VERR_INVALID_PARAMETER);
     1513
     1514    PQCOWIMAGE pImage = (PQCOWIMAGE)RTMemAllocZ(sizeof(QCOWIMAGE));
     1515    if (RT_LIKELY(pImage))
     1516    {
     1517        pImage->pszFilename = pszFilename;
     1518        pImage->pStorage = NULL;
     1519        pImage->pVDIfsDisk = pVDIfsDisk;
     1520        pImage->pVDIfsImage = pVDIfsImage;
     1521
     1522        rc = qcowOpenImage(pImage, uOpenFlags);
     1523        if (RT_SUCCESS(rc))
     1524            *ppBackendData = pImage;
     1525        else
     1526            RTMemFree(pImage);
     1527    }
     1528    else
    16211529        rc = VERR_NO_MEMORY;
    1622         goto out;
    1623     }
    1624     pImage->pszFilename = pszFilename;
    1625     pImage->pStorage = NULL;
    1626     pImage->pVDIfsDisk = pVDIfsDisk;
    1627     pImage->pVDIfsImage = pVDIfsImage;
    1628 
    1629     rc = qcowOpenImage(pImage, uOpenFlags);
    1630     if (RT_SUCCESS(rc))
    1631         *ppBackendData = pImage;
    1632     else
    1633         RTMemFree(pImage);
    1634 
    1635 out:
     1530
    16361531    LogFlowFunc(("returns %Rrc (pBackendData=%#p)\n", rc, *ppBackendData));
    16371532    return rc;
     
    16521547                 pszFilename, cbSize, uImageFlags, pszComment, pPCHSGeometry, pLCHSGeometry, pUuid, uOpenFlags, uPercentStart, uPercentSpan, pVDIfsDisk, pVDIfsImage, pVDIfsOperation, enmType, ppBackendData));
    16531548    int rc;
    1654     PQCOWIMAGE pImage;
    1655 
    1656     PFNVDPROGRESS pfnProgress = NULL;
    1657     void *pvUser = NULL;
    1658     PVDINTERFACEPROGRESS pIfProgress = VDIfProgressGet(pVDIfsOperation);
    1659     if (pIfProgress)
    1660     {
    1661         pfnProgress = pIfProgress->pfnProgress;
    1662         pvUser = pIfProgress->Core.pvUser;
    1663     }
    16641549
    16651550    /* Check the VD container type. */
    16661551    if (enmType != VDTYPE_HDD)
    1667     {
    1668         rc = VERR_VD_INVALID_TYPE;
    1669         goto out;
    1670     }
     1552        return VERR_VD_INVALID_TYPE;
    16711553
    16721554    /* Check open flags. All valid flags are supported. */
    1673     if (uOpenFlags & ~VD_OPEN_FLAGS_MASK)
    1674     {
    1675         rc = VERR_INVALID_PARAMETER;
    1676         goto out;
    1677     }
    1678 
    1679     /* Check remaining arguments. */
    1680     if (   !VALID_PTR(pszFilename)
    1681         || !*pszFilename
    1682         || !VALID_PTR(pPCHSGeometry)
    1683         || !VALID_PTR(pLCHSGeometry))
    1684     {
    1685         rc = VERR_INVALID_PARAMETER;
    1686         goto out;
    1687     }
    1688 
    1689     pImage = (PQCOWIMAGE)RTMemAllocZ(sizeof(QCOWIMAGE));
    1690     if (!pImage)
    1691     {
     1555    AssertReturn(!(uOpenFlags & ~VD_OPEN_FLAGS_MASK), VERR_INVALID_PARAMETER);
     1556    AssertReturn(   VALID_PTR(pszFilename)
     1557                 && *pszFilename
     1558                 && VALID_PTR(pPCHSGeometry)
     1559                 && VALID_PTR(pLCHSGeometry), VERR_INVALID_PARAMETER);
     1560
     1561    PQCOWIMAGE pImage = (PQCOWIMAGE)RTMemAllocZ(sizeof(QCOWIMAGE));
     1562    if (RT_LIKELY(pImage))
     1563    {
     1564        PVDINTERFACEPROGRESS pIfProgress = VDIfProgressGet(pVDIfsOperation);
     1565
     1566        pImage->pszFilename = pszFilename;
     1567        pImage->pStorage = NULL;
     1568        pImage->pVDIfsDisk = pVDIfsDisk;
     1569        pImage->pVDIfsImage = pVDIfsImage;
     1570
     1571        rc = qcowCreateImage(pImage, cbSize, uImageFlags, pszComment,
     1572                             pPCHSGeometry, pLCHSGeometry, uOpenFlags,
     1573                             pIfProgress, uPercentStart, uPercentSpan);
     1574        if (RT_SUCCESS(rc))
     1575        {
     1576            /* So far the image is opened in read/write mode. Make sure the
     1577             * image is opened in read-only mode if the caller requested that. */
     1578            if (uOpenFlags & VD_OPEN_FLAGS_READONLY)
     1579            {
     1580                qcowFreeImage(pImage, false);
     1581                rc = qcowOpenImage(pImage, uOpenFlags);
     1582            }
     1583
     1584            if (RT_SUCCESS(rc))
     1585                *ppBackendData = pImage;
     1586        }
     1587
     1588        if (RT_FAILURE(rc))
     1589            RTMemFree(pImage);
     1590    }
     1591    else
    16921592        rc = VERR_NO_MEMORY;
    1693         goto out;
    1694     }
    1695     pImage->pszFilename = pszFilename;
    1696     pImage->pStorage = NULL;
    1697     pImage->pVDIfsDisk = pVDIfsDisk;
    1698     pImage->pVDIfsImage = pVDIfsImage;
    1699 
    1700     rc = qcowCreateImage(pImage, cbSize, uImageFlags, pszComment,
    1701                         pPCHSGeometry, pLCHSGeometry, uOpenFlags,
    1702                         pfnProgress, pvUser, uPercentStart, uPercentSpan);
    1703     if (RT_SUCCESS(rc))
    1704     {
    1705         /* So far the image is opened in read/write mode. Make sure the
    1706          * image is opened in read-only mode if the caller requested that. */
    1707         if (uOpenFlags & VD_OPEN_FLAGS_READONLY)
    1708         {
    1709             qcowFreeImage(pImage, false);
    1710             rc = qcowOpenImage(pImage, uOpenFlags);
    1711             if (RT_FAILURE(rc))
    1712             {
    1713                 RTMemFree(pImage);
    1714                 goto out;
    1715             }
    1716         }
    1717         *ppBackendData = pImage;
    1718     }
    1719     else
    1720         RTMemFree(pImage);
    1721 
    1722 out:
     1593
    17231594    LogFlowFunc(("returns %Rrc (pBackendData=%#p)\n", rc, *ppBackendData));
    17241595    return rc;
     
    17331604
    17341605    /* Check arguments. */
    1735     if (   !pImage
    1736         || !pszFilename
    1737         || !*pszFilename)
    1738     {
    1739         rc = VERR_INVALID_PARAMETER;
    1740         goto out;
    1741     }
     1606    AssertReturn((pImage && pszFilename && *pszFilename), VERR_INVALID_PARAMETER);
    17421607
    17431608    /* Close the image. */
    17441609    rc = qcowFreeImage(pImage, false);
    1745     if (RT_FAILURE(rc))
    1746         goto out;
    1747 
    1748     /* Rename the file. */
    1749     rc = vdIfIoIntFileMove(pImage->pIfIo, pImage->pszFilename, pszFilename, 0);
    1750     if (RT_FAILURE(rc))
    1751     {
    1752         /* The move failed, try to reopen the original image. */
    1753         int rc2 = qcowOpenImage(pImage, pImage->uOpenFlags);
    1754         if (RT_FAILURE(rc2))
    1755             rc = rc2;
    1756 
    1757         goto out;
    1758     }
    1759 
    1760     /* Update pImage with the new information. */
    1761     pImage->pszFilename = pszFilename;
    1762 
    1763     /* Open the old image with new name. */
    1764     rc = qcowOpenImage(pImage, pImage->uOpenFlags);
    1765     if (RT_FAILURE(rc))
    1766         goto out;
    1767 
    1768 out:
     1610    if (RT_SUCCESS(rc))
     1611    {
     1612        /* Rename the file. */
     1613        rc = vdIfIoIntFileMove(pImage->pIfIo, pImage->pszFilename, pszFilename, 0);
     1614        if (RT_SUCCESS(rc))
     1615        {
     1616            /* Update pImage with the new information. */
     1617            pImage->pszFilename = pszFilename;
     1618
     1619            /* Open the old image with new name. */
     1620            rc = qcowOpenImage(pImage, pImage->uOpenFlags);
     1621        }
     1622        else
     1623        {
     1624            /* The move failed, try to reopen the original image. */
     1625            int rc2 = qcowOpenImage(pImage, pImage->uOpenFlags);
     1626            if (RT_FAILURE(rc2))
     1627                rc = rc2;
     1628        }
     1629    }
     1630
    17691631    LogFlowFunc(("returns %Rrc\n", rc));
    17701632    return rc;
     
    17761638    LogFlowFunc(("pBackendData=%#p fDelete=%d\n", pBackendData, fDelete));
    17771639    PQCOWIMAGE pImage = (PQCOWIMAGE)pBackendData;
    1778     int rc;
    1779 
    1780     rc = qcowFreeImage(pImage, fDelete);
     1640
     1641    int rc = qcowFreeImage(pImage, fDelete);
    17811642    RTMemFree(pImage);
    17821643
     
    18001661    Assert(uOffset % 512 == 0);
    18011662    Assert(cbToRead % 512 == 0);
    1802 
    1803     if (!VALID_PTR(pIoCtx) || !cbToRead)
    1804     {
    1805         rc = VERR_INVALID_PARAMETER;
    1806         goto out;
    1807     }
    1808 
    1809     if (   uOffset + cbToRead > pImage->cbSize
    1810         || cbToRead == 0)
    1811     {
    1812         rc = VERR_INVALID_PARAMETER;
    1813         goto out;
    1814     }
     1663    AssertReturn((VALID_PTR(pIoCtx) && cbToRead), VERR_INVALID_PARAMETER);
     1664    AssertReturn(uOffset + cbToRead <= pImage->cbSize, VERR_INVALID_PARAMETER);
    18151665
    18161666    qcowConvertLogicalOffset(pImage, uOffset, &idxL1, &idxL2, &offCluster);
     
    18311681        *pcbActuallyRead = cbToRead;
    18321682
    1833 out:
    18341683    LogFlowFunc(("returns %Rrc\n", rc));
    18351684    return rc;
     
    18521701    Assert(!(uOffset % 512));
    18531702    Assert(!(cbToWrite % 512));
    1854 
    1855     if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
    1856     {
    1857         rc = VERR_VD_IMAGE_READ_ONLY;
    1858         goto out;
    1859     }
    1860 
    1861     if (!VALID_PTR(pIoCtx) || !cbToWrite)
    1862     {
    1863         rc = VERR_INVALID_PARAMETER;
    1864         goto out;
    1865     }
    1866 
    1867     if (   uOffset + cbToWrite > pImage->cbSize
    1868         || cbToWrite == 0)
    1869     {
    1870         rc = VERR_INVALID_PARAMETER;
    1871         goto out;
    1872     }
    1873 
    1874     /* Convert offset to L1, L2 index and cluster offset. */
    1875     qcowConvertLogicalOffset(pImage, uOffset, &idxL1, &idxL2, &offCluster);
    1876 
    1877     /* Clip write size to remain in the cluster. */
    1878     cbToWrite = RT_MIN(cbToWrite, pImage->cbCluster - offCluster);
    1879     Assert(!(cbToWrite % 512));
    1880 
    1881     /* Get offset in image. */
    1882     rc = qcowConvertToImageOffset(pImage, pIoCtx, idxL1, idxL2, offCluster, &offImage);
    1883     if (RT_SUCCESS(rc))
    1884         rc = vdIfIoIntFileWriteUser(pImage->pIfIo, pImage->pStorage,
    1885                                     offImage, pIoCtx, cbToWrite, NULL, NULL);
    1886     else if (rc == VERR_VD_BLOCK_FREE)
    1887     {
    1888         if (   cbToWrite == pImage->cbCluster
    1889             && !(fWrite & VD_WRITE_NO_ALLOC))
    1890         {
    1891             PQCOWL2CACHEENTRY pL2Entry = NULL;
    1892 
    1893             /* Full cluster write to previously unallocated cluster.
    1894              * Allocate cluster and write data. */
    1895             Assert(!offCluster);
    1896 
    1897             do
     1703    AssertReturn((VALID_PTR(pIoCtx) && cbToWrite), VERR_INVALID_PARAMETER);
     1704    AssertReturn(uOffset + cbToWrite <= pImage->cbSize, VERR_INVALID_PARAMETER);
     1705
     1706    if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
     1707    {
     1708        /* Convert offset to L1, L2 index and cluster offset. */
     1709        qcowConvertLogicalOffset(pImage, uOffset, &idxL1, &idxL2, &offCluster);
     1710
     1711        /* Clip write size to remain in the cluster. */
     1712        cbToWrite = RT_MIN(cbToWrite, pImage->cbCluster - offCluster);
     1713        Assert(!(cbToWrite % 512));
     1714
     1715        /* Get offset in image. */
     1716        rc = qcowConvertToImageOffset(pImage, pIoCtx, idxL1, idxL2, offCluster, &offImage);
     1717        if (RT_SUCCESS(rc))
     1718            rc = vdIfIoIntFileWriteUser(pImage->pIfIo, pImage->pStorage,
     1719                                        offImage, pIoCtx, cbToWrite, NULL, NULL);
     1720        else if (rc == VERR_VD_BLOCK_FREE)
     1721        {
     1722            if (   cbToWrite == pImage->cbCluster
     1723                && !(fWrite & VD_WRITE_NO_ALLOC))
    18981724            {
    1899                 /* Check if we have to allocate a new cluster for L2 tables. */
    1900                 if (!pImage->paL1Table[idxL1])
     1725                PQCOWL2CACHEENTRY pL2Entry = NULL;
     1726
     1727                /* Full cluster write to previously unallocated cluster.
     1728                 * Allocate cluster and write data. */
     1729                Assert(!offCluster);
     1730
     1731                do
    19011732                {
    1902                     uint64_t offL2Tbl;
    1903                     PQCOWCLUSTERASYNCALLOC pL2ClusterAlloc = NULL;
    1904 
    1905                     /* Allocate new async cluster allocation state. */
    1906                     pL2ClusterAlloc = (PQCOWCLUSTERASYNCALLOC)RTMemAllocZ(sizeof(QCOWCLUSTERASYNCALLOC));
    1907                     if (RT_UNLIKELY(!pL2ClusterAlloc))
     1733                    /* Check if we have to allocate a new cluster for L2 tables. */
     1734                    if (!pImage->paL1Table[idxL1])
    19081735                    {
    1909                         rc = VERR_NO_MEMORY;
    1910                         break;
    1911                     }
    1912 
    1913                     pL2Entry = qcowL2TblCacheEntryAlloc(pImage);
    1914                     if (!pL2Entry)
    1915                     {
    1916                         rc = VERR_NO_MEMORY;
    1917                         RTMemFree(pL2ClusterAlloc);
    1918                         break;
    1919                     }
    1920 
    1921                     offL2Tbl = qcowClusterAllocate(pImage, qcowByte2Cluster(pImage, pImage->cbL2Table));
    1922                     pL2Entry->offL2Tbl = offL2Tbl;
    1923                     memset(pL2Entry->paL2Tbl, 0, pImage->cbL2Table);
    1924 
    1925                     pL2ClusterAlloc->enmAllocState     = QCOWCLUSTERASYNCALLOCSTATE_L2_ALLOC;
    1926                     pL2ClusterAlloc->offNextClusterOld = offL2Tbl;
    1927                     pL2ClusterAlloc->offClusterNew     = offL2Tbl;
    1928                     pL2ClusterAlloc->idxL1             = idxL1;
    1929                     pL2ClusterAlloc->idxL2             = idxL2;
    1930                     pL2ClusterAlloc->cbToWrite         = cbToWrite;
    1931                     pL2ClusterAlloc->pL2Entry          = pL2Entry;
    1932 
    1933                     /*
    1934                      * Write the L2 table first and link to the L1 table afterwards.
    1935                      * If something unexpected happens the worst case which can happen
    1936                      * is a leak of some clusters.
    1937                      */
    1938                     rc = vdIfIoIntFileWriteMeta(pImage->pIfIo, pImage->pStorage,
    1939                                                 offL2Tbl, pL2Entry->paL2Tbl, pImage->cbL2Table, pIoCtx,
    1940                                                 qcowAsyncClusterAllocUpdate, pL2ClusterAlloc);
    1941                     if (rc == VERR_VD_ASYNC_IO_IN_PROGRESS)
    1942                         break;
    1943                     else if (RT_FAILURE(rc))
    1944                     {
    1945                         RTMemFree(pL2ClusterAlloc);
    1946                         qcowL2TblCacheEntryFree(pImage, pL2Entry);
    1947                         break;
    1948                     }
    1949 
    1950                     rc = qcowAsyncClusterAllocUpdate(pImage, pIoCtx, pL2ClusterAlloc, rc);
    1951                 }
    1952                 else
    1953                 {
    1954                     rc = qcowL2TblCacheFetch(pImage, pIoCtx, pImage->paL1Table[idxL1],
    1955                                              &pL2Entry);
    1956                     if (RT_SUCCESS(rc))
    1957                     {
    1958                         PQCOWCLUSTERASYNCALLOC pDataClusterAlloc = NULL;
     1736                        uint64_t offL2Tbl;
     1737                        PQCOWCLUSTERASYNCALLOC pL2ClusterAlloc = NULL;
    19591738
    19601739                        /* Allocate new async cluster allocation state. */
    1961                         pDataClusterAlloc = (PQCOWCLUSTERASYNCALLOC)RTMemAllocZ(sizeof(QCOWCLUSTERASYNCALLOC));
    1962                         if (RT_UNLIKELY(!pDataClusterAlloc))
     1740                        pL2ClusterAlloc = (PQCOWCLUSTERASYNCALLOC)RTMemAllocZ(sizeof(QCOWCLUSTERASYNCALLOC));
     1741                        if (RT_UNLIKELY(!pL2ClusterAlloc))
    19631742                        {
    19641743                            rc = VERR_NO_MEMORY;
     
    19661745                        }
    19671746
    1968                         /* Allocate new cluster for the data. */
    1969                         uint64_t offData = qcowClusterAllocate(pImage, 1);
    1970 
    1971                         pDataClusterAlloc->enmAllocState     = QCOWCLUSTERASYNCALLOCSTATE_USER_ALLOC;
    1972                         pDataClusterAlloc->offNextClusterOld = offData;
    1973                         pDataClusterAlloc->offClusterNew     = offData;
    1974                         pDataClusterAlloc->idxL1             = idxL1;
    1975                         pDataClusterAlloc->idxL2             = idxL2;
    1976                         pDataClusterAlloc->cbToWrite         = cbToWrite;
    1977                         pDataClusterAlloc->pL2Entry          = pL2Entry;
    1978 
    1979                         /* Write data. */
    1980                         rc = vdIfIoIntFileWriteUser(pImage->pIfIo, pImage->pStorage,
    1981                                                     offData, pIoCtx, cbToWrite,
    1982                                                     qcowAsyncClusterAllocUpdate, pDataClusterAlloc);
     1747                        pL2Entry = qcowL2TblCacheEntryAlloc(pImage);
     1748                        if (!pL2Entry)
     1749                        {
     1750                            rc = VERR_NO_MEMORY;
     1751                            RTMemFree(pL2ClusterAlloc);
     1752                            break;
     1753                        }
     1754
     1755                        offL2Tbl = qcowClusterAllocate(pImage, qcowByte2Cluster(pImage, pImage->cbL2Table));
     1756                        pL2Entry->offL2Tbl = offL2Tbl;
     1757                        memset(pL2Entry->paL2Tbl, 0, pImage->cbL2Table);
     1758
     1759                        pL2ClusterAlloc->enmAllocState     = QCOWCLUSTERASYNCALLOCSTATE_L2_ALLOC;
     1760                        pL2ClusterAlloc->offNextClusterOld = offL2Tbl;
     1761                        pL2ClusterAlloc->offClusterNew     = offL2Tbl;
     1762                        pL2ClusterAlloc->idxL1             = idxL1;
     1763                        pL2ClusterAlloc->idxL2             = idxL2;
     1764                        pL2ClusterAlloc->cbToWrite         = cbToWrite;
     1765                        pL2ClusterAlloc->pL2Entry          = pL2Entry;
     1766
     1767                        /*
     1768                         * Write the L2 table first and link to the L1 table afterwards.
     1769                         * If something unexpected happens the worst case which can happen
     1770                         * is a leak of some clusters.
     1771                         */
     1772                        rc = vdIfIoIntFileWriteMeta(pImage->pIfIo, pImage->pStorage,
     1773                                                    offL2Tbl, pL2Entry->paL2Tbl, pImage->cbL2Table, pIoCtx,
     1774                                                    qcowAsyncClusterAllocUpdate, pL2ClusterAlloc);
    19831775                        if (rc == VERR_VD_ASYNC_IO_IN_PROGRESS)
    19841776                            break;
    19851777                        else if (RT_FAILURE(rc))
    19861778                        {
    1987                             RTMemFree(pDataClusterAlloc);
     1779                            RTMemFree(pL2ClusterAlloc);
     1780                            qcowL2TblCacheEntryFree(pImage, pL2Entry);
    19881781                            break;
    19891782                        }
    19901783
    1991                         rc = qcowAsyncClusterAllocUpdate(pImage, pIoCtx, pDataClusterAlloc, rc);
     1784                        rc = qcowAsyncClusterAllocUpdate(pImage, pIoCtx, pL2ClusterAlloc, rc);
    19921785                    }
    1993                 }
    1994 
    1995             } while (0);
    1996 
    1997             *pcbPreRead = 0;
    1998             *pcbPostRead = 0;
     1786                    else
     1787                    {
     1788                        rc = qcowL2TblCacheFetch(pImage, pIoCtx, pImage->paL1Table[idxL1],
     1789                                                 &pL2Entry);
     1790                        if (RT_SUCCESS(rc))
     1791                        {
     1792                            PQCOWCLUSTERASYNCALLOC pDataClusterAlloc = NULL;
     1793
     1794                            /* Allocate new async cluster allocation state. */
     1795                            pDataClusterAlloc = (PQCOWCLUSTERASYNCALLOC)RTMemAllocZ(sizeof(QCOWCLUSTERASYNCALLOC));
     1796                            if (RT_UNLIKELY(!pDataClusterAlloc))
     1797                            {
     1798                                rc = VERR_NO_MEMORY;
     1799                                break;
     1800                            }
     1801
     1802                            /* Allocate new cluster for the data. */
     1803                            uint64_t offData = qcowClusterAllocate(pImage, 1);
     1804
     1805                            pDataClusterAlloc->enmAllocState     = QCOWCLUSTERASYNCALLOCSTATE_USER_ALLOC;
     1806                            pDataClusterAlloc->offNextClusterOld = offData;
     1807                            pDataClusterAlloc->offClusterNew     = offData;
     1808                            pDataClusterAlloc->idxL1             = idxL1;
     1809                            pDataClusterAlloc->idxL2             = idxL2;
     1810                            pDataClusterAlloc->cbToWrite         = cbToWrite;
     1811                            pDataClusterAlloc->pL2Entry          = pL2Entry;
     1812
     1813                            /* Write data. */
     1814                            rc = vdIfIoIntFileWriteUser(pImage->pIfIo, pImage->pStorage,
     1815                                                        offData, pIoCtx, cbToWrite,
     1816                                                        qcowAsyncClusterAllocUpdate, pDataClusterAlloc);
     1817                            if (rc == VERR_VD_ASYNC_IO_IN_PROGRESS)
     1818                                break;
     1819                            else if (RT_FAILURE(rc))
     1820                            {
     1821                                RTMemFree(pDataClusterAlloc);
     1822                                break;
     1823                            }
     1824
     1825                            rc = qcowAsyncClusterAllocUpdate(pImage, pIoCtx, pDataClusterAlloc, rc);
     1826                        }
     1827                    }
     1828
     1829                } while (0);
     1830
     1831                *pcbPreRead = 0;
     1832                *pcbPostRead = 0;
     1833            }
     1834            else
     1835            {
     1836                /* Trying to do a partial write to an unallocated cluster. Don't do
     1837                 * anything except letting the upper layer know what to do. */
     1838                *pcbPreRead = offCluster;
     1839                *pcbPostRead = pImage->cbCluster - cbToWrite - *pcbPreRead;
     1840            }
    19991841        }
    2000         else
    2001         {
    2002             /* Trying to do a partial write to an unallocated cluster. Don't do
    2003              * anything except letting the upper layer know what to do. */
    2004             *pcbPreRead = offCluster;
    2005             *pcbPostRead = pImage->cbCluster - cbToWrite - *pcbPreRead;
     1842
     1843        if (pcbWriteProcess)
     1844            *pcbWriteProcess = cbToWrite;
     1845    }
     1846    else
     1847        rc = VERR_VD_IMAGE_READ_ONLY;
     1848
     1849    LogFlowFunc(("returns %Rrc\n", rc));
     1850    return rc;
     1851}
     1852
     1853static DECLCALLBACK(int) qcowFlush(void *pBackendData, PVDIOCTX pIoCtx)
     1854{
     1855    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
     1856    PQCOWIMAGE pImage = (PQCOWIMAGE)pBackendData;
     1857    int rc = VINF_SUCCESS;
     1858
     1859    AssertPtr(pImage);
     1860    AssertPtrReturn(pIoCtx, VERR_INVALID_PARAMETER);
     1861
     1862    if (   pImage->pStorage
     1863        && !(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
     1864    {
     1865        QCowHeader Header;
     1866
     1867        rc = qcowTblWrite(pImage, pIoCtx, pImage->offL1Table, pImage->paL1Table,
     1868                          pImage->cbL1Table, pImage->cL1TableEntries, NULL, NULL);
     1869        if (RT_SUCCESS(rc) || rc == VERR_VD_ASYNC_IO_IN_PROGRESS)
     1870        {
     1871            /* Write header. */
     1872            size_t cbHeader = 0;
     1873            qcowHdrConvertFromHostEndianess(pImage, &Header, &cbHeader);
     1874            rc = vdIfIoIntFileWriteMeta(pImage->pIfIo, pImage->pStorage,
     1875                                        0, &Header, cbHeader,
     1876                                        pIoCtx, NULL, NULL);
     1877            if (RT_SUCCESS(rc) || rc == VERR_VD_ASYNC_IO_IN_PROGRESS)
     1878                rc = vdIfIoIntFileFlush(pImage->pIfIo, pImage->pStorage,
     1879                                        pIoCtx, NULL, NULL);
    20061880        }
    20071881    }
    2008 
    2009     if (pcbWriteProcess)
    2010         *pcbWriteProcess = cbToWrite;
    2011 
    2012 
    2013 out:
    2014     LogFlowFunc(("returns %Rrc\n", rc));
    2015     return rc;
    2016 }
    2017 
    2018 static DECLCALLBACK(int) qcowFlush(void *pBackendData, PVDIOCTX pIoCtx)
    2019 {
    2020     LogFlowFunc(("pBackendData=%#p\n", pBackendData));
    2021     PQCOWIMAGE pImage = (PQCOWIMAGE)pBackendData;
    2022     int rc = VINF_SUCCESS;
    2023 
    2024     Assert(pImage);
    2025 
    2026     if (VALID_PTR(pIoCtx))
    2027         rc = qcowFlushImageAsync(pImage, pIoCtx);
    2028     else
    2029         rc = VERR_INVALID_PARAMETER;
    20301882
    20311883    LogFlowFunc(("returns %Rrc\n", rc));
     
    20391891    PQCOWIMAGE pImage = (PQCOWIMAGE)pBackendData;
    20401892
    2041     AssertPtr(pImage);
    2042 
    2043     if (pImage)
    2044         return pImage->uVersion;
    2045     else
    2046         return 0;
     1893    AssertPtrReturn(pImage, 0);
     1894
     1895    return pImage->uVersion;
    20471896}
    20481897
     
    20541903    uint32_t cb = 0;
    20551904
    2056     AssertPtr(pImage);
    2057 
    2058     if (pImage && pImage->pStorage)
     1905    AssertPtrReturn(pImage, 0);
     1906
     1907    if (pImage->pStorage)
    20591908        cb = 512;
    20601909
     
    20701919    uint64_t cb = 0;
    20711920
    2072     AssertPtr(pImage);
    2073 
    2074     if (pImage && pImage->pStorage)
     1921    AssertPtrReturn(pImage, 0);
     1922
     1923    if (pImage->pStorage)
    20751924        cb = pImage->cbSize;
    20761925
     
    20861935    uint64_t cb = 0;
    20871936
    2088     AssertPtr(pImage);
    2089 
    2090     if (pImage)
    2091     {
    2092         uint64_t cbFile;
    2093         if (pImage->pStorage)
    2094         {
    2095             int rc = vdIfIoIntFileGetSize(pImage->pIfIo, pImage->pStorage, &cbFile);
    2096             if (RT_SUCCESS(rc))
    2097                 cb += cbFile;
    2098         }
     1937    AssertPtrReturn(pImage, 0);
     1938
     1939    uint64_t cbFile;
     1940    if (pImage->pStorage)
     1941    {
     1942        int rc = vdIfIoIntFileGetSize(pImage->pIfIo, pImage->pStorage, &cbFile);
     1943        if (RT_SUCCESS(rc))
     1944            cb += cbFile;
    20991945    }
    21001946
     
    21041950
    21051951/** @copydoc VDIMAGEBACKEND::pfnGetPCHSGeometry */
    2106 static DECLCALLBACK(int) qcowGetPCHSGeometry(void *pBackendData,
    2107                               PVDGEOMETRY pPCHSGeometry)
     1952static DECLCALLBACK(int) qcowGetPCHSGeometry(void *pBackendData, PVDGEOMETRY pPCHSGeometry)
    21081953{
    21091954    LogFlowFunc(("pBackendData=%#p pPCHSGeometry=%#p\n", pBackendData, pPCHSGeometry));
    21101955    PQCOWIMAGE pImage = (PQCOWIMAGE)pBackendData;
    2111     int rc;
    2112 
    2113     AssertPtr(pImage);
    2114 
    2115     if (pImage)
    2116     {
    2117         if (pImage->PCHSGeometry.cCylinders)
    2118         {
    2119             *pPCHSGeometry = pImage->PCHSGeometry;
    2120             rc = VINF_SUCCESS;
    2121         }
    2122         else
    2123             rc = VERR_VD_GEOMETRY_NOT_SET;
    2124     }
     1956    int rc = VINF_SUCCESS;
     1957
     1958    AssertPtrReturn(pImage, VERR_VD_NOT_OPENED);
     1959
     1960    if (pImage->PCHSGeometry.cCylinders)
     1961        *pPCHSGeometry = pImage->PCHSGeometry;
    21251962    else
    2126         rc = VERR_VD_NOT_OPENED;
     1963        rc = VERR_VD_GEOMETRY_NOT_SET;
    21271964
    21281965    LogFlowFunc(("returns %Rrc (PCHS=%u/%u/%u)\n", rc, pPCHSGeometry->cCylinders, pPCHSGeometry->cHeads, pPCHSGeometry->cSectors));
     
    21311968
    21321969/** @copydoc VDIMAGEBACKEND::pfnSetPCHSGeometry */
    2133 static DECLCALLBACK(int) qcowSetPCHSGeometry(void *pBackendData,
    2134                               PCVDGEOMETRY pPCHSGeometry)
    2135 {
    2136     LogFlowFunc(("pBackendData=%#p pPCHSGeometry=%#p PCHS=%u/%u/%u\n", pBackendData, pPCHSGeometry, pPCHSGeometry->cCylinders, pPCHSGeometry->cHeads, pPCHSGeometry->cSectors));
    2137     PQCOWIMAGE pImage = (PQCOWIMAGE)pBackendData;
    2138     int rc;
    2139 
    2140     AssertPtr(pImage);
    2141 
    2142     if (pImage)
    2143     {
    2144         if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
    2145         {
    2146             rc = VERR_VD_IMAGE_READ_ONLY;
    2147             goto out;
    2148         }
    2149 
     1970static DECLCALLBACK(int) qcowSetPCHSGeometry(void *pBackendData, PCVDGEOMETRY pPCHSGeometry)
     1971{
     1972    LogFlowFunc(("pBackendData=%#p pPCHSGeometry=%#p PCHS=%u/%u/%u\n",
     1973                 pBackendData, pPCHSGeometry, pPCHSGeometry->cCylinders, pPCHSGeometry->cHeads, pPCHSGeometry->cSectors));
     1974    PQCOWIMAGE pImage = (PQCOWIMAGE)pBackendData;
     1975    int rc = VINF_SUCCESS;
     1976
     1977    AssertPtrReturn(pImage, VERR_VD_NOT_OPENED);
     1978
     1979    if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
     1980        rc = VERR_VD_IMAGE_READ_ONLY;
     1981    else
    21501982        pImage->PCHSGeometry = *pPCHSGeometry;
    2151         rc = VINF_SUCCESS;
    2152     }
     1983
     1984    LogFlowFunc(("returns %Rrc\n", rc));
     1985    return rc;
     1986}
     1987
     1988/** @copydoc VDIMAGEBACKEND::pfnGetLCHSGeometry */
     1989static DECLCALLBACK(int) qcowGetLCHSGeometry(void *pBackendData, PVDGEOMETRY pLCHSGeometry)
     1990{
     1991    LogFlowFunc(("pBackendData=%#p pLCHSGeometry=%#p\n", pBackendData, pLCHSGeometry));
     1992    PQCOWIMAGE pImage = (PQCOWIMAGE)pBackendData;
     1993    int rc = VINF_SUCCESS;
     1994
     1995    AssertPtrReturn(pImage, VERR_VD_NOT_OPENED);
     1996
     1997    if (pImage->LCHSGeometry.cCylinders)
     1998        *pLCHSGeometry = pImage->LCHSGeometry;
    21531999    else
    2154         rc = VERR_VD_NOT_OPENED;
    2155 
    2156 out:
    2157     LogFlowFunc(("returns %Rrc\n", rc));
    2158     return rc;
    2159 }
    2160 
    2161 /** @copydoc VDIMAGEBACKEND::pfnGetLCHSGeometry */
    2162 static DECLCALLBACK(int) qcowGetLCHSGeometry(void *pBackendData,
    2163                               PVDGEOMETRY pLCHSGeometry)
    2164 {
    2165      LogFlowFunc(("pBackendData=%#p pLCHSGeometry=%#p\n", pBackendData, pLCHSGeometry));
    2166     PQCOWIMAGE pImage = (PQCOWIMAGE)pBackendData;
    2167     int rc;
    2168 
    2169     AssertPtr(pImage);
    2170 
    2171     if (pImage)
    2172     {
    2173         if (pImage->LCHSGeometry.cCylinders)
    2174         {
    2175             *pLCHSGeometry = pImage->LCHSGeometry;
    2176             rc = VINF_SUCCESS;
    2177         }
    2178         else
    2179             rc = VERR_VD_GEOMETRY_NOT_SET;
    2180     }
     2000        rc = VERR_VD_GEOMETRY_NOT_SET;
     2001
     2002    LogFlowFunc(("returns %Rrc (LCHS=%u/%u/%u)\n", rc, pLCHSGeometry->cCylinders,
     2003                 pLCHSGeometry->cHeads, pLCHSGeometry->cSectors));
     2004    return rc;
     2005}
     2006
     2007/** @copydoc VDIMAGEBACKEND::pfnSetLCHSGeometry */
     2008static DECLCALLBACK(int) qcowSetLCHSGeometry(void *pBackendData, PCVDGEOMETRY pLCHSGeometry)
     2009{
     2010    LogFlowFunc(("pBackendData=%#p pLCHSGeometry=%#p LCHS=%u/%u/%u\n", pBackendData,
     2011                 pLCHSGeometry, pLCHSGeometry->cCylinders, pLCHSGeometry->cHeads, pLCHSGeometry->cSectors));
     2012    PQCOWIMAGE pImage = (PQCOWIMAGE)pBackendData;
     2013    int rc = VINF_SUCCESS;
     2014
     2015    AssertPtrReturn(pImage, VERR_VD_NOT_OPENED);
     2016
     2017    if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
     2018        rc = VERR_VD_IMAGE_READ_ONLY;
    21812019    else
    2182         rc = VERR_VD_NOT_OPENED;
    2183 
    2184     LogFlowFunc(("returns %Rrc (LCHS=%u/%u/%u)\n", rc, pLCHSGeometry->cCylinders, pLCHSGeometry->cHeads, pLCHSGeometry->cSectors));
    2185     return rc;
    2186 }
    2187 
    2188 /** @copydoc VDIMAGEBACKEND::pfnSetLCHSGeometry */
    2189 static DECLCALLBACK(int) qcowSetLCHSGeometry(void *pBackendData,
    2190                                PCVDGEOMETRY pLCHSGeometry)
    2191 {
    2192     LogFlowFunc(("pBackendData=%#p pLCHSGeometry=%#p LCHS=%u/%u/%u\n", pBackendData, pLCHSGeometry, pLCHSGeometry->cCylinders, pLCHSGeometry->cHeads, pLCHSGeometry->cSectors));
    2193     PQCOWIMAGE pImage = (PQCOWIMAGE)pBackendData;
    2194     int rc;
    2195 
    2196     AssertPtr(pImage);
    2197 
    2198     if (pImage)
    2199     {
    2200         if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
    2201         {
    2202             rc = VERR_VD_IMAGE_READ_ONLY;
    2203             goto out;
    2204         }
    2205 
    22062020        pImage->LCHSGeometry = *pLCHSGeometry;
    2207         rc = VINF_SUCCESS;
    2208     }
    2209     else
    2210         rc = VERR_VD_NOT_OPENED;
    2211 
    2212 out:
     2021
    22132022    LogFlowFunc(("returns %Rrc\n", rc));
    22142023    return rc;
     
    22202029    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
    22212030    PQCOWIMAGE pImage = (PQCOWIMAGE)pBackendData;
    2222     unsigned uImageFlags;
    2223 
    2224     AssertPtr(pImage);
    2225 
    2226     if (pImage)
    2227         uImageFlags = pImage->uImageFlags;
    2228     else
    2229         uImageFlags = 0;
    2230 
    2231     LogFlowFunc(("returns %#x\n", uImageFlags));
    2232     return uImageFlags;
     2031
     2032    AssertPtrReturn(pImage, 0);
     2033
     2034    LogFlowFunc(("returns %#x\n", pImage->uImageFlags));
     2035    return pImage->uImageFlags;
    22332036}
    22342037
     
    22382041    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
    22392042    PQCOWIMAGE pImage = (PQCOWIMAGE)pBackendData;
    2240     unsigned uOpenFlags;
    2241 
    2242     AssertPtr(pImage);
    2243 
    2244     if (pImage)
    2245         uOpenFlags = pImage->uOpenFlags;
    2246     else
    2247         uOpenFlags = 0;
    2248 
    2249     LogFlowFunc(("returns %#x\n", uOpenFlags));
    2250     return uOpenFlags;
     2043
     2044    AssertPtrReturn(pImage, 0);
     2045
     2046    LogFlowFunc(("returns %#x\n", pImage->uOpenFlags));
     2047    return pImage->uOpenFlags;
    22512048}
    22522049
     
    22562053    LogFlowFunc(("pBackendData=%#p\n uOpenFlags=%#x", pBackendData, uOpenFlags));
    22572054    PQCOWIMAGE pImage = (PQCOWIMAGE)pBackendData;
    2258     int rc;
     2055    int rc = VINF_SUCCESS;
    22592056
    22602057    /* Image must be opened and the new flags must be valid. */
    22612058    if (!pImage || (uOpenFlags & ~(  VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO
    2262                                    | VD_OPEN_FLAGS_ASYNC_IO | VD_OPEN_FLAGS_SKIP_CONSISTENCY_CHECKS)))
    2263     {
     2059                                   | VD_OPEN_FLAGS_ASYNC_IO | VD_OPEN_FLAGS_SHAREABLE
     2060                                   | VD_OPEN_FLAGS_SEQUENTIAL | VD_OPEN_FLAGS_SKIP_CONSISTENCY_CHECKS)))
    22642061        rc = VERR_INVALID_PARAMETER;
    2265         goto out;
    2266     }
    2267 
    2268     /* Implement this operation via reopening the image. */
    2269     rc = qcowFreeImage(pImage, false);
    2270     if (RT_FAILURE(rc))
    2271         goto out;
    2272     rc = qcowOpenImage(pImage, uOpenFlags);
    2273 
    2274 out:
     2062    else
     2063    {
     2064        /* Implement this operation via reopening the image. */
     2065        rc = qcowFreeImage(pImage, false);
     2066        if (RT_SUCCESS(rc))
     2067            rc = qcowOpenImage(pImage, uOpenFlags);
     2068    }
     2069
    22752070    LogFlowFunc(("returns %Rrc\n", rc));
    22762071    return rc;
     
    22832078    LogFlowFunc(("pBackendData=%#p pszComment=%#p cbComment=%zu\n", pBackendData, pszComment, cbComment));
    22842079    PQCOWIMAGE pImage = (PQCOWIMAGE)pBackendData;
    2285     int rc;
    2286 
    2287     AssertPtr(pImage);
    2288 
    2289     if (pImage)
    2290         rc = VERR_NOT_SUPPORTED;
    2291     else
    2292         rc = VERR_VD_NOT_OPENED;
    2293 
    2294     LogFlowFunc(("returns %Rrc comment='%s'\n", rc, pszComment));
    2295     return rc;
     2080
     2081    AssertPtrReturn(pImage, VERR_VD_NOT_OPENED);
     2082
     2083    LogFlowFunc(("returns %Rrc comment='%s'\n", VERR_NOT_SUPPORTED, pszComment));
     2084    return VERR_NOT_SUPPORTED;
    22962085}
    22972086
     
    23022091    LogFlowFunc(("pBackendData=%#p pszComment=\"%s\"\n", pBackendData, pszComment));
    23032092    PQCOWIMAGE pImage = (PQCOWIMAGE)pBackendData;
     2093
     2094    AssertPtrReturn(pImage, VERR_VD_NOT_OPENED);
     2095
    23042096    int rc;
    2305 
    2306     AssertPtr(pImage);
    2307 
    2308     if (pImage)
    2309     {
    2310         if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
    2311             rc = VERR_VD_IMAGE_READ_ONLY;
    2312         else
    2313             rc = VERR_NOT_SUPPORTED;
    2314     }
     2097    if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
     2098        rc = VERR_VD_IMAGE_READ_ONLY;
    23152099    else
    2316         rc = VERR_VD_NOT_OPENED;
     2100        rc = VERR_NOT_SUPPORTED;
    23172101
    23182102    LogFlowFunc(("returns %Rrc\n", rc));
     
    23262110    LogFlowFunc(("pBackendData=%#p pUuid=%#p\n", pBackendData, pUuid));
    23272111    PQCOWIMAGE pImage = (PQCOWIMAGE)pBackendData;
    2328     int rc;
    2329 
    2330     AssertPtr(pImage);
    2331 
    2332     if (pImage)
    2333         rc = VERR_NOT_SUPPORTED;
    2334     else
    2335         rc = VERR_VD_NOT_OPENED;
    2336 
    2337     LogFlowFunc(("returns %Rrc (%RTuuid)\n", rc, pUuid));
    2338     return rc;
     2112
     2113    AssertPtrReturn(pImage, VERR_VD_NOT_OPENED);
     2114
     2115    LogFlowFunc(("returns %Rrc (%RTuuid)\n", VERR_NOT_SUPPORTED, pUuid));
     2116    return VERR_NOT_SUPPORTED;
    23392117}
    23402118
     
    23452123    LogFlowFunc(("pBackendData=%#p Uuid=%RTuuid\n", pBackendData, pUuid));
    23462124    PQCOWIMAGE pImage = (PQCOWIMAGE)pBackendData;
     2125
     2126    AssertPtrReturn(pImage, VERR_VD_NOT_OPENED);
     2127
    23472128    int rc;
    2348 
    2349     LogFlowFunc(("%RTuuid\n", pUuid));
    2350     AssertPtr(pImage);
    2351 
    2352     if (pImage)
    2353     {
    2354         if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
    2355             rc = VERR_NOT_SUPPORTED;
    2356         else
    2357             rc = VERR_VD_IMAGE_READ_ONLY;
    2358     }
     2129    if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
     2130        rc = VERR_VD_IMAGE_READ_ONLY;
    23592131    else
    2360         rc = VERR_VD_NOT_OPENED;
     2132        rc = VERR_NOT_SUPPORTED;
    23612133
    23622134    LogFlowFunc(("returns %Rrc\n", rc));
     
    23702142    LogFlowFunc(("pBackendData=%#p pUuid=%#p\n", pBackendData, pUuid));
    23712143    PQCOWIMAGE pImage = (PQCOWIMAGE)pBackendData;
    2372     int rc;
    2373 
    2374     AssertPtr(pImage);
    2375 
    2376     if (pImage)
    2377         rc = VERR_NOT_SUPPORTED;
    2378     else
    2379         rc = VERR_VD_NOT_OPENED;
    2380 
    2381     LogFlowFunc(("returns %Rrc (%RTuuid)\n", rc, pUuid));
    2382     return rc;
     2144
     2145    AssertPtrReturn(pImage, VERR_VD_NOT_OPENED);
     2146
     2147    LogFlowFunc(("returns %Rrc (%RTuuid)\n", VERR_NOT_SUPPORTED, pUuid));
     2148    return VERR_NOT_SUPPORTED;
    23832149}
    23842150
     
    23892155    LogFlowFunc(("pBackendData=%#p Uuid=%RTuuid\n", pBackendData, pUuid));
    23902156    PQCOWIMAGE pImage = (PQCOWIMAGE)pBackendData;
     2157
     2158    AssertPtrReturn(pImage, VERR_VD_NOT_OPENED);
     2159
    23912160    int rc;
    2392 
    2393     AssertPtr(pImage);
    2394 
    2395     if (pImage)
    2396     {
    2397         if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
    2398             rc = VERR_NOT_SUPPORTED;
    2399         else
    2400             rc = VERR_VD_IMAGE_READ_ONLY;
    2401     }
     2161    if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
     2162        rc = VERR_VD_IMAGE_READ_ONLY;
    24022163    else
    2403         rc = VERR_VD_NOT_OPENED;
     2164        rc = VERR_NOT_SUPPORTED;
    24042165
    24052166    LogFlowFunc(("returns %Rrc\n", rc));
     
    24132174    LogFlowFunc(("pBackendData=%#p pUuid=%#p\n", pBackendData, pUuid));
    24142175    PQCOWIMAGE pImage = (PQCOWIMAGE)pBackendData;
    2415     int rc;
    2416 
    2417     AssertPtr(pImage);
    2418 
    2419     if (pImage)
    2420         rc = VERR_NOT_SUPPORTED;
    2421     else
    2422         rc = VERR_VD_NOT_OPENED;
    2423 
    2424     LogFlowFunc(("returns %Rrc (%RTuuid)\n", rc, pUuid));
    2425     return rc;
     2176
     2177    AssertPtrReturn(pImage, VERR_VD_NOT_OPENED);
     2178
     2179    LogFlowFunc(("returns %Rrc (%RTuuid)\n", VERR_NOT_SUPPORTED, pUuid));
     2180    return VERR_NOT_SUPPORTED;
    24262181}
    24272182
     
    24322187    LogFlowFunc(("pBackendData=%#p Uuid=%RTuuid\n", pBackendData, pUuid));
    24332188    PQCOWIMAGE pImage = (PQCOWIMAGE)pBackendData;
     2189
     2190    AssertPtrReturn(pImage, VERR_VD_NOT_OPENED);
     2191
    24342192    int rc;
    2435 
    2436     AssertPtr(pImage);
    2437 
    2438     if (pImage)
    2439     {
    2440         if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
    2441             rc = VERR_NOT_SUPPORTED;
    2442         else
    2443             rc = VERR_VD_IMAGE_READ_ONLY;
    2444     }
     2193    if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
     2194        rc = VERR_VD_IMAGE_READ_ONLY;
    24452195    else
    2446         rc = VERR_VD_NOT_OPENED;
     2196        rc = VERR_NOT_SUPPORTED;
    24472197
    24482198    LogFlowFunc(("returns %Rrc\n", rc));
     
    24562206    LogFlowFunc(("pBackendData=%#p pUuid=%#p\n", pBackendData, pUuid));
    24572207    PQCOWIMAGE pImage = (PQCOWIMAGE)pBackendData;
    2458     int rc;
    2459 
    2460     AssertPtr(pImage);
    2461 
    2462     if (pImage)
    2463         rc = VERR_NOT_SUPPORTED;
    2464     else
    2465         rc = VERR_VD_NOT_OPENED;
    2466 
    2467     LogFlowFunc(("returns %Rrc (%RTuuid)\n", rc, pUuid));
    2468     return rc;
     2208
     2209    AssertPtrReturn(pImage, VERR_VD_NOT_OPENED);
     2210
     2211    LogFlowFunc(("returns %Rrc (%RTuuid)\n", VERR_NOT_SUPPORTED, pUuid));
     2212    return VERR_NOT_SUPPORTED;
    24692213}
    24702214
     
    24752219    LogFlowFunc(("pBackendData=%#p Uuid=%RTuuid\n", pBackendData, pUuid));
    24762220    PQCOWIMAGE pImage = (PQCOWIMAGE)pBackendData;
     2221
     2222    AssertPtrReturn(pImage, VERR_VD_NOT_OPENED);
     2223
    24772224    int rc;
    2478 
    2479     AssertPtr(pImage);
    2480 
    2481     if (pImage)
    2482     {
    2483         if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
    2484             rc = VERR_NOT_SUPPORTED;
    2485         else
    2486             rc = VERR_VD_IMAGE_READ_ONLY;
    2487     }
     2225    if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
     2226        rc = VERR_VD_IMAGE_READ_ONLY;
    24882227    else
    2489         rc = VERR_VD_NOT_OPENED;
     2228        rc = VERR_NOT_SUPPORTED;
    24902229
    24912230    LogFlowFunc(("returns %Rrc\n", rc));
     
    24982237    PQCOWIMAGE pImage = (PQCOWIMAGE)pBackendData;
    24992238
    2500     AssertPtr(pImage);
    2501     if (pImage)
    2502     {
    2503         vdIfErrorMessage(pImage->pIfError, "Header: Geometry PCHS=%u/%u/%u LCHS=%u/%u/%u cSector=%llu\n",
    2504                          pImage->PCHSGeometry.cCylinders, pImage->PCHSGeometry.cHeads, pImage->PCHSGeometry.cSectors,
    2505                          pImage->LCHSGeometry.cCylinders, pImage->LCHSGeometry.cHeads, pImage->LCHSGeometry.cSectors,
    2506                          pImage->cbSize / 512);
    2507     }
     2239    AssertPtrReturnVoid(pImage);
     2240    vdIfErrorMessage(pImage->pIfError, "Header: Geometry PCHS=%u/%u/%u LCHS=%u/%u/%u cbSector=%llu\n",
     2241                     pImage->PCHSGeometry.cCylinders, pImage->PCHSGeometry.cHeads, pImage->PCHSGeometry.cSectors,
     2242                     pImage->LCHSGeometry.cCylinders, pImage->LCHSGeometry.cHeads, pImage->LCHSGeometry.cSectors,
     2243                     pImage->cbSize / 512);
    25082244}
    25092245
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