- 時間撮記:
- 2010-6-10 下午04:23:36 (14 年 以前)
- 檔案:
-
- 修改 1 筆資料
圖例:
- 未更動
- 新增
- 刪除
-
trunk/src/VBox/Additions/linux/sharedfolders/regops.c
r29935 r30153 24 24 25 25 26 static void *alloc_bounch_buffer 26 static void *alloc_bounch_buffer(size_t *tmp_sizep, PRTCCPHYS physp, size_t xfer_size, const char *caller) 27 27 { 28 28 size_t tmp_size; … … 33 33 if (tmp_size > 16U*_1K) 34 34 tmp_size = 16U*_1K; 35 tmp = kmalloc 35 tmp = kmalloc(tmp_size, GFP_KERNEL); 36 36 if (!tmp) { 37 37 38 38 /* fall back on a page sized buffer. */ 39 tmp = kmalloc 39 tmp = kmalloc(PAGE_SIZE, GFP_KERNEL); 40 40 if (!tmp) { 41 41 LogRel(("%s: could not allocate bounce buffer for xfer_size=%zu %s\n", caller, xfer_size)); … … 50 50 } 51 51 52 static void free_bounch_buffer 52 static void free_bounch_buffer(void *tmp) 53 53 { 54 54 kfree (tmp); … … 58 58 /* fops */ 59 59 static int 60 sf_reg_read_aux 61 62 60 sf_reg_read_aux(const char *caller, struct sf_glob_info *sf_g, 61 struct sf_reg_info *sf_r, void *buf, uint32_t *nread, 62 uint64_t pos) 63 63 { 64 64 /** @todo bird: yes, kmap() and kmalloc() input only. Since the buffer is 65 65 * contiguous in physical memory (kmalloc or single page), we should 66 66 * use a physical address here to speed things up. */ 67 int rc = vboxCallRead 68 69 if (RT_FAILURE 67 int rc = vboxCallRead(&client_handle, &sf_g->map, sf_r->handle, 68 pos, nread, buf, false /* already locked? */); 69 if (RT_FAILURE(rc)) { 70 70 LogFunc(("vboxCallRead failed. caller=%s, rc=%Rrc\n", 71 71 caller, rc)); … … 76 76 77 77 static int 78 sf_reg_write_aux 78 sf_reg_write_aux(const char *caller, struct sf_glob_info *sf_g, 79 79 struct sf_reg_info *sf_r, void *buf, uint32_t *nwritten, 80 80 uint64_t pos) … … 83 83 * contiguous in physical memory (kmalloc or single page), we should 84 84 * use a physical address here to speed things up. */ 85 int rc = vboxCallWrite 85 int rc = vboxCallWrite(&client_handle, &sf_g->map, sf_r->handle, 86 86 pos, nwritten, buf, false /* already locked? */); 87 if (RT_FAILURE 87 if (RT_FAILURE(rc)) { 88 88 LogFunc(("vboxCallWrite failed. caller=%s, rc=%Rrc\n", 89 89 caller, rc)); … … 94 94 95 95 static ssize_t 96 sf_reg_read 96 sf_reg_read(struct file *file, char *buf, size_t size, loff_t *off) 97 97 { 98 98 int err; … … 103 103 ssize_t total_bytes_read = 0; 104 104 struct inode *inode = file->f_dentry->d_inode; 105 struct sf_glob_info *sf_g = GET_GLOB_INFO 105 struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb); 106 106 struct sf_reg_info *sf_r = file->private_data; 107 107 loff_t pos = *off; 108 108 109 TRACE 110 if (!S_ISREG 109 TRACE(); 110 if (!S_ISREG(inode->i_mode)) { 111 111 LogFunc(("read from non regular file %d\n", inode->i_mode)); 112 112 return -EINVAL; … … 119 119 } 120 120 121 tmp = alloc_bounch_buffer 121 tmp = alloc_bounch_buffer(&tmp_size, &tmp_phys, size, __PRETTY_FUNCTION__); 122 122 if (!tmp) 123 123 return -ENOMEM; … … 132 132 nread = to_read; 133 133 134 err = sf_reg_read_aux 134 err = sf_reg_read_aux(__func__, sf_g, sf_r, tmp, &nread, pos); 135 135 if (err) 136 136 goto fail; 137 137 138 if (copy_to_user 138 if (copy_to_user(buf, tmp, nread)) { 139 139 err = -EFAULT; 140 140 goto fail; … … 151 151 152 152 *off += total_bytes_read; 153 free_bounch_buffer 153 free_bounch_buffer(tmp); 154 154 return total_bytes_read; 155 155 156 156 fail: 157 free_bounch_buffer 157 free_bounch_buffer(tmp); 158 158 return err; 159 159 } 160 160 161 161 static ssize_t 162 sf_reg_write 162 sf_reg_write(struct file *file, const char *buf, size_t size, loff_t *off) 163 163 { 164 164 int err; … … 169 169 ssize_t total_bytes_written = 0; 170 170 struct inode *inode = file->f_dentry->d_inode; 171 struct sf_inode_info *sf_i = GET_INODE_INFO 172 struct sf_glob_info *sf_g = GET_GLOB_INFO 171 struct sf_inode_info *sf_i = GET_INODE_INFO(inode); 172 struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb); 173 173 struct sf_reg_info *sf_r = file->private_data; 174 174 loff_t pos; 175 175 176 TRACE 177 BUG_ON 178 BUG_ON 179 BUG_ON 180 181 if (!S_ISREG 176 TRACE(); 177 BUG_ON(!sf_i); 178 BUG_ON(!sf_g); 179 BUG_ON(!sf_r); 180 181 if (!S_ISREG(inode->i_mode)) { 182 182 LogFunc(("write to non regular file %d\n", inode->i_mode)); 183 183 return -EINVAL; … … 196 196 return 0; 197 197 198 tmp = alloc_bounch_buffer 198 tmp = alloc_bounch_buffer(&tmp_size, &tmp_phys, size, __PRETTY_FUNCTION__); 199 199 if (!tmp) 200 200 return -ENOMEM; … … 209 209 nwritten = to_write; 210 210 211 if (copy_from_user 211 if (copy_from_user(tmp, buf, to_write)) { 212 212 err = -EFAULT; 213 213 goto fail; … … 216 216 #if 1 217 217 if (VbglR0CanUsePhysPageList()) { 218 err = VbglR0SfWritePhysCont 219 218 err = VbglR0SfWritePhysCont(&client_handle, &sf_g->map, sf_r->handle, 219 pos, &nwritten, tmp_phys); 220 220 err = RT_FAILURE(err) ? -EPROTO : 0; 221 221 } else 222 222 #endif 223 err = sf_reg_write_aux 223 err = sf_reg_write_aux(__func__, sf_g, sf_r, tmp, &nwritten, pos); 224 224 if (err) 225 225 goto fail; … … 238 238 239 239 sf_i->force_restat = 1; 240 free_bounch_buffer 240 free_bounch_buffer(tmp); 241 241 return total_bytes_written; 242 242 243 243 fail: 244 free_bounch_buffer 244 free_bounch_buffer(tmp); 245 245 return err; 246 246 } 247 247 248 248 static int 249 sf_reg_open 249 sf_reg_open(struct inode *inode, struct file *file) 250 250 { 251 251 int rc, rc_linux = 0; 252 struct sf_glob_info *sf_g = GET_GLOB_INFO 253 struct sf_inode_info *sf_i = GET_INODE_INFO 252 struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb); 253 struct sf_inode_info *sf_i = GET_INODE_INFO(inode); 254 254 struct sf_reg_info *sf_r; 255 255 SHFLCREATEPARMS params; 256 256 257 TRACE 258 BUG_ON 259 BUG_ON 257 TRACE(); 258 BUG_ON(!sf_g); 259 BUG_ON(!sf_i); 260 260 261 261 LogFunc(("open %s\n", sf_i->path->String.utf8)); 262 262 263 sf_r = kmalloc (sizeof(*sf_r), GFP_KERNEL);263 sf_r = kmalloc(sizeof(*sf_r), GFP_KERNEL); 264 264 if (!sf_r) { 265 265 LogRelFunc(("could not allocate reg info\n")); … … 342 342 LogFunc(("sf_reg_open: calling vboxCallCreate, file %s, flags=%#x, %#x\n", 343 343 sf_i->path->String.utf8 , file->f_flags, params.CreateFlags)); 344 rc = vboxCallCreate 345 346 if (RT_FAILURE 344 rc = vboxCallCreate(&client_handle, &sf_g->map, sf_i->path, ¶ms); 345 346 if (RT_FAILURE(rc)) { 347 347 LogFunc(("vboxCallCreate failed flags=%d,%#x rc=%Rrc\n", 348 348 file->f_flags, params.CreateFlags, rc)); 349 kfree 349 kfree(sf_r); 350 350 return -RTErrConvertToErrno(rc); 351 351 } … … 373 373 374 374 static int 375 sf_reg_release 375 sf_reg_release(struct inode *inode, struct file *file) 376 376 { 377 377 int rc; 378 378 struct sf_reg_info *sf_r; 379 379 struct sf_glob_info *sf_g; 380 struct sf_inode_info *sf_i = GET_INODE_INFO 381 382 TRACE 383 sf_g = GET_GLOB_INFO 380 struct sf_inode_info *sf_i = GET_INODE_INFO(inode); 381 382 TRACE(); 383 sf_g = GET_GLOB_INFO(inode->i_sb); 384 384 sf_r = file->private_data; 385 385 386 BUG_ON 387 BUG_ON 388 389 rc = vboxCallClose 390 if (RT_FAILURE 386 BUG_ON(!sf_g); 387 BUG_ON(!sf_r); 388 389 rc = vboxCallClose(&client_handle, &sf_g->map, sf_r->handle); 390 if (RT_FAILURE(rc)) { 391 391 LogFunc(("vboxCallClose failed rc=%Rrc\n", rc)); 392 392 } 393 393 394 kfree 394 kfree(sf_r); 395 395 sf_i->file = NULL; 396 396 sf_i->handle = SHFL_HANDLE_NIL; … … 399 399 } 400 400 401 #if LINUX_VERSION_CODE > KERNEL_VERSION 401 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25) 402 402 static int 403 403 sf_reg_fault(struct vm_area_struct *vma, struct vm_fault *vmf) 404 #elif LINUX_VERSION_CODE >= KERNEL_VERSION 404 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) 405 405 static struct page * 406 sf_reg_nopage 406 sf_reg_nopage(struct vm_area_struct *vma, unsigned long vaddr, int *type) 407 407 # define SET_TYPE(t) *type = (t) 408 408 #else /* LINUX_VERSION_CODE < KERNEL_VERSION (2, 6, 0) */ 409 409 static struct page * 410 sf_reg_nopage 410 sf_reg_nopage(struct vm_area_struct *vma, unsigned long vaddr, int unused) 411 411 # define SET_TYPE(t) 412 412 #endif … … 419 419 struct file *file = vma->vm_file; 420 420 struct inode *inode = file->f_dentry->d_inode; 421 struct sf_glob_info *sf_g = GET_GLOB_INFO 421 struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb); 422 422 struct sf_reg_info *sf_r = file->private_data; 423 423 424 TRACE 425 #if LINUX_VERSION_CODE > KERNEL_VERSION 424 TRACE(); 425 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25) 426 426 if (vmf->pgoff > vma->vm_end) 427 427 return VM_FAULT_SIGBUS; 428 428 #else 429 429 if (vaddr > vma->vm_end) { 430 SET_TYPE 430 SET_TYPE(VM_FAULT_SIGBUS); 431 431 return NOPAGE_SIGBUS; 432 432 } 433 433 #endif 434 434 435 page = alloc_page 435 page = alloc_page(GFP_HIGHUSER); 436 436 if (!page) { 437 437 LogRelFunc(("failed to allocate page\n")); 438 #if LINUX_VERSION_CODE > KERNEL_VERSION 438 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25) 439 439 return VM_FAULT_OOM; 440 440 #else 441 SET_TYPE 441 SET_TYPE(VM_FAULT_OOM); 442 442 return NOPAGE_OOM; 443 443 #endif 444 444 } 445 445 446 buf = kmap 447 #if LINUX_VERSION_CODE > KERNEL_VERSION 446 buf = kmap(page); 447 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25) 448 448 off = (vmf->pgoff << PAGE_SHIFT); 449 449 #else 450 450 off = (vaddr - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT); 451 451 #endif 452 err = sf_reg_read_aux 452 err = sf_reg_read_aux(__func__, sf_g, sf_r, buf, &nread, off); 453 453 if (err) { 454 kunmap 455 put_page 456 #if LINUX_VERSION_CODE > KERNEL_VERSION 454 kunmap(page); 455 put_page(page); 456 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25) 457 457 return VM_FAULT_SIGBUS; 458 458 #else 459 SET_TYPE 459 SET_TYPE(VM_FAULT_SIGBUS); 460 460 return NOPAGE_SIGBUS; 461 461 #endif … … 464 464 BUG_ON (nread > PAGE_SIZE); 465 465 if (!nread) { 466 #if LINUX_VERSION_CODE > KERNEL_VERSION 467 clear_user_page (page_address(page), vmf->pgoff, page);468 #elif LINUX_VERSION_CODE >= KERNEL_VERSION 469 clear_user_page (page_address(page), vaddr, page);470 #else 471 clear_user_page (page_address(page), vaddr);466 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25) 467 clear_user_page(page_address(page), vmf->pgoff, page); 468 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) 469 clear_user_page(page_address(page), vaddr, page); 470 #else 471 clear_user_page(page_address(page), vaddr); 472 472 #endif 473 473 } 474 474 else { 475 memset 476 } 477 478 flush_dcache_page 479 kunmap 480 #if LINUX_VERSION_CODE > KERNEL_VERSION 475 memset(buf + nread, 0, PAGE_SIZE - nread); 476 } 477 478 flush_dcache_page(page); 479 kunmap(page); 480 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25) 481 481 vmf->page = page; 482 482 return 0; 483 483 #else 484 SET_TYPE 484 SET_TYPE(VM_FAULT_MAJOR); 485 485 return page; 486 486 #endif … … 488 488 489 489 static struct vm_operations_struct sf_vma_ops = { 490 #if LINUX_VERSION_CODE > KERNEL_VERSION 490 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25) 491 491 .fault = sf_reg_fault 492 492 #else … … 496 496 497 497 static int 498 sf_reg_mmap 499 { 500 TRACE 498 sf_reg_mmap(struct file *file, struct vm_area_struct *vma) 499 { 500 TRACE(); 501 501 if (vma->vm_flags & VM_SHARED) { 502 502 LogFunc(("shared mmapping not available\n")); … … 514 514 .release = sf_reg_release, 515 515 .mmap = sf_reg_mmap, 516 #if LINUX_VERSION_CODE >= KERNEL_VERSION 517 # if LINUX_VERSION_CODE >= KERNEL_VERSION 516 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) 517 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) 518 518 .splice_read = generic_file_splice_read, 519 519 # else … … 522 522 .aio_read = generic_file_aio_read, 523 523 .aio_write = generic_file_aio_write, 524 # if LINUX_VERSION_CODE >= KERNEL_VERSION 524 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) 525 525 .fsync = noop_fsync, 526 526 # else … … 533 533 534 534 struct inode_operations sf_reg_iops = { 535 #if LINUX_VERSION_CODE < KERNEL_VERSION 535 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) 536 536 .revalidate = sf_inode_revalidate 537 537 #else … … 542 542 543 543 544 #if LINUX_VERSION_CODE >= KERNEL_VERSION 544 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) 545 545 static int 546 546 sf_readpage(struct file *file, struct page *page) 547 547 { 548 548 struct inode *inode = file->f_dentry->d_inode; 549 struct sf_glob_info *sf_g = GET_GLOB_INFO 549 struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb); 550 550 struct sf_reg_info *sf_r = file->private_data; 551 551 uint32_t nread = PAGE_SIZE; … … 554 554 int ret; 555 555 556 TRACE 556 TRACE(); 557 557 558 558 buf = kmap(page); 559 ret = sf_reg_read_aux 559 ret = sf_reg_read_aux(__func__, sf_g, sf_r, buf, &nread, off); 560 560 if (ret) { 561 kunmap 561 kunmap(page); 562 562 if (PageLocked(page)) 563 563 unlock_page(page); 564 564 return ret; 565 565 } 566 BUG_ON 566 BUG_ON(nread > PAGE_SIZE); 567 567 memset(&buf[nread], 0, PAGE_SIZE - nread); 568 flush_dcache_page 569 kunmap 568 flush_dcache_page(page); 569 kunmap(page); 570 570 SetPageUptodate(page); 571 571 unlock_page(page); … … 578 578 struct address_space *mapping = page->mapping; 579 579 struct inode *inode = mapping->host; 580 struct sf_glob_info *sf_g = GET_GLOB_INFO 581 struct sf_inode_info *sf_i = GET_INODE_INFO 580 struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb); 581 struct sf_inode_info *sf_i = GET_INODE_INFO(inode); 582 582 struct file *file = sf_i->file; 583 583 struct sf_reg_info *sf_r = file->private_data; … … 588 588 int err; 589 589 590 TRACE 590 TRACE(); 591 591 592 592 if (page->index >= end_index) … … 595 595 buf = kmap(page); 596 596 597 err = sf_reg_write_aux 597 err = sf_reg_write_aux(__func__, sf_g, sf_r, buf, &nwritten, off); 598 598 if (err < 0) { 599 599 ClearPageUptodate(page); … … 614 614 } 615 615 616 # if LINUX_VERSION_CODE >= KERNEL_VERSION 616 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) 617 617 int 618 618 sf_write_begin(struct file *file, struct address_space *mapping, loff_t pos, 619 619 unsigned len, unsigned flags, struct page **pagep, void **fsdata) 620 620 { 621 TRACE 621 TRACE(); 622 622 623 623 return simple_write_begin(file, mapping, pos, len, flags, pagep, fsdata); … … 629 629 { 630 630 struct inode *inode = mapping->host; 631 struct sf_glob_info *sf_g = GET_GLOB_INFO 631 struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb); 632 632 struct sf_reg_info *sf_r = file->private_data; 633 633 void *buf; … … 636 636 int err; 637 637 638 TRACE 638 TRACE(); 639 639 640 640 buf = kmap(page); 641 err = sf_reg_write_aux 641 err = sf_reg_write_aux(__func__, sf_g, sf_r, buf+from, &nwritten, pos); 642 642 kunmap(page); 643 643 … … 662 662 .readpage = sf_readpage, 663 663 .writepage = sf_writepage, 664 # if LINUX_VERSION_CODE >= KERNEL_VERSION 664 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) 665 665 .write_begin = sf_write_begin, 666 666 .write_end = sf_write_end,
注意:
瀏覽 TracChangeset
來幫助您使用更動檢視器