Changeset 75550 in vbox for trunk/src/VBox/Additions/os2/VBoxSF
- Timestamp:
- Nov 18, 2018 4:53:44 AM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/os2/VBoxSF/VBoxSFFile.cpp
r75543 r75550 464 464 } 465 465 466 #include <VBox/VBoxGuest.h> 467 468 469 470 471 DECLVBGL(int) VbglR0SfFastPhysFsInfo(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile, 472 uint32_t flags, uint32_t *pcbBuffer, PSHFLDIRINFO pBuffer) 473 { 474 struct FsInfoReq 475 { 476 VBGLIOCIDCHGCMFASTCALL Hdr; 477 VMMDevHGCMCall Call; 478 VBoxSFParmInformation Parms; 479 HGCMPageListInfo PgLst; 480 RTGCPHYS64 PageTwo; 481 } *pReq; 482 AssertCompileMemberOffset(struct FsInfoReq, Call, 52); 483 AssertCompileMemberOffset(struct FsInfoReq, Parms, 0x60); 484 485 pReq = (struct FsInfoReq *)VbglR0PhysHeapAlloc(sizeof(*pReq)); 486 if (!pReq) 487 return VERR_NO_MEMORY; 488 489 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, pClient->idClient, 490 SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, sizeof(*pReq)); 491 #if 0 492 VBGLREQHDR_INIT_EX(&pReq->Hdr.Hdr, sizeof(*pReq), sizeof(*pReq)); 493 pReq->Hdr.GCPhysReq = VbglR0PhysHeapGetPhysAddr(pReq) + sizeof(pReq->Hdr); 494 pReq->Hdr.fInterruptible = false; 495 496 pReq->Call.header.header.size = sizeof(*pReq) - sizeof(pReq->Hdr); 497 pReq->Call.header.header.version = VBGLREQHDR_VERSION; 498 pReq->Call.header.header.requestType= VMMDevReq_HGCMCall32; 499 pReq->Call.header.header.rc = VERR_INTERNAL_ERROR; 500 pReq->Call.header.header.reserved1 = 0; 501 pReq->Call.header.header.fRequestor = VMMDEV_REQUESTOR_KERNEL | VMMDEV_REQUESTOR_USR_DRV_OTHER 502 | VMMDEV_REQUESTOR_CON_DONT_KNOW | VMMDEV_REQUESTOR_TRUST_NOT_GIVEN; 503 pReq->Call.header.fu32Flags = 0; 504 pReq->Call.header.result = VERR_INTERNAL_ERROR; 505 pReq->Call.u32ClientID = pClient->idClient; 506 pReq->Call.u32Function = SHFL_FN_INFORMATION; 507 pReq->Call.cParms = SHFL_CPARMS_INFORMATION; 508 #endif 509 uint32_t const cbBuffer = *pcbBuffer; 510 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit; 511 pReq->Parms.id32Root.u.value32 = pMap->root; 512 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit; 513 pReq->Parms.u64Handle.u.value64 = hFile; 514 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit; 515 pReq->Parms.f32Flags.u.value32 = flags; 516 pReq->Parms.cb32.type = VMMDevHGCMParmType_32bit; 517 pReq->Parms.cb32.u.value32 = cbBuffer; 518 pReq->Parms.pInfo.type = VMMDevHGCMParmType_PageList; 519 pReq->Parms.pInfo.u.PageList.size = cbBuffer; 520 pReq->Parms.pInfo.u.PageList.offset = RT_UOFFSETOF(struct FsInfoReq, PgLst) - RT_UOFFSETOF(struct FsInfoReq, Call); 521 522 Assert(cbBuffer < _1K); 523 pReq->PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST; 524 pReq->PgLst.cPages = cbBuffer <= (PAGE_SIZE - ((uintptr_t)pBuffer & PAGE_OFFSET_MASK)) ? 1 : 2; 525 pReq->PgLst.offFirstPage = (uint16_t)((uintptr_t)pBuffer & PAGE_OFFSET_MASK); 526 pReq->PgLst.aPages[0] = VbglR0PhysHeapGetPhysAddr(pBuffer) & ~(RTGCPHYS64)PAGE_OFFSET_MASK; 527 if (pReq->PgLst.cPages == 1) 528 pReq->PageTwo = NIL_RTGCPHYS64; 529 else 530 pReq->PageTwo = pReq->PgLst.aPages[0] + PAGE_SIZE; 531 532 int rc = VbglR0HGCMFastCall(pClient->handle, &pReq->Hdr, sizeof(*pReq)); 533 if (RT_SUCCESS(rc)) 534 { 535 rc = pReq->Call.header.result; 536 *pcbBuffer = pReq->Parms.cb32.u.value32; 537 } 538 VbglR0PhysHeapFree(pReq); 539 return rc; 540 } 541 542 543 DECLVBGL(int) VbglR0SfPhysFsInfo(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile, 544 uint32_t flags, uint32_t *pcbBuffer, PSHFLDIRINFO pBuffer) 545 { 546 uint32_t const cbBuffer = *pcbBuffer; 547 548 struct 549 { 550 VBoxSFInformation Core; 551 HGCMPageListInfo PgLst; 552 RTGCPHYS64 PageTwo; 553 } Req; 554 555 VBGL_HGCM_HDR_INIT_EX(&Req.Core.callInfo, pClient->idClient, SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, sizeof(Req)); 556 Req.Core.callInfo.fInterruptible = false; 557 558 Req.Core.root.type = VMMDevHGCMParmType_32bit; 559 Req.Core.root.u.value32 = pMap->root; 560 561 Req.Core.handle.type = VMMDevHGCMParmType_64bit; 562 Req.Core.handle.u.value64 = hFile; 563 Req.Core.flags.type = VMMDevHGCMParmType_32bit; 564 Req.Core.flags.u.value32 = flags; 565 Req.Core.cb.type = VMMDevHGCMParmType_32bit; 566 Req.Core.cb.u.value32 = cbBuffer; 567 Req.Core.info.type = VMMDevHGCMParmType_PageList; 568 Req.Core.info.u.PageList.size = cbBuffer; 569 Req.Core.info.u.PageList.offset = sizeof(Req.Core); 570 571 Assert(cbBuffer < _1K); 572 Req.PgLst.flags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST; 573 Req.PgLst.cPages = cbBuffer <= (PAGE_SIZE - ((uintptr_t)pBuffer & PAGE_OFFSET_MASK)) ? 1 : 2; 574 Req.PgLst.offFirstPage = (uint16_t)((uintptr_t)pBuffer & PAGE_OFFSET_MASK); 575 Req.PgLst.aPages[0] = VbglR0PhysHeapGetPhysAddr(pBuffer) & ~(RTGCPHYS64)PAGE_OFFSET_MASK; 576 if (Req.PgLst.cPages == 1) 577 Req.PageTwo = NIL_RTGCPHYS64; 578 else 579 Req.PageTwo = Req.PgLst.aPages[0] + PAGE_SIZE; 580 581 int rc = VbglR0HGCMCallRaw(pClient->handle, &Req.Core.callInfo, sizeof(Req)); 582 //Log(("VBOXSF: VbglR0SfFsInfo: VbglR0HGCMCall rc = %#x, result = %#x\n", rc, data.callInfo.Hdr.rc)); 583 if (RT_SUCCESS(rc)) 584 { 585 rc = Req.Core.callInfo.Hdr.rc; 586 *pcbBuffer = Req.Core.cb.u.value32; 587 } 588 return rc; 589 } 590 466 591 467 592 /** … … 480 605 vboxSfOs2QueryFileInfo(PVBOXSFFOLDER pFolder, PSFFSI pSfFsi, PVBOXSFSYFI pSfFsd, ULONG uLevel, PBYTE pbData, ULONG cbData) 481 606 { 607 /* 608 * Performance notes: 609 * 610 * This function was used for some performance hacking in an attempt at 611 * squeezing more performance out of the HGCM and shared folders code. 612 * 613 * 0. Skip calling the host and returning zeros: 614 * 906 ns / 3653 ticks 615 * 616 * This is comparable to JFS (859 ns) and HPFS (1107 ns) and give an 617 * idea what we're up against compared to a "local" file system. 618 * 619 * 1. Having shortcircuted the host side processing by faking a success when 620 * VMMDevHGCM.cpp is about to do pThis->pHGCMDrv->pfnCall, then measuring 621 * various guest side changes in the request and request submission path: 622 * 623 * - Wasted on virtual address vs page list buffer: 624 * 4095 ns / 16253 ticks 625 * 626 * Suspect this is due to expensive memory locking on the guest side and 627 * the host doing extra virtual address conversion. 628 * 629 * - Wasted repackaging the HGCM request: 630 * 450 ns / 1941 ticks 631 * 632 * - Embedding the SHFLFSOBJINFO into the buffer may save a little as well: 633 * 286 ns / 1086 ticks 634 * 635 * Raw data: 636 * 11843ns / 47469 ticks - VbglR0SfFsInfo 637 * 7748ns / 31216 ticks - VbglR0SfPhysFsInfo 638 * 7298ns / 29275 ticks - VbglR0SfFastPhysFsInfo 639 * 7012ns / 28189 ticks - Embedded buffer. 640 * 641 * 2. should've done measurements of the host side optimizations too... 642 * 643 */ 644 #if 0 482 645 APIRET rc; 483 646 PSHFLFSOBJINFO pObjInfo = (PSHFLFSOBJINFO)VbglR0PhysHeapAlloc(sizeof(*pObjInfo)); … … 487 650 uint32_t cbObjInfo = sizeof(*pObjInfo); 488 651 489 int vrc = VbglR0SfF sInfo(&g_SfClient, &pFolder->hHostFolder, pSfFsd->hHostFile,490 SHFL_INFO_FILE | SHFL_INFO_GET, &cbObjInfo, (PSHFLDIRINFO)pObjInfo);652 int vrc = VbglR0SfFastPhysFsInfo(&g_SfClient, &pFolder->hHostFolder, pSfFsd->hHostFile, 653 SHFL_INFO_FILE | SHFL_INFO_GET, &cbObjInfo, (PSHFLDIRINFO)pObjInfo); 491 654 if (RT_SUCCESS(vrc)) 492 655 { … … 513 676 else 514 677 rc = ERROR_NOT_ENOUGH_MEMORY; 678 #else 679 APIRET rc; 680 struct MyEmbReq 681 { 682 VBGLIOCIDCHGCMFASTCALL Hdr; 683 VMMDevHGCMCall Call; 684 VBoxSFParmInformation Parms; 685 SHFLFSOBJINFO ObjInfo; 686 } *pReq = (struct MyEmbReq *)VbglR0PhysHeapAlloc(sizeof(*pReq)); 687 if (pReq) 688 { 689 RT_ZERO(pReq->ObjInfo); 690 691 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClient.idClient, 692 SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, sizeof(*pReq)); 693 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit; 694 pReq->Parms.id32Root.u.value32 = pFolder->hHostFolder.root; 695 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit; 696 pReq->Parms.u64Handle.u.value64 = pSfFsd->hHostFile; 697 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit; 698 pReq->Parms.f32Flags.u.value32 = SHFL_INFO_FILE | SHFL_INFO_GET; 699 pReq->Parms.cb32.type = VMMDevHGCMParmType_32bit; 700 pReq->Parms.cb32.u.value32 = sizeof(pReq->ObjInfo); 701 pReq->Parms.pInfo.type = VMMDevHGCMParmType_Embedded; 702 pReq->Parms.pInfo.u.Embedded.cbData = sizeof(pReq->ObjInfo); 703 pReq->Parms.pInfo.u.Embedded.offData = RT_UOFFSETOF(struct MyEmbReq, ObjInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL); 704 pReq->Parms.pInfo.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST; 705 706 int vrc = VbglR0HGCMFastCall(g_SfClient.handle, &pReq->Hdr, sizeof(*pReq)); 707 if (RT_SUCCESS(vrc)) 708 vrc = pReq->Call.header.result; 709 if (RT_SUCCESS(vrc)) 710 { 711 rc = vboxSfOs2FileStatusFromObjInfo(pbData, cbData, uLevel, &pReq->ObjInfo); 712 if (rc == NO_ERROR) 713 { 714 /* Update the timestamps in the independent file data: */ 715 int16_t cMinLocalTimeDelta = vboxSfOs2GetLocalTimeDelta(); 716 vboxSfOs2DateTimeFromTimeSpec(&pSfFsi->sfi_cdate, &pSfFsi->sfi_ctime, pReq->ObjInfo.BirthTime, cMinLocalTimeDelta); 717 vboxSfOs2DateTimeFromTimeSpec(&pSfFsi->sfi_adate, &pSfFsi->sfi_atime, pReq->ObjInfo.AccessTime, cMinLocalTimeDelta); 718 vboxSfOs2DateTimeFromTimeSpec(&pSfFsi->sfi_mdate, &pSfFsi->sfi_mtime, pReq->ObjInfo.ModificationTime, cMinLocalTimeDelta); 719 720 /* And the size field as we're at it: */ 721 pSfFsi->sfi_sizel = pReq->ObjInfo.cbObject; 722 } 723 } 724 else 725 { 726 Log(("vboxSfOs2QueryFileInfo: VbglR0SfFsInfo failed: %Rrc\n", vrc)); 727 rc = vboxSfOs2ConvertStatusToOs2(vrc, ERROR_GEN_FAILURE); 728 } 729 730 VbglR0PhysHeapFree(pReq); 731 } 732 else 733 rc = ERROR_NOT_ENOUGH_MEMORY; 734 #endif 515 735 return rc; 516 736 }
Note:
See TracChangeset
for help on using the changeset viewer.