Changeset 54340 in vbox
- Timestamp:
- Feb 20, 2015 6:51:07 PM (10 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vd.h
r52830 r54340 242 242 /** @}*/ 243 243 244 /** @name VBox HDD container filter flags 245 * @{ 246 */ 247 /** The filter is applied during writes. */ 248 #define VD_FILTER_FLAGS_WRITE RT_BIT(0) 249 /** The filter is applied during reads. */ 250 #define VD_FILTER_FLAGS_READ RT_BIT(1) 251 /** Default set of filter flags. */ 252 #define VD_FILTER_FLAGS_DEFAULT (VD_FILTER_FLAGS_WRITE | VD_FILTER_FLAGS_READ) 253 /** Mask of valid flags. */ 254 #define VD_FILTER_FLAGS_MASK (VD_FILTER_FLAGS_WRITE | VD_FILTER_FLAGS_READ) 255 /** @} */ 256 244 257 /** 245 258 * Helper functions to handle open flags. … … 641 654 * @param pDisk Pointer to the HDD container which should use the filter. 642 655 * @param pszFilter Name of the filter backend to use (case insensitive). 656 * @param fFlags Flags which apply to the filter, combination of VD_FILTER_FLAGS_* 657 * defines. 643 658 * @param pVDIfsFilter Pointer to the per-filter VD interface list. 644 659 */ 645 VBOXDDU_DECL(int) VDFilterAdd(PVBOXHDD pDisk, const char *pszFilter, 660 VBOXDDU_DECL(int) VDFilterAdd(PVBOXHDD pDisk, const char *pszFilter, uint32_t fFlags, 646 661 PVDINTERFACE pVDIfsFilter); 647 662 … … 907 922 908 923 /** 909 * Removes the last added filter in the HDD container .924 * Removes the last added filter in the HDD container from the specified chain. 910 925 * 911 926 * @return VBox status code. 912 927 * @retval VERR_VD_NOT_OPENED if no filter is present for the disk. 913 928 * @param pDisk Pointer to HDD container. 914 */ 915 VBOXDDU_DECL(int) VDFilterRemove(PVBOXHDD pDisk); 929 * @param fFlags Combination of VD_FILTER_FLAGS_* defines. 930 */ 931 VBOXDDU_DECL(int) VDFilterRemove(PVBOXHDD pDisk, uint32_t fFlags); 916 932 917 933 /** -
trunk/src/VBox/Devices/Storage/DrvVD.cpp
r53539 r54340 1767 1767 { 1768 1768 /* Unload the crypto filter first to make sure it doesn't access the keys anymore. */ 1769 rc = VDFilterRemove(pThis->pDisk );1769 rc = VDFilterRemove(pThis->pDisk, VD_FILTER_FLAGS_DEFAULT); 1770 1770 AssertRC(rc); 1771 1771 … … 1787 1787 1788 1788 /* Load the crypt filter plugin. */ 1789 rc = VDFilterAdd(pThis->pDisk, "CRYPT", pVDIfFilter);1789 rc = VDFilterAdd(pThis->pDisk, "CRYPT", VD_FILTER_FLAGS_DEFAULT, pVDIfFilter); 1790 1790 if (RT_FAILURE(rc)) 1791 1791 pThis->pIfSecKey = NULL; … … 2235 2235 AssertRC(rc); 2236 2236 2237 rc = VDFilterAdd(pThis->pDisk, pszFilterName, pVDIfsFilter);2237 rc = VDFilterAdd(pThis->pDisk, pszFilterName, VD_FILTER_FLAGS_DEFAULT, pVDIfsFilter); 2238 2238 2239 2239 MMR3HeapFree(pszFilterName); -
trunk/src/VBox/Storage/VD.cpp
r54117 r54340 198 198 typedef struct VDFILTER 199 199 { 200 /** Pointer to the previous filter. */ 201 struct VDFILTER *pPrev; 202 /** Pointer to the next filter. */ 203 struct VDFILTER *pNext; 200 /** List node for the read filter chain. */ 201 RTLISTNODE ListNodeChainRead; 202 /** List node for the write filter chain. */ 203 RTLISTNODE ListNodeChainWrite; 204 /** Number of references to this filter. */ 205 uint32_t cRefs; 204 206 /** Opaque VD filter backend instance data. */ 205 207 void *pvBackendData; … … 290 292 PVDDISCARDSTATE pDiscard; 291 293 292 /** Pointer to the first filter in the chain. */293 PVDFILTER pFilterHead;294 /** Pointer to the last filter in the chain. */295 PVDFILTER pFilterTail;294 /** Read filter chain - PVDFILTER. */ 295 RTLISTANCHOR ListFilterChainRead; 296 /** Write filter chain - PVDFILTER. */ 297 RTLISTANCHOR ListFilterChainWrite; 296 298 }; 297 299 … … 938 940 939 941 /** 940 * internal: add filter structure to the end of filter list. 941 */ 942 static void vdAddFilterToList(PVBOXHDD pDisk, PVDFILTER pFilter) 943 { 944 pFilter->pPrev = NULL; 945 pFilter->pNext = NULL; 946 947 if (pDisk->pFilterHead) 948 { 949 pFilter->pPrev = pDisk->pFilterTail; 950 pDisk->pFilterTail->pNext = pFilter; 951 pDisk->pFilterTail = pFilter; 952 } 953 else 954 { 955 pDisk->pFilterHead = pFilter; 956 pDisk->pFilterTail = pFilter; 957 } 958 } 959 960 /** 961 * internal: Remove last filter structure from the filter list. 962 */ 963 static void vdRemoveFilterFromList(PVBOXHDD pDisk, PVDFILTER pFilter) 964 { 965 Assert(pDisk->pFilterHead != NULL && pDisk->pFilterTail != NULL); 966 967 if (pFilter->pPrev) 968 pFilter->pPrev->pNext = pFilter->pNext; 969 else 970 pDisk->pFilterHead = pFilter->pNext; 971 972 if (pFilter->pNext) 973 pFilter->pNext->pPrev = pFilter->pPrev; 974 else 975 pDisk->pFilterTail = pFilter->pPrev; 976 977 pFilter->pPrev = NULL; 978 pFilter->pNext = NULL; 942 * Release a referene to the filter decrementing the counter and destroying the filter 943 * when the counter reaches zero. 944 * 945 * @returns The new reference count. 946 * @param pFilter The filter to release. 947 */ 948 static uint32_t vdFilterRelease(PVDFILTER pFilter) 949 { 950 uint32_t cRefs = ASMAtomicDecU32(&pFilter->cRefs); 951 if (!cRefs) 952 { 953 pFilter->pBackend->pfnDestroy(pFilter->pvBackendData); 954 RTMemFree(pFilter); 955 } 956 957 return cRefs; 958 } 959 960 /** 961 * Increments the reference counter of the given filter. 962 * 963 * @return The new reference count. 964 * @param pFilter The filter. 965 */ 966 static uint32_t vdFilterRetain(PVDFILTER pFilter) 967 { 968 return ASMAtomicIncU32(&pFilter->cRefs); 979 969 } 980 970 … … 1011 1001 VD_IS_LOCKED(pDisk); 1012 1002 1013 if (pDisk->pFilterHead) 1014 { 1015 PVDFILTER pFilterCurr = pDisk->pFilterHead; 1016 1017 do 1018 { 1019 rc = pFilterCurr->pBackend->pfnFilterWrite(pFilterCurr->pvBackendData, uOffset, cbWrite, pIoCtx); 1020 /* Reset S/G buffer for the next filter. */ 1021 RTSgBufReset(&pIoCtx->Req.Io.SgBuf); 1022 1023 pFilterCurr = pFilterCurr->pNext; 1024 } while ( RT_SUCCESS(rc) 1025 && pFilterCurr); 1003 PVDFILTER pFilter; 1004 RTListForEach(&pDisk->ListFilterChainWrite, pFilter, VDFILTER, ListNodeChainWrite) 1005 { 1006 rc = pFilter->pBackend->pfnFilterWrite(pFilter->pvBackendData, uOffset, cbWrite, pIoCtx); 1007 if (RT_FAILURE(rc)) 1008 break; 1009 /* Reset S/G buffer for the next filter. */ 1010 RTSgBufReset(&pIoCtx->Req.Io.SgBuf); 1026 1011 } 1027 1012 … … 1045 1030 VD_IS_LOCKED(pDisk); 1046 1031 1047 if (pDisk->pFilterHead) 1048 { 1049 PVDFILTER pFilterCurr = pDisk->pFilterHead; 1050 1051 /* Reset buffer before starting. */ 1032 /* Reset buffer before starting. */ 1033 RTSgBufReset(&pIoCtx->Req.Io.SgBuf); 1034 1035 PVDFILTER pFilter; 1036 RTListForEach(&pDisk->ListFilterChainRead, pFilter, VDFILTER, ListNodeChainRead) 1037 { 1038 rc = pFilter->pBackend->pfnFilterRead(pFilter->pvBackendData, uOffset, cbRead, pIoCtx); 1039 if (RT_FAILURE(rc)) 1040 break; 1041 /* Reset S/G buffer for the next filter. */ 1052 1042 RTSgBufReset(&pIoCtx->Req.Io.SgBuf); 1053 1054 do1055 {1056 rc = pFilterCurr->pBackend->pfnFilterRead(pFilterCurr->pvBackendData, uOffset, cbRead, pIoCtx);1057 /* Reset S/G buffer for the next filter. */1058 RTSgBufReset(&pIoCtx->Req.Io.SgBuf);1059 1060 pFilterCurr = pFilterCurr->pNext;1061 } while ( RT_SUCCESS(rc)1062 && pFilterCurr);1063 1043 } 1064 1044 … … 2397 2377 bool fLockReadFrom = false; 2398 2378 bool fLockWriteTo = false; 2399 bool fBlockwiseCopy = f SuppressRedundantIo || (cImagesFromRead > 0);2379 bool fBlockwiseCopy = false; 2400 2380 unsigned uProgressOld = 0; 2401 2381 2402 2382 LogFlowFunc(("pDiskFrom=%#p pImageFrom=%#p pDiskTo=%#p cbSize=%llu cImagesFromRead=%u cImagesToRead=%u fSuppressRedundantIo=%RTbool pIfProgress=%#p pDstIfProgress=%#p\n", 2403 2383 pDiskFrom, pImageFrom, pDiskTo, cbSize, cImagesFromRead, cImagesToRead, fSuppressRedundantIo, pDstIfProgress, pDstIfProgress)); 2384 2385 if ( (fSuppressRedundantIo || (cImagesFromRead > 0)) 2386 && RTListIsEmpty(&pDiskFrom->ListFilterChainRead)) 2387 fBlockwiseCopy = true; 2404 2388 2405 2389 /* Allocate tmp buffer. */ … … 6011 5995 pDisk->hMemCacheIoCtx = NIL_RTMEMCACHE; 6012 5996 pDisk->hMemCacheIoTask = NIL_RTMEMCACHE; 6013 pDisk->pFilterHead = NULL;6014 pDisk->pFilterTail = NULL;5997 RTListInit(&pDisk->ListFilterChainWrite); 5998 RTListInit(&pDisk->ListFilterChainRead); 6015 5999 6016 6000 /* Create the I/O ctx cache */ … … 6740 6724 } 6741 6725 6742 /** 6743 * Adds a filter to the disk. 6744 * 6745 * @returns VBox status code. 6746 * @param pDisk Pointer to the HDD container which should use the filter. 6747 * @param pszFilter Name of the filter backend to use (case insensitive). 6748 * @param pVDIfsFilter Pointer to the per-filter VD interface list. 6749 */ 6750 VBOXDDU_DECL(int) VDFilterAdd(PVBOXHDD pDisk, const char *pszFilter, 6726 VBOXDDU_DECL(int) VDFilterAdd(PVBOXHDD pDisk, const char *pszFilter, uint32_t fFlags, 6751 6727 PVDINTERFACE pVDIfsFilter) 6752 6728 { … … 6768 6744 AssertMsgBreakStmt(VALID_PTR(pszFilter) && *pszFilter, 6769 6745 ("pszFilter=%#p \"%s\"\n", pszFilter, pszFilter), 6746 rc = VERR_INVALID_PARAMETER); 6747 6748 AssertMsgBreakStmt(!(fFlags & ~VD_FILTER_FLAGS_MASK), 6749 ("Invalid flags set (fFlags=%#x)\n", fFlags), 6770 6750 rc = VERR_INVALID_PARAMETER); 6771 6751 … … 6814 6794 fLockWrite = true; 6815 6795 6816 /* Add filter to chain. */ 6817 vdAddFilterToList(pDisk, pFilter); 6796 /* Add filter to chains. */ 6797 if (fFlags & VD_FILTER_FLAGS_WRITE) 6798 { 6799 RTListAppend(&pDisk->ListFilterChainWrite, &pFilter->ListNodeChainWrite); 6800 vdFilterRetain(pFilter); 6801 } 6802 6803 if (fFlags & VD_FILTER_FLAGS_READ) 6804 { 6805 RTListAppend(&pDisk->ListFilterChainRead, &pFilter->ListNodeChainRead); 6806 vdFilterRetain(pFilter); 6807 } 6818 6808 } while (0); 6819 6809 … … 8820 8810 } 8821 8811 8822 /** 8823 * Removes the last added filter in the HDD container. 8824 * 8825 * @return VBox status code. 8826 * @retval VERR_VD_NOT_OPENED if no filter is present for the disk. 8827 * @param pDisk Pointer to HDD container. 8828 */ 8829 VBOXDDU_DECL(int) VDFilterRemove(PVBOXHDD pDisk) 8812 VBOXDDU_DECL(int) VDFilterRemove(PVBOXHDD pDisk, uint32_t fFlags) 8830 8813 { 8831 8814 int rc = VINF_SUCCESS; … … 8842 8825 AssertMsg(pDisk->u32Signature == VBOXHDDDISK_SIGNATURE, ("u32Signature=%08x\n", pDisk->u32Signature)); 8843 8826 8827 AssertMsgBreakStmt(!(fFlags & VD_FILTER_FLAGS_MASK), 8828 ("Invalid flags set (fFlags=%#x)\n", fFlags), 8829 rc = VERR_INVALID_PARAMETER); 8830 8844 8831 rc2 = vdThreadStartWrite(pDisk); 8845 8832 AssertRC(rc2); 8846 8833 fLockWrite = true; 8847 8834 8848 AssertPtrBreakStmt(pDisk->pFilterHead, rc = VERR_VD_NOT_OPENED); 8849 8850 pFilter = pDisk->pFilterTail; 8851 vdRemoveFilterFromList(pDisk, pFilter); 8852 8853 pFilter->pBackend->pfnDestroy(pFilter->pvBackendData); 8854 RTMemFree(pFilter); 8835 if (fFlags & VD_FILTER_FLAGS_WRITE) 8836 { 8837 AssertBreakStmt(!RTListIsEmpty(&pDisk->ListFilterChainWrite), rc = VERR_VD_NOT_OPENED); 8838 pFilter = RTListGetLast(&pDisk->ListFilterChainWrite, VDFILTER, ListNodeChainWrite); 8839 AssertPtr(pFilter); 8840 RTListNodeRemove(&pFilter->ListNodeChainWrite); 8841 vdFilterRelease(pFilter); 8842 } 8843 8844 if (fFlags & VD_FILTER_FLAGS_READ) 8845 { 8846 AssertPtrBreakStmt(!RTListIsEmpty(&pDisk->ListFilterChainRead), rc = VERR_VD_NOT_OPENED); 8847 pFilter = RTListGetLast(&pDisk->ListFilterChainRead, VDFILTER, ListNodeChainRead); 8848 AssertPtr(pFilter); 8849 RTListNodeRemove(&pFilter->ListNodeChainRead); 8850 vdFilterRelease(pFilter); 8851 } 8855 8852 } while (0); 8856 8853 … … 8953 8950 fLockWrite = true; 8954 8951 8955 PVDFILTER pFilter = pDisk->pFilterTail;8956 while (VALID_PTR(pFilter))8957 { 8958 PVDFILTER pPrev = pFilter->pPrev;8959 vd RemoveFilterFromList(pDisk,pFilter);8960 8961 rc2 = pFilter->pBackend->pfnDestroy(pFilter->pvBackendData); 8962 if (RT_FAILURE(rc2) && RT_SUCCESS(rc))8963 rc = rc2;8964 /* Free remaining resources related to the image. */8965 RTMemFree(pFilter);8966 pFilter = pPrev;8967 }8968 Assert( !VALID_PTR(pDisk->pFilterTail));8952 PVDFILTER pFilter, pFilterNext; 8953 RTListForEachSafe(&pDisk->ListFilterChainWrite, pFilter, pFilterNext, VDFILTER, ListNodeChainWrite) 8954 { 8955 RTListNodeRemove(&pFilter->ListNodeChainWrite); 8956 vdFilterRelease(pFilter); 8957 } 8958 8959 RTListForEachSafe(&pDisk->ListFilterChainRead, pFilter, pFilterNext, VDFILTER, ListNodeChainRead) 8960 { 8961 RTListNodeRemove(&pFilter->ListNodeChainRead); 8962 vdFilterRelease(pFilter); 8963 } 8964 Assert(RTListIsEmpty(&pDisk->ListFilterChainRead)); 8965 Assert(RTListIsEmpty(&pDisk->ListFilterChainWrite)); 8969 8966 } while (0); 8970 8967
Note:
See TracChangeset
for help on using the changeset viewer.