Changeset 66598 in vbox
- Timestamp:
- Apr 17, 2017 3:52:56 PM (7 years ago)
- File:
-
- 1 edited
-
trunk/src/VBox/Runtime/common/vfs/vfsreadahead.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/vfs/vfsreadahead.cpp
r62562 r66598 814 814 } 815 815 816 817 /** 818 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnValidate} 819 */ 820 static DECLCALLBACK(int) rtVfsChainReadAhead_Validate(PCRTVFSCHAINELEMENTREG pProviderReg, PRTVFSCHAINSPEC pSpec, 821 PRTVFSCHAINELEMSPEC pElement, uint32_t *poffError) 822 { 823 RT_NOREF(pProviderReg, poffError); 824 825 /* 826 * Basics. 827 */ 828 if (pElement->enmTypeIn == RTVFSOBJTYPE_INVALID) 829 return VERR_VFS_CHAIN_CANNOT_BE_FIRST_ELEMENT; 830 if (pElement->cArgs > 2) 831 return VERR_VFS_CHAIN_AT_MOST_TWO_ARGS; 832 if ( pElement->enmType != RTVFSOBJTYPE_FILE 833 && pElement->enmType != RTVFSOBJTYPE_IO_STREAM) 834 return VERR_VFS_CHAIN_ONLY_FILE_OR_IOS; 835 if (pSpec->fOpenFile & RTFILE_O_WRITE) 836 return VERR_VFS_CHAIN_READ_ONLY_IOS; 837 838 /* 839 * Parse the two optional arguments. 840 */ 841 uint32_t cBuffers = 0; 842 if (pElement->cArgs > 0) 843 { 844 const char *psz = pElement->paArgs[0].psz; 845 if (*psz) 846 { 847 int rc = RTStrToUInt32Full(psz, 0, &cBuffers); 848 if (RT_FAILURE(rc)) 849 { 850 *poffError = pElement->paArgs[0].offSpec; 851 return VERR_VFS_CHAIN_INVALID_ARGUMENT; 852 } 853 } 854 } 855 856 uint32_t cbBuffer = 0; 857 if (pElement->cArgs > 1) 858 { 859 const char *psz = pElement->paArgs[1].psz; 860 if (*psz) 861 { 862 int rc = RTStrToUInt32Full(psz, 0, &cbBuffer); 863 if (RT_FAILURE(rc)) 864 { 865 *poffError = pElement->paArgs[1].offSpec; 866 return VERR_VFS_CHAIN_INVALID_ARGUMENT; 867 } 868 } 869 } 870 871 /* 872 * Save the parsed arguments in the spec since their both optional. 873 */ 874 pSpec->uProvider = RT_MAKE_U64(cBuffers, cbBuffer); 875 876 return VINF_SUCCESS; 877 } 878 879 880 /** 881 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnInstantiate} 882 */ 883 static DECLCALLBACK(int) rtVfsChainReadAhead_Instantiate(PCRTVFSCHAINELEMENTREG pProviderReg, PCRTVFSCHAINSPEC pSpec, 884 PCRTVFSCHAINELEMSPEC pElement, RTVFSOBJ hPrevVfsObj, 885 PRTVFSOBJ phVfsObj, uint32_t *poffError) 886 { 887 RT_NOREF(pProviderReg, pSpec, pElement, poffError); 888 AssertReturn(hPrevVfsObj != NIL_RTVFSOBJ, VERR_VFS_CHAIN_IPE); 889 890 /* Try for a file if we can. */ 891 int rc; 892 RTVFSFILE hVfsFileIn = RTVfsObjToFile(hPrevVfsObj); 893 if (hVfsFileIn != NIL_RTVFSFILE) 894 { 895 RTVFSFILE hVfsFile = NIL_RTVFSFILE; 896 rc = RTVfsCreateReadAheadForFile(hVfsFileIn, 0 /*fFlags*/, RT_LO_U32(pSpec->uProvider), 897 RT_HI_U32(pSpec->uProvider), &hVfsFile); 898 RTVfsFileRelease(hVfsFileIn); 899 if (RT_SUCCESS(rc)) 900 { 901 *phVfsObj = RTVfsObjFromFile(hVfsFile); 902 RTVfsFileRelease(hVfsFile); 903 if (*phVfsObj != NIL_RTVFSOBJ) 904 return VINF_SUCCESS; 905 rc = VERR_VFS_CHAIN_CAST_FAILED; 906 } 907 } 908 else if (pElement->enmType == RTVFSOBJTYPE_IO_STREAM) 909 { 910 RTVFSIOSTREAM hVfsIosIn = RTVfsObjToIoStream(hPrevVfsObj); 911 if (hVfsIosIn != NIL_RTVFSIOSTREAM) 912 { 913 RTVFSIOSTREAM hVfsIos = NIL_RTVFSIOSTREAM; 914 rc = RTVfsCreateReadAheadForIoStream(hVfsIosIn, 0 /*fFlags*/, RT_LO_U32(pSpec->uProvider), 915 RT_HI_U32(pSpec->uProvider), &hVfsIos); 916 RTVfsIoStrmRelease(hVfsIosIn); 917 if (RT_SUCCESS(rc)) 918 { 919 *phVfsObj = RTVfsObjFromIoStream(hVfsIos); 920 RTVfsIoStrmRelease(hVfsIos); 921 if (*phVfsObj != NIL_RTVFSOBJ) 922 return VINF_SUCCESS; 923 rc = VERR_VFS_CHAIN_CAST_FAILED; 924 } 925 } 926 else 927 rc = VERR_VFS_CHAIN_CAST_FAILED; 928 } 929 else 930 rc = VERR_VFS_CHAIN_CAST_FAILED; 931 return rc; 932 } 933 934 935 /** 936 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnCanReuseElement} 937 */ 938 static DECLCALLBACK(bool) rtVfsChainReadAhead_CanReuseElement(PCRTVFSCHAINELEMENTREG pProviderReg, 939 PCRTVFSCHAINSPEC pSpec, PCRTVFSCHAINELEMSPEC pElement, 940 PCRTVFSCHAINSPEC pReuseSpec, PCRTVFSCHAINELEMSPEC pReuseElement) 941 { 942 RT_NOREF(pProviderReg, pSpec, pElement, pReuseSpec, pReuseElement); 943 return false; 944 } 945 946 947 /** VFS chain element 'pull'. */ 948 static RTVFSCHAINELEMENTREG g_rtVfsChainReadAheadReg = 949 { 950 /* uVersion = */ RTVFSCHAINELEMENTREG_VERSION, 951 /* fReserved = */ 0, 952 /* pszName = */ "pull", 953 /* ListEntry = */ { NULL, NULL }, 954 /* pszHelp = */ "Takes an I/O stream or file and provides read-ahead caching.\n" 955 "Optional first argument specifies how many buffers to use, 0 indicating the default.\n" 956 "Optional second argument specifies the buffer size, 0 indicating the default.", 957 /* pfnValidate = */ rtVfsChainReadAhead_Validate, 958 /* pfnInstantiate = */ rtVfsChainReadAhead_Instantiate, 959 /* pfnCanReuseElement = */ rtVfsChainReadAhead_CanReuseElement, 960 /* uEndMarker = */ RTVFSCHAINELEMENTREG_VERSION 961 }; 962 963 RTVFSCHAIN_AUTO_REGISTER_ELEMENT_PROVIDER(&g_rtVfsChainReadAheadReg, rtVfsChainReadAheadReg); 964
Note:
See TracChangeset
for help on using the changeset viewer.

