Changeset 77561 in vbox for trunk/src/VBox/Additions/linux
- Timestamp:
- Mar 4, 2019 7:56:32 PM (6 years ago)
- Location:
- trunk/src/VBox/Additions/linux/sharedfolders
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/linux/sharedfolders/dirops.c
r77559 r77561 1117 1117 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 18) 1118 1118 .getattr = vbsf_inode_getattr, 1119 #else 1120 .revalidate = vbsf_inode_revalidate, 1121 #endif 1119 1122 .setattr = vbsf_inode_setattr, 1120 #else1121 .revalidate = vbsf_inode_revalidate1122 #endif1123 1123 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) 1124 .symlink = vbsf_ino_symlink 1124 .symlink = vbsf_ino_symlink, 1125 1125 #endif 1126 1126 }; -
trunk/src/VBox/Additions/linux/sharedfolders/regops.c
r77559 r77561 1361 1361 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 18) 1362 1362 .getattr = vbsf_inode_getattr, 1363 .setattr = vbsf_inode_setattr1364 1363 #else 1365 .revalidate = vbsf_inode_revalidate 1366 #endif 1364 .revalidate = vbsf_inode_revalidate, 1365 #endif 1366 .setattr = vbsf_inode_setattr, 1367 1367 }; 1368 1368 -
trunk/src/VBox/Additions/linux/sharedfolders/utils.c
r77559 r77561 571 571 572 572 /* Add birth time. */ 573 # if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)573 # if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) 574 574 if (dentry->d_inode) { 575 575 struct vbsf_inode_info *pInodeInfo = VBSF_GET_INODE_INFO(dentry->d_inode); … … 579 579 } 580 580 } 581 # endif581 # endif 582 582 583 583 /* … … 608 608 return rc; 609 609 } 610 611 610 #endif /* >= 2.5.18 */ 611 612 613 /** 614 * Modify inode attributes. 615 */ 612 616 int vbsf_inode_setattr(struct dentry *dentry, struct iattr *iattr) 613 617 { 614 struct vbsf_super_info *sf_g; 615 struct vbsf_inode_info *sf_i; 616 union SetAttrReqs 617 { 618 VBOXSFCREATEREQ Create; 619 VBOXSFOBJINFOREQ Info; 620 VBOXSFSETFILESIZEREQ SetSize; 621 VBOXSFCLOSEREQ Close; 622 } *pReq; 623 size_t cbReq; 624 SHFLHANDLE hHostFile; 618 struct inode *pInode = dentry->d_inode; 619 struct vbsf_super_info *sf_g = VBSF_GET_SUPER_INFO(pInode->i_sb); 620 struct vbsf_inode_info *sf_i = VBSF_GET_INODE_INFO(pInode); 625 621 int vrc; 626 int err = 0; 627 628 TRACE(); 629 630 sf_g = VBSF_GET_SUPER_INFO(dentry->d_inode->i_sb); 631 sf_i = VBSF_GET_INODE_INFO(dentry->d_inode); 632 cbReq = RT_MAX(sizeof(pReq->Info), sizeof(pReq->Create) + SHFLSTRING_HEADER_SIZE + sf_i->path->u16Size); 633 pReq = (union SetAttrReqs *)VbglR0PhysHeapAlloc(cbReq); 634 if (!pReq) { 635 LogFunc(("Failed to allocate %#x byte request buffer!\n", cbReq)); 636 return -ENOMEM; 637 } 638 639 RT_ZERO(pReq->Create.CreateParms); 640 pReq->Create.CreateParms.Handle = SHFL_HANDLE_NIL; 641 pReq->Create.CreateParms.CreateFlags = SHFL_CF_ACT_OPEN_IF_EXISTS 642 | SHFL_CF_ACT_FAIL_IF_NEW 643 | SHFL_CF_ACCESS_ATTR_WRITE; 644 645 /* this is at least required for Posix hosts */ 646 if (iattr->ia_valid & ATTR_SIZE) 647 pReq->Create.CreateParms.CreateFlags |= SHFL_CF_ACCESS_WRITE; 648 649 memcpy(&pReq->Create.StrPath, sf_i->path, SHFLSTRING_HEADER_SIZE + sf_i->path->u16Size); 650 vrc = VbglR0SfHostReqCreate(sf_g->map.root, &pReq->Create); 651 if (RT_SUCCESS(vrc)) { 652 hHostFile = pReq->Create.CreateParms.Handle; 653 } else { 654 err = -RTErrConvertToErrno(vrc); 655 LogFunc(("VbglR0SfCreate(%s) failed vrc=%Rrc err=%d\n", sf_i->path->String.ach, vrc, err)); 656 goto fail2; 657 } 658 if (pReq->Create.CreateParms.Result != SHFL_FILE_EXISTS) { 659 LogFunc(("file %s does not exist\n", sf_i->path->String.utf8)); 660 err = -ENOENT; 661 goto fail1; 662 } 663 664 /* Setting the file size and setting the other attributes has to be 665 * handled separately, see implementation of vbsfSetFSInfo() in 666 * vbsf.cpp */ 667 if (iattr->ia_valid & (ATTR_MODE | ATTR_ATIME | ATTR_MTIME)) { 668 RT_ZERO(pReq->Info.ObjInfo); 669 670 if (iattr->ia_valid & ATTR_MODE) { 671 pReq->Info.ObjInfo.Attr.fMode = sf_access_permissions_to_vbox(iattr->ia_mode); 672 if (iattr->ia_mode & S_IFDIR) 673 pReq->Info.ObjInfo.Attr.fMode |= RTFS_TYPE_DIRECTORY; 674 else if (iattr->ia_mode & S_IFLNK) 675 pReq->Info.ObjInfo.Attr.fMode |= RTFS_TYPE_SYMLINK; 676 else 677 pReq->Info.ObjInfo.Attr.fMode |= RTFS_TYPE_FILE; 678 } 679 680 if (iattr->ia_valid & ATTR_ATIME) 681 vbsf_time_to_vbox(&pReq->Info.ObjInfo.AccessTime, &iattr->ia_atime); 682 if (iattr->ia_valid & ATTR_MTIME) 683 vbsf_time_to_vbox(&pReq->Info.ObjInfo.ModificationTime, &iattr->ia_mtime); 684 /* ignore ctime (inode change time) as it can't be set from userland anyway */ 685 686 vrc = VbglR0SfHostReqSetObjInfo(sf_g->map.root, &pReq->Info, hHostFile); 687 if (RT_FAILURE(vrc)) { 688 err = -RTErrConvertToErrno(vrc); 689 LogFunc(("VbglR0SfHostReqSetObjInfo(%s) failed vrc=%Rrc err=%d\n", sf_i->path->String.ach, vrc, err)); 690 goto fail1; 691 } 692 } 693 694 if (iattr->ia_valid & ATTR_SIZE) { 695 vrc = VbglR0SfHostReqSetFileSize(sf_g->map.root, &pReq->SetSize, hHostFile, iattr->ia_size); 696 /** @todo Implement fallback if host is < 6.0? */ 697 if (RT_FAILURE(vrc)) { 698 err = -RTErrConvertToErrno(vrc); 699 LogFunc(("VbglR0SfHostReqSetFileSize(%s, %#llx) failed vrc=%Rrc err=%d\n", 700 sf_i->path->String.ach, (unsigned long long)iattr->ia_size, vrc, err)); 701 goto fail1; 702 } 703 } 704 705 vrc = VbglR0SfHostReqClose(sf_g->map.root, &pReq->Close, hHostFile); 706 if (RT_FAILURE(vrc)) 707 LogFunc(("VbglR0SfHostReqClose(%s [%#llx]) failed vrc=%Rrc\n", sf_i->path->String.utf8, hHostFile, vrc)); 708 VbglR0PhysHeapFree(pReq); 709 710 /** @todo r=bird: I guess we're calling revalidate here to update the inode 711 * info. However, due to the TTL optimization this is not guarenteed to happen. 712 * 713 * Also, we already have accurate stat information on the file, either from the 714 * SHFL_FN_CREATE call or from SHFL_FN_INFORMATION, so there is no need to do a 715 * slow stat()-like operation to retrieve the information again. 716 * 717 * What's more, given that the SHFL_FN_CREATE call succeeded, we know that the 718 * dentry and all its parent entries are valid and could touch their timestamps 719 * extending their TTL (CIFS does that). */ 720 return vbsf_inode_revalidate_worker(dentry, true /*fForced*/, true /*fInodeLocked*/); 721 722 fail1: 723 vrc = VbglR0SfHostReqClose(sf_g->map.root, &pReq->Close, hHostFile); 724 if (RT_FAILURE(vrc)) 725 LogFunc(("VbglR0SfHostReqClose(%s [%#llx]) failed vrc=%Rrc; err=%d\n", sf_i->path->String.utf8, hHostFile, vrc, err)); 726 727 fail2: 728 VbglR0PhysHeapFree(pReq); 729 return err; 730 } 731 732 #endif /* >= 2.5.18 */ 622 int rc; 623 624 SFLOGFLOW(("vbsf_inode_setattr: dentry=%p inode=%p ia_valid=%#x %s\n", 625 dentry, pInode, iattr->ia_valid, sf_i ? sf_i->path->String.ach : NULL)); 626 AssertReturn(sf_i, -EINVAL); 627 628 /* 629 * Need to check whether the caller is allowed to modify the attributes or not. 630 */ 631 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) 632 rc = setattr_prepare(dentry, iattr); 633 #else 634 rc = inode_change_ok(pInode, iattr); 635 #endif 636 if (rc == 0) { 637 /* 638 * We only implement a handful of attributes, so ignore any attempts 639 * at setting bits we don't support. 640 */ 641 if (iattr->ia_valid & (ATTR_MODE | ATTR_ATIME | ATTR_MTIME | ATTR_CTIME | ATTR_SIZE)) { 642 /* 643 * Try find a handle which allows us to modify the attributes, otherwise 644 * open the file/dir/whatever. 645 */ 646 union SetAttrReqs 647 { 648 VBOXSFCREATEREQ Create; 649 VBOXSFOBJINFOREQ Info; 650 VBOXSFSETFILESIZEREQ SetSize; 651 VBOXSFCLOSEREQ Close; 652 } *pReq; 653 size_t cbReq; 654 SHFLHANDLE hHostFile; 655 struct vbsf_handle *pHandle = iattr->ia_valid & ATTR_SIZE 656 ? vbsf_handle_find(sf_i, VBSF_HANDLE_F_WRITE, 0) 657 : vbsf_handle_find(sf_i, 0, 0); 658 if (pHandle) { 659 hHostFile = pHandle->hHost; 660 cbReq = RT_MAX(sizeof(VBOXSFOBJINFOREQ), sizeof(VBOXSFSETFILESIZEREQ)); 661 pReq = (union SetAttrReqs *)VbglR0PhysHeapAlloc(cbReq); 662 if (pReq) { 663 /* likely */ 664 } else 665 rc = -ENOMEM; 666 } else { 667 hHostFile = SHFL_HANDLE_NIL; 668 cbReq = RT_MAX(sizeof(pReq->Info), sizeof(pReq->Create) + SHFLSTRING_HEADER_SIZE + sf_i->path->u16Size); 669 pReq = (union SetAttrReqs *)VbglR0PhysHeapAlloc(cbReq); 670 if (pReq) { 671 RT_ZERO(pReq->Create.CreateParms); 672 pReq->Create.CreateParms.Handle = SHFL_HANDLE_NIL; 673 pReq->Create.CreateParms.CreateFlags = SHFL_CF_ACT_OPEN_IF_EXISTS 674 | SHFL_CF_ACT_FAIL_IF_NEW 675 | SHFL_CF_ACCESS_ATTR_WRITE; 676 if (iattr->ia_valid & ATTR_SIZE) 677 pReq->Create.CreateParms.CreateFlags |= SHFL_CF_ACCESS_WRITE; 678 memcpy(&pReq->Create.StrPath, sf_i->path, SHFLSTRING_HEADER_SIZE + sf_i->path->u16Size); 679 vrc = VbglR0SfHostReqCreate(sf_g->map.root, &pReq->Create); 680 if (RT_SUCCESS(vrc)) { 681 if (pReq->Create.CreateParms.Result == SHFL_FILE_EXISTS) { 682 hHostFile = pReq->Create.CreateParms.Handle; 683 Assert(hHostFile != SHFL_HANDLE_NIL); 684 vbsf_dentry_chain_increase_ttl(dentry); 685 } else { 686 LogFunc(("file %s does not exist\n", sf_i->path->String.utf8)); 687 /** @todo */ 688 rc = -ENOENT; 689 } 690 } else { 691 rc = -RTErrConvertToErrno(vrc); 692 LogFunc(("VbglR0SfCreate(%s) failed vrc=%Rrc rc=%d\n", sf_i->path->String.ach, vrc, rc)); 693 } 694 } else 695 rc = -ENOMEM; 696 } 697 if (rc == 0) { 698 /* 699 * Set mode and/or timestamps. 700 */ 701 if (iattr->ia_valid & (ATTR_MODE | ATTR_ATIME | ATTR_MTIME | ATTR_CTIME)) { 702 /* Fill in the attributes. Start by setting all to zero 703 since the host will ignore zeroed fields. */ 704 RT_ZERO(pReq->Info.ObjInfo); 705 706 if (iattr->ia_valid & ATTR_MODE) { 707 pReq->Info.ObjInfo.Attr.fMode = sf_access_permissions_to_vbox(iattr->ia_mode); 708 if (iattr->ia_mode & S_IFDIR) 709 pReq->Info.ObjInfo.Attr.fMode |= RTFS_TYPE_DIRECTORY; 710 else if (iattr->ia_mode & S_IFLNK) 711 pReq->Info.ObjInfo.Attr.fMode |= RTFS_TYPE_SYMLINK; 712 else 713 pReq->Info.ObjInfo.Attr.fMode |= RTFS_TYPE_FILE; 714 } 715 if (iattr->ia_valid & ATTR_ATIME) 716 vbsf_time_to_vbox(&pReq->Info.ObjInfo.AccessTime, &iattr->ia_atime); 717 if (iattr->ia_valid & ATTR_MTIME) 718 vbsf_time_to_vbox(&pReq->Info.ObjInfo.ModificationTime, &iattr->ia_mtime); 719 if (iattr->ia_valid & ATTR_CTIME) 720 vbsf_time_to_vbox(&pReq->Info.ObjInfo.ChangeTime, &iattr->ia_ctime); 721 722 /* Make the change. */ 723 vrc = VbglR0SfHostReqSetObjInfo(sf_g->map.root, &pReq->Info, hHostFile); 724 if (RT_SUCCESS(vrc)) { 725 vbsf_update_inode(pInode, sf_i, &pReq->Info.ObjInfo, sf_g, true /*fLocked*/); 726 } else { 727 rc = -RTErrConvertToErrno(vrc); 728 LogFunc(("VbglR0SfHostReqSetObjInfo(%s) failed vrc=%Rrc rc=%d\n", sf_i->path->String.ach, vrc, rc)); 729 } 730 } 731 732 /* 733 * Change the file size. 734 * Note! Old API is more convenient here as it gives us up to date 735 * inode info back. 736 */ 737 if ((iattr->ia_valid & ATTR_SIZE) && rc == 0) { 738 /*vrc = VbglR0SfHostReqSetFileSize(sf_g->map.root, &pReq->SetSize, hHostFile, iattr->ia_size); 739 if (RT_SUCCESS(vrc)) { 740 i_size_write(pInode, iattr->ia_size); 741 } else if (vrc == VERR_NOT_IMPLEMENTED)*/ { 742 /* Fallback for pre 6.0 hosts: */ 743 RT_ZERO(pReq->Info.ObjInfo); 744 pReq->Info.ObjInfo.cbObject = iattr->ia_size; 745 vrc = VbglR0SfHostReqSetFileSizeOld(sf_g->map.root, &pReq->Info, hHostFile); 746 if (RT_SUCCESS(vrc)) 747 vbsf_update_inode(pInode, sf_i, &pReq->Info.ObjInfo, sf_g, true /*fLocked*/); 748 } 749 if (RT_SUCCESS(vrc)) { 750 /** @todo there is potentially more to be done here if there are mappings of 751 * the lovely file. */ 752 } else { 753 rc = -RTErrConvertToErrno(vrc); 754 LogFunc(("VbglR0SfHostReqSetFileSize(%s, %#llx) failed vrc=%Rrc rc=%d\n", 755 sf_i->path->String.ach, (unsigned long long)iattr->ia_size, vrc, rc)); 756 } 757 } 758 759 /* 760 * Clean up. 761 */ 762 if (!pHandle) { 763 vrc = VbglR0SfHostReqClose(sf_g->map.root, &pReq->Close, hHostFile); 764 if (RT_FAILURE(vrc)) 765 LogFunc(("VbglR0SfHostReqClose(%s [%#llx]) failed vrc=%Rrc\n", sf_i->path->String.utf8, hHostFile, vrc)); 766 } 767 } 768 if (pReq) 769 VbglR0PhysHeapFree(pReq); 770 if (pHandle) 771 vbsf_handle_release(pHandle, sf_g, "vbsf_inode_setattr"); 772 } else 773 SFLOGFLOW(("vbsf_inode_setattr: Notthing to do here (%#x).\n", iattr->ia_valid)); 774 } 775 return rc; 776 } 777 733 778 734 779 static int vbsf_make_path(const char *caller, struct vbsf_inode_info *sf_i, -
trunk/src/VBox/Additions/linux/sharedfolders/vfsmod.h
r77559 r77561 221 221 extern int vbsf_inode_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *kstat); 222 222 # endif 223 extern int vbsf_inode_setattr(struct dentry *dentry, struct iattr *iattr);224 223 #else /* < 2.5.44 */ 225 224 extern int vbsf_inode_revalidate(struct dentry *dentry); 226 225 #endif /* < 2.5.44 */ 226 extern int vbsf_inode_setattr(struct dentry *dentry, struct iattr *iattr); 227 227 228 228
Note:
See TracChangeset
for help on using the changeset viewer.