VirtualBox

Changeset 26986 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Mar 3, 2010 1:26:28 PM (15 years ago)
Author:
vboxsync
Message:

tstVD: Fix crashes due to unitialized pfnMessage callback

Location:
trunk/src/VBox/Devices/Storage
Files:
2 edited

Legend:

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

    r26163 r26986  
    4141
    4242#include <VBox/VBoxHDD-Plugin.h>
    43 
    44 
    45 #define VBOXHDDDISK_SIGNATURE 0x6f0e2a7d
    46 
    47 /** Buffer size used for merging images. */
    48 #define VD_MERGE_BUFFER_SIZE    (16 * _1M)
    49 
    50 /**
    51  * VD async I/O interface storage descriptor.
    52  */
    53 typedef struct VDIASYNCIOSTORAGE
    54 {
    55     /** File handle. */
    56     RTFILE         File;
    57     /** Completion callback. */
    58     PFNVDCOMPLETED pfnCompleted;
    59     /** Thread for async access. */
    60     RTTHREAD       ThreadAsync;
    61 } VDIASYNCIOSTORAGE, *PVDIASYNCIOSTORAGE;
    62 
    63 /**
    64  * VBox HDD Container image descriptor.
    65  */
    66 typedef struct VDIMAGE
    67 {
    68     /** Link to parent image descriptor, if any. */
    69     struct VDIMAGE  *pPrev;
    70     /** Link to child image descriptor, if any. */
    71     struct VDIMAGE  *pNext;
    72     /** Container base filename. (UTF-8) */
    73     char            *pszFilename;
    74     /** Data managed by the backend which keeps the actual info. */
    75     void            *pvBackendData;
    76     /** Cached sanitized image flags. */
    77     unsigned        uImageFlags;
    78     /** Image open flags (only those handled generically in this code and which
    79      * the backends will never ever see). */
    80     unsigned        uOpenFlags;
    81 
    82     /** Function pointers for the various backend methods. */
    83     PCVBOXHDDBACKEND    Backend;
    84 
    85     /** Pointer to list of VD interfaces, per-image. */
    86     PVDINTERFACE        pVDIfsImage;
    87 } VDIMAGE, *PVDIMAGE;
    88 
    89 /**
    90  * uModified bit flags.
    91  */
    92 #define VD_IMAGE_MODIFIED_FLAG                  RT_BIT(0)
    93 #define VD_IMAGE_MODIFIED_FIRST                 RT_BIT(1)
    94 #define VD_IMAGE_MODIFIED_DISABLE_UUID_UPDATE   RT_BIT(2)
    95 
    96 
    97 /**
    98  * VBox HDD Container main structure, private part.
    99  */
    100 struct VBOXHDD
    101 {
    102     /** Structure signature (VBOXHDDDISK_SIGNATURE). */
    103     uint32_t            u32Signature;
    104 
    105     /** Number of opened images. */
    106     unsigned            cImages;
    107 
    108     /** Base image. */
    109     PVDIMAGE            pBase;
    110 
    111     /** Last opened image in the chain.
    112      * The same as pBase if only one image is used. */
    113     PVDIMAGE            pLast;
    114 
    115     /** Flags representing the modification state. */
    116     unsigned            uModified;
    117 
    118     /** Cached size of this disk. */
    119     uint64_t            cbSize;
    120     /** Cached PCHS geometry for this disk. */
    121     PDMMEDIAGEOMETRY    PCHSGeometry;
    122     /** Cached LCHS geometry for this disk. */
    123     PDMMEDIAGEOMETRY    LCHSGeometry;
    124 
    125     /** Pointer to list of VD interfaces, per-disk. */
    126     PVDINTERFACE        pVDIfsDisk;
    127     /** Pointer to the common interface structure for error reporting. */
    128     PVDINTERFACE        pInterfaceError;
    129     /** Pointer to the error interface we use if available. */
    130     PVDINTERFACEERROR   pInterfaceErrorCallbacks;
    131 
    132     /** Fallback async interface. */
    133     VDINTERFACE         VDIAsyncIO;
    134     /** Fallback async I/O interface callback table. */
    135     VDINTERFACEASYNCIO  VDIAsyncIOCallbacks;
    136 };
    137 
    138 
    139 /**
    140  * VBox parent read descriptor, used internally for compaction.
    141  */
    142 typedef struct VDPARENTSTATEDESC
    143 {
    144     /** Pointer to disk descriptor. */
    145     PVBOXHDD pDisk;
    146     /** Pointer to image descriptor. */
    147     PVDIMAGE pImage;
    148 } VDPARENTSTATEDESC, *PVDPARENTSTATEDESC;
     43#include "VBoxHDDInternal.h"
    14944
    15045
     
    283178 * internal: find image by index into the images list.
    284179 */
    285 static PVDIMAGE vdGetImageByNumber(PVBOXHDD pDisk, unsigned nImage)
     180PVDIMAGE vdGetImageByNumber(PVBOXHDD pDisk, unsigned nImage)
    286181{
    287182    PVDIMAGE pImage = pDisk->pBase;
     
    373268 * internal: mark the disk as modified.
    374269 */
    375 static void vdSetModifiedFlag(PVBOXHDD pDisk)
     270void vdSetModifiedFlag(PVBOXHDD pDisk)
    376271{
    377272    pDisk->uModified |= VD_IMAGE_MODIFIED_FLAG;
     
    870765}
    871766
     767/**
     768 * internal: send output to the log (unconditionally).
     769 */
     770void vdLogError(void *pvUser, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va)
     771{
     772    NOREF(pvUser);
     773    RTLogPrintf("Error occurred: %Rrc\n", rc);
     774    RTLogPrintf(pszFormat, va);
     775}
    872776
    873777/**
     
    1044948            if (pDisk->pInterfaceError)
    1045949                pDisk->pInterfaceErrorCallbacks = VDGetInterfaceError(pDisk->pInterfaceError);
     950            else
     951            {
     952                /* Provide our own interface */
     953                pDisk->VDIErrorCallbacks.cbSize        = sizeof(VDINTERFACEERROR);
     954                pDisk->VDIErrorCallbacks.enmInterface  = VDINTERFACETYPE_ERROR;
     955                pDisk->VDIErrorCallbacks.pfnMessage    = vdLogMessage;
     956                pDisk->VDIErrorCallbacks.pfnError      = vdLogError;
     957                rc = VDInterfaceAdd(&pDisk->VDIError, "VD_Error", VDINTERFACETYPE_ERROR,
     958                                    &pDisk->VDIErrorCallbacks, pDisk, &pDisk->pVDIfsDisk);
     959                AssertRC(rc);
     960            }
    1046961
    1047962            /* Use the fallback async I/O interface if the caller doesn't provide one. */
     
    37253640}
    37263641
    3727 /**
    3728  * Query if asynchronous operations are supported for this disk.
    3729  *
    3730  * @returns VBox status code.
    3731  * @returns VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
    3732  * @param   pDisk           Pointer to the HDD container.
    3733  * @param   nImage          Image number, counts from 0. 0 is always base image of container.
    3734  * @param   pfAIOSupported  Where to store if async IO is supported.
    3735  */
    3736 VBOXDDU_DECL(int) VDImageIsAsyncIOSupported(PVBOXHDD pDisk, unsigned nImage, bool *pfAIOSupported)
    3737 {
    3738     int rc = VINF_SUCCESS;
    3739 
    3740     LogFlowFunc(("pDisk=%#p nImage=%u pfAIOSupported=%#p\n", pDisk, nImage, pfAIOSupported));
    3741     do
    3742     {
    3743         /* sanity check */
    3744         AssertPtrBreakStmt(pDisk, rc = VERR_INVALID_PARAMETER);
    3745         AssertMsg(pDisk->u32Signature == VBOXHDDDISK_SIGNATURE, ("u32Signature=%08x\n", pDisk->u32Signature));
    3746 
    3747         /* Check arguments. */
    3748         AssertMsgBreakStmt(VALID_PTR(pfAIOSupported),
    3749                            ("pfAIOSupported=%#p\n", pfAIOSupported),
    3750                            rc = VERR_INVALID_PARAMETER);
    3751 
    3752         PVDIMAGE pImage = vdGetImageByNumber(pDisk, nImage);
    3753         AssertPtrBreakStmt(pImage, rc = VERR_VD_IMAGE_NOT_FOUND);
    3754 
    3755         if (pImage->Backend->uBackendCaps & VD_CAP_ASYNC)
    3756             *pfAIOSupported = pImage->Backend->pfnIsAsyncIOSupported(pImage->pvBackendData);
    3757         else
    3758             *pfAIOSupported = false;
    3759     } while (0);
    3760 
    3761     LogFlowFunc(("returns %Rrc, fAIOSupported=%u\n", rc, *pfAIOSupported));
    3762     return rc;
    3763 }
    3764 
    3765 /**
    3766  * Start a asynchronous read request.
    3767  *
    3768  * @returns VBox status code.
    3769  * @param   pDisk           Pointer to the HDD container.
    3770  * @param   uOffset         The offset of the virtual disk to read from.
    3771  * @param   cbRead          How many bytes to read.
    3772  * @param   paSeg           Pointer to an array of segments.
    3773  * @param   cSeg            Number of segments in the array.
    3774  * @param   pvUser          User data which is passed on completion
    3775  */
    3776 VBOXDDU_DECL(int) VDAsyncRead(PVBOXHDD pDisk, uint64_t uOffset, size_t cbRead,
    3777                               PPDMDATASEG paSeg, unsigned cSeg,
    3778                               void *pvUser)
    3779 {
    3780     int rc = VERR_VD_BLOCK_FREE;
    3781 
    3782     LogFlowFunc(("pDisk=%#p uOffset=%llu paSeg=%p cSeg=%u cbRead=%zu\n",
    3783                  pDisk, uOffset, paSeg, cSeg, cbRead));
    3784     do
    3785     {
    3786         /* sanity check */
    3787         AssertPtrBreakStmt(pDisk, rc = VERR_INVALID_PARAMETER);
    3788         AssertMsg(pDisk->u32Signature == VBOXHDDDISK_SIGNATURE, ("u32Signature=%08x\n", pDisk->u32Signature));
    3789 
    3790         /* Check arguments. */
    3791         AssertMsgBreakStmt(cbRead,
    3792                            ("cbRead=%zu\n", cbRead),
    3793                            rc = VERR_INVALID_PARAMETER);
    3794         AssertMsgBreakStmt(uOffset + cbRead <= pDisk->cbSize,
    3795                            ("uOffset=%llu cbRead=%zu pDisk->cbSize=%llu\n",
    3796                             uOffset, cbRead, pDisk->cbSize),
    3797                            rc = VERR_INVALID_PARAMETER);
    3798         AssertMsgBreakStmt(VALID_PTR(paSeg),
    3799                            ("paSeg=%#p\n", paSeg),
    3800                            rc = VERR_INVALID_PARAMETER);
    3801         AssertMsgBreakStmt(cSeg,
    3802                            ("cSeg=%zu\n", cSeg),
    3803                            rc = VERR_INVALID_PARAMETER);
    3804 
    3805 
    3806         PVDIMAGE pImage = pDisk->pLast;
    3807         AssertPtrBreakStmt(pImage, rc = VERR_VD_NOT_OPENED);
    3808 
    3809         /* @todo: This does not work for images which do not have all meta data in memory. */
    3810         for (PVDIMAGE pCurrImage = pImage;
    3811              pCurrImage != NULL && rc == VERR_VD_BLOCK_FREE;
    3812              pCurrImage = pCurrImage->pPrev)
    3813         {
    3814             rc = pCurrImage->Backend->pfnAsyncRead(pCurrImage->pvBackendData,
    3815                                                    uOffset, cbRead, paSeg, cSeg,
    3816                                                    pvUser);
    3817         }
    3818 
    3819         /* No image in the chain contains the data for the block. */
    3820         if (rc == VERR_VD_BLOCK_FREE)
    3821         {
    3822             for (unsigned i = 0; i < cSeg && (cbRead > 0); i++)
    3823             {
    3824                 memset(paSeg[i].pvSeg, '\0', paSeg[i].cbSeg);
    3825                 cbRead -= paSeg[i].cbSeg;
    3826             }
    3827             /* Request finished without the need to enqueue a async I/O request. Tell caller. */
    3828             rc = VINF_VD_ASYNC_IO_FINISHED;
    3829         }
    3830 
    3831     } while (0);
    3832 
    3833     LogFlowFunc(("returns %Rrc\n", rc));
    3834     return rc;
    3835 }
    3836 
    3837 
    3838 /**
    3839  * Start a asynchronous write request.
    3840  *
    3841  * @returns VBox status code.
    3842  * @param   pDisk           Pointer to the HDD container.
    3843  * @param   uOffset         The offset of the virtual disk to write to.
    3844  * @param   cbWrtie         How many bytes to write.
    3845  * @param   paSeg           Pointer to an array of segments.
    3846  * @param   cSeg            Number of segments in the array.
    3847  * @param   pvUser          User data which is passed on completion.
    3848  */
    3849 VBOXDDU_DECL(int) VDAsyncWrite(PVBOXHDD pDisk, uint64_t uOffset, size_t cbWrite,
    3850                                PPDMDATASEG paSeg, unsigned cSeg,
    3851                                void *pvUser)
    3852 {
    3853     int rc;
    3854 
    3855     LogFlowFunc(("pDisk=%#p uOffset=%llu paSeg=%p cSeg=%u cbWrite=%zu\n",
    3856                  pDisk, uOffset, paSeg, cSeg, cbWrite));
    3857     do
    3858     {
    3859         /* sanity check */
    3860         AssertPtrBreakStmt(pDisk, rc = VERR_INVALID_PARAMETER);
    3861         AssertMsg(pDisk->u32Signature == VBOXHDDDISK_SIGNATURE, ("u32Signature=%08x\n", pDisk->u32Signature));
    3862 
    3863         /* Check arguments. */
    3864         AssertMsgBreakStmt(cbWrite,
    3865                            ("cbWrite=%zu\n", cbWrite),
    3866                            rc = VERR_INVALID_PARAMETER);
    3867         AssertMsgBreakStmt(uOffset + cbWrite <= pDisk->cbSize,
    3868                            ("uOffset=%llu cbWrite=%zu pDisk->cbSize=%llu\n",
    3869                             uOffset, cbWrite, pDisk->cbSize),
    3870                            rc = VERR_INVALID_PARAMETER);
    3871         AssertMsgBreakStmt(VALID_PTR(paSeg),
    3872                            ("paSeg=%#p\n", paSeg),
    3873                            rc = VERR_INVALID_PARAMETER);
    3874         AssertMsgBreakStmt(cSeg,
    3875                            ("cSeg=%zu\n", cSeg),
    3876                            rc = VERR_INVALID_PARAMETER);
    3877 
    3878 
    3879         PVDIMAGE pImage = pDisk->pLast;
    3880         AssertPtrBreakStmt(pImage, rc = VERR_VD_NOT_OPENED);
    3881 
    3882         vdSetModifiedFlag(pDisk);
    3883         rc = pImage->Backend->pfnAsyncWrite(pImage->pvBackendData,
    3884                                             uOffset, cbWrite,
    3885                                             paSeg, cSeg, pvUser);
    3886     } while (0);
    3887 
    3888     LogFlowFunc(("returns %Rrc\n", rc));
    3889     return rc;
    3890 
    3891 }
    3892 
    38933642#if 0
    38943643/** @copydoc VBOXHDDBACKEND::pfnComposeLocation */
  • trunk/src/VBox/Devices/Storage/VmdkHDDCore.cpp

    r26008 r26986  
    45714571    pImage->pGTCache = NULL;
    45724572    pImage->pDescData = NULL;
    4573     pImage->pVDIfsDisk = NULL;
     4573    pImage->pVDIfsDisk = pVDIfsDisk;
    45744574    /* Descriptors for split images can be pretty large, especially if the
    45754575     * filename is long. So prepare for the worst, and allocate quite some
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