Changeset 70460 in vbox for trunk/src/VBox/Additions/linux/sharedfolders
- Timestamp:
- Jan 4, 2018 4:56:53 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/linux/sharedfolders/regops.c
r69500 r70460 92 92 } 93 93 94 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) && \ 95 LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31) 96 97 void free_pipebuf(struct page *kpage) 98 { 99 kunmap(kpage); 100 __free_pages(kpage, 0); 101 } 102 103 void *sf_pipe_buf_map(struct pipe_inode_info *pipe, 104 struct pipe_buffer *pipe_buf, int atomic) 105 { 106 return 0; 107 } 108 109 void sf_pipe_buf_get(struct pipe_inode_info *pipe, struct pipe_buffer *pipe_buf) 110 { 111 } 112 113 void sf_pipe_buf_unmap(struct pipe_inode_info *pipe, struct pipe_buffer *pipe_buf, void *map_data) 114 { 115 } 116 117 int sf_pipe_buf_steal(struct pipe_inode_info *pipe, 118 struct pipe_buffer *pipe_buf) { 119 return 0; 120 } 121 122 static void sf_pipe_buf_release(struct pipe_inode_info *pipe, 123 struct pipe_buffer *pipe_buf) 124 { 125 free_pipebuf(pipe_buf->page); 126 } 127 128 int sf_pipe_buf_confirm(struct pipe_inode_info *info, 129 struct pipe_buffer *pipe_buf) 130 { 131 return 0; 132 } 133 134 static struct pipe_buf_operations sf_pipe_buf_ops = { 135 .can_merge = 0, 136 .map = sf_pipe_buf_map, 137 .unmap = sf_pipe_buf_unmap, 138 .confirm = sf_pipe_buf_confirm, 139 .release = sf_pipe_buf_release, 140 .steal = sf_pipe_buf_steal, 141 .get = sf_pipe_buf_get, 142 }; 143 144 #define LOCK_PIPE(pipe) \ 145 if (pipe->inode) \ 146 mutex_lock(&pipe->inode->i_mutex); 147 148 #define UNLOCK_PIPE(pipe) \ 149 if (pipe->inode) \ 150 mutex_unlock(&pipe->inode->i_mutex); 151 152 ssize_t 153 sf_splice_read(struct file *in, loff_t *poffset, 154 struct pipe_inode_info *pipe, size_t len, 155 unsigned int flags) 156 { 157 size_t bytes_remaining = len; 158 loff_t orig_offset = *poffset; 159 loff_t offset = orig_offset; 160 struct inode *inode = GET_F_DENTRY(in)->d_inode; 161 struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb); 162 struct sf_reg_info *sf_r = in->private_data; 163 ssize_t retval; 164 struct page *kpage = 0; 165 size_t nsent = 0; 166 167 TRACE(); 168 if (!S_ISREG(inode->i_mode)) 169 { 170 LogFunc(("read from non regular file %d\n", inode->i_mode)); 171 return -EINVAL; 172 } 173 if (!len) { 174 return 0; 175 } 176 177 LOCK_PIPE(pipe); 178 179 uint32_t req_size = 0; 180 while (bytes_remaining > 0) 181 { 182 kpage = alloc_page(GFP_KERNEL); 183 if (unlikely(kpage == NULL)) 184 { 185 UNLOCK_PIPE(pipe); 186 return -ENOMEM; 187 } 188 req_size = 0; 189 uint32_t nread = req_size = (uint32_t)min(bytes_remaining, (size_t)PAGE_SIZE); 190 uint32_t chunk = 0; 191 void *kbuf = kmap(kpage); 192 while (chunk < req_size) 193 { 194 retval = sf_reg_read_aux(__func__, sf_g, sf_r, kbuf + chunk, &nread, offset); 195 if (retval < 0) 196 goto err; 197 if (nread == 0) 198 break; 199 chunk += nread; 200 offset += nread; 201 nread = req_size - chunk; 202 } 203 if (!pipe->readers) 204 { 205 send_sig(SIGPIPE, current, 0); 206 retval = -EPIPE; 207 goto err; 208 } 209 if (pipe->nrbufs < PIPE_BUFFERS) 210 { 211 struct pipe_buffer *pipebuf = 212 pipe->bufs + ((pipe->curbuf + pipe->nrbufs) & (PIPE_BUFFERS - 1)); 213 pipebuf->page = kpage; 214 pipebuf->ops = &sf_pipe_buf_ops; 215 pipebuf->len = req_size; 216 pipebuf->offset = 0; 217 pipebuf->private = 0; 218 pipebuf->flags = 0; 219 pipe->nrbufs++; 220 nsent += req_size; 221 bytes_remaining -= req_size; 222 if (signal_pending(current)) 223 break; 224 } 225 else /* pipe full */ 226 { 227 if (flags & SPLICE_F_NONBLOCK) { 228 retval = -EAGAIN; 229 goto err; 230 } 231 free_pipebuf(kpage); 232 break; 233 } 234 } 235 UNLOCK_PIPE(pipe); 236 if (!nsent && signal_pending(current)) 237 return -ERESTARTSYS; 238 *poffset += nsent; 239 return offset - orig_offset; 240 241 err: 242 UNLOCK_PIPE(pipe); 243 free_pipebuf(kpage); 244 return retval; 245 } 246 247 #endif 248 94 249 /** 95 250 * Read from a regular file. … … 567 722 * cached. Investigate. */ 568 723 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) 569 .splice_read = generic_file_splice_read,724 .splice_read = sf_splice_read, 570 725 # else 571 726 .sendfile = generic_file_sendfile,
Note:
See TracChangeset
for help on using the changeset viewer.