Changeset 77942 in vbox
- Timestamp:
- Mar 28, 2019 5:33:49 PM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 129663
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/linux/sharedfolders/regops.c
r77940 r77942 690 690 if (cbRet == 0) 691 691 cbRet = -ERESTARTSYS; 692 SFLOGFLOW(("vbsf_feed_pages_to_pipe: pending signal! (% d)\n", cbRet));692 SFLOGFLOW(("vbsf_feed_pages_to_pipe: pending signal! (%zd)\n", cbRet)); 693 693 break; 694 694 } else { … … 714 714 * For splicing from a file to a pipe. 715 715 */ 716 static ssize_t vbsf_splice_read(struct file * in, loff_t *poffset, struct pipe_inode_info *pipe, size_t len, unsigned int flags)717 { 718 struct inode *inode = VBSF_GET_F_DENTRY( in)->d_inode;716 static ssize_t vbsf_splice_read(struct file *file, loff_t *poffset, struct pipe_inode_info *pipe, size_t len, unsigned int flags) 717 { 718 struct inode *inode = VBSF_GET_F_DENTRY(file)->d_inode; 719 719 struct vbsf_super_info *sf_g = VBSF_GET_SUPER_INFO(inode->i_sb); 720 720 ssize_t cbRet; 721 721 722 SFLOGFLOW(("vbsf_splice_read: in=%p poffset=%p{%#RX64} pipe=%p len=%#zx flags=%#x\n", in, poffset, *poffset, pipe, len, flags));723 if (vbsf_should_use_cached_read( in, inode->i_mapping, sf_g)) {724 cbRet = generic_file_splice_read( in, poffset, pipe, len, flags);722 SFLOGFLOW(("vbsf_splice_read: file=%p poffset=%p{%#RX64} pipe=%p len=%#zx flags=%#x\n", file, poffset, *poffset, pipe, len, flags)); 723 if (vbsf_should_use_cached_read(file, inode->i_mapping, sf_g)) { 724 cbRet = generic_file_splice_read(file, poffset, pipe, len, flags); 725 725 } else { 726 726 /* … … 759 759 */ 760 760 uint32_t const cbToRead = RT_MIN((cPages << PAGE_SHIFT) - (offFile & PAGE_OFFSET_MASK), len); 761 struct vbsf_reg_info *sf_r = (struct vbsf_reg_info *) in->private_data;761 struct vbsf_reg_info *sf_r = (struct vbsf_reg_info *)file->private_data; 762 762 int vrc = VbglR0SfHostReqReadPgLst(sf_g->map.root, pReq, sf_r->Handle.hHost, offFile, cbToRead, cPages); 763 763 if (RT_SUCCESS(vrc)) { … … 797 797 } 798 798 SFLOGFLOW(("vbsf_splice_read: returns %zd (%#zx), *poffset=%#RX64\n", cbRet, cbRet, *poffset)); 799 return cbRet; 800 } 801 802 803 /** 804 * For splicing from a pipe to a file. 805 */ 806 static ssize_t vbsf_splice_write(struct pipe_inode_info *pPipe, struct file *file, loff_t *poffset, size_t len, unsigned int flags) 807 { 808 struct inode *inode = VBSF_GET_F_DENTRY(file)->d_inode; 809 struct vbsf_super_info *sf_g = VBSF_GET_SUPER_INFO(inode->i_sb); 810 ssize_t cbRet; 811 812 SFLOGFLOW(("vbsf_splice_write: pPipe=%p file=%p poffset=%p{%#RX64} len=%#zx flags=%#x\n", pPipe, file, poffset, *poffset, len, flags)); 813 if (false /** @todo later */) { 814 cbRet = generic_file_splice_write(pPipe, file, poffset, len, flags); 815 } else { 816 /* 817 * Prepare a write request. 818 */ 819 struct vbsf_reg_info *sf_r = (struct vbsf_reg_info *)file->private_data; 820 loff_t offFile = *poffset; 821 uint32_t const cMaxPages = RT_MIN(PIPE_BUFFERS, RT_ALIGN_Z(len, PAGE_SIZE) >> PAGE_SHIFT); 822 VBOXSFWRITEPGLSTREQ *pReq = (VBOXSFWRITEPGLSTREQ *)VbglR0PhysHeapAlloc(RT_UOFFSETOF_DYN(VBOXSFREADPGLSTREQ, 823 PgLst.aPages[cMaxPages])); 824 if (pReq) { 825 /* 826 * Feed from the pipe. 827 */ 828 bool fNeedWakeUp = false; 829 cbRet = 0; 830 831 LOCK_PIPE(pPipe); 832 833 for (;;) { 834 unsigned cBufs = pPipe->nrbufs; 835 /*SFLOG2(("vbsf_splice_write: nrbufs=%#x curbuf=%#x\n", cBufs, pPipe->curbuf));*/ 836 if (cBufs) { 837 /* 838 * There is data available. Write it to the file. 839 */ 840 int vrc; 841 struct pipe_buffer *pPipeBuf = &pPipe->bufs[pPipe->curbuf]; 842 uint32_t cPagesToWrite = 1; 843 uint32_t cbToWrite = pPipeBuf->len; 844 845 Assert(pPipeBuf->offset < PAGE_SIZE); 846 Assert(pPipeBuf->offset + pPipeBuf->len <= PAGE_SIZE); 847 848 pReq->PgLst.offFirstPage = pPipeBuf->offset & PAGE_OFFSET; 849 pReq->PgLst.aPages[0] = page_to_phys(pPipeBuf->page); 850 851 /* Add any adjacent page buffers: */ 852 while ( cPagesToWrite < cBufs 853 && cPagesToWrite < cMaxPages 854 && ((pReq->PgLst.offFirstPage + cbToWrite) & PAGE_OFFSET_MASK) == 0) { 855 struct pipe_buffer *pPipeBuf2 = &pPipe->bufs[(pPipe->curbuf + cPagesToWrite) % PIPE_BUFFERS]; 856 Assert(pPipeBuf2->len <= PAGE_SIZE); 857 Assert(pPipeBuf2->offset < PAGE_SIZE); 858 if (pPipeBuf2->offset != 0) 859 break; 860 pReq->PgLst.aPages[cPagesToWrite] = page_to_phys(pPipeBuf2->page); 861 cbToWrite += pPipeBuf2->len; 862 cPagesToWrite += 1; 863 } 864 865 vrc = VbglR0SfHostReqWritePgLst(sf_g->map.root, pReq, sf_r->Handle.hHost, offFile, cbToWrite, cPagesToWrite); 866 if (RT_SUCCESS(vrc)) { 867 /* 868 * Get the number of bytes actually written, update file position 869 * and return value, and advance the pipe buffer. 870 */ 871 uint32_t cbActual = pReq->Parms.cb32Write.u.value32; 872 AssertStmt(cbActual <= cbToWrite, cbActual = cbToWrite); 873 SFLOG2(("vbsf_splice_write: write -> %#x bytes @ %#RX64\n", cbActual, offFile)); 874 875 cbRet += cbActual; 876 offFile += cbActual; 877 *poffset = offFile; 878 879 while (cbActual > 0) { 880 uint32_t cbAdvance = RT_MIN(pPipeBuf->len, cbActual); 881 cbActual -= cbAdvance; 882 pPipeBuf->offset += cbAdvance; 883 pPipeBuf->len -= cbAdvance; 884 if (!pPipeBuf->len) { 885 struct pipe_buf_operations *pOps = pPipeBuf->ops; 886 pPipeBuf->ops = NULL; 887 pOps->release(pPipe, pPipeBuf); 888 889 pPipe->curbuf = (pPipe->curbuf + 1) % PIPE_BUFFERS; 890 pPipe->nrbufs -= 1; 891 pPipeBuf = &pPipe->bufs[pPipe->curbuf]; 892 893 fNeedWakeUp |= pPipe->inode != NULL; 894 } else { 895 Assert(cbActual == 0); 896 break; 897 } 898 } 899 } else { 900 if (cbRet == 0) 901 cbRet = -RTErrConvertToErrno(vrc); 902 SFLOGFLOW(("vbsf_splice_write: Write failed: %Rrc -> %zd (cbRet=%#zx)\n", 903 vrc, -RTErrConvertToErrno(vrc), cbRet)); 904 break; 905 } 906 } else { 907 /* 908 * Wait for data to become available, if there is chance that'll happen. 909 */ 910 /* Quit if there are no writers (think EOF): */ 911 if (pPipe->writers == 0) { 912 SFLOGFLOW(("vbsf_splice_write: No buffers. No writers. The show is done!\n")); 913 break; 914 } 915 916 /* Quit if if we've written some and no writers waiting on the lock: */ 917 if (cbRet > 0 && pPipe->waiting_writers == 0) { 918 SFLOGFLOW(("vbsf_splice_write: No waiting writers, returning what we've got.\n")); 919 break; 920 } 921 922 /* Quit with EAGAIN if non-blocking: */ 923 if (flags & SPLICE_F_NONBLOCK) { 924 if (cbRet == 0) 925 cbRet = -EAGAIN; 926 break; 927 } 928 929 /* Quit if we've got pending signals: */ 930 if (signal_pending(current)) { 931 if (cbRet == 0) 932 cbRet = -ERESTARTSYS; 933 SFLOGFLOW(("vbsf_splice_write: pending signal! (%zd)\n", cbRet)); 934 break; 935 } 936 937 /* Wake up writers before we start waiting: */ 938 if (fNeedWakeUp) { 939 vbsf_wake_up_pipe(pPipe, false /*fReaders*/); 940 fNeedWakeUp = false; 941 } 942 vbsf_wait_pipe(pPipe); 943 } 944 } /* feed loop */ 945 946 if (fNeedWakeUp) 947 vbsf_wake_up_pipe(pPipe, false /*fReaders*/); 948 949 UNLOCK_PIPE(pPipe); 950 951 VbglR0PhysHeapFree(pReq); 952 } else { 953 cbRet = -ENOMEM; 954 } 955 } 956 SFLOGFLOW(("vbsf_splice_write: returns %zd (%#zx), *poffset=%#RX64\n", cbRet, cbRet, *poffset)); 799 957 return cbRet; 800 958 } … … 2971 3129 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31) 2972 3130 .splice_read = vbsf_splice_read, 2973 /// @todo.splice_write = vbsf_splice_write,3131 .splice_write = vbsf_splice_write, 2974 3132 #endif 2975 3133 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
Note:
See TracChangeset
for help on using the changeset viewer.