VirtualBox

Changeset 46237 in vbox


Ignore:
Timestamp:
May 23, 2013 2:39:41 PM (12 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
85966
Message:

solaris/SharedFolders: Fix bug with truncating existing files on open. Avoids re-opening files during such a case for every read/write operation. Also avoid extra call through HGCM for each read-only file open operation.

Location:
trunk/src/VBox/Additions/solaris/SharedFolders
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.c

    r44528 r46237  
    4141#include <sys/sunddi.h>
    4242#include <sys/dirent.h>
     43#include <sys/file.h>
    4344#include "vboxfs_prov.h"
    4445#ifdef u
     
    357358
    358359int
    359 sfprov_open(sfp_mount_t *mnt, char *path, sfp_file_t **fp)
     360sfprov_diropen(sfp_mount_t *mnt, char *path, sfp_file_t **fp)
    360361{
    361362        int rc;
     
    365366        sfp_file_t *newfp;
    366367
    367         /*
    368          * First we attempt to open it read/write. If that fails we
    369          * try read only.
    370          */
    371368        bzero(&parms, sizeof(parms));
    372369        str = sfprov_string(path, &size);
    373370        parms.Handle = SHFL_HANDLE_NIL;
    374371        parms.Info.cbObject = 0;
    375         parms.CreateFlags = SHFL_CF_ACT_FAIL_IF_NEW | SHFL_CF_ACCESS_READWRITE;
     372        parms.CreateFlags =   SHFL_CF_DIRECTORY
     373                                                | SHFL_CF_ACCESS_READ
     374                                                | SHFL_CF_ACT_OPEN_IF_EXISTS
     375                                                | SHFL_CF_ACT_FAIL_IF_NEW;
     376
     377        /*
     378         * Open the host directory.
     379         */
    376380        rc = vboxCallCreate(&vbox_client, &mnt->map, str, &parms);
    377         if (RT_FAILURE(rc) && rc != VERR_ACCESS_DENIED) {
     381
     382        /*
     383         * Our VBoxFS interface here isn't very clear regarding failure and informational status.
     384         * Check the file-handle as well as the return code to make sure the operation succeeded.
     385         */
     386        if (RT_FAILURE(rc)) {
    378387                kmem_free(str, size);
    379388                return (sfprov_vbox2errno(rc));
    380389        }
     390
    381391        if (parms.Handle == SHFL_HANDLE_NIL) {
    382                 if (parms.Result == SHFL_PATH_NOT_FOUND ||
    383                     parms.Result == SHFL_FILE_NOT_FOUND) {
    384                         kmem_free(str, size);
    385                         return (ENOENT);
    386                 }
    387                 parms.CreateFlags =
    388                     SHFL_CF_ACT_FAIL_IF_NEW | SHFL_CF_ACCESS_READ;
    389                 rc = vboxCallCreate(&vbox_client, &mnt->map, str, &parms);
    390                 if (RT_FAILURE(rc)) {
    391                         kmem_free(str, size);
    392                         return (sfprov_vbox2errno(rc));
    393                 }
    394                 if (parms.Handle == SHFL_HANDLE_NIL) {
    395                         kmem_free(str, size);
    396                         return (ENOENT);
    397                 }
    398         }
    399         else
    400392                kmem_free(str, size);
     393                return (ENOENT);
     394        }
     395
    401396        newfp = kmem_alloc(sizeof(sfp_file_t), KM_SLEEP);
    402397        newfp->handle = parms.Handle;
     
    407402
    408403int
    409 sfprov_trunc(sfp_mount_t *mnt, char *path)
     404sfprov_open(sfp_mount_t *mnt, char *path, sfp_file_t **fp, int flag)
    410405{
    411406        int rc;
     
    413408        SHFLSTRING *str;
    414409        int size;
     410        sfp_file_t *newfp;
     411
     412        bzero(&parms, sizeof(parms));
     413        str = sfprov_string(path, &size);
     414        parms.Handle = SHFL_HANDLE_NIL;
     415        parms.Info.cbObject = 0;
    415416
    416417        /*
    417          * open it read/write.
     418         * Translate file modes.
    418419         */
    419         str = sfprov_string(path, &size);
    420         parms.Handle = 0;
    421         parms.Info.cbObject = 0;
    422         parms.CreateFlags = SHFL_CF_ACT_FAIL_IF_NEW | SHFL_CF_ACCESS_READWRITE |
    423             SHFL_CF_ACT_OVERWRITE_IF_EXISTS;
     420        if (flag & FCREAT) {
     421                parms.CreateFlags |= SHFL_CF_ACT_CREATE_IF_NEW;
     422                if (!(flag & FTRUNC))
     423                        parms.CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS;
     424        }
     425        else
     426                parms.CreateFlags |= SHFL_CF_ACT_FAIL_IF_NEW;
     427
     428        if (flag & FTRUNC)
     429                parms.CreateFlags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS | SHFL_CF_ACCESS_WRITE;
     430        if (flag & FWRITE)
     431                parms.CreateFlags |= SHFL_CF_ACCESS_WRITE;
     432        if (flag & FREAD)
     433                parms.CreateFlags |= SHFL_CF_ACCESS_READ;
     434    if (flag & FAPPEND)
     435                parms.CreateFlags |= SHFL_CF_ACCESS_APPEND;
     436
     437        /*
     438         * Open/create the host file.
     439         */
    424440        rc = vboxCallCreate(&vbox_client, &mnt->map, str, &parms);
    425         kmem_free(str, size);
    426 
     441
     442        /*
     443         * Our VBoxFS interface here isn't very clear regarding failure and informational status.
     444         * Check the file-handle as well as the return code to make sure the operation succeeded.
     445         */
    427446        if (RT_FAILURE(rc)) {
    428                 return (EINVAL);
    429         }
    430         (void)vboxCallClose(&vbox_client, &mnt->map, parms.Handle);
     447                kmem_free(str, size);
     448                return (sfprov_vbox2errno(rc));
     449        }
     450
     451        if (parms.Handle == SHFL_HANDLE_NIL) {
     452                kmem_free(str, size);
     453                return (ENOENT);
     454        }
     455
     456        newfp = kmem_alloc(sizeof(sfp_file_t), KM_SLEEP);
     457        newfp->handle = parms.Handle;
     458        newfp->map = mnt->map;
     459        *fp = newfp;
    431460        return (0);
    432461}
     
    890919        sfp_mount_t *mnt,
    891920        char *path,
    892         sffs_dirents_t **dirents)
     921        sffs_dirents_t **dirents,
     922        int flag)
    893923{
    894924        int error;
     
    911941        *dirents = NULL;
    912942
    913         error = sfprov_open(mnt, path, &fp);
     943        error = sfprov_diropen(mnt, path, &fp);
    914944        if (error != 0)
    915945                return (ENOENT);
  • trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.h

    r44528 r46237  
    101101extern int sfprov_create(sfp_mount_t *, char *path, mode_t mode,
    102102    sfp_file_t **fp, sffs_stat_t *stat);
    103 extern int sfprov_open(sfp_mount_t *, char *path, sfp_file_t **fp);
     103extern int sfprov_diropen(sfp_mount_t *mnt, char *path, sfp_file_t **fp);
     104extern int sfprov_open(sfp_mount_t *, char *path, sfp_file_t **fp, int flag);
    104105extern int sfprov_close(sfp_file_t *fp);
    105106extern int sfprov_read(sfp_file_t *, char * buffer, uint64_t offset,
     
    127128 * File/Directory operations
    128129 */
    129 extern int sfprov_trunc(sfp_mount_t *, char *);
    130130extern int sfprov_remove(sfp_mount_t *, char *path, uint_t is_link);
    131131extern int sfprov_mkdir(sfp_mount_t *, char *path, mode_t mode,
     
    165165
    166166extern int sfprov_readdir(sfp_mount_t *mnt, char *path,
    167         sffs_dirents_t **dirents);
     167        sffs_dirents_t **dirents, int flag);
    168168
    169169#ifdef  __cplusplus
  • trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c

    r44528 r46237  
    186186 */
    187187static void
    188 sfnode_open(sfnode_t *node)
     188sfnode_open(sfnode_t *node, int flag)
    189189{
    190190        int error;
     
    193193        if (node->sf_file != NULL)
    194194                return;
    195         error = sfprov_open(node->sf_sffs->sf_handle, node->sf_path, &fp);
     195        error = sfprov_open(node->sf_sffs->sf_handle, node->sf_path, &fp, flag);
    196196        if (error == 0)
     197        {
    197198                node->sf_file = fp;
     199                node->sf_flag = flag;
     200        }
     201        else
     202                node->sf_flag = ~0;
    198203}
    199204
     
    256261        node->sf_is_stale = 0;  /* never stale at creation */
    257262        node->sf_file = fp;
     263        node->sf_flag = ~0;
    258264        node->sf_vnode = NULL;  /* do this before any sfnode_get_vnode() */
    259265        node->sf_children = 0;
     
    699705        int             *eofp,
    700706        caller_context_t *ct,
    701         int             flags)
     707        int             flag)
    702708{
    703709        sfnode_t *dir = VN2SFN(vp);
     
    734740        if (dir->sf_dir_list == NULL) {
    735741                error = sfprov_readdir(dir->sf_sffs->sf_handle, dir->sf_path,
    736                     &dir->sf_dir_list);
     742                    &dir->sf_dir_list, flag);
    737743                if (error != 0)
    738744                        goto done;
     
    10321038
    10331039        mutex_enter(&sffs_lock);
    1034         sfnode_open(node);
    10351040        if (node->sf_file == NULL) {
    1036                 mutex_exit(&sffs_lock);
    1037                 return (EINVAL);
     1041                ASSERT(node->sf_flag != ~0);
     1042                sfnode_open(node, node->sf_flag);
     1043                if (node->sf_file == NULL)
     1044                        return (EBADF);
    10381045        }
    10391046
     
    10831090         */
    10841091        mutex_enter(&sffs_lock);
    1085         sfnode_open(node);
    10861092        if (node->sf_file == NULL) {
    1087                 mutex_exit(&sffs_lock);
    1088                 return (EINVAL);
     1093                ASSERT(node->sf_flag != ~0);
     1094                sfnode_open(node, node->sf_flag);
     1095                if (node->sf_file == NULL)
     1096                        return (EBADF);
    10891097        }
    10901098
     
    13051313                if (vp->v_type == VREG && (vap->va_mask & AT_SIZE) &&
    13061314                    vap->va_size == 0) {
    1307                         sfnode_open(node);
    1308                         if (node->sf_path == NULL)
    1309                                 error = ENOENT;
    1310                         else
    1311                                 error = sfprov_trunc(node->sf_sffs->sf_handle,
    1312                                     node->sf_path);
    1313                         if (error) {
     1315                        sfnode_open(node, flag | FTRUNC);
     1316                        if (node->sf_path == NULL) {
    13141317                                mutex_exit(&sffs_lock);
    13151318                                VN_RELE(vp);
    1316                                 return (error);
     1319                                return (ENOENT);
    13171320                        }
    13181321                }
     
    22192222
    22202223/*
    2221  * All the work for this is really done in lookup.
     2224 * All the work for this is really done in sffs_lookup().
    22222225 */
    22232226/*ARGSUSED*/
     
    22312234
    22322235        node = VN2SFN(*vpp);
    2233         sfnode_open(node);
     2236        sfnode_open(node, flag);
    22342237        if (node->sf_file == NULL)
    22352238                error = EINVAL;
    2236 
    22372239        mutex_exit(&sffs_lock);
    22382240
  • trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.h

    r44528 r46237  
    5353        vnode_t         *sf_vnode;      /* vnode if active */
    5454        sfp_file_t      *sf_file;       /* non NULL if open */
     55    int                 sf_flag;    /* last opened file-mode. */
    5556        struct sfnode   *sf_parent;     /* parent sfnode of this one */
    5657        uint16_t        sf_children;    /* number of children sfnodes */
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