Changeset 39031 in vbox
- Timestamp:
- Oct 19, 2011 11:01:20 AM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/PDMAsyncCompletionFile.cpp
r38886 r39031 5 5 6 6 /* 7 * Copyright (C) 2006-20 09Oracle Corporation7 * Copyright (C) 2006-2011 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 42 42 #include <iprt/path.h> 43 43 44 #if defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)45 # include <errno.h>46 # include <sys/ioctl.h>47 # include <sys/types.h>48 # include <sys/stat.h>49 # include <fcntl.h>50 # include <unistd.h>51 #endif52 53 #ifdef RT_OS_WINDOWS54 # define _WIN32_WINNT 0x050055 # include <windows.h>56 # include <winioctl.h>57 #endif58 #ifdef RT_OS_DARWIN59 # include <sys/disk.h>60 #endif /* RT_OS_DARWIN */61 #ifdef RT_OS_SOLARIS62 # include <stropts.h>63 # include <sys/dkio.h>64 # include <sys/vtoc.h>65 #endif /* RT_OS_SOLARIS */66 #ifdef RT_OS_FREEBSD67 # include <sys/disk.h>68 #endif /* RT_OS_FREEBSD */69 70 44 #include "PDMAsyncCompletionFileInternal.h" 71 45 … … 111 85 }; 112 86 #endif 87 113 88 114 89 /** … … 119 94 * @param pTask The task to free. 120 95 */ 121 void pdmacFileTaskFree(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, 122 PPDMACTASKFILE pTask) 96 void pdmacFileTaskFree(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMACTASKFILE pTask) 123 97 { 124 98 PPDMASYNCCOMPLETIONEPCLASSFILE pEpClass = (PPDMASYNCCOMPLETIONEPCLASSFILE)pEndpoint->Core.pEpClass; … … 186 160 PPDMACTASKFILE pdmacFileEpGetNewTasks(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint) 187 161 { 188 PPDMACTASKFILE pTasks = NULL;189 190 162 /* 191 163 * Get pending tasks. 192 164 */ 193 pTasks = ASMAtomicXchgPtrT(&pEndpoint->pTasksNewHead, NULL, PPDMACTASKFILE);165 PPDMACTASKFILE pTasks = ASMAtomicXchgPtrT(&pEndpoint->pTasksNewHead, NULL, PPDMACTASKFILE); 194 166 195 167 /* Reverse the list to process in FIFO order. */ … … 215 187 { 216 188 bool fWokenUp = ASMAtomicXchgBool(&pAioMgr->fWokenUp, true); 217 218 189 if (!fWokenUp) 219 190 { 220 int rc = VINF_SUCCESS;221 191 bool fWaitingEventSem = ASMAtomicReadBool(&pAioMgr->fWaitingEventSem); 222 223 192 if (fWaitingEventSem) 224 rc = RTSemEventSignal(pAioMgr->EventSem); 225 226 AssertRC(rc); 193 { 194 int rc = RTSemEventSignal(pAioMgr->EventSem); 195 AssertRC(rc); 196 } 227 197 } 228 198 } … … 230 200 static int pdmacFileAioMgrWaitForBlockingEvent(PPDMACEPFILEMGR pAioMgr, PDMACEPFILEAIOMGRBLOCKINGEVENT enmEvent) 231 201 { 232 int rc = VINF_SUCCESS;233 234 202 ASMAtomicWriteU32((volatile uint32_t *)&pAioMgr->enmBlockingEvent, enmEvent); 235 203 Assert(!pAioMgr->fBlockingEventPending); … … 240 208 241 209 /* Wait for completion. */ 242 rc = RTSemEventWait(pAioMgr->EventSemBlock, RT_INDEFINITE_WAIT);210 int rc = RTSemEventWait(pAioMgr->EventSemBlock, RT_INDEFINITE_WAIT); 243 211 AssertRC(rc); 244 212 … … 251 219 int pdmacFileAioMgrAddEndpoint(PPDMACEPFILEMGR pAioMgr, PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint) 252 220 { 253 int rc;254 255 221 LogFlowFunc(("pAioMgr=%#p pEndpoint=%#p{%s}\n", pAioMgr, pEndpoint, pEndpoint->Core.pszUri)); 256 222 … … 258 224 ASMAtomicWritePtr(&pEndpoint->pAioMgr, pAioMgr); 259 225 260 rc = RTCritSectEnter(&pAioMgr->CritSectBlockingEvent);226 int rc = RTCritSectEnter(&pAioMgr->CritSectBlockingEvent); 261 227 AssertRCReturn(rc, rc); 262 228 … … 272 238 static int pdmacFileAioMgrRemoveEndpoint(PPDMACEPFILEMGR pAioMgr, PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint) 273 239 { 274 int rc; 275 276 rc = RTCritSectEnter(&pAioMgr->CritSectBlockingEvent); 240 int rc = RTCritSectEnter(&pAioMgr->CritSectBlockingEvent); 277 241 AssertRCReturn(rc, rc); 278 242 … … 288 252 static int pdmacFileAioMgrCloseEndpoint(PPDMACEPFILEMGR pAioMgr, PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint) 289 253 { 290 int rc; 291 292 rc = RTCritSectEnter(&pAioMgr->CritSectBlockingEvent); 254 int rc = RTCritSectEnter(&pAioMgr->CritSectBlockingEvent); 293 255 AssertRCReturn(rc, rc); 294 256 … … 304 266 static int pdmacFileAioMgrShutdown(PPDMACEPFILEMGR pAioMgr) 305 267 { 306 int rc; 307 308 rc = RTCritSectEnter(&pAioMgr->CritSectBlockingEvent); 268 int rc = RTCritSectEnter(&pAioMgr->CritSectBlockingEvent); 309 269 AssertRCReturn(rc, rc); 310 270 … … 337 297 338 298 if (pTask->enmTransferType == PDMACTASKFILETRANSFER_FLUSH) 339 {340 299 pdmR3AsyncCompletionCompleteTask(&pTaskFile->Core, rc, true); 341 }342 300 else 343 301 { … … 414 372 PPDMASYNCCOMPLETIONENDPOINTFILE pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEndpoint; 415 373 PPDMASYNCCOMPLETIONTASKFILE pTaskFile = (PPDMASYNCCOMPLETIONTASKFILE)pTask; 416 PPDMACEPFILEMGR pAioMgr = pEpFile->pAioMgr;417 374 418 375 Assert( (enmTransfer == PDMACTASKFILETRANSFER_READ) 419 376 || (enmTransfer == PDMACTASKFILETRANSFER_WRITE)); 420 377 421 for ( unsignedi = 0; i < cSegments; i++)378 for (size_t i = 0; i < cSegments; i++) 422 379 { 423 380 PPDMACTASKFILE pIoTask = pdmacFileTaskAlloc(pEpFile); … … 454 411 PDMACEPFILEMGRTYPE enmMgrType) 455 412 { 456 int rc = VINF_SUCCESS; 413 LogFlowFunc((": Entered\n")); 414 457 415 PPDMACEPFILEMGR pAioMgrNew; 458 459 LogFlowFunc((": Entered\n")); 460 461 rc = MMR3HeapAllocZEx(pEpClass->Core.pVM, MM_TAG_PDM_ASYNC_COMPLETION, sizeof(PDMACEPFILEMGR), (void **)&pAioMgrNew); 416 int rc = MMR3HeapAllocZEx(pEpClass->Core.pVM, MM_TAG_PDM_ASYNC_COMPLETION, sizeof(PDMACEPFILEMGR), (void **)&pAioMgrNew); 462 417 if (RT_SUCCESS(rc)) 463 418 { … … 627 582 static int pdmacFileEpNativeGetSize(RTFILE hFile, uint64_t *pcbSize) 628 583 { 629 int rc = VINF_SUCCESS; 630 uint64_t cbSize = 0; 631 632 rc = RTFileGetSize(hFile, &cbSize); 633 if (RT_SUCCESS(rc) && (cbSize != 0)) 634 *pcbSize = cbSize; 635 else 636 { 637 #ifdef RT_OS_WINDOWS 638 DISK_GEOMETRY DriveGeo; 639 DWORD cbDriveGeo; 640 if (DeviceIoControl((HANDLE)RTFileToNative(hFile), 641 IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, 642 &DriveGeo, sizeof(DriveGeo), &cbDriveGeo, NULL)) 643 { 644 if ( DriveGeo.MediaType == FixedMedia 645 || DriveGeo.MediaType == RemovableMedia) 646 { 647 cbSize = DriveGeo.Cylinders.QuadPart 648 * DriveGeo.TracksPerCylinder 649 * DriveGeo.SectorsPerTrack 650 * DriveGeo.BytesPerSector; 651 652 GET_LENGTH_INFORMATION DiskLenInfo; 653 DWORD junk; 654 if (DeviceIoControl((HANDLE)RTFileToNative(hFile), 655 IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, 656 &DiskLenInfo, sizeof(DiskLenInfo), &junk, (LPOVERLAPPED)NULL)) 657 { 658 /* IOCTL_DISK_GET_LENGTH_INFO is supported -- override cbSize. */ 659 cbSize = DiskLenInfo.Length.QuadPart; 660 } 661 662 rc = VINF_SUCCESS; 663 } 664 else 665 { 666 rc = VERR_INVALID_PARAMETER; 667 } 668 } 669 else 670 rc = RTErrConvertFromWin32(GetLastError()); 671 672 #elif defined(RT_OS_DARWIN) 673 struct stat DevStat; 674 if (!fstat(RTFileToNative(hFile), &DevStat) && S_ISBLK(DevStat.st_mode)) 675 { 676 uint64_t cBlocks; 677 uint32_t cbBlock; 678 if (!ioctl(RTFileToNative(hFile), DKIOCGETBLOCKCOUNT, &cBlocks)) 679 { 680 if (!ioctl(RTFileToNative(hFile), DKIOCGETBLOCKSIZE, &cbBlock)) 681 cbSize = cBlocks * cbBlock; 682 else 683 rc = RTErrConvertFromErrno(errno); 684 } 685 else 686 rc = RTErrConvertFromErrno(errno); 687 } 584 uint64_t cbFile; 585 int rc = RTFileGetSize(hFile, &cbFile); 586 if (RT_SUCCESS(rc)) 587 { 588 if (cbFile != 0) 589 *pcbSize = cbFile; 688 590 else 689 591 rc = VERR_INVALID_PARAMETER; 690 691 #elif defined(RT_OS_SOLARIS)692 struct stat DevStat;693 if ( !fstat(RTFileToNative(hFile), &DevStat)694 && ( S_ISBLK(DevStat.st_mode)695 || S_ISCHR(DevStat.st_mode)))696 {697 struct dk_minfo mediainfo;698 if (!ioctl(RTFileToNative(hFile), DKIOCGMEDIAINFO, &mediainfo))699 cbSize = mediainfo.dki_capacity * mediainfo.dki_lbsize;700 else701 rc = RTErrConvertFromErrno(errno);702 }703 else704 rc = VERR_INVALID_PARAMETER;705 706 #elif defined(RT_OS_FREEBSD)707 struct stat DevStat;708 if (!fstat(RTFileToNative(hFile), &DevStat) && S_ISCHR(DevStat.st_mode))709 {710 off_t cbMedia = 0;711 if (!ioctl(RTFileToNative(hFile), DIOCGMEDIASIZE, &cbMedia))712 {713 cbSize = cbMedia;714 }715 else716 rc = RTErrConvertFromErrno(errno);717 }718 else719 rc = VERR_INVALID_PARAMETER;720 #else721 /* Could be a block device */722 rc = RTFileSeek(hFile, 0, RTFILE_SEEK_END, &cbSize);723 #endif724 725 if (RT_SUCCESS(rc) && (cbSize != 0))726 *pcbSize = cbSize;727 else if (RT_SUCCESS(rc))728 rc = VERR_NOT_SUPPORTED;729 592 } 730 593 … … 733 596 734 597 #ifdef VBOX_WITH_DEBUGGER 598 735 599 /** 736 600 * Error inject callback. … … 867 731 static int pdmacFileInitialize(PPDMASYNCCOMPLETIONEPCLASS pClassGlobals, PCFGMNODE pCfgNode) 868 732 { 869 int rc = VINF_SUCCESS;870 RTFILEAIOLIMITS AioLimits; /** < Async I/O limitations. */871 872 733 PPDMASYNCCOMPLETIONEPCLASSFILE pEpClassFile = (PPDMASYNCCOMPLETIONEPCLASSFILE)pClassGlobals; 873 874 rc = RTFileAioGetLimits(&AioLimits); 734 RTFILEAIOLIMITS AioLimits; /** < Async I/O limitations. */ 735 736 int rc = RTFileAioGetLimits(&AioLimits); 875 737 #ifdef DEBUG 876 738 if (RT_SUCCESS(rc) && RTEnvExist("VBOX_ASYNC_IO_FAILBACK")) … … 963 825 const char *pszUri, uint32_t fFlags) 964 826 { 965 int rc = VINF_SUCCESS;966 827 PPDMASYNCCOMPLETIONENDPOINTFILE pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEndpoint; 967 828 PPDMASYNCCOMPLETIONEPCLASSFILE pEpClassFile = (PPDMASYNCCOMPLETIONEPCLASSFILE)pEndpoint->pEpClass; … … 1004 865 fFileFlags |= RTFILE_O_ASYNC_IO; 1005 866 867 int rc; 1006 868 if (enmEpBackend == PDMACFILEEPBACKEND_NON_BUFFERED) 1007 869 { … … 1041 903 /* Open with final flags. */ 1042 904 rc = RTFileOpen(&pEpFile->hFile, pszUri, fFileFlags); 1043 if ((rc == VERR_INVALID_FUNCTION) || (rc == VERR_INVALID_PARAMETER)) 905 if ( rc == VERR_INVALID_FUNCTION 906 || rc == VERR_INVALID_PARAMETER) 1044 907 { 1045 908 LogRel(("pdmacFileEpInitialize: RTFileOpen %s / %08x failed with %Rrc\n", … … 1180 1043 static int pdmacFileEpClose(PPDMASYNCCOMPLETIONENDPOINT pEndpoint) 1181 1044 { 1182 int rc = VINF_SUCCESS; 1183 PPDMASYNCCOMPLETIONENDPOINTFILE pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEndpoint; 1184 PPDMASYNCCOMPLETIONEPCLASSFILE pEpClassFile = (PPDMASYNCCOMPLETIONEPCLASSFILE)pEndpoint->pEpClass; 1045 PPDMASYNCCOMPLETIONENDPOINTFILE pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEndpoint; 1046 PPDMASYNCCOMPLETIONEPCLASSFILE pEpClassFile = (PPDMASYNCCOMPLETIONEPCLASSFILE)pEndpoint->pEpClass; 1185 1047 1186 1048 /* Make sure that all tasks finished for this endpoint. */ 1187 rc = pdmacFileAioMgrCloseEndpoint(pEpFile->pAioMgr, pEpFile);1049 int rc = pdmacFileAioMgrCloseEndpoint(pEpFile->pAioMgr, pEpFile); 1188 1050 AssertRC(rc); 1189 1051 … … 1223 1085 size_t cbRead) 1224 1086 { 1225 int rc = VINF_SUCCESS;1226 1087 PPDMASYNCCOMPLETIONENDPOINTFILE pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEndpoint; 1227 1088 … … 1231 1092 STAM_PROFILE_ADV_START(&pEpFile->StatRead, Read); 1232 1093 pdmacFileEpTaskInit(pTask, cbRead); 1233 rc = pdmacFileEpTaskInitiate(pTask, pEndpoint, off, paSegments, cSegments, cbRead,1234 PDMACTASKFILETRANSFER_READ);1094 int rc = pdmacFileEpTaskInitiate(pTask, pEndpoint, off, paSegments, cSegments, cbRead, 1095 PDMACTASKFILETRANSFER_READ); 1235 1096 STAM_PROFILE_ADV_STOP(&pEpFile->StatRead, Read); 1236 1097 … … 1243 1104 size_t cbWrite) 1244 1105 { 1245 int rc = VINF_SUCCESS;1246 1106 PPDMASYNCCOMPLETIONENDPOINTFILE pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEndpoint; 1247 1107 … … 1253 1113 pdmacFileEpTaskInit(pTask, cbWrite); 1254 1114 1255 rc = pdmacFileEpTaskInitiate(pTask, pEndpoint, off, paSegments, cSegments, cbWrite,1256 PDMACTASKFILETRANSFER_WRITE);1115 int rc = pdmacFileEpTaskInitiate(pTask, pEndpoint, off, paSegments, cSegments, cbWrite, 1116 PDMACTASKFILETRANSFER_WRITE); 1257 1117 1258 1118 STAM_PROFILE_ADV_STOP(&pEpFile->StatWrite, Write); … … 1264 1124 PPDMASYNCCOMPLETIONENDPOINT pEndpoint) 1265 1125 { 1266 PPDMASYNCCOMPLETIONENDPOINTFILE pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEndpoint;1267 PPDMASYNCCOMPLETIONTASKFILE pTaskFile = (PPDMASYNCCOMPLETIONTASKFILE)pTask;1126 PPDMASYNCCOMPLETIONENDPOINTFILE pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEndpoint; 1127 PPDMASYNCCOMPLETIONTASKFILE pTaskFile = (PPDMASYNCCOMPLETIONTASKFILE)pTask; 1268 1128 1269 1129 if (RT_UNLIKELY(pEpFile->fReadonly))
Note:
See TracChangeset
for help on using the changeset viewer.