Changeset 77502 in vbox for trunk/src/VBox/Additions
- Timestamp:
- Feb 28, 2019 12:05:56 PM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 129098
- Location:
- trunk/src/VBox/Additions/linux/sharedfolders
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/linux/sharedfolders/dirops.c
r77492 r77502 379 379 380 380 /** 381 * Worker for sf_lookup() and sf_instantiate(). 382 */ 383 static struct inode *sf_create_inode(struct inode *parent, struct dentry *dentry, PSHFLSTRING path, 384 PSHFLFSOBJINFO pObjInfo, struct sf_glob_info *sf_g, bool fInstantiate) 385 { 386 /* 387 * Allocate memory for our additional inode info and create an inode. 388 */ 389 struct sf_inode_info *sf_new_i = (struct sf_inode_info *)kmalloc(sizeof(*sf_new_i), GFP_KERNEL); 390 if (sf_new_i) { 391 ino_t iNodeNo = iunique(parent->i_sb, 1); 392 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 25) 393 struct inode *pInode = iget_locked(parent->i_sb, iNodeNo); 394 #else 395 struct inode *pInode = iget(parent->i_sb, iNodeNo); 396 #endif 397 if (pInode) { 398 /* 399 * Initialize the two structures. 400 */ 401 #ifdef VBOX_STRICT 402 sf_new_i->u32Magic = SF_INODE_INFO_MAGIC; 403 #endif 404 sf_new_i->path = path; 405 sf_new_i->force_reread = 0; 406 sf_new_i->force_restat = 0; 407 sf_new_i->ts_up_to_date = jiffies; 408 RTListInit(&sf_new_i->HandleList); 409 sf_new_i->handle = SHFL_HANDLE_NIL; 410 411 SET_INODE_INFO(pInode, sf_new_i); 412 sf_init_inode(pInode, sf_new_i, pObjInfo, sf_g); 413 414 /* 415 * Before we unlock the new inode, we may need to call d_instantiate. 416 */ 417 if (fInstantiate) 418 d_instantiate(dentry, pInode); 419 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 25) 420 unlock_new_inode(pInode); 421 #endif 422 return pInode; 423 424 } 425 LogFunc(("iget failed\n")); 426 kfree(sf_new_i); 427 } else 428 LogRelFunc(("could not allocate memory for new inode info\n")); 429 return NULL; 430 } 431 432 /** 381 433 * This is called when vfs failed to locate dentry in the cache. The 382 434 * job of this function is to allocate inode and link it to dentry. … … 395 447 ) 396 448 { 397 int err; 398 struct sf_inode_info *sf_i, *sf_new_i; 399 struct sf_glob_info *sf_g; 400 SHFLSTRING *path; 401 struct inode *inode; 402 ino_t ino; 403 SHFLFSOBJINFO fsinfo; 404 405 TRACE(); 406 sf_g = GET_GLOB_INFO(parent->i_sb); 407 sf_i = GET_INODE_INFO(parent); 408 409 BUG_ON(!sf_g); 410 BUG_ON(!sf_i); 411 412 err = sf_path_from_dentry(__func__, sf_g, sf_i, dentry, &path); 413 if (err) 414 goto fail0; 415 416 /** @todo call host directly and avoid unnecessary copying here. */ 417 err = sf_stat(__func__, sf_g, path, &fsinfo, 1); 418 if (err) { 419 if (err == -ENOENT) { 420 /* -ENOENT: add NULL inode to dentry so it later can be 421 created via call to create/mkdir/open */ 449 struct sf_glob_info *sf_g = GET_GLOB_INFO(parent->i_sb); 450 struct sf_inode_info *sf_i = GET_INODE_INFO(parent); 451 SHFLSTRING *path; 452 struct dentry *dret; 453 int rc; 454 455 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) 456 SFLOGFLOW(("sf_lookup: parent=%p dentry=%p flags=%#x\n", parent, dentry, flags)); 457 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) 458 SFLOGFLOW(("sf_lookup: parent=%p dentry=%p nd=%p{.flags=%#x}\n", parent, dentry, nd, nd ? nd->flags : 0)); 459 #else 460 SFLOGFLOW(("sf_lookup: parent=%p dentry=%p\n", parent, dentry)); 461 #endif 462 463 Assert(sf_g); 464 Assert(sf_i && sf_i->u32Magic == SF_INODE_INFO_MAGIC); 465 466 /* 467 * Build the path. We'll associate the path with dret's inode on success. 468 */ 469 rc = sf_path_from_dentry(__func__, sf_g, sf_i, dentry, &path); 470 if (rc == 0) { 471 /* 472 * Do a lookup on the host side. 473 */ 474 VBOXSFCREATEREQ *pReq = (VBOXSFCREATEREQ *)VbglR0PhysHeapAlloc(sizeof(*pReq) + path->u16Size); 475 if (pReq) { 476 struct inode *pInode = NULL; 477 478 RT_ZERO(*pReq); 479 memcpy(&pReq->StrPath, path, SHFLSTRING_HEADER_SIZE + path->u16Size); 480 pReq->CreateParms.Handle = SHFL_HANDLE_NIL; 481 pReq->CreateParms.CreateFlags = SHFL_CF_LOOKUP | SHFL_CF_ACT_FAIL_IF_NEW; 482 483 LogFunc(("Calling VbglR0SfHostReqCreate on %s\n", path->String.utf8)); 484 rc = VbglR0SfHostReqCreate(sf_g->map.root, pReq); 485 if (RT_SUCCESS(rc)) { 486 if (pReq->CreateParms.Result == SHFL_FILE_EXISTS) { 487 /* 488 * Create an inode for the result. Since this also confirms 489 * the existence of all parent dentries, we increase their TTL. 490 */ 491 pInode = sf_create_inode(parent, dentry, path, &pReq->CreateParms.Info, 492 sf_g, false /*fInstantiate*/); 493 if (rc == 0) { 494 path = NULL; /* given to the inode */ 495 dret = dentry; 496 } else 497 dret = (struct dentry *)ERR_PTR(-ENOMEM); 498 sf_dentry_chain_increase_parent_ttl(dentry); 499 } else if ( pReq->CreateParms.Result == SHFL_FILE_NOT_FOUND 500 || pReq->CreateParms.Result == SHFL_PATH_NOT_FOUND /*this probably should happen*/) { 501 dret = dentry; 502 } else { 503 AssertMsgFailed(("%d\n", pReq->CreateParms.Result)); 504 dret = (struct dentry *)ERR_PTR(-EPROTO); 505 } 506 } else if (rc == VERR_INVALID_NAME) { 507 dret = dentry; /* this can happen for names like 'foo*' on a Windows host */ 508 } else { 509 LogFunc(("VbglR0SfHostReqCreate failed on %s: %Rrc\n", path->String.utf8, rc)); 510 dret = (struct dentry *)ERR_PTR(-EPROTO); 511 } 512 VbglR0PhysHeapFree(pReq); 513 514 /* 515 * When dret is set to dentry we got something to insert, 516 * though it may be negative (pInode == NULL). 517 */ 518 if (dret == dentry) { 519 sf_dentry_set_update_jiffies(dentry, jiffies); 520 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38) 521 Assert(dentry->d_op == &sf_dentry_ops); /* (taken from the superblock) */ 522 #else 523 dentry->d_op = &sf_dentry_ops; 524 #endif 525 d_add(dentry, pInode); 526 dret = NULL; 527 } 528 } else 529 dret = (struct dentry *)ERR_PTR(-ENOMEM); 530 if (path) 422 531 kfree(path); 423 inode = NULL; 424 } else 425 goto fail1; 426 } else { 427 sf_new_i = kmalloc(sizeof(*sf_new_i), GFP_KERNEL); 428 if (!sf_new_i) { 429 LogRelFunc(("could not allocate memory for new inode info\n")); 430 err = -ENOMEM; 431 goto fail1; 432 } 433 sf_new_i->handle = SHFL_HANDLE_NIL; 434 sf_new_i->force_reread = 0; 435 RTListInit(&sf_new_i->HandleList); 436 #ifdef VBOX_STRICT 437 sf_new_i->u32Magic = SF_INODE_INFO_MAGIC; 438 #endif 439 440 ino = iunique(parent->i_sb, 1); 441 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 25) 442 inode = iget_locked(parent->i_sb, ino); 443 #else 444 inode = iget(parent->i_sb, ino); 445 #endif 446 if (!inode) { 447 LogFunc(("iget failed\n")); 448 err = -ENOMEM; /* XXX: ??? */ 449 goto fail2; 450 } 451 452 sf_new_i->path = path; 453 SET_INODE_INFO(inode, sf_new_i); 454 sf_init_inode(inode, sf_new_i, &fsinfo, sf_g); 455 456 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 25) 457 unlock_new_inode(inode); 458 #endif 459 sf_dentry_chain_increase_parent_ttl(dentry); 460 } 461 462 //sf_i->force_restat = 0; /** @todo r=bird: This looks like confusion. */ 463 464 sf_dentry_set_update_jiffies(dentry, jiffies); 465 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38) 466 Assert(dentry->d_op == &sf_dentry_ops); /* (taken from the superblock) */ 467 #else 468 dentry->d_op = &sf_dentry_ops; 469 #endif 470 d_add(dentry, inode); 471 return NULL; 472 473 fail2: 474 kfree(sf_new_i); 475 476 fail1: 477 kfree(path); 478 479 fail0: 480 return ERR_PTR(err); 532 } else 533 dret = (struct dentry *)ERR_PTR(rc); 534 return dret; 481 535 } 482 536 … … 488 542 * @param parent inode entry of the directory 489 543 * @param dentry directory cache entry 490 * @param path path name 544 * @param path path name. Consumed on success. 491 545 * @param info file information 492 546 * @param handle handle … … 494 548 */ 495 549 static int sf_instantiate(struct inode *parent, struct dentry *dentry, 496 SHFLSTRING *path, PSHFLFSOBJINFO info,550 PSHFLSTRING path, PSHFLFSOBJINFO info, 497 551 SHFLHANDLE handle) 498 552 { 499 int err; 500 ino_t ino; 501 struct inode *inode; 502 struct sf_inode_info *sf_new_i; 503 struct sf_glob_info *sf_g = GET_GLOB_INFO(parent->i_sb); 504 505 TRACE(); 506 BUG_ON(!sf_g); 507 508 sf_new_i = kmalloc(sizeof(*sf_new_i), GFP_KERNEL); 509 if (!sf_new_i) { 510 LogRelFunc(("could not allocate inode info.\n")); 511 err = -ENOMEM; 512 goto fail0; 513 } 514 515 ino = iunique(parent->i_sb, 1); 516 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 25) 517 inode = iget_locked(parent->i_sb, ino); 518 #else 519 inode = iget(parent->i_sb, ino); 520 #endif 521 if (!inode) { 522 LogFunc(("iget failed\n")); 523 err = -ENOMEM; 524 goto fail1; 525 } 526 527 sf_init_inode(inode, sf_new_i, info, sf_g); 528 529 sf_new_i->path = path; 530 RTListInit(&sf_new_i->HandleList); 531 sf_new_i->force_restat = 1; 532 sf_new_i->force_reread = 0; 533 sf_new_i->ts_up_to_date = jiffies - INT_MAX / 2; 534 #ifdef VBOX_STRICT 535 sf_new_i->u32Magic = SF_INODE_INFO_MAGIC; 536 #endif 537 SET_INODE_INFO(inode, sf_new_i); 538 539 d_instantiate(dentry, inode); 540 541 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 25) 542 unlock_new_inode(inode); 543 #endif 544 545 /* Store this handle if we leave the handle open. */ 546 sf_new_i->handle = handle; 547 return 0; 548 549 fail1: 550 kfree(sf_new_i); 551 552 fail0: 553 return err; 554 553 struct sf_glob_info *sf_g = GET_GLOB_INFO(parent->i_sb); 554 struct inode *pInode = sf_create_inode(parent, dentry, path, info, sf_g, true /*fInstantiate*/); 555 if (pInode) { 556 /* Store this handle if we leave the handle open. */ 557 struct sf_inode_info *sf_new_i = GET_INODE_INFO(pInode); 558 sf_new_i->handle = handle; 559 return 0; 560 } 561 return -ENOMEM; 555 562 } 556 563 … … 568 575 { 569 576 int rc, err; 570 struct sf_inode_info *sf_ i = GET_INODE_INFO(parent);577 struct sf_inode_info *sf_parent_i = GET_INODE_INFO(parent); 571 578 struct sf_glob_info *sf_g = GET_GLOB_INFO(parent->i_sb); 572 579 SHFLSTRING *path; … … 579 586 580 587 TRACE(); 581 BUG_ON(!sf_ i);588 BUG_ON(!sf_parent_i); 582 589 BUG_ON(!sf_g); 583 590 584 err = sf_path_from_dentry(__func__, sf_g, sf_ i, dentry, &path);591 err = sf_path_from_dentry(__func__, sf_g, sf_parent_i, dentry, &path); 585 592 if (err) 586 593 goto fail0; … … 615 622 err = -EPROTO; 616 623 LogFunc(("(%d): SHFL_FN_CREATE(%s) failed rc=%Rrc\n", 617 fDirectory, sf_ i->path->String.utf8, rc));624 fDirectory, sf_parent_i->path->String.utf8, rc)); 618 625 goto fail2; 619 626 } … … 622 629 err = -EPERM; 623 630 LogFunc(("(%d): could not create file %s result=%d\n", 624 fDirectory, sf_ i->path->String.utf8, pCreateParms->Result));631 fDirectory, sf_parent_i->path->String.utf8, pCreateParms->Result)); 625 632 goto fail2; 626 633 } … … 631 638 fDirectory ? SHFL_HANDLE_NIL : pCreateParms->Handle); 632 639 if (err) { 633 LogFunc(("(%d): could not instantiate dentry for %s err=%d\n", 634 fDirectory, sf_i->path->String.utf8, err)); 640 LogFunc(("(%d): could not instantiate dentry for %s err=%d\n", fDirectory, path->String.utf8, err)); 635 641 goto fail3; 636 642 } … … 648 654 } 649 655 650 sf_ i->force_restat = 1; /**< @todo r=bird: Why?!? */656 sf_parent_i->force_restat = 1; 651 657 VbglR0PhysHeapFree(pReq); 652 658 return 0; -
trunk/src/VBox/Additions/linux/sharedfolders/utils.c
r77492 r77502 192 192 193 193 194 /** @note Currently only used for the root directory during (re-)mount. */ 194 195 int sf_stat(const char *caller, struct sf_glob_info *sf_g, 195 196 SHFLSTRING *path, PSHFLFSOBJINFO result, int ok_to_fail) … … 971 972 972 973 973 /* this is called during name resolution/lookup to check if the 974 [dentry] in the cache is still valid. the job is handled by 975 [sf_inode_revalidate] */ 974 /** 975 * This is called during name resolution/lookup to check if the @a dentry in the 976 * cache is still valid. The actual validation is job is handled by 977 * sf_inode_revalidate(). 978 */ 976 979 static int 977 980 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) … … 1082 1085 } 1083 1086 1087 /** For logging purposes only. */ 1084 1088 static int sf_dentry_init(struct dentry *pDirEntry) 1085 1089 { … … 1090 1094 #endif /* SFLOG_ENABLED */ 1091 1095 1092 1096 /** 1097 * Directory entry operations. 1098 * 1099 * Since 2.6.38 this is used via the super_block::s_d_op member. 1100 */ 1093 1101 struct dentry_operations sf_dentry_ops = { 1094 1102 .d_revalidate = sf_dentry_revalidate, … … 1098 1106 #endif 1099 1107 }; 1108 1100 1109 1101 1110 int sf_init_backing_dev(struct super_block *sb, struct sf_glob_info *sf_g) -
trunk/src/VBox/Additions/linux/sharedfolders/vfsmod.c
r77492 r77502 533 533 } 534 534 535 /** Show mount options. */ 535 /** 536 * Show mount options. 537 * 538 * This is needed by the VBoxService automounter in order for it to pick up 539 * the the 'tag' option value it sets on its mount. 540 */ 536 541 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0) 537 542 static int sf_show_options(struct seq_file *m, struct vfsmount *mnt) … … 555 560 } 556 561 } 557 558 return 0; 562 return 0; 559 563 } 560 564
Note:
See TracChangeset
for help on using the changeset viewer.