Changeset 38469 in vbox for trunk/include/VBox
- Timestamp:
- Aug 16, 2011 10:34:32 AM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 73520
- Location:
- trunk/include/VBox
- Files:
-
- 2 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vd-cache-plugin.h
r33567 r38469 28 28 29 29 #include <VBox/vd.h> 30 #include <VBox/vd-ifs-internal.h> 30 31 31 32 /** -
trunk/include/VBox/vd-plugin.h
r36633 r38469 28 28 29 29 #include <VBox/vd.h> 30 #include <VBox/vd-ifs-internal.h> 30 31 31 32 -
trunk/include/VBox/vd.h
r38203 r38469 36 36 #include <VBox/types.h> 37 37 #include <VBox/err.h> 38 #include <VBox/vd-ifs.h> 38 39 39 40 RT_C_DECLS_BEGIN … … 266 267 /** @}*/ 267 268 268 /**269 * Supported interface types.270 */271 typedef enum VDINTERFACETYPE272 {273 /** First valid interface. */274 VDINTERFACETYPE_FIRST = 0,275 /** Interface to pass error message to upper layers. Per-disk. */276 VDINTERFACETYPE_ERROR = VDINTERFACETYPE_FIRST,277 /** Interface for I/O operations. Per-image. */278 VDINTERFACETYPE_IO,279 /** Interface for progress notification. Per-operation. */280 VDINTERFACETYPE_PROGRESS,281 /** Interface for configuration information. Per-image. */282 VDINTERFACETYPE_CONFIG,283 /** Interface for TCP network stack. Per-image. */284 VDINTERFACETYPE_TCPNET,285 /** Interface for getting parent image state. Per-operation. */286 VDINTERFACETYPE_PARENTSTATE,287 /** Interface for synchronizing accesses from several threads. Per-disk. */288 VDINTERFACETYPE_THREADSYNC,289 /** Interface for I/O between the generic VBoxHDD code and the backend. Per-image (internal).290 * This interface is completely internal and must not be used elsewhere. */291 VDINTERFACETYPE_IOINT,292 /** invalid interface. */293 VDINTERFACETYPE_INVALID294 } VDINTERFACETYPE;295 296 /**297 * Common structure for all interfaces.298 */299 typedef struct VDINTERFACE300 {301 /** Human readable interface name. */302 const char *pszInterfaceName;303 /** The size of the struct. */304 uint32_t cbSize;305 /** Pointer to the next common interface structure. */306 struct VDINTERFACE *pNext;307 /** Interface type. */308 VDINTERFACETYPE enmInterface;309 /** Opaque user data which is passed on every call. */310 void *pvUser;311 /** Pointer to the function call table of the interface.312 * As this is opaque this must be casted to the right interface313 * struct defined below based on the interface type in enmInterface. */314 void *pCallbacks;315 } VDINTERFACE;316 /** Pointer to a VDINTERFACE. */317 typedef VDINTERFACE *PVDINTERFACE;318 /** Pointer to a const VDINTERFACE. */319 typedef const VDINTERFACE *PCVDINTERFACE;320 321 /**322 * Helper functions to handle interface lists.323 *324 * @note These interface lists are used consistently to pass per-disk,325 * per-image and/or per-operation callbacks. Those three purposes are strictly326 * separate. See the individual interface declarations for what context they327 * apply to. The caller is responsible for ensuring that the lifetime of the328 * interface descriptors is appropriate for the category of interface.329 */330 331 /**332 * Get a specific interface from a list of interfaces specified by the type.333 *334 * @return Pointer to the matching interface or NULL if none was found.335 * @param pVDIfs Pointer to the VD interface list.336 * @param enmInterface Interface to search for.337 */338 DECLINLINE(PVDINTERFACE) VDInterfaceGet(PVDINTERFACE pVDIfs, VDINTERFACETYPE enmInterface)339 {340 AssertMsgReturn( enmInterface >= VDINTERFACETYPE_FIRST341 && enmInterface < VDINTERFACETYPE_INVALID,342 ("enmInterface=%u", enmInterface), NULL);343 344 while (pVDIfs)345 {346 /* Sanity checks. */347 AssertMsgBreak(pVDIfs->cbSize == sizeof(VDINTERFACE),348 ("cbSize=%u\n", pVDIfs->cbSize));349 350 if (pVDIfs->enmInterface == enmInterface)351 return pVDIfs;352 pVDIfs = pVDIfs->pNext;353 }354 355 /* No matching interface was found. */356 return NULL;357 }358 359 /**360 * Add an interface to a list of interfaces.361 *362 * @return VBox status code.363 * @param pInterface Pointer to an unitialized common interface structure.364 * @param pszName Name of the interface.365 * @param enmInterface Type of the interface.366 * @param pCallbacks The callback table of the interface.367 * @param pvUser Opaque user data passed on every function call.368 * @param ppVDIfs Pointer to the VD interface list.369 */370 DECLINLINE(int) VDInterfaceAdd(PVDINTERFACE pInterface, const char *pszName,371 VDINTERFACETYPE enmInterface, void *pCallbacks,372 void *pvUser, PVDINTERFACE *ppVDIfs)373 {374 /* Argument checks. */375 AssertMsgReturn( enmInterface >= VDINTERFACETYPE_FIRST376 && enmInterface < VDINTERFACETYPE_INVALID,377 ("enmInterface=%u", enmInterface), VERR_INVALID_PARAMETER);378 379 AssertMsgReturn(VALID_PTR(pCallbacks),380 ("pCallbacks=%#p", pCallbacks),381 VERR_INVALID_PARAMETER);382 383 AssertMsgReturn(VALID_PTR(ppVDIfs),384 ("pInterfaceList=%#p", ppVDIfs),385 VERR_INVALID_PARAMETER);386 387 /* Fill out interface descriptor. */388 pInterface->cbSize = sizeof(VDINTERFACE);389 pInterface->pszInterfaceName = pszName;390 pInterface->enmInterface = enmInterface;391 pInterface->pCallbacks = pCallbacks;392 pInterface->pvUser = pvUser;393 pInterface->pNext = *ppVDIfs;394 395 /* Remember the new start of the list. */396 *ppVDIfs = pInterface;397 398 return VINF_SUCCESS;399 }400 401 /**402 * Removes an interface from a list of interfaces.403 *404 * @return VBox status code405 * @param pInterface Pointer to an initialized common interface structure to remove.406 * @param ppVDIfs Pointer to the VD interface list to remove from.407 */408 DECLINLINE(int) VDInterfaceRemove(PVDINTERFACE pInterface, PVDINTERFACE *ppVDIfs)409 {410 int rc = VERR_NOT_FOUND;411 412 /* Argument checks. */413 AssertMsgReturn(VALID_PTR(pInterface),414 ("pInterface=%#p", pInterface),415 VERR_INVALID_PARAMETER);416 417 AssertMsgReturn(VALID_PTR(ppVDIfs),418 ("pInterfaceList=%#p", ppVDIfs),419 VERR_INVALID_PARAMETER);420 421 if (*ppVDIfs)422 {423 PVDINTERFACE pPrev = NULL;424 PVDINTERFACE pCurr = *ppVDIfs;425 426 while ( pCurr427 && (pCurr != pInterface))428 {429 pPrev = pCurr;430 pCurr = pCurr->pNext;431 }432 433 /* First interface */434 if (!pPrev)435 {436 *ppVDIfs = pCurr->pNext;437 rc = VINF_SUCCESS;438 }439 else if (pCurr)440 {441 pPrev = pCurr->pNext;442 rc = VINF_SUCCESS;443 }444 }445 446 return rc;447 }448 449 /**450 * Interface to deliver error messages (and also informational messages)451 * to upper layers.452 *453 * Per-disk interface. Optional, but think twice if you want to miss the454 * opportunity of reporting better human-readable error messages.455 */456 typedef struct VDINTERFACEERROR457 {458 /**459 * Size of the error interface.460 */461 uint32_t cbSize;462 463 /**464 * Interface type.465 */466 VDINTERFACETYPE enmInterface;467 468 /**469 * Error message callback. Must be able to accept special IPRT format470 * strings.471 *472 * @param pvUser The opaque data passed on container creation.473 * @param rc The VBox error code.474 * @param RT_SRC_POS_DECL Use RT_SRC_POS.475 * @param pszFormat Error message format string.476 * @param va Error message arguments.477 */478 DECLR3CALLBACKMEMBER(void, pfnError, (void *pvUser, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va));479 480 /**481 * Informational message callback. May be NULL. Used e.g. in482 * VDDumpImages(). Must be able to accept special IPRT format strings.483 *484 * @return VBox status code.485 * @param pvUser The opaque data passed on container creation.486 * @param pszFormat Message format string.487 * @param va Message arguments.488 */489 DECLR3CALLBACKMEMBER(int, pfnMessage, (void *pvUser, const char *pszFormat, va_list va));490 491 } VDINTERFACEERROR, *PVDINTERFACEERROR;492 493 /**494 * Get error interface from opaque callback table.495 *496 * @return Pointer to the callback table.497 * @param pInterface Pointer to the interface descriptor.498 */499 DECLINLINE(PVDINTERFACEERROR) VDGetInterfaceError(PVDINTERFACE pInterface)500 {501 PVDINTERFACEERROR pInterfaceError;502 503 /* Check that the interface descriptor is a error interface. */504 AssertMsgReturn( pInterface->enmInterface == VDINTERFACETYPE_ERROR505 && pInterface->cbSize == sizeof(VDINTERFACE),506 ("Not an error interface"), NULL);507 508 pInterfaceError = (PVDINTERFACEERROR)pInterface->pCallbacks;509 510 /* Do basic checks. */511 AssertMsgReturn( pInterfaceError->cbSize == sizeof(VDINTERFACEERROR)512 && pInterfaceError->enmInterface == VDINTERFACETYPE_ERROR,513 ("A non error callback table attached to a error interface descriptor\n"), NULL);514 515 return pInterfaceError;516 }517 518 /**519 * Completion callback which is called by the interface owner520 * to inform the backend that a task finished.521 *522 * @return VBox status code.523 * @param pvUser Opaque user data which is passed on request submission.524 * @param rcReq Status code of the completed request.525 */526 typedef DECLCALLBACK(int) FNVDCOMPLETED(void *pvUser, int rcReq);527 /** Pointer to FNVDCOMPLETED() */528 typedef FNVDCOMPLETED *PFNVDCOMPLETED;529 530 /**531 * Support interface for I/O532 *533 * Per-image. Optional as input.534 */535 typedef struct VDINTERFACEIO536 {537 /**538 * Size of the I/O interface.539 */540 uint32_t cbSize;541 542 /**543 * Interface type.544 */545 VDINTERFACETYPE enmInterface;546 547 /**548 * Open callback549 *550 * @return VBox status code.551 * @param pvUser The opaque data passed on container creation.552 * @param pszLocation Name of the location to open.553 * @param fOpen Flags for opening the backend.554 * See RTFILE_O_* #defines, inventing another set555 * of open flags is not worth the mapping effort.556 * @param pfnCompleted The callback which is called whenever a task557 * completed. The backend has to pass the user data558 * of the request initiator (ie the one who calls559 * VDAsyncRead or VDAsyncWrite) in pvCompletion560 * if this is NULL.561 * @param ppStorage Where to store the opaque storage handle.562 */563 DECLR3CALLBACKMEMBER(int, pfnOpen, (void *pvUser, const char *pszLocation,564 uint32_t fOpen,565 PFNVDCOMPLETED pfnCompleted,566 void **ppStorage));567 568 /**569 * Close callback.570 *571 * @return VBox status code.572 * @param pvUser The opaque data passed on container creation.573 * @param pStorage The opaque storage handle to close.574 */575 DECLR3CALLBACKMEMBER(int, pfnClose, (void *pvUser, void *pStorage));576 577 /**578 * Delete callback.579 *580 * @return VBox status code.581 * @param pvUser The opaque data passed on container creation.582 * @param pcszFilename Name of the file to delete.583 */584 DECLR3CALLBACKMEMBER(int, pfnDelete, (void *pvUser, const char *pcszFilename));585 586 /**587 * Move callback.588 *589 * @return VBox status code.590 * @param pvUser The opaque data passed on container creation.591 * @param pcszSrc The path to the source file.592 * @param pcszDst The path to the destination file.593 * This file will be created.594 * @param fMove A combination of the RTFILEMOVE_* flags.595 */596 DECLR3CALLBACKMEMBER(int, pfnMove, (void *pvUser, const char *pcszSrc, const char *pcszDst, unsigned fMove));597 598 /**599 * Returns the free space on a disk.600 *601 * @return VBox status code.602 * @param pvUser The opaque data passed on container creation.603 * @param pcszFilename Name of a file to identify the disk.604 * @param pcbFreeSpace Where to store the free space of the disk.605 */606 DECLR3CALLBACKMEMBER(int, pfnGetFreeSpace, (void *pvUser, const char *pcszFilename, int64_t *pcbFreeSpace));607 608 /**609 * Returns the last modification timestamp of a file.610 *611 * @return VBox status code.612 * @param pvUser The opaque data passed on container creation.613 * @param pcszFilename Name of a file to identify the disk.614 * @param pModificationTime Where to store the timestamp of the file.615 */616 DECLR3CALLBACKMEMBER(int, pfnGetModificationTime, (void *pvUser, const char *pcszFilename, PRTTIMESPEC pModificationTime));617 618 /**619 * Returns the size of the opened storage backend.620 *621 * @return VBox status code.622 * @param pvUser The opaque data passed on container creation.623 * @param pStorage The opaque storage handle to close.624 * @param pcbSize Where to store the size of the storage backend.625 */626 DECLR3CALLBACKMEMBER(int, pfnGetSize, (void *pvUser, void *pStorage, uint64_t *pcbSize));627 628 /**629 * Sets the size of the opened storage backend if possible.630 *631 * @return VBox status code.632 * @retval VERR_NOT_SUPPORTED if the backend does not support this operation.633 * @param pvUser The opaque data passed on container creation.634 * @param pStorage The opaque storage handle to close.635 * @param cbSize The new size of the image.636 */637 DECLR3CALLBACKMEMBER(int, pfnSetSize, (void *pvUser, void *pStorage, uint64_t cbSize));638 639 /**640 * Synchronous write callback.641 *642 * @return VBox status code.643 * @param pvUser The opaque data passed on container creation.644 * @param pStorage The storage handle to use.645 * @param uOffset The offset to start from.646 * @param pvBuffer Pointer to the bits need to be written.647 * @param cbBuffer How many bytes to write.648 * @param pcbWritten Where to store how many bytes were actually written.649 */650 DECLR3CALLBACKMEMBER(int, pfnWriteSync, (void *pvUser, void *pStorage, uint64_t uOffset,651 const void *pvBuffer, size_t cbBuffer, size_t *pcbWritten));652 653 /**654 * Synchronous read callback.655 *656 * @return VBox status code.657 * @param pvUser The opaque data passed on container creation.658 * @param pStorage The storage handle to use.659 * @param uOffset The offset to start from.660 * @param pvBuffer Where to store the read bits.661 * @param cbBuffer How many bytes to read.662 * @param pcbRead Where to store how many bytes were actually read.663 */664 DECLR3CALLBACKMEMBER(int, pfnReadSync, (void *pvUser, void *pStorage, uint64_t uOffset,665 void *pvBuffer, size_t cbBuffer, size_t *pcbRead));666 667 /**668 * Flush data to the storage backend.669 *670 * @return VBox status code.671 * @param pvUser The opaque data passed on container creation.672 * @param pStorage The storage handle to flush.673 */674 DECLR3CALLBACKMEMBER(int, pfnFlushSync, (void *pvUser, void *pStorage));675 676 /**677 * Initiate an asynchronous read request.678 *679 * @return VBox status code.680 * @param pvUser The opaque user data passed on container creation.681 * @param pStorage The storage handle.682 * @param uOffset The offset to start reading from.683 * @param paSegments Scatter gather list to store the data in.684 * @param cSegments Number of segments in the list.685 * @param cbRead How many bytes to read.686 * @param pvCompletion The opaque user data which is returned upon completion.687 * @param ppTask Where to store the opaque task handle.688 */689 DECLR3CALLBACKMEMBER(int, pfnReadAsync, (void *pvUser, void *pStorage, uint64_t uOffset,690 PCRTSGSEG paSegments, size_t cSegments,691 size_t cbRead, void *pvCompletion,692 void **ppTask));693 694 /**695 * Initiate an asynchronous write request.696 *697 * @return VBox status code.698 * @param pvUser The opaque user data passed on conatiner creation.699 * @param pStorage The storage handle.700 * @param uOffset The offset to start writing to.701 * @param paSegments Scatter gather list of the data to write702 * @param cSegments Number of segments in the list.703 * @param cbWrite How many bytes to write.704 * @param pvCompletion The opaque user data which is returned upon completion.705 * @param ppTask Where to store the opaque task handle.706 */707 DECLR3CALLBACKMEMBER(int, pfnWriteAsync, (void *pvUser, void *pStorage, uint64_t uOffset,708 PCRTSGSEG paSegments, size_t cSegments,709 size_t cbWrite, void *pvCompletion,710 void **ppTask));711 712 /**713 * Initiates an async flush request.714 *715 * @return VBox status code.716 * @param pvUser The opaque data passed on container creation.717 * @param pStorage The storage handle to flush.718 * @param pvCompletion The opaque user data which is returned upon completion.719 * @param ppTask Where to store the opaque task handle.720 */721 DECLR3CALLBACKMEMBER(int, pfnFlushAsync, (void *pvUser, void *pStorage,722 void *pvCompletion, void **ppTask));723 724 } VDINTERFACEIO, *PVDINTERFACEIO;725 726 /**727 * Get I/O interface from opaque callback table.728 *729 * @return Pointer to the callback table.730 * @param pInterface Pointer to the interface descriptor.731 */732 DECLINLINE(PVDINTERFACEIO) VDGetInterfaceIO(PVDINTERFACE pInterface)733 {734 PVDINTERFACEIO pInterfaceIO;735 736 /* Check that the interface descriptor is an I/O interface. */737 AssertMsgReturn( (pInterface->enmInterface == VDINTERFACETYPE_IO)738 && (pInterface->cbSize == sizeof(VDINTERFACE)),739 ("Not an I/O interface"), NULL);740 741 pInterfaceIO = (PVDINTERFACEIO)pInterface->pCallbacks;742 743 /* Do basic checks. */744 AssertMsgReturn( (pInterfaceIO->cbSize == sizeof(VDINTERFACEIO))745 && (pInterfaceIO->enmInterface == VDINTERFACETYPE_IO),746 ("A non I/O callback table attached to an I/O interface descriptor\n"), NULL);747 748 return pInterfaceIO;749 }750 751 /**752 * Callback which provides progress information about a currently running753 * lengthy operation.754 *755 * @return VBox status code.756 * @param pvUser The opaque user data associated with this interface.757 * @param uPercent Completion percentage.758 */759 typedef DECLCALLBACK(int) FNVDPROGRESS(void *pvUser, unsigned uPercentage);760 /** Pointer to FNVDPROGRESS() */761 typedef FNVDPROGRESS *PFNVDPROGRESS;762 763 /**764 * Progress notification interface765 *766 * Per-operation. Optional.767 */768 typedef struct VDINTERFACEPROGRESS769 {770 /**771 * Size of the progress interface.772 */773 uint32_t cbSize;774 775 /**776 * Interface type.777 */778 VDINTERFACETYPE enmInterface;779 780 /**781 * Progress notification callbacks.782 */783 PFNVDPROGRESS pfnProgress;784 785 } VDINTERFACEPROGRESS, *PVDINTERFACEPROGRESS;786 787 /**788 * Get progress interface from opaque callback table.789 *790 * @return Pointer to the callback table.791 * @param pInterface Pointer to the interface descriptor.792 */793 DECLINLINE(PVDINTERFACEPROGRESS) VDGetInterfaceProgress(PVDINTERFACE pInterface)794 {795 PVDINTERFACEPROGRESS pInterfaceProgress;796 797 /* Check that the interface descriptor is a progress interface. */798 AssertMsgReturn( (pInterface->enmInterface == VDINTERFACETYPE_PROGRESS)799 && (pInterface->cbSize == sizeof(VDINTERFACE)),800 ("Not a progress interface"), NULL);801 802 803 pInterfaceProgress = (PVDINTERFACEPROGRESS)pInterface->pCallbacks;804 805 /* Do basic checks. */806 AssertMsgReturn( (pInterfaceProgress->cbSize == sizeof(VDINTERFACEPROGRESS))807 && (pInterfaceProgress->enmInterface == VDINTERFACETYPE_PROGRESS),808 ("A non progress callback table attached to a progress interface descriptor\n"), NULL);809 810 return pInterfaceProgress;811 }812 813 814 /**815 * Configuration information interface816 *817 * Per-image. Optional for most backends, but mandatory for images which do818 * not operate on files (including standard block or character devices).819 */820 typedef struct VDINTERFACECONFIG821 {822 /**823 * Size of the configuration interface.824 */825 uint32_t cbSize;826 827 /**828 * Interface type.829 */830 VDINTERFACETYPE enmInterface;831 832 /**833 * Validates that the keys are within a set of valid names.834 *835 * @return true if all key names are found in pszzAllowed.836 * @return false if not.837 * @param pvUser The opaque user data associated with this interface.838 * @param pszzValid List of valid key names separated by '\\0' and ending with839 * a double '\\0'.840 */841 DECLR3CALLBACKMEMBER(bool, pfnAreKeysValid, (void *pvUser, const char *pszzValid));842 843 /**844 * Retrieves the length of the string value associated with a key (including845 * the terminator, for compatibility with CFGMR3QuerySize).846 *847 * @return VBox status code.848 * VERR_CFGM_VALUE_NOT_FOUND means that the key is not known.849 * @param pvUser The opaque user data associated with this interface.850 * @param pszName Name of the key to query.851 * @param pcbValue Where to store the value length. Non-NULL.852 */853 DECLR3CALLBACKMEMBER(int, pfnQuerySize, (void *pvUser, const char *pszName, size_t *pcbValue));854 855 /**856 * Query the string value associated with a key.857 *858 * @return VBox status code.859 * VERR_CFGM_VALUE_NOT_FOUND means that the key is not known.860 * VERR_CFGM_NOT_ENOUGH_SPACE means that the buffer is not big enough.861 * @param pvUser The opaque user data associated with this interface.862 * @param pszName Name of the key to query.863 * @param pszValue Pointer to buffer where to store value.864 * @param cchValue Length of value buffer.865 */866 DECLR3CALLBACKMEMBER(int, pfnQuery, (void *pvUser, const char *pszName, char *pszValue, size_t cchValue));867 868 } VDINTERFACECONFIG, *PVDINTERFACECONFIG;869 870 /**871 * Get configuration information interface from opaque callback table.872 *873 * @return Pointer to the callback table.874 * @param pInterface Pointer to the interface descriptor.875 */876 DECLINLINE(PVDINTERFACECONFIG) VDGetInterfaceConfig(PVDINTERFACE pInterface)877 {878 PVDINTERFACECONFIG pInterfaceConfig;879 880 /* Check that the interface descriptor is a config interface. */881 AssertMsgReturn( (pInterface->enmInterface == VDINTERFACETYPE_CONFIG)882 && (pInterface->cbSize == sizeof(VDINTERFACE)),883 ("Not a config interface"), NULL);884 885 pInterfaceConfig = (PVDINTERFACECONFIG)pInterface->pCallbacks;886 887 /* Do basic checks. */888 AssertMsgReturn( (pInterfaceConfig->cbSize == sizeof(VDINTERFACECONFIG))889 && (pInterfaceConfig->enmInterface == VDINTERFACETYPE_CONFIG),890 ("A non config callback table attached to a config interface descriptor\n"), NULL);891 892 return pInterfaceConfig;893 }894 895 /**896 * Query configuration, validates that the keys are within a set of valid names.897 *898 * @return true if all key names are found in pszzAllowed.899 * @return false if not.900 * @param pCfgIf Pointer to configuration callback table.901 * @param pvUser The opaque user data associated with this interface.902 * @param pszzValid List of valid names separated by '\\0' and ending with903 * a double '\\0'.904 */905 DECLINLINE(bool) VDCFGAreKeysValid(PVDINTERFACECONFIG pCfgIf, void *pvUser,906 const char *pszzValid)907 {908 return pCfgIf->pfnAreKeysValid(pvUser, pszzValid);909 }910 911 /**912 * Query configuration, unsigned 64-bit integer value with default.913 *914 * @return VBox status code.915 * @param pCfgIf Pointer to configuration callback table.916 * @param pvUser The opaque user data associated with this interface.917 * @param pszName Name of an integer value918 * @param pu64 Where to store the value. Set to default on failure.919 * @param u64Def The default value.920 */921 DECLINLINE(int) VDCFGQueryU64Def(PVDINTERFACECONFIG pCfgIf, void *pvUser,922 const char *pszName, uint64_t *pu64,923 uint64_t u64Def)924 {925 char aszBuf[32];926 int rc = pCfgIf->pfnQuery(pvUser, pszName, aszBuf, sizeof(aszBuf));927 if (RT_SUCCESS(rc))928 {929 rc = RTStrToUInt64Full(aszBuf, 0, pu64);930 }931 else if (rc == VERR_CFGM_VALUE_NOT_FOUND)932 {933 rc = VINF_SUCCESS;934 *pu64 = u64Def;935 }936 return rc;937 }938 939 /**940 * Query configuration, unsigned 32-bit integer value with default.941 *942 * @return VBox status code.943 * @param pCfgIf Pointer to configuration callback table.944 * @param pvUser The opaque user data associated with this interface.945 * @param pszName Name of an integer value946 * @param pu32 Where to store the value. Set to default on failure.947 * @param u32Def The default value.948 */949 DECLINLINE(int) VDCFGQueryU32Def(PVDINTERFACECONFIG pCfgIf, void *pvUser,950 const char *pszName, uint32_t *pu32,951 uint32_t u32Def)952 {953 uint64_t u64;954 int rc = VDCFGQueryU64Def(pCfgIf, pvUser, pszName, &u64, u32Def);955 if (RT_SUCCESS(rc))956 {957 if (!(u64 & UINT64_C(0xffffffff00000000)))958 *pu32 = (uint32_t)u64;959 else960 rc = VERR_CFGM_INTEGER_TOO_BIG;961 }962 return rc;963 }964 965 /**966 * Query configuration, bool value with default.967 *968 * @return VBox status code.969 * @param pCfgIf Pointer to configuration callback table.970 * @param pvUser The opaque user data associated with this interface.971 * @param pszName Name of an integer value972 * @param pf Where to store the value. Set to default on failure.973 * @param fDef The default value.974 */975 DECLINLINE(int) VDCFGQueryBoolDef(PVDINTERFACECONFIG pCfgIf, void *pvUser,976 const char *pszName, bool *pf,977 bool fDef)978 {979 uint64_t u64;980 int rc = VDCFGQueryU64Def(pCfgIf, pvUser, pszName, &u64, fDef);981 if (RT_SUCCESS(rc))982 *pf = u64 ? true : false;983 return rc;984 }985 986 /**987 * Query configuration, dynamically allocated (RTMemAlloc) zero terminated988 * character value.989 *990 * @return VBox status code.991 * @param pCfgIf Pointer to configuration callback table.992 * @param pvUser The opaque user data associated with this interface.993 * @param pszName Name of an zero terminated character value994 * @param ppszString Where to store the string pointer. Not set on failure.995 * Free this using RTMemFree().996 */997 DECLINLINE(int) VDCFGQueryStringAlloc(PVDINTERFACECONFIG pCfgIf,998 void *pvUser, const char *pszName,999 char **ppszString)1000 {1001 size_t cb;1002 int rc = pCfgIf->pfnQuerySize(pvUser, pszName, &cb);1003 if (RT_SUCCESS(rc))1004 {1005 char *pszString = (char *)RTMemAlloc(cb);1006 if (pszString)1007 {1008 rc = pCfgIf->pfnQuery(pvUser, pszName, pszString, cb);1009 if (RT_SUCCESS(rc))1010 *ppszString = pszString;1011 else1012 RTMemFree(pszString);1013 }1014 else1015 rc = VERR_NO_MEMORY;1016 }1017 return rc;1018 }1019 1020 /**1021 * Query configuration, dynamically allocated (RTMemAlloc) zero terminated1022 * character value with default.1023 *1024 * @return VBox status code.1025 * @param pCfgIf Pointer to configuration callback table.1026 * @param pvUser The opaque user data associated with this interface.1027 * @param pszName Name of an zero terminated character value1028 * @param ppszString Where to store the string pointer. Not set on failure.1029 * Free this using RTMemFree().1030 * @param pszDef The default value.1031 */1032 DECLINLINE(int) VDCFGQueryStringAllocDef(PVDINTERFACECONFIG pCfgIf,1033 void *pvUser, const char *pszName,1034 char **ppszString,1035 const char *pszDef)1036 {1037 size_t cb;1038 int rc = pCfgIf->pfnQuerySize(pvUser, pszName, &cb);1039 if (rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT)1040 {1041 cb = strlen(pszDef) + 1;1042 rc = VINF_SUCCESS;1043 }1044 if (RT_SUCCESS(rc))1045 {1046 char *pszString = (char *)RTMemAlloc(cb);1047 if (pszString)1048 {1049 rc = pCfgIf->pfnQuery(pvUser, pszName, pszString, cb);1050 if (rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT)1051 {1052 memcpy(pszString, pszDef, cb);1053 rc = VINF_SUCCESS;1054 }1055 if (RT_SUCCESS(rc))1056 *ppszString = pszString;1057 else1058 RTMemFree(pszString);1059 }1060 else1061 rc = VERR_NO_MEMORY;1062 }1063 return rc;1064 }1065 1066 /**1067 * Query configuration, dynamically allocated (RTMemAlloc) byte string value.1068 *1069 * @return VBox status code.1070 * @param pCfgIf Pointer to configuration callback table.1071 * @param pvUser The opaque user data associated with this interface.1072 * @param pszName Name of an zero terminated character value1073 * @param ppvData Where to store the byte string pointer. Not set on failure.1074 * Free this using RTMemFree().1075 * @param pcbData Where to store the byte string length.1076 */1077 DECLINLINE(int) VDCFGQueryBytesAlloc(PVDINTERFACECONFIG pCfgIf,1078 void *pvUser, const char *pszName,1079 void **ppvData, size_t *pcbData)1080 {1081 size_t cb;1082 int rc = pCfgIf->pfnQuerySize(pvUser, pszName, &cb);1083 if (RT_SUCCESS(rc))1084 {1085 char *pbData;1086 Assert(cb);1087 1088 pbData = (char *)RTMemAlloc(cb);1089 if (pbData)1090 {1091 rc = pCfgIf->pfnQuery(pvUser, pszName, pbData, cb);1092 if (RT_SUCCESS(rc))1093 {1094 *ppvData = pbData;1095 *pcbData = cb - 1; /* Exclude terminator of the queried string. */1096 }1097 else1098 RTMemFree(pbData);1099 }1100 else1101 rc = VERR_NO_MEMORY;1102 }1103 return rc;1104 }1105 1106 /** Forward declaration of a VD socket. */1107 typedef struct VDSOCKETINT *VDSOCKET;1108 /** Pointer to a VD socket. */1109 typedef VDSOCKET *PVDSOCKET;1110 /** Nil socket handle. */1111 #define NIL_VDSOCKET ((VDSOCKET)0)1112 1113 /** Connect flag to indicate that the backend wants to use the extended1114 * socket I/O multiplexing call. This might not be supported on all configurations1115 * (internal networking and iSCSI)1116 * and the backend needs to take appropriate action.1117 */1118 #define VD_INTERFACETCPNET_CONNECT_EXTENDED_SELECT RT_BIT_32(0)1119 1120 /** @name Select events1121 * @{ */1122 /** Readable without blocking. */1123 #define VD_INTERFACETCPNET_EVT_READ RT_BIT_32(0)1124 /** Writable without blocking. */1125 #define VD_INTERFACETCPNET_EVT_WRITE RT_BIT_32(1)1126 /** Error condition, hangup, exception or similar. */1127 #define VD_INTERFACETCPNET_EVT_ERROR RT_BIT_32(2)1128 /** Hint for the select that getting interrupted while waiting is more likely.1129 * The interface implementation can optimize the waiting strategy based on this.1130 * It is assumed that it is more likely to get one of the above socket events1131 * instead of being interrupted if the flag is not set. */1132 #define VD_INTERFACETCPNET_HINT_INTERRUPT RT_BIT_32(3)1133 /** Mask of the valid bits. */1134 #define VD_INTERFACETCPNET_EVT_VALID_MASK UINT32_C(0x0000000f)1135 /** @} */1136 1137 /**1138 * TCP network stack interface1139 *1140 * Per-image. Mandatory for backends which have the VD_CAP_TCPNET bit set.1141 */1142 typedef struct VDINTERFACETCPNET1143 {1144 /**1145 * Size of the configuration interface.1146 */1147 uint32_t cbSize;1148 1149 /**1150 * Interface type.1151 */1152 VDINTERFACETYPE enmInterface;1153 1154 /**1155 * Creates a socket. The socket is not connected if this succeeds.1156 *1157 * @return iprt status code.1158 * @retval VERR_NOT_SUPPORTED if the combination of flags is not supported.1159 * @param fFlags Combination of the VD_INTERFACETCPNET_CONNECT_* #defines.1160 * @param pSock Where to store the handle.1161 */1162 DECLR3CALLBACKMEMBER(int, pfnSocketCreate, (uint32_t fFlags, PVDSOCKET pSock));1163 1164 /**1165 * Destroys the socket.1166 *1167 * @return iprt status code.1168 * @param Sock Socket descriptor.1169 */1170 DECLR3CALLBACKMEMBER(int, pfnSocketDestroy, (VDSOCKET Sock));1171 1172 /**1173 * Connect as a client to a TCP port.1174 *1175 * @return iprt status code.1176 * @param Sock Socket descriptor.1177 * @param pszAddress The address to connect to.1178 * @param uPort The port to connect to.1179 */1180 DECLR3CALLBACKMEMBER(int, pfnClientConnect, (VDSOCKET Sock, const char *pszAddress, uint32_t uPort));1181 1182 /**1183 * Close a TCP connection.1184 *1185 * @return iprt status code.1186 * @param Sock Socket descriptor.1187 */1188 DECLR3CALLBACKMEMBER(int, pfnClientClose, (VDSOCKET Sock));1189 1190 /**1191 * Returns whether the socket is currently connected to the client.1192 *1193 * @returns true if the socket is connected.1194 * false otherwise.1195 * @param Sock Socket descriptor.1196 */1197 DECLR3CALLBACKMEMBER(bool, pfnIsClientConnected, (VDSOCKET Sock));1198 1199 /**1200 * Socket I/O multiplexing.1201 * Checks if the socket is ready for reading.1202 *1203 * @return iprt status code.1204 * @param Sock Socket descriptor.1205 * @param cMillies Number of milliseconds to wait for the socket.1206 * Use RT_INDEFINITE_WAIT to wait for ever.1207 */1208 DECLR3CALLBACKMEMBER(int, pfnSelectOne, (VDSOCKET Sock, RTMSINTERVAL cMillies));1209 1210 /**1211 * Receive data from a socket.1212 *1213 * @return iprt status code.1214 * @param Sock Socket descriptor.1215 * @param pvBuffer Where to put the data we read.1216 * @param cbBuffer Read buffer size.1217 * @param pcbRead Number of bytes read.1218 * If NULL the entire buffer will be filled upon successful return.1219 * If not NULL a partial read can be done successfully.1220 */1221 DECLR3CALLBACKMEMBER(int, pfnRead, (VDSOCKET Sock, void *pvBuffer, size_t cbBuffer, size_t *pcbRead));1222 1223 /**1224 * Send data to a socket.1225 *1226 * @return iprt status code.1227 * @param Sock Socket descriptor.1228 * @param pvBuffer Buffer to write data to socket.1229 * @param cbBuffer How much to write.1230 */1231 DECLR3CALLBACKMEMBER(int, pfnWrite, (VDSOCKET Sock, const void *pvBuffer, size_t cbBuffer));1232 1233 /**1234 * Send data from scatter/gather buffer to a socket.1235 *1236 * @return iprt status code.1237 * @param Sock Socket descriptor.1238 * @param pSgBuffer Scatter/gather buffer to write data to socket.1239 */1240 DECLR3CALLBACKMEMBER(int, pfnSgWrite, (VDSOCKET Sock, PCRTSGBUF pSgBuffer));1241 1242 /**1243 * Receive data from a socket - not blocking.1244 *1245 * @return iprt status code.1246 * @param Sock Socket descriptor.1247 * @param pvBuffer Where to put the data we read.1248 * @param cbBuffer Read buffer size.1249 * @param pcbRead Number of bytes read.1250 */1251 DECLR3CALLBACKMEMBER(int, pfnReadNB, (VDSOCKET Sock, void *pvBuffer, size_t cbBuffer, size_t *pcbRead));1252 1253 /**1254 * Send data to a socket - not blocking.1255 *1256 * @return iprt status code.1257 * @param Sock Socket descriptor.1258 * @param pvBuffer Buffer to write data to socket.1259 * @param cbBuffer How much to write.1260 * @param pcbWritten Number of bytes written.1261 */1262 DECLR3CALLBACKMEMBER(int, pfnWriteNB, (VDSOCKET Sock, const void *pvBuffer, size_t cbBuffer, size_t *pcbWritten));1263 1264 /**1265 * Send data from scatter/gather buffer to a socket - not blocking.1266 *1267 * @return iprt status code.1268 * @param Sock Socket descriptor.1269 * @param pSgBuffer Scatter/gather buffer to write data to socket.1270 * @param pcbWritten Number of bytes written.1271 */1272 DECLR3CALLBACKMEMBER(int, pfnSgWriteNB, (VDSOCKET Sock, PRTSGBUF pSgBuffer, size_t *pcbWritten));1273 1274 /**1275 * Flush socket write buffers.1276 *1277 * @return iprt status code.1278 * @param Sock Socket descriptor.1279 */1280 DECLR3CALLBACKMEMBER(int, pfnFlush, (VDSOCKET Sock));1281 1282 /**1283 * Enables or disables delaying sends to coalesce packets.1284 *1285 * @return iprt status code.1286 * @param Sock Socket descriptor.1287 * @param fEnable When set to true enables coalescing.1288 */1289 DECLR3CALLBACKMEMBER(int, pfnSetSendCoalescing, (VDSOCKET Sock, bool fEnable));1290 1291 /**1292 * Gets the address of the local side.1293 *1294 * @return iprt status code.1295 * @param Sock Socket descriptor.1296 * @param pAddr Where to store the local address on success.1297 */1298 DECLR3CALLBACKMEMBER(int, pfnGetLocalAddress, (VDSOCKET Sock, PRTNETADDR pAddr));1299 1300 /**1301 * Gets the address of the other party.1302 *1303 * @return iprt status code.1304 * @param Sock Socket descriptor.1305 * @param pAddr Where to store the peer address on success.1306 */1307 DECLR3CALLBACKMEMBER(int, pfnGetPeerAddress, (VDSOCKET Sock, PRTNETADDR pAddr));1308 1309 /**1310 * Socket I/O multiplexing - extended version which can be woken up.1311 * Checks if the socket is ready for reading or writing.1312 *1313 * @return iprt status code.1314 * @retval VERR_INTERRUPTED if the thread was woken up by a pfnPoke call.1315 * @param Sock Socket descriptor.1316 * @param fEvents Mask of events to wait for.1317 * @param pfEvents Where to store the received events.1318 * @param cMillies Number of milliseconds to wait for the socket.1319 * Use RT_INDEFINITE_WAIT to wait for ever.1320 */1321 DECLR3CALLBACKMEMBER(int, pfnSelectOneEx, (VDSOCKET Sock, uint32_t fEvents,1322 uint32_t *pfEvents, RTMSINTERVAL cMillies));1323 1324 /**1325 * Wakes up the thread waiting in pfnSelectOneEx.1326 *1327 * @return iprt status code.1328 * @param Sock Socket descriptor.1329 */1330 DECLR3CALLBACKMEMBER(int, pfnPoke, (VDSOCKET Sock));1331 1332 } VDINTERFACETCPNET, *PVDINTERFACETCPNET;1333 1334 /**1335 * Get TCP network stack interface from opaque callback table.1336 *1337 * @return Pointer to the callback table.1338 * @param pInterface Pointer to the interface descriptor.1339 */1340 DECLINLINE(PVDINTERFACETCPNET) VDGetInterfaceTcpNet(PVDINTERFACE pInterface)1341 {1342 PVDINTERFACETCPNET pInterfaceTcpNet;1343 1344 /* Check that the interface descriptor is a TCP network stack interface. */1345 AssertMsgReturn( (pInterface->enmInterface == VDINTERFACETYPE_TCPNET)1346 && (pInterface->cbSize == sizeof(VDINTERFACE)),1347 ("Not a TCP network stack interface"), NULL);1348 1349 pInterfaceTcpNet = (PVDINTERFACETCPNET)pInterface->pCallbacks;1350 1351 /* Do basic checks. */1352 AssertMsgReturn( (pInterfaceTcpNet->cbSize == sizeof(VDINTERFACETCPNET))1353 && (pInterfaceTcpNet->enmInterface == VDINTERFACETYPE_TCPNET),1354 ("A non TCP network stack callback table attached to a TCP network stack interface descriptor\n"), NULL);1355 1356 return pInterfaceTcpNet;1357 }1358 1359 /**1360 * Interface to get the parent state.1361 *1362 * Per-operation interface. Optional, present only if there is a parent, and1363 * used only internally for compacting.1364 */1365 typedef struct VDINTERFACEPARENTSTATE1366 {1367 /**1368 * Size of the parent state interface.1369 */1370 uint32_t cbSize;1371 1372 /**1373 * Interface type.1374 */1375 VDINTERFACETYPE enmInterface;1376 1377 /**1378 * Read data callback.1379 *1380 * @return VBox status code.1381 * @return VERR_VD_NOT_OPENED if no image is opened in HDD container.1382 * @param pvUser The opaque data passed for the operation.1383 * @param uOffset Offset of first reading byte from start of disk.1384 * Must be aligned to a sector boundary.1385 * @param pvBuffer Pointer to buffer for reading data.1386 * @param cbBuffer Number of bytes to read.1387 * Must be aligned to a sector boundary.1388 */1389 DECLR3CALLBACKMEMBER(int, pfnParentRead, (void *pvUser, uint64_t uOffset, void *pvBuffer, size_t cbBuffer));1390 1391 } VDINTERFACEPARENTSTATE, *PVDINTERFACEPARENTSTATE;1392 1393 1394 /**1395 * Get parent state interface from opaque callback table.1396 *1397 * @return Pointer to the callback table.1398 * @param pInterface Pointer to the interface descriptor.1399 */1400 DECLINLINE(PVDINTERFACEPARENTSTATE) VDGetInterfaceParentState(PVDINTERFACE pInterface)1401 {1402 PVDINTERFACEPARENTSTATE pInterfaceParentState;1403 1404 /* Check that the interface descriptor is a parent state interface. */1405 AssertMsgReturn( (pInterface->enmInterface == VDINTERFACETYPE_PARENTSTATE)1406 && (pInterface->cbSize == sizeof(VDINTERFACE)),1407 ("Not a parent state interface"), NULL);1408 1409 pInterfaceParentState = (PVDINTERFACEPARENTSTATE)pInterface->pCallbacks;1410 1411 /* Do basic checks. */1412 AssertMsgReturn( (pInterfaceParentState->cbSize == sizeof(VDINTERFACEPARENTSTATE))1413 && (pInterfaceParentState->enmInterface == VDINTERFACETYPE_PARENTSTATE),1414 ("A non parent state callback table attached to a parent state interface descriptor\n"), NULL);1415 1416 return pInterfaceParentState;1417 }1418 1419 /**1420 * Interface to synchronize concurrent accesses by several threads.1421 *1422 * @note The scope of this interface is to manage concurrent accesses after1423 * the HDD container has been created, and they must stop before destroying the1424 * container. Opening or closing images is covered by the synchronization, but1425 * that does not mean it is safe to close images while a thread executes1426 * <link to="VDMerge"/> or <link to="VDCopy"/> operating on these images.1427 * Making them safe would require the lock to be held during the entire1428 * operation, which prevents other concurrent acitivities.1429 *1430 * @note Right now this is kept as simple as possible, and does not even1431 * attempt to provide enough information to allow e.g. concurrent write1432 * accesses to different areas of the disk. The reason is that it is very1433 * difficult to predict which area of a disk is affected by a write,1434 * especially when different image formats are mixed. Maybe later a more1435 * sophisticated interface will be provided which has the necessary information1436 * about worst case affected areas.1437 *1438 * Per-disk interface. Optional, needed if the disk is accessed concurrently1439 * by several threads, e.g. when merging diff images while a VM is running.1440 */1441 typedef struct VDINTERFACETHREADSYNC1442 {1443 /**1444 * Size of the thread synchronization interface.1445 */1446 uint32_t cbSize;1447 1448 /**1449 * Interface type.1450 */1451 VDINTERFACETYPE enmInterface;1452 1453 /**1454 * Start a read operation.1455 */1456 DECLR3CALLBACKMEMBER(int, pfnStartRead, (void *pvUser));1457 1458 /**1459 * Finish a read operation.1460 */1461 DECLR3CALLBACKMEMBER(int, pfnFinishRead, (void *pvUser));1462 1463 /**1464 * Start a write operation.1465 */1466 DECLR3CALLBACKMEMBER(int, pfnStartWrite, (void *pvUser));1467 1468 /**1469 * Finish a write operation.1470 */1471 DECLR3CALLBACKMEMBER(int, pfnFinishWrite, (void *pvUser));1472 1473 } VDINTERFACETHREADSYNC, *PVDINTERFACETHREADSYNC;1474 1475 /**1476 * Get thread synchronization interface from opaque callback table.1477 *1478 * @return Pointer to the callback table.1479 * @param pInterface Pointer to the interface descriptor.1480 */1481 DECLINLINE(PVDINTERFACETHREADSYNC) VDGetInterfaceThreadSync(PVDINTERFACE pInterface)1482 {1483 PVDINTERFACETHREADSYNC pInterfaceThreadSync;1484 1485 /* Check that the interface descriptor is a thread synchronization interface. */1486 AssertMsgReturn( (pInterface->enmInterface == VDINTERFACETYPE_THREADSYNC)1487 && (pInterface->cbSize == sizeof(VDINTERFACE)),1488 ("Not a thread synchronization interface"), NULL);1489 1490 pInterfaceThreadSync = (PVDINTERFACETHREADSYNC)pInterface->pCallbacks;1491 1492 /* Do basic checks. */1493 AssertMsgReturn( (pInterfaceThreadSync->cbSize == sizeof(VDINTERFACETHREADSYNC))1494 && (pInterfaceThreadSync->enmInterface == VDINTERFACETYPE_THREADSYNC),1495 ("A non thread synchronization callback table attached to a thread synchronization interface descriptor\n"), NULL);1496 1497 return pInterfaceThreadSync;1498 }1499 269 1500 270 /** @name Configuration interface key handling flags. … … 1596 366 1597 367 1598 /** Forward declaration. Only visible in the VBoxHDD module. */1599 /** I/O context */1600 typedef struct VDIOCTX *PVDIOCTX;1601 /** Storage backend handle. */1602 typedef struct VDIOSTORAGE *PVDIOSTORAGE;1603 /** Pointer to a storage backend handle. */1604 typedef PVDIOSTORAGE *PPVDIOSTORAGE;1605 1606 /**1607 * Completion callback for meta/userdata reads or writes.1608 *1609 * @return VBox status code.1610 * VINF_SUCCESS if everything was successful and the transfer can continue.1611 * VERR_VD_ASYNC_IO_IN_PROGRESS if there is another data transfer pending.1612 * @param pBackendData The opaque backend data.1613 * @param pIoCtx I/O context associated with this request.1614 * @param pvUser Opaque user data passed during a read/write request.1615 * @param rcReq Status code for the completed request.1616 */1617 typedef DECLCALLBACK(int) FNVDXFERCOMPLETED(void *pBackendData, PVDIOCTX pIoCtx, void *pvUser, int rcReq);1618 /** Pointer to FNVDXFERCOMPLETED() */1619 typedef FNVDXFERCOMPLETED *PFNVDXFERCOMPLETED;1620 1621 /** Metadata transfer handle. */1622 typedef struct VDMETAXFER *PVDMETAXFER;1623 /** Pointer to a metadata transfer handle. */1624 typedef PVDMETAXFER *PPVDMETAXFER;1625 1626 1627 /**1628 * Internal I/O interface between the generic VD layer and the backends.1629 *1630 * Per-image. Always passed to backends.1631 */1632 typedef struct VDINTERFACEIOINT1633 {1634 /**1635 * Size of the internal I/O interface.1636 */1637 uint32_t cbSize;1638 1639 /**1640 * Interface type.1641 */1642 VDINTERFACETYPE enmInterface;1643 1644 /**1645 * Open callback1646 *1647 * @return VBox status code.1648 * @param pvUser The opaque data passed on container creation.1649 * @param pszLocation Name of the location to open.1650 * @param fOpen Flags for opening the backend.1651 * See RTFILE_O_* #defines, inventing another set1652 * of open flags is not worth the mapping effort.1653 * @param ppStorage Where to store the storage handle.1654 */1655 DECLR3CALLBACKMEMBER(int, pfnOpen, (void *pvUser, const char *pszLocation,1656 uint32_t fOpen, PPVDIOSTORAGE ppStorage));1657 1658 /**1659 * Close callback.1660 *1661 * @return VBox status code.1662 * @param pvUser The opaque data passed on container creation.1663 * @param pStorage The storage handle to close.1664 */1665 DECLR3CALLBACKMEMBER(int, pfnClose, (void *pvUser, PVDIOSTORAGE pStorage));1666 1667 /**1668 * Delete callback.1669 *1670 * @return VBox status code.1671 * @param pvUser The opaque data passed on container creation.1672 * @param pcszFilename Name of the file to delete.1673 */1674 DECLR3CALLBACKMEMBER(int, pfnDelete, (void *pvUser, const char *pcszFilename));1675 1676 /**1677 * Move callback.1678 *1679 * @return VBox status code.1680 * @param pvUser The opaque data passed on container creation.1681 * @param pcszSrc The path to the source file.1682 * @param pcszDst The path to the destination file.1683 * This file will be created.1684 * @param fMove A combination of the RTFILEMOVE_* flags.1685 */1686 DECLR3CALLBACKMEMBER(int, pfnMove, (void *pvUser, const char *pcszSrc, const char *pcszDst, unsigned fMove));1687 1688 /**1689 * Returns the free space on a disk.1690 *1691 * @return VBox status code.1692 * @param pvUser The opaque data passed on container creation.1693 * @param pcszFilename Name of a file to identify the disk.1694 * @param pcbFreeSpace Where to store the free space of the disk.1695 */1696 DECLR3CALLBACKMEMBER(int, pfnGetFreeSpace, (void *pvUser, const char *pcszFilename, int64_t *pcbFreeSpace));1697 1698 /**1699 * Returns the last modification timestamp of a file.1700 *1701 * @return VBox status code.1702 * @param pvUser The opaque data passed on container creation.1703 * @param pcszFilename Name of a file to identify the disk.1704 * @param pModificationTime Where to store the timestamp of the file.1705 */1706 DECLR3CALLBACKMEMBER(int, pfnGetModificationTime, (void *pvUser, const char *pcszFilename, PRTTIMESPEC pModificationTime));1707 1708 /**1709 * Returns the size of the opened storage backend.1710 *1711 * @return VBox status code.1712 * @param pvUser The opaque data passed on container creation.1713 * @param pStorage The storage handle to get the size from.1714 * @param pcbSize Where to store the size of the storage backend.1715 */1716 DECLR3CALLBACKMEMBER(int, pfnGetSize, (void *pvUser, PVDIOSTORAGE pStorage,1717 uint64_t *pcbSize));1718 1719 /**1720 * Sets the size of the opened storage backend if possible.1721 *1722 * @return VBox status code.1723 * @retval VERR_NOT_SUPPORTED if the backend does not support this operation.1724 * @param pvUser The opaque data passed on container creation.1725 * @param pStorage The storage handle.1726 * @param cbSize The new size of the image.1727 */1728 DECLR3CALLBACKMEMBER(int, pfnSetSize, (void *pvUser, PVDIOSTORAGE pStorage,1729 uint64_t cbSize));1730 1731 /**1732 * Synchronous write callback.1733 *1734 * @return VBox status code.1735 * @param pvUser The opaque data passed on container creation.1736 * @param pStorage The storage handle to use.1737 * @param uOffset The offset to start from.1738 * @param pvBuffer Pointer to the bits need to be written.1739 * @param cbBuffer How many bytes to write.1740 * @param pcbWritten Where to store how many bytes were actually written.1741 *1742 * @notes Do not use in code called from the async read/write entry points in the backends.1743 * This should be only used during open/close of images and for the support functions1744 * which are not called while a VM is running (pfnCompact).1745 */1746 DECLR3CALLBACKMEMBER(int, pfnWriteSync, (void *pvUser, PVDIOSTORAGE pStorage, uint64_t uOffset,1747 const void *pvBuffer, size_t cbBuffer, size_t *pcbWritten));1748 1749 /**1750 * Synchronous read callback.1751 *1752 * @return VBox status code.1753 * @param pvUser The opaque data passed on container creation.1754 * @param pStorage The storage handle to use.1755 * @param uOffset The offset to start from.1756 * @param pvBuffer Where to store the read bits.1757 * @param cbBuffer How many bytes to read.1758 * @param pcbRead Where to store how many bytes were actually read.1759 *1760 * @notes See pfnWriteSync()1761 */1762 DECLR3CALLBACKMEMBER(int, pfnReadSync, (void *pvUser, PVDIOSTORAGE pStorage, uint64_t uOffset,1763 void *pvBuffer, size_t cbBuffer, size_t *pcbRead));1764 1765 /**1766 * Flush data to the storage backend.1767 *1768 * @return VBox status code.1769 * @param pvUser The opaque data passed on container creation.1770 * @param pStorage The storage handle to flush.1771 *1772 * @notes See pfnWriteSync()1773 */1774 DECLR3CALLBACKMEMBER(int, pfnFlushSync, (void *pvUser, PVDIOSTORAGE pStorage));1775 1776 /**1777 * Initiate an asynchronous read request for user data.1778 *1779 * @return VBox status code.1780 * @param pvUser The opaque user data passed on container creation.1781 * @param pStorage The storage handle.1782 * @param uOffset The offset to start reading from.1783 * @param pIoCtx I/O context passed in VDAsyncRead/Write.1784 * @param cbRead How many bytes to read.1785 */1786 DECLR3CALLBACKMEMBER(int, pfnReadUserAsync, (void *pvUser, PVDIOSTORAGE pStorage,1787 uint64_t uOffset, PVDIOCTX pIoCtx,1788 size_t cbRead));1789 1790 /**1791 * Initiate an asynchronous write request for user data.1792 *1793 * @return VBox status code.1794 * @param pvUser The opaque user data passed on container creation.1795 * @param pStorage The storage handle.1796 * @param uOffset The offset to start writing to.1797 * @param pIoCtx I/O context passed in VDAsyncRead/Write1798 * @param cbWrite How many bytes to write.1799 * @param pfnCompleted Completion callback.1800 * @param pvCompleteUser Opaque user data passed in the completion callback.1801 */1802 DECLR3CALLBACKMEMBER(int, pfnWriteUserAsync, (void *pvUser, PVDIOSTORAGE pStorage,1803 uint64_t uOffset, PVDIOCTX pIoCtx,1804 size_t cbWrite,1805 PFNVDXFERCOMPLETED pfnComplete,1806 void *pvCompleteUser));1807 1808 /**1809 * Reads metadata asynchronously from storage.1810 * The current I/O context will be halted.1811 *1812 * @returns VBox status code.1813 * @param pvUser The opaque user data passed on container creation.1814 * @param pStorage The storage handle.1815 * @param uOffset Offset to start reading from.1816 * @param pvBuffer Where to store the data.1817 * @param cbBuffer How many bytes to read.1818 * @param pIoCtx The I/O context which triggered the read.1819 * @param ppMetaXfer Where to store the metadata transfer handle on success.1820 * @param pfnCompleted Completion callback.1821 * @param pvCompleteUser Opaque user data passed in the completion callback.1822 */1823 DECLR3CALLBACKMEMBER(int, pfnReadMetaAsync, (void *pvUser, PVDIOSTORAGE pStorage,1824 uint64_t uOffset, void *pvBuffer,1825 size_t cbBuffer, PVDIOCTX pIoCtx,1826 PPVDMETAXFER ppMetaXfer,1827 PFNVDXFERCOMPLETED pfnComplete,1828 void *pvCompleteUser));1829 1830 /**1831 * Writes metadata asynchronously to storage.1832 *1833 * @returns VBox status code.1834 * @param pvUser The opaque user data passed on container creation.1835 * @param pStorage The storage handle.1836 * @param uOffset Offset to start writing to.1837 * @param pvBuffer Written data.1838 * @param cbBuffer How many bytes to write.1839 * @param pIoCtx The I/O context which triggered the write.1840 * @param pfnCompleted Completion callback.1841 * @param pvCompleteUser Opaque user data passed in the completion callback.1842 */1843 DECLR3CALLBACKMEMBER(int, pfnWriteMetaAsync, (void *pvUser, PVDIOSTORAGE pStorage,1844 uint64_t uOffset, void *pvBuffer,1845 size_t cbBuffer, PVDIOCTX pIoCtx,1846 PFNVDXFERCOMPLETED pfnComplete,1847 void *pvCompleteUser));1848 1849 /**1850 * Releases a metadata transfer handle.1851 * The free space can be used for another transfer.1852 *1853 * @returns nothing.1854 * @param pvUser The opaque user data passed on container creation.1855 * @param pMetaXfer The metadata transfer handle to release.1856 */1857 DECLR3CALLBACKMEMBER(void, pfnMetaXferRelease, (void *pvUser, PVDMETAXFER pMetaXfer));1858 1859 /**1860 * Initiates an async flush request.1861 *1862 * @return VBox status code.1863 * @param pvUser The opaque data passed on container creation.1864 * @param pStorage The storage handle to flush.1865 * @param pIoCtx I/O context which triggered the flush.1866 * @param pfnCompleted Completion callback.1867 * @param pvCompleteUser Opaque user data passed in the completion callback.1868 */1869 DECLR3CALLBACKMEMBER(int, pfnFlushAsync, (void *pvUser, PVDIOSTORAGE pStorage,1870 PVDIOCTX pIoCtx,1871 PFNVDXFERCOMPLETED pfnComplete,1872 void *pvCompleteUser));1873 1874 /**1875 * Copies a buffer into the I/O context.1876 *1877 * @return Number of bytes copied.1878 * @param pvUser The opaque user data passed on container creation.1879 * @param pIoCtx I/O context to copy the data to.1880 * @param pvBuffer Buffer to copy.1881 * @param cbBuffer Number of bytes to copy.1882 */1883 DECLR3CALLBACKMEMBER(size_t, pfnIoCtxCopyTo, (void *pvUser, PVDIOCTX pIoCtx,1884 void *pvBuffer, size_t cbBuffer));1885 1886 /**1887 * Copies data from the I/O context into a buffer.1888 *1889 * @return Number of bytes copied.1890 * @param pvUser The opaque user data passed on container creation.1891 * @param pIoCtx I/O context to copy the data from.1892 * @param pvBuffer Destination buffer.1893 * @param cbBuffer Number of bytes to copy.1894 */1895 DECLR3CALLBACKMEMBER(size_t, pfnIoCtxCopyFrom, (void *pvUser, PVDIOCTX pIoCtx,1896 void *pvBuffer, size_t cbBuffer));1897 1898 /**1899 * Sets the buffer of the given context to a specific byte.1900 *1901 * @return Number of bytes set.1902 * @param pvUser The opaque user data passed on container creation.1903 * @param pIoCtx I/O context to copy the data from.1904 * @param ch The byte to set.1905 * @param cbSet Number of bytes to set.1906 */1907 DECLR3CALLBACKMEMBER(size_t, pfnIoCtxSet, (void *pvUser, PVDIOCTX pIoCtx,1908 int ch, size_t cbSet));1909 1910 /**1911 * Creates a segment array from the I/O context data buffer.1912 *1913 * @returns Number of bytes the array describes.1914 * @param pvUser The opaque user data passed on container creation.1915 * @param pIoCtx I/O context to copy the data from.1916 * @param paSeg The uninitialized segment array.1917 * If NULL pcSeg will contain the number of segments needed1918 * to describe the requested amount of data.1919 * @param pcSeg The number of segments the given array has.1920 * This will hold the actual number of entries needed upon return.1921 * @param cbData Number of bytes the new array should describe.1922 */1923 DECLR3CALLBACKMEMBER(size_t, pfnIoCtxSegArrayCreate, (void *pvUser, PVDIOCTX pIoCtx,1924 PRTSGSEG paSeg, unsigned *pcSeg,1925 size_t cbData));1926 /**1927 * Marks the given number of bytes as completed and continues the I/O context.1928 *1929 * @returns nothing.1930 * @param pvUser The opaque user data passed on container creation.1931 * @param pIoCtx The I/O context.1932 * @param rcReq Status code the request completed with.1933 * @param cbCompleted Number of bytes completed.1934 */1935 DECLR3CALLBACKMEMBER(void, pfnIoCtxCompleted, (void *pvUser, PVDIOCTX pIoCtx,1936 int rcReq, size_t cbCompleted));1937 } VDINTERFACEIOINT, *PVDINTERFACEIOINT;1938 1939 /**1940 * Get internal I/O interface from opaque callback table.1941 *1942 * @return Pointer to the callback table.1943 * @param pInterface Pointer to the interface descriptor.1944 */1945 DECLINLINE(PVDINTERFACEIOINT) VDGetInterfaceIOInt(PVDINTERFACE pInterface)1946 {1947 PVDINTERFACEIOINT pInterfaceIOInt;1948 1949 /* Check that the interface descriptor is an internal I/O interface. */1950 AssertMsgReturn( (pInterface->enmInterface == VDINTERFACETYPE_IOINT)1951 && (pInterface->cbSize == sizeof(VDINTERFACE)),1952 ("Not an internal I/O interface"), NULL);1953 1954 pInterfaceIOInt = (PVDINTERFACEIOINT)pInterface->pCallbacks;1955 1956 /* Do basic checks. */1957 AssertMsgReturn( (pInterfaceIOInt->cbSize == sizeof(VDINTERFACEIOINT))1958 && (pInterfaceIOInt->enmInterface == VDINTERFACETYPE_IOINT),1959 ("A non internal I/O callback table attached to an internal I/O interface descriptor\n"), NULL);1960 1961 return pInterfaceIOInt;1962 }1963 1964 368 /** 1965 369 * Request completion callback for the async read/write API.
Note:
See TracChangeset
for help on using the changeset viewer.