Changeset 77704 in vbox for trunk/src/VBox/Additions/linux/sharedfolders
- Timestamp:
- Mar 14, 2019 5:00:37 PM (6 years ago)
- Location:
- trunk/src/VBox/Additions/linux/sharedfolders
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/linux/sharedfolders/dirops.c
r77561 r77704 562 562 }; 563 563 564 /* iops */ 565 566 /** 567 * Worker for vbsf_inode_lookup() and vbsf_inode_instantiate(). 564 565 566 /********************************************************************************************************************************* 567 * Directory Inode Operations * 568 *********************************************************************************************************************************/ 569 570 /** 571 * Worker for vbsf_inode_lookup(), vbsf_create_worker() and 572 * vbsf_inode_instantiate(). 568 573 */ 569 574 static struct inode *vbsf_create_inode(struct inode *parent, struct dentry *dentry, PSHFLSTRING path, … … 614 619 return NULL; 615 620 } 621 622 623 /** Helper for vbsf_create_worker() and vbsf_inode_lookup() that wraps 624 * d_add() and setting d_op. */ 625 DECLINLINE(void) vbsf_d_add_inode(struct dentry *dentry, struct inode *pNewInode) 626 { 627 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38) 628 Assert(dentry->d_op == &vbsf_dentry_ops); /* (taken from the superblock) */ 629 #else 630 dentry->d_op = &vbsf_dentry_ops; 631 #endif 632 d_add(dentry, pNewInode); 633 } 634 616 635 617 636 /** … … 702 721 if (dret == dentry) { 703 722 vbsf_dentry_set_update_jiffies(dentry, jiffies); 704 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38) 705 Assert(dentry->d_op == &vbsf_dentry_ops); /* (taken from the superblock) */ 706 #else 707 dentry->d_op = &vbsf_dentry_ops; 708 #endif 709 d_add(dentry, pInode); 723 vbsf_d_add_inode(dentry, pInode); 710 724 dret = NULL; 711 725 } … … 719 733 } 720 734 735 721 736 /** 722 737 * This should allocate memory for vbsf_inode_info, compute a unique inode … … 745 760 } 746 761 762 747 763 /** 748 764 * Create a new regular file / directory. … … 751 767 * @param dentry directory cache entry 752 768 * @param mode file mode 753 * @param f Directory true if directory, false otherwise769 * @param fCreateFlags SHFL_CF_XXX. 754 770 * @returns 0 on success, Linux error code otherwise 755 771 */ 756 static int vbsf_create_worker(struct inode *parent, struct dentry *dentry, umode_t mode, int fDirectory) 757 { 758 int rc, err; 772 static int vbsf_create_worker(struct inode *parent, struct dentry *dentry, umode_t mode, uint32_t fCreateFlags, 773 bool fStashHandle, bool fDoLookup, SHFLHANDLE *phHostFile, bool *pfCreated) 774 775 { 776 #ifdef SFLOG_ENABLED 777 const char * const pszPrefix = S_ISDIR(mode) ? "vbsf_create_worker/dir:" : "vbsf_create_worker/file:"; 778 #endif 759 779 struct vbsf_inode_info *sf_parent_i = VBSF_GET_INODE_INFO(parent); 760 struct vbsf_super_info *sf_g = VBSF_GET_SUPER_INFO(parent->i_sb); 761 SHFLSTRING *path; 762 union CreateAuxReq 763 { 764 VBOXSFCREATEREQ Create; 765 VBOXSFCLOSEREQ Close; 766 } *pReq; 767 768 TRACE(); 769 BUG_ON(!sf_parent_i); 770 BUG_ON(!sf_g); 771 772 err = vbsf_path_from_dentry(__func__, sf_g, sf_parent_i, dentry, &path); 773 if (err) 774 goto fail0; 775 776 /** @todo combine with vbsf_path_from_dentry? */ 777 pReq = (union CreateAuxReq *)VbglR0PhysHeapAlloc(RT_UOFFSETOF(VBOXSFCREATEREQ, StrPath.String) + path->u16Size); 778 if (pReq) { 779 memcpy(&pReq->Create.StrPath, path, SHFLSTRING_HEADER_SIZE + path->u16Size); 780 struct vbsf_super_info *sf_g = VBSF_GET_SUPER_INFO(parent->i_sb); 781 PSHFLSTRING path; 782 int rc; 783 784 AssertReturn(sf_parent_i, -EINVAL); 785 AssertReturn(sf_g, -EINVAL); 786 787 /* 788 * Build a path. We'll donate this to the inode on success. 789 */ 790 rc = vbsf_path_from_dentry(__func__, sf_g, sf_parent_i, dentry, &path); 791 if (rc == 0) { 792 /* 793 * Allocate, initialize and issue the SHFL_CREATE request. 794 */ 795 /** @todo combine with vbsf_path_from_dentry? */ 796 union CreateAuxReq 797 { 798 VBOXSFCREATEREQ Create; 799 VBOXSFCLOSEREQ Close; 800 } *pReq = (union CreateAuxReq *)VbglR0PhysHeapAlloc(RT_UOFFSETOF(VBOXSFCREATEREQ, StrPath.String) + path->u16Size); 801 if (pReq) { 802 memcpy(&pReq->Create.StrPath, path, SHFLSTRING_HEADER_SIZE + path->u16Size); 803 804 RT_ZERO(pReq->Create.CreateParms); 805 pReq->Create.CreateParms.Handle = SHFL_HANDLE_NIL; 806 pReq->Create.CreateParms.CreateFlags = fCreateFlags; 807 pReq->Create.CreateParms.Info.Attr.fMode = (S_ISDIR(mode) ? RTFS_TYPE_DIRECTORY : RTFS_TYPE_FILE) 808 | sf_access_permissions_to_vbox(mode); 809 pReq->Create.CreateParms.Info.Attr.enmAdditional = RTFSOBJATTRADD_NOTHING; 810 811 SFLOGFLOW(("%s calling VbglR0SfHostReqCreate(%s, %#x)\n", pszPrefix, path->String.ach, pReq->Create.CreateParms.CreateFlags)); 812 rc = VbglR0SfHostReqCreate(sf_g->map.root, &pReq->Create); 813 if (RT_SUCCESS(rc)) { 814 SFLOGFLOW(("%s VbglR0SfHostReqCreate returned %Rrc Result=%d Handle=%#llx\n", 815 pszPrefix, rc, pReq->Create.CreateParms.Result, pReq->Create.CreateParms.Handle)); 816 817 /* 818 * Work the dentry cache and inode restatting. 819 */ 820 if ( pReq->Create.CreateParms.Result == SHFL_FILE_CREATED 821 || pReq->Create.CreateParms.Result == SHFL_FILE_REPLACED) { 822 vbsf_dentry_chain_increase_parent_ttl(dentry); 823 sf_parent_i->force_restat = 1; 824 } else if ( pReq->Create.CreateParms.Result == SHFL_FILE_EXISTS 825 || pReq->Create.CreateParms.Result == SHFL_FILE_NOT_FOUND) 826 vbsf_dentry_chain_increase_parent_ttl(dentry); 827 828 /* 829 * If we got a handle back, we're good. Create an inode for it and return. 830 */ 831 if (pReq->Create.CreateParms.Handle != SHFL_HANDLE_NIL) { 832 struct inode *pNewInode = vbsf_create_inode(parent, dentry, path, &pReq->Create.CreateParms.Info, sf_g, 833 !fDoLookup /*fInstantiate*/); 834 if (pNewInode) { 835 struct vbsf_inode_info *sf_new_i = VBSF_GET_INODE_INFO(pNewInode); 836 if (phHostFile) { 837 *phHostFile = pReq->Create.CreateParms.Handle; 838 pReq->Create.CreateParms.Handle = SHFL_HANDLE_NIL; 839 } else if (fStashHandle) { 840 sf_new_i->handle = pReq->Create.CreateParms.Handle; 841 pReq->Create.CreateParms.Handle = SHFL_HANDLE_NIL; 842 } 843 if (fDoLookup) 844 vbsf_d_add_inode(dentry, pNewInode); 845 path = NULL; 846 } else { 847 SFLOGFLOW(("%s vbsf_create_inode failed: -ENOMEM (path %s)\n", pszPrefix, rc, path->String.ach)); 848 rc = -ENOMEM; 849 } 850 } else if (pReq->Create.CreateParms.Result == SHFL_FILE_EXISTS) { 851 /* 852 * For atomic_open (at least), we should create an inode and 853 * convert the dentry from a negative to a positive one. 854 */ 855 SFLOGFLOW(("%s SHFL_FILE_EXISTS for %s\n", pszPrefix, sf_parent_i->path->String.ach)); 856 if (fDoLookup) { 857 struct inode *pNewInode = vbsf_create_inode(parent, dentry, path, &pReq->Create.CreateParms.Info, 858 sf_g, false /*fInstantiate*/); 859 if (pNewInode) 860 vbsf_d_add_inode(dentry, pNewInode); 861 path = NULL; 862 } 863 rc = -EEXIST; 864 } else if (pReq->Create.CreateParms.Result == SHFL_FILE_NOT_FOUND) { 865 SFLOGFLOW(("%s SHFL_FILE_NOT_FOUND for %s\n", pszPrefix, sf_parent_i->path->String.ach)); 866 rc = -ENOENT; 867 } else if (pReq->Create.CreateParms.Result == SHFL_PATH_NOT_FOUND) { 868 SFLOGFLOW(("%s SHFL_PATH_NOT_FOUND for %s\n", pszPrefix, sf_parent_i->path->String.ach)); 869 rc = -ENOENT; 870 } else { 871 AssertMsgFailed(("result=%d creating '%s'\n", pReq->Create.CreateParms.Result, sf_parent_i->path->String.ach)); 872 rc = -EPERM; 873 } 874 } else { 875 int const vrc = rc; 876 rc = -RTErrConvertToErrno(vrc); 877 SFLOGFLOW(("%s SHFL_FN_CREATE(%s) failed vrc=%Rrc rc=%d\n", pszPrefix, path->String.ach, vrc, rc)); 878 } 879 880 /* Cleanups. */ 881 if (pReq->Create.CreateParms.Handle != SHFL_HANDLE_NIL) { 882 AssertCompile(RTASSERT_OFFSET_OF(VBOXSFCREATEREQ, CreateParms.Handle) > sizeof(VBOXSFCLOSEREQ)); /* no aliasing issues */ 883 int rc2 = VbglR0SfHostReqClose(sf_g->map.root, &pReq->Close, pReq->Create.CreateParms.Handle); 884 if (RT_FAILURE(rc2)) 885 SFLOGFLOW(("%s VbglR0SfHostReqCloseSimple failed rc=%Rrc\n", pszPrefix, rc2)); 886 } 887 VbglR0PhysHeapFree(pReq); 888 } else 889 rc = -ENOMEM; 890 if (path) 891 kfree(path); 892 } 893 return rc; 894 } 895 896 897 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) 898 /** 899 * More atomic way of handling creation. 900 * 901 * Older kernels would first to a lookup that created the file, followed by 902 * an open call. We've got this horrid vbsf_inode_info::handle member because 903 * of that approach. The call combines the lookup and open. 904 */ 905 static int vbsf_inode_atomic_open(struct inode *pDirInode, struct dentry *dentry, struct file *file, unsigned fOpen, umode_t fMode) 906 { 907 SFLOGFLOW(("vbsf_inode_atomic_open: pDirInode=%p dentry=%p file=%p fOpen=%#x, fMode=%#x\n", pDirInode, dentry, file, fOpen, fMode)); 908 int rc; 909 910 /* Code assumes negative dentry. */ 911 Assert(dentry->d_inode == NULL); 912 913 /** @todo see if we can do this for non-create calls too, as it may save us a 914 * host call to revalidate the dentry. (Can't see anyone else doing 915 * this, so playing it safe for now.) */ 916 if (fOpen & O_CREAT) { 917 /* 918 * Prepare our file info structure. 919 */ 920 struct vbsf_reg_info *sf_r = kmalloc(sizeof(*sf_r), GFP_KERNEL); 921 if (sf_r) { 922 bool fCreated = false; 923 uint32_t fCreateFlags; 924 925 RTListInit(&sf_r->Handle.Entry); 926 sf_r->Handle.cRefs = 1; 927 sf_r->Handle.fFlags = !(fOpen & O_DIRECTORY) 928 ? VBSF_HANDLE_F_FILE | VBSF_HANDLE_F_MAGIC 929 : VBSF_HANDLE_F_DIR | VBSF_HANDLE_F_MAGIC; 930 sf_r->Handle.hHost = SHFL_HANDLE_NIL; 931 932 /* 933 * Try create it. 934 */ 935 /* vbsf_create_worker uses the type from fMode, so match it up to O_DIRECTORY. */ 936 AssertMsg(!(fMode & S_IFMT) || (fMode & S_IFMT) == (fOpen & O_DIRECTORY ? S_IFDIR : S_IFREG), ("0%o\n", fMode)); 937 if (!(fOpen & O_DIRECTORY)) 938 fMode = (fMode & ~S_IFMT) | S_IFREG; 939 else 940 fMode = (fMode & ~S_IFMT) | S_IFDIR; 941 942 fCreateFlags = vbsf_linux_oflags_to_vbox(fOpen, &sf_r->Handle.fFlags, __FUNCTION__); 943 944 rc = vbsf_create_worker(pDirInode, dentry, fMode, fCreateFlags, false /*fStashHandle*/, true /*fDoLookup*/, 945 &sf_r->Handle.hHost, &fCreated); 946 if (rc == 0) { 947 struct inode *inode = dentry->d_inode; 948 struct vbsf_inode_info *sf_i = VBSF_GET_INODE_INFO(inode); 949 950 /* 951 * Set FMODE_CREATED according to the action taken by SHFL_CREATE 952 * and call finish_open() to do the remaining open() work. 953 */ 954 if (fCreated) 955 file->f_mode |= FMODE_CREATED; 956 rc = finish_open(file, dentry, generic_file_open); 957 if (rc == 0) { 958 /* 959 * Now that the file is fully opened, associate sf_r with it 960 * and link the handle to the inode. 961 */ 962 vbsf_handle_append(sf_i, &sf_r->Handle); 963 file->private_data = sf_r; 964 SFLOGFLOW(("vbsf_inode_atomic_open: create succeeded; hHost=%#llx path='%s'\n", 965 rc, sf_r->Handle.hHost, sf_i->path->String.ach)); 966 sf_r = NULL; /* don't free it */ 967 } else { 968 struct vbsf_super_info *sf_g = VBSF_GET_SUPER_INFO(pDirInode->i_sb); 969 SFLOGFLOW(("vbsf_inode_atomic_open: finish_open failed: %d (path='%s'\n", rc, sf_i->path->String.ach)); 970 VbglR0SfHostReqCloseSimple(sf_g->map.root, sf_r->Handle.hHost); 971 sf_r->Handle.hHost = SHFL_HANDLE_NIL; 972 } 973 } else 974 SFLOGFLOW(("vbsf_inode_atomic_open: vbsf_create_worker failed: %d\n", rc)); 975 if (sf_r) 976 kfree(sf_r); 977 } else { 978 LogRelMaxFunc(64, ("could not allocate reg info\n")); 979 rc = -ENOMEM; 980 } 981 } 982 /* 983 * Not creating anything. 984 * Do we need to do a lookup or should we just fail? 985 */ 986 else if (d_in_lookup(dentry)) { 987 struct dentry *pResult = vbsf_inode_lookup(pDirInode, dentry, 0 /*fFlags*/); 988 if (!IS_ERR(pResult)) 989 rc = finish_no_open(file, pResult); 990 else 991 rc = PTR_ERR(pResult); 992 SFLOGFLOW(("vbsf_inode_atomic_open: open -> %d (%p)\n", rc, pResult)); 780 993 } else { 781 err = -ENOMEM; 782 goto fail1; 783 } 784 785 RT_ZERO(pReq->Create.CreateParms); 786 pReq->Create.CreateParms.Handle = SHFL_HANDLE_NIL; 787 pReq->Create.CreateParms.CreateFlags = SHFL_CF_ACT_CREATE_IF_NEW 788 | SHFL_CF_ACT_FAIL_IF_EXISTS 789 | SHFL_CF_ACCESS_READWRITE 790 | (fDirectory ? SHFL_CF_DIRECTORY : 0); 791 pReq->Create.CreateParms.Info.Attr.fMode = (fDirectory ? RTFS_TYPE_DIRECTORY : RTFS_TYPE_FILE) 792 | sf_access_permissions_to_vbox(mode); 793 pReq->Create.CreateParms.Info.Attr.enmAdditional = RTFSOBJATTRADD_NOTHING; 794 795 LogFunc(("calling VbglR0SfHostReqCreate, folder %s, flags %#x\n", path->String.ach, pReq->Create.CreateParms.CreateFlags)); 796 rc = VbglR0SfHostReqCreate(sf_g->map.root, &pReq->Create); 797 if (RT_FAILURE(rc)) { 798 err = -RTErrConvertToErrno(rc); 799 LogFunc(("(%d): SHFL_FN_CREATE(%s) failed rc=%Rrc err=%d\n", fDirectory, sf_parent_i->path->String.utf8, rc, err)); 800 goto fail2; 801 } 802 803 if (pReq->Create.CreateParms.Result != SHFL_FILE_CREATED) { 804 err = -EPERM; 805 LogFunc(("(%d): could not create file %s result=%d\n", 806 fDirectory, sf_parent_i->path->String.utf8, pReq->Create.CreateParms.Result)); 807 goto fail2; 808 } 809 810 vbsf_dentry_chain_increase_parent_ttl(dentry); 811 812 err = vbsf_inode_instantiate(parent, dentry, path, &pReq->Create.CreateParms.Info, 813 fDirectory ? SHFL_HANDLE_NIL : pReq->Create.CreateParms.Handle); 814 if (err) { 815 LogFunc(("(%d): could not instantiate dentry for %s err=%d\n", fDirectory, path->String.utf8, err)); 816 goto fail3; 817 } 818 819 /* 820 * Don't close this handle right now. We assume that the same file is 821 * opened with vbsf_reg_open() and later closed with sf_reg_close(). Save 822 * the handle in between. Does not apply to directories. True? 823 */ 824 if (fDirectory) { 825 AssertCompile(RTASSERT_OFFSET_OF(VBOXSFCREATEREQ, CreateParms.Handle) > sizeof(VBOXSFCLOSEREQ)); /* no aliasing issues */ 826 rc = VbglR0SfHostReqClose(sf_g->map.root, &pReq->Close, pReq->Create.CreateParms.Handle); 827 if (RT_FAILURE(rc)) 828 LogFunc(("(%d): VbglR0SfHostReqClose failed rc=%Rrc\n", fDirectory, rc)); 829 } 830 831 sf_parent_i->force_restat = 1; 832 VbglR0PhysHeapFree(pReq); 833 return 0; 834 835 fail3: 836 rc = VbglR0SfHostReqClose(sf_g->map.root, &pReq->Close, pReq->Create.CreateParms.Handle); 837 if (RT_FAILURE(rc)) 838 LogFunc(("(%d): VbglR0SfHostReqCloseSimple failed rc=%Rrc\n", fDirectory, rc)); 839 fail2: 840 VbglR0PhysHeapFree(pReq); 841 fail1: 842 kfree(path); 843 844 fail0: 845 return err; 846 } 994 SFLOGFLOW(("vbsf_inode_atomic_open: open -> -ENOENT\n")); 995 rc = -ENOENT; 996 } 997 return rc; 998 } 999 #endif /* 3.6.0 */ 1000 847 1001 848 1002 /** … … 869 1023 * changed (investigate)... */ 870 1024 TRACE(); 871 return vbsf_create_worker(parent, dentry, mode, 0 /*fDirectory*/); 1025 AssertMsg(!(mode & S_IFMT) || (mode & S_IFMT) == S_IFREG, ("0%o\n", mode)); 1026 return vbsf_create_worker(parent, dentry, (mode & ~S_IFMT) | S_IFREG, 1027 SHFL_CF_ACT_CREATE_IF_NEW 1028 | SHFL_CF_ACT_FAIL_IF_EXISTS 1029 | SHFL_CF_ACCESS_READWRITE, 1030 true /*fStashHandle*/, false /*fDoLookup*/, NULL /*phHandle*/, NULL /*fCreated*/); 872 1031 } 873 1032 … … 887 1046 { 888 1047 TRACE(); 889 return vbsf_create_worker(parent, dentry, mode, 1 /*fDirectory*/); 1048 AssertMsg(!(mode & S_IFMT) || (mode & S_IFMT) == S_IFDIR, ("0%o\n", mode)); 1049 return vbsf_create_worker(parent, dentry, (mode & ~S_IFMT) | S_IFDIR, 1050 SHFL_CF_ACT_CREATE_IF_NEW 1051 | SHFL_CF_ACT_FAIL_IF_EXISTS 1052 | SHFL_CF_ACCESS_READWRITE 1053 | SHFL_CF_DIRECTORY, 1054 false /*fStashHandle*/, false /*fDoLookup*/, NULL /*phHandle*/, NULL /*fCreated*/); 890 1055 } 891 1056 … … 930 1095 } else if (rc == VERR_FILE_NOT_FOUND || rc == VERR_PATH_NOT_FOUND) { 931 1096 LogFunc(("(%d): VbglR0SfRemove(%s) failed rc=%Rrc; calling d_drop on %p\n", 932 fDirectory, path->String. utf8, rc, dentry));1097 fDirectory, path->String.ach, rc, dentry)); 933 1098 d_drop(dentry); 934 1099 } else { 935 LogFunc(("(%d): VbglR0SfRemove(%s) failed rc=%Rrc\n", fDirectory, path->String. utf8, rc));1100 LogFunc(("(%d): VbglR0SfRemove(%s) failed rc=%Rrc\n", fDirectory, path->String.ach, rc)); 936 1101 err = -RTErrConvertToErrno(rc); 937 1102 } … … 1110 1275 struct inode_operations vbsf_dir_iops = { 1111 1276 .lookup = vbsf_inode_lookup, 1277 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) 1278 .atomic_open = vbsf_inode_atomic_open, 1279 #endif 1112 1280 .create = vbsf_inode_create, 1113 1281 .mkdir = vbsf_inode_mkdir, -
trunk/src/VBox/Additions/linux/sharedfolders/regops.c
r77631 r77704 1874 1874 1875 1875 /** 1876 * Used by vbsf_reg_open() and vbsf_inode_atomic_open() to 1877 * 1878 * @returns shared folders create flags. 1879 * @param fLnxOpen The linux O_XXX flags to convert. 1880 * @param pfHandle Pointer to vbsf_handle::fFlags. 1881 * @param pszCaller Caller, for logging purposes. 1882 */ 1883 uint32_t vbsf_linux_oflags_to_vbox(unsigned fLnxOpen, uint32_t *pfHandle, const char *pszCaller) 1884 { 1885 uint32_t fVBoxFlags = SHFL_CF_ACCESS_DENYNONE; 1886 1887 /* 1888 * Disposition. 1889 */ 1890 if (fLnxOpen & O_CREAT) { 1891 Log(("%s: O_CREAT set\n", pszCaller)); 1892 fVBoxFlags |= SHFL_CF_ACT_CREATE_IF_NEW; 1893 if (fLnxOpen & O_EXCL) { 1894 Log(("%s: O_EXCL set\n", pszCaller)); 1895 fVBoxFlags |= SHFL_CF_ACT_FAIL_IF_EXISTS; 1896 } else if (fLnxOpen & O_TRUNC) { 1897 Log(("%s: O_TRUNC set\n", pszCaller)); 1898 fVBoxFlags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS; 1899 } else 1900 fVBoxFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS; 1901 } else { 1902 fVBoxFlags |= SHFL_CF_ACT_FAIL_IF_NEW; 1903 if (fLnxOpen & O_TRUNC) { 1904 Log(("%s: O_TRUNC set\n", pszCaller)); 1905 fVBoxFlags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS; 1906 } 1907 } 1908 1909 /* 1910 * Access. 1911 */ 1912 switch (fLnxOpen & O_ACCMODE) { 1913 case O_RDONLY: 1914 fVBoxFlags |= SHFL_CF_ACCESS_READ; 1915 *pfHandle |= VBSF_HANDLE_F_READ; 1916 break; 1917 1918 case O_WRONLY: 1919 fVBoxFlags |= SHFL_CF_ACCESS_WRITE; 1920 *pfHandle |= VBSF_HANDLE_F_WRITE; 1921 break; 1922 1923 case O_RDWR: 1924 fVBoxFlags |= SHFL_CF_ACCESS_READWRITE; 1925 *pfHandle |= VBSF_HANDLE_F_READ | VBSF_HANDLE_F_WRITE; 1926 break; 1927 1928 default: 1929 BUG(); 1930 } 1931 1932 if (fLnxOpen & O_APPEND) { 1933 Log(("%s: O_APPEND set\n", pszCaller)); 1934 fVBoxFlags |= SHFL_CF_ACCESS_APPEND; 1935 *pfHandle |= VBSF_HANDLE_F_APPEND; 1936 } 1937 1938 /* 1939 * Only directories? 1940 */ 1941 if (fLnxOpen & O_DIRECTORY) { 1942 Log(("%s: O_DIRECTORY set\n", pszCaller)); 1943 fVBoxFlags |= SHFL_CF_DIRECTORY; 1944 } 1945 1946 return fVBoxFlags; 1947 } 1948 1949 1950 /** 1876 1951 * Open a regular file. 1877 1952 * … … 1939 2014 * to make the shared folders host service use our fMode parameter */ 1940 2015 1941 if (file->f_flags & O_CREAT) { 1942 LogFunc(("O_CREAT set\n")); 1943 pReq->CreateParms.CreateFlags |= SHFL_CF_ACT_CREATE_IF_NEW; 1944 /* We ignore O_EXCL, as the Linux kernel seems to call create 1945 beforehand itself, so O_EXCL should always fail. */ 1946 if (file->f_flags & O_TRUNC) { 1947 LogFunc(("O_TRUNC set\n")); 1948 pReq->CreateParms.CreateFlags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS; 1949 } else 1950 pReq->CreateParms.CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS; 1951 } else { 1952 pReq->CreateParms.CreateFlags |= SHFL_CF_ACT_FAIL_IF_NEW; 1953 if (file->f_flags & O_TRUNC) { 1954 LogFunc(("O_TRUNC set\n")); 1955 pReq->CreateParms.CreateFlags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS; 1956 } 1957 } 1958 1959 switch (file->f_flags & O_ACCMODE) { 1960 case O_RDONLY: 1961 pReq->CreateParms.CreateFlags |= SHFL_CF_ACCESS_READ; 1962 sf_r->Handle.fFlags |= VBSF_HANDLE_F_READ; 1963 break; 1964 1965 case O_WRONLY: 1966 pReq->CreateParms.CreateFlags |= SHFL_CF_ACCESS_WRITE; 1967 sf_r->Handle.fFlags |= VBSF_HANDLE_F_WRITE; 1968 break; 1969 1970 case O_RDWR: 1971 pReq->CreateParms.CreateFlags |= SHFL_CF_ACCESS_READWRITE; 1972 sf_r->Handle.fFlags |= VBSF_HANDLE_F_READ | VBSF_HANDLE_F_WRITE; 1973 break; 1974 1975 default: 1976 BUG(); 1977 } 1978 1979 if (file->f_flags & O_APPEND) { 1980 LogFunc(("O_APPEND set\n")); 1981 pReq->CreateParms.CreateFlags |= SHFL_CF_ACCESS_APPEND; 1982 sf_r->Handle.fFlags |= VBSF_HANDLE_F_APPEND; 1983 } 1984 2016 /* We ignore O_EXCL, as the Linux kernel seems to call create 2017 beforehand itself, so O_EXCL should always fail. */ 2018 pReq->CreateParms.CreateFlags = vbsf_linux_oflags_to_vbox(file->f_flags & ~O_EXCL, &sf_r->Handle.fFlags, __FUNCTION__); 1985 2019 pReq->CreateParms.Info.Attr.fMode = inode->i_mode; 1986 2020 LogFunc(("vbsf_reg_open: calling VbglR0SfHostReqCreate, file %s, flags=%#x, %#x\n", … … 2036 2070 static int vbsf_reg_release(struct inode *inode, struct file *file) 2037 2071 { 2038 struct vbsf_reg_info *sf_r;2039 struct vbsf_super_info *sf_g;2040 2072 struct vbsf_inode_info *sf_i = VBSF_GET_INODE_INFO(inode); 2073 struct vbsf_reg_info *sf_r = file->private_data; 2041 2074 2042 2075 SFLOGFLOW(("vbsf_reg_release: inode=%p file=%p\n", inode, file)); 2043 sf_g = VBSF_GET_SUPER_INFO(inode->i_sb); 2044 sf_r = file->private_data; 2045 2046 BUG_ON(!sf_g); 2047 BUG_ON(!sf_r); 2076 if (sf_r) { 2077 struct vbsf_super_info *sf_g = VBSF_GET_SUPER_INFO(inode->i_sb); 2078 Assert(sf_g); 2048 2079 2049 2080 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 25) 2050 /* See the smbfs source (file.c). mmap in particular can cause data to be2051 * written to the file after it is closed, which we can't cope with. We2052 * copy and paste the body of filemap_write_and_wait() here as it was not2053 * defined before 2.6.6 and not exported until quite a bit later. */2054 /* filemap_write_and_wait(inode->i_mapping); */2055 if (inode->i_mapping->nrpages2056 && filemap_fdatawrite(inode->i_mapping) != -EIO)2057 filemap_fdatawait(inode->i_mapping);2081 /* See the smbfs source (file.c). mmap in particular can cause data to be 2082 * written to the file after it is closed, which we can't cope with. We 2083 * copy and paste the body of filemap_write_and_wait() here as it was not 2084 * defined before 2.6.6 and not exported until quite a bit later. */ 2085 /* filemap_write_and_wait(inode->i_mapping); */ 2086 if (inode->i_mapping->nrpages 2087 && filemap_fdatawrite(inode->i_mapping) != -EIO) 2088 filemap_fdatawait(inode->i_mapping); 2058 2089 #endif 2059 2090 2060 /* Release sf_r, closing the handle if we're the last user. */ 2061 file->private_data = NULL; 2062 vbsf_handle_release(&sf_r->Handle, sf_g, "vbsf_reg_release"); 2063 2064 sf_i->handle = SHFL_HANDLE_NIL; 2091 /* Release sf_r, closing the handle if we're the last user. */ 2092 file->private_data = NULL; 2093 vbsf_handle_release(&sf_r->Handle, sf_g, "vbsf_reg_release"); 2094 2095 sf_i->handle = SHFL_HANDLE_NIL; 2096 } 2065 2097 return 0; 2066 2098 } -
trunk/src/VBox/Additions/linux/sharedfolders/vfsmod.h
r77631 r77704 286 286 }; 287 287 288 uint32_t vbsf_linux_oflags_to_vbox(unsigned fLnxOpen, uint32_t *pfHandle, const char *pszCaller); 289 288 290 289 291 /**
Note:
See TracChangeset
for help on using the changeset viewer.