Changeset 63830 in vbox for trunk/src/VBox/Storage/VD.cpp
- Timestamp:
- Sep 14, 2016 11:19:56 AM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Storage/VD.cpp
r63811 r63830 1635 1635 1636 1636 /** 1637 * Process the I/O context, core method which assumes that the I/O context 1638 * acquired the lock. 1637 * Returns whether the given I/O context has completed. 1639 1638 * 1640 * @returns VBox status code. 1641 * @param pIoCtx I/O context to process. 1642 */ 1643 static int vdIoCtxProcessLocked(PVDIOCTX pIoCtx) 1644 { 1645 int rc = VINF_SUCCESS; 1646 1647 VD_IS_LOCKED(pIoCtx->pDisk); 1648 1649 LogFlowFunc(("pIoCtx=%#p\n", pIoCtx)); 1650 1639 * @returns Flag whether the I/O context is complete. 1640 * @param pIoCtx The I/O context to check. 1641 */ 1642 DECLINLINE(bool) vdIoCtxIsComplete(PVDIOCTX pIoCtx) 1643 { 1651 1644 if ( !pIoCtx->cMetaTransfersPending 1652 1645 && !pIoCtx->cDataTransfersPending 1653 1646 && !pIoCtx->pfnIoCtxTransfer) 1654 { 1655 rc = VINF_VD_ASYNC_IO_FINISHED; 1656 goto out; 1657 } 1647 return true; 1658 1648 1659 1649 /* … … 1664 1654 && !pIoCtx->cMetaTransfersPending 1665 1655 && !pIoCtx->cDataTransfersPending) 1666 { 1667 rc = VINF_VD_ASYNC_IO_FINISHED; 1668 goto out; 1669 } 1670 1656 return true; 1657 1658 return false; 1659 } 1660 1661 /** 1662 * Returns whether the given I/O context is blocked due to a metadata transfer 1663 * or because the backend blocked it. 1664 * 1665 * @returns Flag whether the I/O context is blocked. 1666 * @param pIoCtx The I/O context to check. 1667 */ 1668 DECLINLINE(bool) vdIoCtxIsBlocked(PVDIOCTX pIoCtx) 1669 { 1671 1670 /* Don't change anything if there is a metadata transfer pending or we are blocked. */ 1672 1671 if ( pIoCtx->cMetaTransfersPending 1673 1672 || (pIoCtx->fFlags & VDIOCTX_FLAGS_BLOCKED)) 1674 { 1675 rc = VERR_VD_ASYNC_IO_IN_PROGRESS; 1676 goto out; 1677 } 1678 1679 if (pIoCtx->pfnIoCtxTransfer) 1680 { 1681 /* Call the transfer function advancing to the next while there is no error. */ 1682 while ( pIoCtx->pfnIoCtxTransfer 1683 && !pIoCtx->cMetaTransfersPending 1684 && RT_SUCCESS(rc)) 1685 { 1686 LogFlowFunc(("calling transfer function %#p\n", pIoCtx->pfnIoCtxTransfer)); 1687 rc = pIoCtx->pfnIoCtxTransfer(pIoCtx); 1688 1689 /* Advance to the next part of the transfer if the current one succeeded. */ 1690 if (RT_SUCCESS(rc)) 1673 return true; 1674 1675 return false; 1676 } 1677 1678 /** 1679 * Process the I/O context, core method which assumes that the I/O context 1680 * acquired the lock. 1681 * 1682 * @returns VBox status code. 1683 * @param pIoCtx I/O context to process. 1684 */ 1685 static int vdIoCtxProcessLocked(PVDIOCTX pIoCtx) 1686 { 1687 int rc = VINF_SUCCESS; 1688 1689 VD_IS_LOCKED(pIoCtx->pDisk); 1690 1691 LogFlowFunc(("pIoCtx=%#p\n", pIoCtx)); 1692 1693 if (!vdIoCtxIsComplete(pIoCtx)) 1694 { 1695 if (!vdIoCtxIsBlocked(pIoCtx)) 1696 { 1697 if (pIoCtx->pfnIoCtxTransfer) 1691 1698 { 1692 pIoCtx->pfnIoCtxTransfer = pIoCtx->pfnIoCtxTransferNext; 1693 pIoCtx->pfnIoCtxTransferNext = NULL; 1699 /* Call the transfer function advancing to the next while there is no error. */ 1700 while ( pIoCtx->pfnIoCtxTransfer 1701 && !pIoCtx->cMetaTransfersPending 1702 && RT_SUCCESS(rc)) 1703 { 1704 LogFlowFunc(("calling transfer function %#p\n", pIoCtx->pfnIoCtxTransfer)); 1705 rc = pIoCtx->pfnIoCtxTransfer(pIoCtx); 1706 1707 /* Advance to the next part of the transfer if the current one succeeded. */ 1708 if (RT_SUCCESS(rc)) 1709 { 1710 pIoCtx->pfnIoCtxTransfer = pIoCtx->pfnIoCtxTransferNext; 1711 pIoCtx->pfnIoCtxTransferNext = NULL; 1712 } 1713 } 1694 1714 } 1695 } 1696 } 1697 1698 if ( RT_SUCCESS(rc) 1699 && !pIoCtx->cMetaTransfersPending 1700 && !pIoCtx->cDataTransfersPending 1701 && !(pIoCtx->fFlags & VDIOCTX_FLAGS_BLOCKED)) 1702 rc = VINF_VD_ASYNC_IO_FINISHED; 1703 else if ( RT_SUCCESS(rc) 1704 || rc == VERR_VD_NOT_ENOUGH_METADATA 1705 || rc == VERR_VD_IOCTX_HALT) 1706 rc = VERR_VD_ASYNC_IO_IN_PROGRESS; 1707 else if ( RT_FAILURE(rc) 1708 && (rc != VERR_VD_ASYNC_IO_IN_PROGRESS)) 1709 { 1710 ASMAtomicCmpXchgS32(&pIoCtx->rcReq, rc, VINF_SUCCESS); 1711 1712 /* 1713 * The I/O context completed if we have an error and there is no data 1714 * or meta data transfer pending. 1715 */ 1716 if ( !pIoCtx->cMetaTransfersPending 1717 && !pIoCtx->cDataTransfersPending) 1718 rc = VINF_VD_ASYNC_IO_FINISHED; 1715 1716 if ( RT_SUCCESS(rc) 1717 && !pIoCtx->cMetaTransfersPending 1718 && !pIoCtx->cDataTransfersPending 1719 && !(pIoCtx->fFlags & VDIOCTX_FLAGS_BLOCKED)) 1720 rc = VINF_VD_ASYNC_IO_FINISHED; 1721 else if ( RT_SUCCESS(rc) 1722 || rc == VERR_VD_NOT_ENOUGH_METADATA 1723 || rc == VERR_VD_IOCTX_HALT) 1724 rc = VERR_VD_ASYNC_IO_IN_PROGRESS; 1725 else if ( RT_FAILURE(rc) 1726 && (rc != VERR_VD_ASYNC_IO_IN_PROGRESS)) 1727 { 1728 ASMAtomicCmpXchgS32(&pIoCtx->rcReq, rc, VINF_SUCCESS); 1729 1730 /* 1731 * The I/O context completed if we have an error and there is no data 1732 * or meta data transfer pending. 1733 */ 1734 if ( !pIoCtx->cMetaTransfersPending 1735 && !pIoCtx->cDataTransfersPending) 1736 rc = VINF_VD_ASYNC_IO_FINISHED; 1737 else 1738 rc = VERR_VD_ASYNC_IO_IN_PROGRESS; 1739 } 1740 } 1719 1741 else 1720 1742 rc = VERR_VD_ASYNC_IO_IN_PROGRESS; 1721 1743 } 1722 1723 out: 1744 else 1745 rc = VINF_VD_ASYNC_IO_FINISHED; 1746 1724 1747 LogFlowFunc(("pIoCtx=%#p rc=%Rrc cDataTransfersPending=%u cMetaTransfersPending=%u fComplete=%RTbool\n", 1725 1748 pIoCtx, rc, pIoCtx->cDataTransfersPending, pIoCtx->cMetaTransfersPending, … … 3750 3773 size_t cbPluginDirEntry = sizeof(RTDIRENTRYEX); 3751 3774 int rc = RTDirOpenFiltered(&pPluginDir, pszPluginFilter, RTDIRFILTER_WINNT, 0); 3752 if (RT_FAILURE(rc)) 3775 if (RT_SUCCESS(rc)) 3776 { 3777 pPluginDirEntry = (PRTDIRENTRYEX)RTMemAllocZ(sizeof(RTDIRENTRYEX)); 3778 if (pPluginDirEntry) 3779 { 3780 while ( (rc = RTDirReadEx(pPluginDir, pPluginDirEntry, &cbPluginDirEntry, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK)) 3781 != VERR_NO_MORE_FILES) 3782 { 3783 char *pszPluginPath = NULL; 3784 3785 if (rc == VERR_BUFFER_OVERFLOW) 3786 { 3787 /* allocate new buffer. */ 3788 RTMemFree(pPluginDirEntry); 3789 pPluginDirEntry = (PRTDIRENTRYEX)RTMemAllocZ(cbPluginDirEntry); 3790 if (!pPluginDirEntry) 3791 { 3792 rc = VERR_NO_MEMORY; 3793 break; 3794 } 3795 /* Retry. */ 3796 rc = RTDirReadEx(pPluginDir, pPluginDirEntry, &cbPluginDirEntry, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK); 3797 if (RT_FAILURE(rc)) 3798 break; 3799 } 3800 else if (RT_FAILURE(rc)) 3801 break; 3802 3803 /* We got the new entry. */ 3804 if (!RTFS_IS_FILE(pPluginDirEntry->Info.Attr.fMode)) 3805 continue; 3806 3807 /* Prepend the path to the libraries. */ 3808 pszPluginPath = RTPathJoinA(pszPath, pPluginDirEntry->szName); 3809 if (!pszPluginPath) 3810 { 3811 rc = VERR_NO_STR_MEMORY; 3812 break; 3813 } 3814 3815 rc = vdPluginLoadFromFilename(pszPluginPath); 3816 RTStrFree(pszPluginPath); 3817 } 3818 3819 RTMemFree(pPluginDirEntry); 3820 } 3821 else 3822 rc = VERR_NO_MEMORY; 3823 3824 RTDirClose(pPluginDir); 3825 } 3826 else 3753 3827 { 3754 3828 /* On Windows the above immediately signals that there are no 3755 3829 * files matching, while on other platforms enumerating the 3756 3830 * files below fails. Either way: no plugins. */ 3757 goto out; 3758 } 3759 3760 pPluginDirEntry = (PRTDIRENTRYEX)RTMemAllocZ(sizeof(RTDIRENTRYEX)); 3761 if (!pPluginDirEntry) 3762 { 3763 rc = VERR_NO_MEMORY; 3764 goto out; 3765 } 3766 3767 while ( (rc = RTDirReadEx(pPluginDir, pPluginDirEntry, &cbPluginDirEntry, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK)) 3768 != VERR_NO_MORE_FILES) 3769 { 3770 char *pszPluginPath = NULL; 3771 3772 if (rc == VERR_BUFFER_OVERFLOW) 3773 { 3774 /* allocate new buffer. */ 3775 RTMemFree(pPluginDirEntry); 3776 pPluginDirEntry = (PRTDIRENTRYEX)RTMemAllocZ(cbPluginDirEntry); 3777 if (!pPluginDirEntry) 3778 { 3779 rc = VERR_NO_MEMORY; 3780 break; 3781 } 3782 /* Retry. */ 3783 rc = RTDirReadEx(pPluginDir, pPluginDirEntry, &cbPluginDirEntry, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK); 3784 if (RT_FAILURE(rc)) 3785 break; 3786 } 3787 else if (RT_FAILURE(rc)) 3788 break; 3789 3790 /* We got the new entry. */ 3791 if (!RTFS_IS_FILE(pPluginDirEntry->Info.Attr.fMode)) 3792 continue; 3793 3794 /* Prepend the path to the libraries. */ 3795 pszPluginPath = RTPathJoinA(pszPath, pPluginDirEntry->szName); 3796 if (!pszPluginPath) 3797 { 3798 rc = VERR_NO_STR_MEMORY; 3799 break; 3800 } 3801 3802 rc = vdPluginLoadFromFilename(pszPluginPath); 3803 RTStrFree(pszPluginPath); 3804 } 3805 out: 3831 } 3832 3806 3833 if (rc == VERR_NO_MORE_FILES) 3807 3834 rc = VINF_SUCCESS; 3808 3835 RTStrFree(pszPluginFilter); 3809 if (pPluginDirEntry)3810 RTMemFree(pPluginDirEntry);3811 if (pPluginDir)3812 RTDirClose(pPluginDir);3813 3836 return rc; 3814 3837 #else … … 3873 3896 size_t cbPluginDirEntry = sizeof(RTDIRENTRYEX); 3874 3897 int rc = RTDirOpenFiltered(&pPluginDir, pszPluginFilter, RTDIRFILTER_WINNT, 0); 3875 if (RT_FAILURE(rc)) 3898 if (RT_SUCCESS(rc)) 3899 { 3900 pPluginDirEntry = (PRTDIRENTRYEX)RTMemAllocZ(sizeof(RTDIRENTRYEX)); 3901 if (pPluginDirEntry) 3902 { 3903 while ((rc = RTDirReadEx(pPluginDir, pPluginDirEntry, &cbPluginDirEntry, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK)) != VERR_NO_MORE_FILES) 3904 { 3905 char *pszPluginPath = NULL; 3906 3907 if (rc == VERR_BUFFER_OVERFLOW) 3908 { 3909 /* allocate new buffer. */ 3910 RTMemFree(pPluginDirEntry); 3911 pPluginDirEntry = (PRTDIRENTRYEX)RTMemAllocZ(cbPluginDirEntry); 3912 if (!pPluginDirEntry) 3913 { 3914 rc = VERR_NO_MEMORY; 3915 break; 3916 } 3917 /* Retry. */ 3918 rc = RTDirReadEx(pPluginDir, pPluginDirEntry, &cbPluginDirEntry, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK); 3919 if (RT_FAILURE(rc)) 3920 break; 3921 } 3922 else if (RT_FAILURE(rc)) 3923 break; 3924 3925 /* We got the new entry. */ 3926 if (!RTFS_IS_FILE(pPluginDirEntry->Info.Attr.fMode)) 3927 continue; 3928 3929 /* Prepend the path to the libraries. */ 3930 pszPluginPath = RTPathJoinA(pszPath, pPluginDirEntry->szName); 3931 if (!pszPluginPath) 3932 { 3933 rc = VERR_NO_STR_MEMORY; 3934 break; 3935 } 3936 3937 rc = vdPluginUnloadFromFilename(pszPluginPath); 3938 RTStrFree(pszPluginPath); 3939 } 3940 3941 RTMemFree(pPluginDirEntry); 3942 } 3943 else 3944 rc = VERR_NO_MEMORY; 3945 3946 RTDirClose(pPluginDir); 3947 } 3948 else 3876 3949 { 3877 3950 /* On Windows the above immediately signals that there are no 3878 3951 * files matching, while on other platforms enumerating the 3879 3952 * files below fails. Either way: no plugins. */ 3880 goto out; 3881 } 3882 3883 pPluginDirEntry = (PRTDIRENTRYEX)RTMemAllocZ(sizeof(RTDIRENTRYEX)); 3884 if (!pPluginDirEntry) 3885 { 3886 rc = VERR_NO_MEMORY; 3887 goto out; 3888 } 3889 3890 while ((rc = RTDirReadEx(pPluginDir, pPluginDirEntry, &cbPluginDirEntry, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK)) != VERR_NO_MORE_FILES) 3891 { 3892 char *pszPluginPath = NULL; 3893 3894 if (rc == VERR_BUFFER_OVERFLOW) 3895 { 3896 /* allocate new buffer. */ 3897 RTMemFree(pPluginDirEntry); 3898 pPluginDirEntry = (PRTDIRENTRYEX)RTMemAllocZ(cbPluginDirEntry); 3899 if (!pPluginDirEntry) 3900 { 3901 rc = VERR_NO_MEMORY; 3902 break; 3903 } 3904 /* Retry. */ 3905 rc = RTDirReadEx(pPluginDir, pPluginDirEntry, &cbPluginDirEntry, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK); 3906 if (RT_FAILURE(rc)) 3907 break; 3908 } 3909 else if (RT_FAILURE(rc)) 3910 break; 3911 3912 /* We got the new entry. */ 3913 if (!RTFS_IS_FILE(pPluginDirEntry->Info.Attr.fMode)) 3914 continue; 3915 3916 /* Prepend the path to the libraries. */ 3917 pszPluginPath = RTPathJoinA(pszPath, pPluginDirEntry->szName); 3918 if (!pszPluginPath) 3919 { 3920 rc = VERR_NO_STR_MEMORY; 3921 break; 3922 } 3923 3924 rc = vdPluginUnloadFromFilename(pszPluginPath); 3925 RTStrFree(pszPluginPath); 3926 } 3927 out: 3953 } 3954 3928 3955 if (rc == VERR_NO_MORE_FILES) 3929 3956 rc = VINF_SUCCESS; 3930 3957 RTStrFree(pszPluginFilter); 3931 if (pPluginDirEntry)3932 RTMemFree(pPluginDirEntry);3933 if (pPluginDir)3934 RTDirClose(pPluginDir);3935 3958 return rc; 3936 3959 #else
Note:
See TracChangeset
for help on using the changeset viewer.