VirtualBox

Changeset 77502 in vbox for trunk/src/VBox/Additions


Ignore:
Timestamp:
Feb 28, 2019 12:05:56 PM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
129098
Message:

linux/vboxsf: Rewrote sf_lookup() combining the inode creation bits with sf_instantiate(). bugref:9172

Location:
trunk/src/VBox/Additions/linux/sharedfolders
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/linux/sharedfolders/dirops.c

    r77492 r77502  
    379379
    380380/**
     381 * Worker for sf_lookup() and sf_instantiate().
     382 */
     383static 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/**
    381433 * This is called when vfs failed to locate dentry in the cache. The
    382434 * job of this function is to allocate inode and link it to dentry.
     
    395447    )
    396448{
    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)
    422531                        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;
    481535}
    482536
     
    488542 * @param parent        inode entry of the directory
    489543 * @param dentry        directory cache entry
    490  * @param path          path name
     544 * @param path          path name.  Consumed on success.
    491545 * @param info          file information
    492546 * @param handle        handle
     
    494548 */
    495549static int sf_instantiate(struct inode *parent, struct dentry *dentry,
    496                           SHFLSTRING * path, PSHFLFSOBJINFO info,
     550                          PSHFLSTRING path, PSHFLFSOBJINFO info,
    497551                          SHFLHANDLE handle)
    498552{
    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;
    555562}
    556563
     
    568575{
    569576        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);
    571578        struct sf_glob_info *sf_g = GET_GLOB_INFO(parent->i_sb);
    572579        SHFLSTRING *path;
     
    579586
    580587        TRACE();
    581         BUG_ON(!sf_i);
     588        BUG_ON(!sf_parent_i);
    582589        BUG_ON(!sf_g);
    583590
    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);
    585592        if (err)
    586593                goto fail0;
     
    615622                err = -EPROTO;
    616623                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));
    618625                goto fail2;
    619626        }
     
    622629                err = -EPERM;
    623630                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));
    625632                goto fail2;
    626633        }
     
    631638                             fDirectory ? SHFL_HANDLE_NIL : pCreateParms->Handle);
    632639        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));
    635641                goto fail3;
    636642        }
     
    648654        }
    649655
    650         sf_i->force_restat = 1; /**< @todo r=bird: Why?!? */
     656        sf_parent_i->force_restat = 1;
    651657        VbglR0PhysHeapFree(pReq);
    652658        return 0;
  • trunk/src/VBox/Additions/linux/sharedfolders/utils.c

    r77492 r77502  
    192192
    193193
     194/** @note Currently only used for the root directory during (re-)mount.  */
    194195int sf_stat(const char *caller, struct sf_glob_info *sf_g,
    195196            SHFLSTRING *path, PSHFLFSOBJINFO result, int ok_to_fail)
     
    971972
    972973
    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 */
    976979static int
    977980#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
     
    10821085}
    10831086
     1087/** For logging purposes only. */
    10841088static int sf_dentry_init(struct dentry *pDirEntry)
    10851089{
     
    10901094#endif /* SFLOG_ENABLED */
    10911095
    1092 
     1096/**
     1097 * Directory entry operations.
     1098 *
     1099 * Since 2.6.38 this is used via the super_block::s_d_op member.
     1100 */
    10931101struct dentry_operations sf_dentry_ops = {
    10941102        .d_revalidate = sf_dentry_revalidate,
     
    10981106#endif
    10991107};
     1108
    11001109
    11011110int sf_init_backing_dev(struct super_block *sb, struct sf_glob_info *sf_g)
  • trunk/src/VBox/Additions/linux/sharedfolders/vfsmod.c

    r77492 r77502  
    533533}
    534534
    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 */
    536541#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0)
    537542static int sf_show_options(struct seq_file *m, struct vfsmount *mnt)
     
    555560                }
    556561        }
    557 
    558     return 0;
     562        return 0;
    559563}
    560564
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette