VirtualBox

Ignore:
Timestamp:
Nov 22, 2018 9:16:48 PM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
126870
Message:

darwin/VBoxSF: Started rewriting this...

Location:
trunk/src/VBox/Additions/darwin/VBoxSF
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/darwin/VBoxSF/VBoxSF-Utils.cpp

    r75666 r75675  
    2020*   Header Files                                                                                                                 *
    2121*********************************************************************************************************************************/
     22#define LOG_GROUP LOG_GROUP_SHARED_FOLDERS
    2223#include "VBoxSFInternal.h"
    2324
    2425#include <iprt/assert.h>
    2526#include <iprt/mem.h>
    26 
    27 
     27#include <VBox/log.h>
     28
     29#if 0
    2830/**
    2931 * Helper function to create XNU VFS vnode object.
     
    387389    parms.CreateFlags   = fFlags;
    388390
    389     rc = VbglR0SfCreate(&g_SfClient, &pMount->pMap, pPath, &parms);
     391    rc = VbglR0SfCreate(&g_SfClientDarwin, &pMount->pMap, pPath, &parms);
    390392    if (RT_SUCCESS(rc))
    391393    {
     
    412414{
    413415    AssertReturn(pMount, EINVAL);
    414     return VbglR0SfClose(&g_SfClient, &pMount->pMap, pHandle);
     416    return VbglR0SfClose(&g_SfClientDarwin, &pMount->pMap, pHandle);
    415417}
    416418
     
    442444    parms.CreateFlags = SHFL_CF_LOOKUP | SHFL_CF_ACT_FAIL_IF_NEW;
    443445
    444     rc = VbglR0SfCreate(&g_SfClient, &pMount->pMap, pSHFLDPath, &parms);
     446    rc = VbglR0SfCreate(&g_SfClientDarwin, &pMount->pMap, pSHFLDPath, &parms);
    445447    if (rc == 0)
    446448        *Info = parms.Info;
     
    594596}
    595597
     598#endif
  • trunk/src/VBox/Additions/darwin/VBoxSF/VBoxSF-VNodeOps.cpp

    r75666 r75675  
    2121*   Header Files                                                                                                                 *
    2222*********************************************************************************************************************************/
     23#define LOG_GROUP LOG_GROUP_SHARED_FOLDERS
    2324#include "VBoxSFInternal.h"
    2425
    2526#include <iprt/mem.h>
    2627#include <iprt/assert.h>
    27 
    28 
    29 
    30 int vboxvfs_dfl_error(void)
    31 {
    32     PDEBUG("vboxvfs_dfl_error is called");
    33 
     28#include <VBox/log.h>
     29
     30
     31/*********************************************************************************************************************************
     32*   Structures and Typedefs                                                                                                      *
     33*********************************************************************************************************************************/
     34struct default_error_args_hack
     35{
     36    struct default_error_vdesc_hack
     37    {
     38        int vdesc_offset;
     39        const char *vdesc_name;
     40    } const *a_desc;
     41};
     42
     43
     44
     45/**
     46 * Default implementation that returns ENOTSUP.
     47 */
     48static int vboxSfDwnVnDefaultError(struct default_error_args_hack *pArgs)
     49{
     50    Log(("vboxSfDwnVnDefaultError: %s\n", RT_VALID_PTR(pArgs) && RT_VALID_PTR(pArgs->a_desc) ? pArgs->a_desc->vdesc_name : "??"));
     51    RT_NOREF(pArgs);
    3452    return ENOTSUP;
    3553}
    3654
    37 int vboxvfs_vnode_getattr(struct vnop_getattr_args *args)
    38 {
     55
     56static int vboxFsDwnVnGetAttr(struct vnop_getattr_args *pArgs)
     57{
     58#if 1
     59    RT_NOREF(pArgs);
     60    return ENOTSUP;
     61#else
     62
    3963    vboxvfs_mount_t   *pMount;
    4064    struct vnode_attr *vnode_args;
     
    5074    PDEBUG("Getting vnode attribute...");
    5175
    52     AssertReturn(args, EINVAL);
    53 
    54     vnode                = args->a_vp;                                   AssertReturn(vnode,           EINVAL);
    55     vnode_args           = args->a_vap;                                  AssertReturn(vnode_args,      EINVAL);
     76    AssertReturn(pArgs, EINVAL);
     77
     78    vnode                = pArgs->a_vp;                                   AssertReturn(vnode,           EINVAL);
     79    vnode_args           = pArgs->a_vap;                                  AssertReturn(vnode_args,      EINVAL);
    5680    mp                   = vnode_mount(vnode);                           AssertReturn(mp,              EINVAL);
    5781    pMount      = (vboxvfs_mount_t *)vfs_fsprivate(mp);     AssertReturn(pMount, EINVAL);
     
    125149
    126150    return rc;
    127 }
    128 
     151#endif
     152}
     153
     154#if 0
    129155/**
    130156 * Helper function for vboxvfs_vnode_lookup(): create new vnode.
     
    217243 */
    218244static int
    219 vboxvfs_vnode_lookup_dot_handler(struct vnop_lookup_args *args, vnode_t *result_vnode)
     245vboxvfs_vnode_lookup_dot_handler(struct vnop_lookup_args *pArgs, vnode_t *result_vnode)
    220246{
    221247    vnode_t vnode = NULL;
    222248
    223     if (args->a_cnp->cn_flags & ISDOTDOT)
    224     {
    225         vnode = vnode_getparent(args->a_dvp);
     249    if (pArgs->a_cnp->cn_flags & ISDOTDOT)
     250    {
     251        vnode = vnode_getparent(pArgs->a_dvp);
    226252        if (vnode)
    227253        {
     
    233259        {
    234260            PDEBUG("return parent directory not found, return current directory");
    235             *result_vnode = args->a_dvp;
     261            *result_vnode = pArgs->a_dvp;
    236262            return 0;
    237263        }
    238264    }
    239     else if ((strncmp(args->a_cnp->cn_nameptr, ".", 1) == 0) &&
    240              args->a_cnp->cn_namelen == 1)
     265    else if ((strncmp(pArgs->a_cnp->cn_nameptr, ".", 1) == 0) &&
     266             pArgs->a_cnp->cn_namelen == 1)
    241267    {
    242268        PDEBUG("return current directory");
    243         *result_vnode = args->a_dvp;
     269        *result_vnode = pArgs->a_dvp;
    244270        return 0;
    245271    }
     
    247273    return ENOENT;
    248274}
    249 
    250 int vboxvfs_vnode_lookup(struct vnop_lookup_args *args)
    251 {
     275#endif
     276
     277static int vboxSfDwnVnLookup(struct vnop_lookup_args *pArgs)
     278{
     279#if 1
     280    RT_NOREF(pArgs);
     281    return ENOTSUP;
     282#else
    252283    int rc;
    253284
     
    257288    PDEBUG("Looking up for vnode...");
    258289
    259     AssertReturn(args,                      EINVAL);
    260     AssertReturn(args->a_dvp,               EINVAL);
    261     AssertReturn(vnode_isdir(args->a_dvp),  EINVAL);
    262     AssertReturn(args->a_cnp,               EINVAL);
    263     AssertReturn(args->a_cnp->cn_nameptr,   EINVAL);
    264     AssertReturn(args->a_vpp,               EINVAL);
    265 
    266     pVnodeData = (vboxvfs_vnode_t *)vnode_fsnode(args->a_dvp);
     290    AssertReturn(pArgs,                      EINVAL);
     291    AssertReturn(pArgs->a_dvp,               EINVAL);
     292    AssertReturn(vnode_isdir(pArgs->a_dvp),  EINVAL);
     293    AssertReturn(pArgs->a_cnp,               EINVAL);
     294    AssertReturn(pArgs->a_cnp->cn_nameptr,   EINVAL);
     295    AssertReturn(pArgs->a_vpp,               EINVAL);
     296
     297    pVnodeData = (vboxvfs_vnode_t *)vnode_fsnode(pArgs->a_dvp);
    267298    AssertReturn(pVnodeData, EINVAL);
    268299    AssertReturn(pVnodeData->pLock, EINVAL);
    269300
    270301    /*
    271     todo: take care about args->a_cnp->cn_nameiop
     302    todo: take care about pArgs->a_cnp->cn_nameiop
    272303    */
    273304
    274     if      (args->a_cnp->cn_nameiop == LOOKUP) PDEBUG("LOOKUP");
    275     else if (args->a_cnp->cn_nameiop == CREATE) PDEBUG("CREATE");
    276     else if (args->a_cnp->cn_nameiop == RENAME) PDEBUG("RENAME");
    277     else if (args->a_cnp->cn_nameiop == DELETE) PDEBUG("DELETE");
    278     else PDEBUG("Unknown cn_nameiop: 0x%X", (int)args->a_cnp->cn_nameiop);
     305    if      (pArgs->a_cnp->cn_nameiop == LOOKUP) PDEBUG("LOOKUP");
     306    else if (pArgs->a_cnp->cn_nameiop == CREATE) PDEBUG("CREATE");
     307    else if (pArgs->a_cnp->cn_nameiop == RENAME) PDEBUG("RENAME");
     308    else if (pArgs->a_cnp->cn_nameiop == DELETE) PDEBUG("DELETE");
     309    else PDEBUG("Unknown cn_nameiop: 0x%X", (int)pArgs->a_cnp->cn_nameiop);
    279310
    280311    lck_rw_lock_exclusive(pVnodeData->pLock);
    281312
    282313    /* Take care about '.' and '..' entries */
    283     if (vboxvfs_vnode_lookup_dot_handler(args, &vnode) == 0)
     314    if (vboxvfs_vnode_lookup_dot_handler(pArgs, &vnode) == 0)
    284315    {
    285316        vnode_get(vnode);
    286         *args->a_vpp = vnode;
     317        *pArgs->a_vpp = vnode;
    287318
    288319        lck_rw_unlock_exclusive(pVnodeData->pLock);
     
    292323
    293324    /* Look into VFS cache and attempt to find previously allocated vnode there. */
    294     rc = cache_lookup(args->a_dvp, &vnode, args->a_cnp);
     325    rc = cache_lookup(pArgs->a_dvp, &vnode, pArgs->a_cnp);
    295326    if (rc == -1) /* Record found */
    296327    {
     
    302333            /* Prepare & return cached vnode */
    303334            vnode_get(vnode);
    304             *args->a_vpp = vnode;
     335            *pArgs->a_vpp = vnode;
    305336
    306337            rc = 0;
     
    318349        PDEBUG("cache_lookup() returned %d, create new VFS vnode", rc);
    319350
    320         rc = vboxvfs_vnode_lookup_instantinate_vnode(args->a_dvp, args->a_cnp->cn_nameptr, &vnode);
     351        rc = vboxvfs_vnode_lookup_instantinate_vnode(pArgs->a_dvp, pArgs->a_cnp->cn_nameptr, &vnode);
    321352        if (rc == 0)
    322353        {
    323             cache_enter(args->a_dvp, vnode, args->a_cnp);
    324             *args->a_vpp = vnode;
     354            cache_enter(pArgs->a_dvp, vnode, pArgs->a_cnp);
     355            *pArgs->a_vpp = vnode;
    325356        }
    326357        else
     
    333364
    334365    return rc;
    335 }
    336 
    337 int vboxvfs_vnode_open(struct vnop_open_args *args)
    338 {
     366#endif
     367}
     368
     369static int vboxSfDwnVnOpen(struct vnop_open_args *pArgs)
     370{
     371#if 1
     372    RT_NOREF(pArgs);
     373    return ENOTSUP;
     374#else
    339375    vnode_t           vnode;
    340376    vboxvfs_vnode_t  *pVnodeData;
     
    347383    PDEBUG("Opening vnode...");
    348384
    349     AssertReturn(args, EINVAL);
    350 
    351     vnode           = args->a_vp;                              AssertReturn(vnode,      EINVAL);
     385    AssertReturn(pArgs, EINVAL);
     386
     387    vnode           = pArgs->a_vp;                              AssertReturn(vnode,      EINVAL);
    352388    pVnodeData      = (vboxvfs_vnode_t *)vnode_fsnode(vnode);  AssertReturn(pVnodeData, EINVAL);
    353389    mp              = vnode_mount(vnode);                      AssertReturn(mp,         EINVAL);
     
    374410    //}
    375411
    376     fHostFlags  = vboxvfs_g2h_mode_inernal(args->a_mode);
     412    fHostFlags  = vboxvfs_g2h_mode_inernal(pArgs->a_mode);
    377413    fHostFlags |= (vnode_isdir(vnode) ? SHFL_CF_DIRECTORY : 0);
    378414
     
    397433
    398434    return rc;
    399 }
    400 
    401 int vboxvfs_vnode_close(struct vnop_close_args *args)
    402 {
     435#endif
     436}
     437
     438static int vboxSfDwnVnClose(struct vnop_close_args *pArgs)
     439{
     440#if 1
     441    RT_NOREF(pArgs);
     442    return ENOTSUP;
     443#else
     444
    403445    vnode_t          vnode;
    404446    mount_t          mp;
     
    410452    PDEBUG("Closing vnode...");
    411453
    412     AssertReturn(args, EINVAL);
    413 
    414     vnode           = args->a_vp;                              AssertReturn(vnode,      EINVAL);
     454    AssertReturn(pArgs, EINVAL);
     455
     456    vnode           = pArgs->a_vp;                              AssertReturn(vnode,      EINVAL);
    415457    pVnodeData      = (vboxvfs_vnode_t *)vnode_fsnode(vnode);  AssertReturn(pVnodeData, EINVAL);
    416458    mp              = vnode_mount(vnode);                      AssertReturn(mp,         EINVAL);
     
    457499
    458500    return rc;
    459 }
    460 
     501#endif
     502}
     503
     504#if 0
    461505/**
    462506 * Convert SHFLDIRINFO to struct dirent and copy it back to user.
     
    501545    return rc;
    502546}
    503 
    504 int vboxvfs_vnode_readdir(struct vnop_readdir_args *args)
    505 {
     547#endif
     548
     549static int vboxSfDwnVnReadDir(struct vnop_readdir_args *pArgs)
     550{
     551#if 1
     552    RT_NOREF(pArgs);
     553    return ENOTSUP;
     554#else
    506555    vboxvfs_mount_t *pMount;
    507556    vboxvfs_vnode_t *pVnodeData;
     
    516565    PDEBUG("Reading directory...");
    517566
    518     AssertReturn(args,              EINVAL);
    519     AssertReturn(args->a_eofflag,   EINVAL);
    520     AssertReturn(args->a_numdirent, EINVAL);
    521 
    522     uio             = args->a_uio;                             AssertReturn(uio,        EINVAL);
    523     vnode           = args->a_vp;                              AssertReturn(vnode,      EINVAL); AssertReturn(vnode_isdir(vnode), EINVAL);
     567    AssertReturn(pArgs,              EINVAL);
     568    AssertReturn(pArgs->a_eofflag,   EINVAL);
     569    AssertReturn(pArgs->a_numdirent, EINVAL);
     570
     571    uio             = pArgs->a_uio;                             AssertReturn(uio,        EINVAL);
     572    vnode           = pArgs->a_vp;                              AssertReturn(vnode,      EINVAL); AssertReturn(vnode_isdir(vnode), EINVAL);
    524573    pVnodeData      = (vboxvfs_vnode_t *)vnode_fsnode(vnode);  AssertReturn(pVnodeData, EINVAL);
    525574    mp              = vnode_mount(vnode);                      AssertReturn(mp,         EINVAL);
     
    572621            uint32_t cbReturned = cbInfo;
    573622            //rc = VbglR0SfDirInfo(&g_vboxSFClient, &pMount->pMap, Handle, pMask, SHFL_LIST_RETURN_ONE, 0, &cbReturned, (PSHFLDIRINFO)Info, &cFiles);
    574             rc = VbglR0SfDirInfo(&g_SfClient, &pMount->pMap, Handle, 0, SHFL_LIST_RETURN_ONE, 0,
     623            rc = VbglR0SfDirInfo(&g_SfClientDarwin, &pMount->pMap, Handle, 0, SHFL_LIST_RETURN_ONE, 0,
    575624                                 &cbReturned, (PSHFLDIRINFO)Info, &cFiles);
    576625
     
    598647        case VINF_SUCCESS:
    599648        {
    600             rc = vboxvfs_vnode_readdir_copy_data((ino_t)(index + 1), Info, uio, args->a_numdirent);
     649            rc = vboxvfs_vnode_readdir_copy_data((ino_t)(index + 1), Info, uio, pArgs->a_numdirent);
    601650            break;
    602651        }
     
    605654        {
    606655            PDEBUG("No more entries in directory");
    607             *(args->a_eofflag) = 1;
     656            *(pArgs->a_eofflag) = 1;
    608657            break;
    609658        }
     
    621670
    622671    return rc;
    623 }
    624 
    625 
    626 int vboxvfs_vnode_access(struct vnop_access_args *args)
     672#endif
     673}
     674
     675
     676static int vboxSfDwnVnPathConf(struct vnop_pathconf_args *pArgs)
    627677{
    628678    PDEBUG("here");
     
    631681
    632682
    633 int vboxvfs_vnode_readdirattr(struct vnop_readdirattr_args *args)
    634 {
    635     PDEBUG("here");
    636     return 0;
    637 }
    638 
    639 int vboxvfs_vnode_pathconf(struct vnop_pathconf_args *args)
    640 {
    641     PDEBUG("here");
    642     return 0;
    643 }
    644 
    645683/**
     684 * vnop_reclaim implementation.
     685 *
    646686 * VBoxVFS reclaim callback.
    647687 * Called when vnode is going to be deallocated. Should release
     
    652692 * @return 0 on success, BSD error code otherwise.
    653693 */
    654 int vboxvfs_vnode_reclaim(struct vnop_reclaim_args *pArgs)
    655 {
    656     PDEBUG("Releasing vnode resources...");
    657 
    658     AssertReturn(pArgs, EINVAL);
    659 
    660     vnode_t          pVnode;
    661     vboxvfs_vnode_t *pVnodeData;
    662     vboxvfs_mount_t *pMount;
    663     mount_t          mp;
    664 
    665     pVnode = pArgs->a_vp;
    666     AssertReturn(pVnode, EINVAL);
    667 
    668     mp = vnode_mount(pVnode);
    669     AssertReturn(mp, EINVAL);
    670 
    671     pMount = (vboxvfs_mount_t *)vfs_fsprivate(mp);
    672     AssertReturn(pMount, EINVAL);
    673 
    674     pVnodeData = (vboxvfs_vnode_t *)vnode_fsnode(pVnode);
    675     AssertReturn(pVnodeData, EINVAL);
    676     AssertReturn(pVnodeData->pPath, EINVAL);
    677     AssertReturn(pVnodeData->pLockAttr, EINVAL);
    678     AssertReturn(pVnodeData->pLock, EINVAL);
    679 
    680     RTMemFree(pVnodeData->pPath);
    681     pVnodeData->pPath = NULL;
    682 
    683     lck_rw_free(pVnodeData->pLock, pMount->pLockGroup);
    684     pVnodeData->pLock = NULL;
    685 
    686     lck_attr_free(pVnodeData->pLockAttr);
    687     pVnodeData->pLockAttr = NULL;
    688 
     694static int vboxSfDwnVnReclaim(struct vnop_reclaim_args *pArgs)
     695{
     696    AssertReturn(pArgs && pArgs->a_vp, EINVAL);
     697
     698    /* Check that it's not a root node that's in use. */
     699    PVBOXSFMNT pMntData = (PVBOXSFMNT)vfs_fsprivate(vnode_mount(pArgs->a_vp));
     700    AssertReturn(!pMntData || pMntData->pVnRoot != pArgs->a_vp, EBUSY);
     701
     702    /* Get the private data and free it. */
     703    PVBOXSFDWNVNDATA pVnData = (PVBOXSFDWNVNDATA)vnode_fsnode(pArgs->a_vp);
     704    AssertPtrReturn(pVnData, 0);
     705
     706    if (pVnData->hHandle != SHFL_HANDLE_NIL)
     707    {
     708        /** @todo can this happen? */
     709        pVnData->hHandle = SHFL_HANDLE_NIL;
     710    }
     711
     712    RTMemFree(pVnData);
    689713    return 0;
     714}
     715
     716
     717/**
     718 * Allocates a vnode.
     719 *
     720 * @returns Pointer to the new VNode, NULL if out of memory.
     721 * @param   pMount          The file system mount structure.
     722 * @param   enmType         The vnode type.
     723 * @param   pParent         The parent vnode, NULL if root.
     724 * @param   cbFile          The file size
     725 */
     726vnode_t vboxSfDwnVnAlloc(mount_t pMount, enum vtype enmType, vnode_t pParent, uint64_t cbFile)
     727{
     728    /*
     729     * Create our private data.
     730     */
     731    PVBOXSFDWNVNDATA pVnData = (PVBOXSFDWNVNDATA)RTMemAllocZ(sizeof(*pVnData));
     732    if (pVnData)
     733    {
     734        pVnData->hHandle = SHFL_HANDLE_NIL;
     735
     736        struct vnode_fsparam VnParms;
     737        RT_ZERO(VnParms);
     738        VnParms.vnfs_mp         = pMount;
     739        VnParms.vnfs_vtype      = enmType;
     740        VnParms.vnfs_str        = "vboxsf";
     741        VnParms.vnfs_dvp        = pParent;
     742        VnParms.vnfs_fsnode     = pVnData;
     743        VnParms.vnfs_vops       = g_papfnVBoxVFSVnodeDirOpsVector;
     744        VnParms.vnfs_markroot   = pParent == NULL;
     745        VnParms.vnfs_marksystem = 0;
     746        VnParms.vnfs_rdev       = 0;
     747        VnParms.vnfs_filesize   = cbFile;
     748        VnParms.vnfs_cnp        = 0;
     749        VnParms.vnfs_flags      = VNFS_NOCACHE;
     750
     751        vnode_t pVnRet;
     752        int rc = vnode_create(VNCREATE_FLAVOR, VCREATESIZE, &VnParms, &pVnRet);
     753        if (rc == 0)
     754            return pVnRet;
     755        RTMemFree(pVnData);
     756    }
     757    printf("vboxSfDwnVnAlloc: out of memory!\n");
     758    return NULL;
    690759}
    691760
     
    697766{
    698767#define VNODEOPFUNC int(*)(void *)
    699     { &vnop_default_desc,     (VNODEOPFUNC)vboxvfs_dfl_error },
    700     { &vnop_lookup_desc,      (VNODEOPFUNC)vboxvfs_vnode_lookup },
    701     { &vnop_create_desc,      (VNODEOPFUNC)vboxvfs_dfl_error },
    702     { &vnop_whiteout_desc,    (VNODEOPFUNC)vboxvfs_dfl_error },
    703     { &vnop_mknod_desc,       (VNODEOPFUNC)vboxvfs_dfl_error },
    704     { &vnop_open_desc,        (VNODEOPFUNC)vboxvfs_vnode_open },
    705     { &vnop_close_desc,       (VNODEOPFUNC)vboxvfs_vnode_close },
    706     { &vnop_access_desc,      (VNODEOPFUNC)vboxvfs_vnode_access },
    707     { &vnop_getattr_desc,     (VNODEOPFUNC)vboxvfs_vnode_getattr },
    708     { &vnop_setattr_desc,     (VNODEOPFUNC)vboxvfs_dfl_error },
    709     { &vnop_read_desc,        (VNODEOPFUNC)vboxvfs_dfl_error },
    710     { &vnop_write_desc,       (VNODEOPFUNC)vboxvfs_dfl_error },
    711     { &vnop_ioctl_desc,       (VNODEOPFUNC)vboxvfs_dfl_error },
    712     { &vnop_select_desc,      (VNODEOPFUNC)vboxvfs_dfl_error },
    713     { &vnop_exchange_desc,    (VNODEOPFUNC)vboxvfs_dfl_error },
    714     { &vnop_revoke_desc,      (VNODEOPFUNC)vboxvfs_dfl_error },
    715     { &vnop_mmap_desc,        (VNODEOPFUNC)vboxvfs_dfl_error },
    716     { &vnop_mnomap_desc,      (VNODEOPFUNC)vboxvfs_dfl_error },
    717     { &vnop_fsync_desc,       (VNODEOPFUNC)vboxvfs_dfl_error },
    718     { &vnop_remove_desc,      (VNODEOPFUNC)vboxvfs_dfl_error },
    719     { &vnop_link_desc,        (VNODEOPFUNC)vboxvfs_dfl_error },
    720     { &vnop_rename_desc,      (VNODEOPFUNC)vboxvfs_dfl_error },
    721     { &vnop_mkdir_desc,       (VNODEOPFUNC)vboxvfs_dfl_error },
    722     { &vnop_rmdir_desc,       (VNODEOPFUNC)vboxvfs_dfl_error },
    723     { &vnop_symlink_desc,     (VNODEOPFUNC)vboxvfs_dfl_error },
    724     { &vnop_readdir_desc,     (VNODEOPFUNC)vboxvfs_vnode_readdir },
    725     { &vnop_readdirattr_desc, (VNODEOPFUNC)vboxvfs_vnode_readdirattr },
    726     { &vnop_readlink_desc,    (VNODEOPFUNC)vboxvfs_dfl_error },
    727     { &vnop_inactive_desc,    (VNODEOPFUNC)vboxvfs_dfl_error },
    728     { &vnop_reclaim_desc,     (VNODEOPFUNC)vboxvfs_vnode_reclaim },
    729     /* { &vnop_print_desc,       (VNODEOPFUNC)vboxvfs_dfl_error }, undefined in ML */
    730     { &vnop_pathconf_desc,    (VNODEOPFUNC)vboxvfs_vnode_pathconf },
    731     { &vnop_advlock_desc,     (VNODEOPFUNC)vboxvfs_dfl_error },
    732     /* { &vnop_truncate_desc,    (VNODEOPFUNC)vboxvfs_dfl_error }, undefined in ML */
    733     { &vnop_allocate_desc,    (VNODEOPFUNC)vboxvfs_dfl_error },
    734     { &vnop_pagein_desc,      (VNODEOPFUNC)vboxvfs_dfl_error },
    735     { &vnop_pageout_desc,     (VNODEOPFUNC)vboxvfs_dfl_error },
    736     { &vnop_searchfs_desc,    (VNODEOPFUNC)vboxvfs_dfl_error },
    737     { &vnop_copyfile_desc,    (VNODEOPFUNC)vboxvfs_dfl_error },
    738     { &vnop_blktooff_desc,    (VNODEOPFUNC)vboxvfs_dfl_error },
    739     { &vnop_offtoblk_desc,    (VNODEOPFUNC)vboxvfs_dfl_error },
    740     { &vnop_blockmap_desc,    (VNODEOPFUNC)vboxvfs_dfl_error },
    741     { &vnop_strategy_desc,    (VNODEOPFUNC)vboxvfs_dfl_error },
    742     { &vnop_bwrite_desc,      (VNODEOPFUNC)vboxvfs_dfl_error },
     768    { &vnop_default_desc,     (VNODEOPFUNC)vboxSfDwnVnDefaultError },
     769    //{ &vnop_access_desc,      (VNODEOPFUNC)vboxSfDwnVnDefaultError }, - probably not needed.
     770    //{ &vnop_advlock_desc,     (VNODEOPFUNC)vboxSfDwnVnDefaultError }, - later.
     771    //{ &vnop_allocate_desc,    (VNODEOPFUNC)vboxSfDwnVnDefaultError }, - maybe, need shfl function
     772    { &vnop_blktooff_desc,    (VNODEOPFUNC)vboxSfDwnVnDefaultError },
     773    //{ &vnop_blockmap_desc,    (VNODEOPFUNC)vboxSfDwnVnDefaultError },
     774    //{ &vnop_bwrite_desc,      (VNODEOPFUNC)vboxSfDwnVnDefaultError },
     775    { &vnop_close_desc,       (VNODEOPFUNC)vboxSfDwnVnClose },
     776    //{ &vnop_copyfile_desc,    (VNODEOPFUNC)vboxSfDwnVnDefaultError },
     777    { &vnop_create_desc,      (VNODEOPFUNC)vboxSfDwnVnDefaultError },
     778    //{ &vnop_exchange_desc,    (VNODEOPFUNC)vboxSfDwnVnDefaultError },
     779    { &vnop_fsync_desc,       (VNODEOPFUNC)vboxSfDwnVnDefaultError },
     780    { &vnop_getattr_desc,     (VNODEOPFUNC)vboxFsDwnVnGetAttr },
     781    //{ &vnop_getnamedstream_desc, (VNODEOPFUNC)vboxSfDwnVnDefaultError },
     782    //{ &vnop_getxattr_desc,    (VNODEOPFUNC)vboxSfDwnVnDefaultError },
     783    { &vnop_inactive_desc,    (VNODEOPFUNC)vboxSfDwnVnDefaultError },
     784    { &vnop_ioctl_desc,       (VNODEOPFUNC)vboxSfDwnVnDefaultError },
     785    { &vnop_link_desc,        (VNODEOPFUNC)vboxSfDwnVnDefaultError },
     786    //{ &vnop_listxattr_desc,   (VNODEOPFUNC)vboxSfDwnVnDefaultError },
     787    { &vnop_lookup_desc,      (VNODEOPFUNC)vboxSfDwnVnLookup },
     788    { &vnop_mkdir_desc,       (VNODEOPFUNC)vboxSfDwnVnDefaultError },
     789    { &vnop_mknod_desc,       (VNODEOPFUNC)vboxSfDwnVnDefaultError },
     790    { &vnop_mmap_desc,        (VNODEOPFUNC)vboxSfDwnVnDefaultError },
     791    { &vnop_mnomap_desc,      (VNODEOPFUNC)vboxSfDwnVnDefaultError },
     792    { &vnop_offtoblk_desc,    (VNODEOPFUNC)vboxSfDwnVnDefaultError },
     793    { &vnop_open_desc,        (VNODEOPFUNC)vboxSfDwnVnOpen },
     794    { &vnop_pagein_desc,      (VNODEOPFUNC)vboxSfDwnVnDefaultError },
     795    { &vnop_pageout_desc,     (VNODEOPFUNC)vboxSfDwnVnDefaultError },
     796    { &vnop_pathconf_desc,    (VNODEOPFUNC)vboxSfDwnVnPathConf },
     797    /* { &vnop_print_desc,       (VNODEOPFUNC)vboxSfDwnVnDefaultError }, undefined in ML */
     798    { &vnop_read_desc,        (VNODEOPFUNC)vboxSfDwnVnDefaultError },
     799    { &vnop_readdir_desc,     (VNODEOPFUNC)vboxSfDwnVnReadDir },
     800    //{ &vnop_readdirattr_desc, (VNODEOPFUNC)vboxSfDwnVnDefaultError }, - hfs specific.
     801    { &vnop_readlink_desc,    (VNODEOPFUNC)vboxSfDwnVnDefaultError },
     802    { &vnop_reclaim_desc,     (VNODEOPFUNC)vboxSfDwnVnReclaim },
     803    { &vnop_remove_desc,      (VNODEOPFUNC)vboxSfDwnVnDefaultError },
     804    //{ &vnop_removexattr_desc, (VNODEOPFUNC)vboxSfDwnVnDefaultError },
     805    { &vnop_rename_desc,      (VNODEOPFUNC)vboxSfDwnVnDefaultError },
     806    //{ &vnop_revoke_desc,      (VNODEOPFUNC)vboxSfDwnVnDefaultError }, - not needed
     807    { &vnop_rmdir_desc,       (VNODEOPFUNC)vboxSfDwnVnDefaultError },
     808    { &vnop_searchfs_desc,    (VNODEOPFUNC)err_searchfs },
     809    //{ &vnop_select_desc,      (VNODEOPFUNC)vboxSfDwnVnDefaultError }, - not needed
     810    { &vnop_setattr_desc,     (VNODEOPFUNC)vboxSfDwnVnDefaultError },
     811    { &vnop_setxattr_desc,    (VNODEOPFUNC)vboxSfDwnVnDefaultError },
     812    //{ &vnop_strategy_desc,    (VNODEOPFUNC)vboxSfDwnVnDefaultError }, - not needed
     813    { &vnop_symlink_desc,     (VNODEOPFUNC)vboxSfDwnVnDefaultError },
     814    /* { &vnop_truncate_desc,    (VNODEOPFUNC)vboxSfDwnVnDefaultError }, undefined in ML */
     815    //{ &vnop_whiteout_desc,    (VNODEOPFUNC)vboxSfDwnVnDefaultError }, - not needed/supported
     816    { &vnop_write_desc,       (VNODEOPFUNC)vboxSfDwnVnDefaultError },
    743817    { NULL,                   (VNODEOPFUNC)NULL              },
    744818#undef VNODEOPFUNC
  • trunk/src/VBox/Additions/darwin/VBoxSF/VBoxSF-VfsOps.cpp

    r75666 r75675  
    2020*   Header Files                                                                                                                 *
    2121*********************************************************************************************************************************/
     22#define LOG_GROUP LOG_GROUP_SHARED_FOLDERS
    2223#include "VBoxSFInternal.h"
    2324
    2425#include <iprt/assert.h>
     26#include <iprt/asm.h>
    2527#include <iprt/mem.h>
    26 #include <iprt/asm.h>
     28#include <iprt/string.h>
     29#include <VBox/log.h>
    2730
    2831
     
    3538
    3639
     40
    3741/**
    38  * Mount helper: Get mounting parameters from user space and validate them.
     42 * vfsops::vfs_getattr implementation.
    3943 *
    40  * @param pUserData     Mounting parameters provided by user space mount tool.
    41  * @param pKernelData   Buffer to store pUserData in kernel space.
    42  *
    43  * @return 0 on success or BSD error code otherwise.
    44  */
    45 static int
    46 vboxvfs_get_mount_info(user_addr_t pUserData, PVBOXSFDRWNMOUNTINFO pKernelData)
     44 * @returns 0 on success or errno.h value on failure.
     45 * @param   pMount      The mount data structure.
     46 * @param   pFsAttr     Input & output structure.
     47 * @param   pContext    Unused kAuth parameter.
     48 */
     49static int vboxSfDwnVfsGetAttr(mount_t pMount, struct vfs_attr *pFsAttr, vfs_context_t pContext)
    4750{
    48     AssertReturn(pKernelData, EINVAL);
    49     AssertReturn(pUserData,   EINVAL);
    50 
    51     /* Get mount parameters from user space */
    52     if (copyin(pUserData, pKernelData, sizeof(*pKernelData)) != 0)
    53     {
    54         PERROR("Unable to copy mount parameters from user space");
    55         return EINVAL;
    56     }
    57 
    58     /* Validate data magic */
    59     if (pKernelData->u32Magic != VBOXSFDRWNMOUNTINFO_MAGIC)
    60     {
    61         PERROR("Mount parameter magic mismatch");
    62         return EINVAL;
    63     }
    64 
    65     return 0;
    66 }
    67 
    68 
    69 /**
    70  * Mount helper: Provide VFS layer with a VBox share name (stored as mounted device).
    71  *
    72  * @param mp            Mount data provided by VFS layer.
    73  * @param szShareName   VBox share name.
    74  * @param cbShareName   Returning parameter which contains VBox share name string length.
    75  *
    76  * @return 0 on success or BSD error code otherwise.
    77  */
    78 static int
    79 vboxvfs_set_share_name(struct mount *mp, char *szShareName, size_t *cbShareName)
    80 {
    81     struct vfsstatfs *pVfsInfo;
    82 
    83     AssertReturn(mp,          EINVAL);
    84     AssertReturn(szShareName, EINVAL);
    85     AssertReturn(cbShareName, EINVAL);
    86 
    87     pVfsInfo = vfs_statfs(mp);
    88     if (!pVfsInfo)
    89     {
    90         PERROR("Unable to get VFS data for the mount structure");
    91         return EINVAL;
    92     }
    93 
    94     return copystr(szShareName, pVfsInfo->f_mntfromname, MAXPATHLEN, cbShareName);
    95 }
    96 
    97 
    98 /**
    99  * Mount helper: allocate locking group attribute and locking group itself.
    100  * Store allocated data into VBoxVFS private data.
    101  *
    102  * @param pMount   VBoxVFS global data which will be updated with
    103  *                          locking group and its attribute in case of success;
    104  *                          otherwise pMount unchanged.
    105  *
    106  * @return 0 on success or BSD error code otherwise.
    107  *
    108  */
    109 static int
    110 vboxvfs_prepare_locking(vboxvfs_mount_t *pMount)
    111 {
    112     lck_grp_attr_t *pGrpAttr;
    113     lck_grp_t      *pGrp;
    114 
    115     AssertReturn(pMount, EINVAL);
    116 
    117     pGrpAttr = lck_grp_attr_alloc_init();
    118     if (pGrpAttr)
    119     {
    120         pGrp = lck_grp_alloc_init("VBoxVFS", pGrpAttr);
    121         if (pGrp)
     51    PVBOXSFMNT pThis = (PVBOXSFMNT)vfs_fsprivate(pMount);
     52    AssertReturn(pThis, EBADMSG);
     53    LogFlow(("vboxSfDwnVfsGetAttr: %s\n", pThis->MntInfo.szFolder));
     54    RT_NOREF(pContext);
     55
     56    /*
     57     * Get the file system stats from the host.
     58     */
     59    int rc;
     60    struct MyEmbReq
     61    {
     62        VBGLIOCIDCHGCMFASTCALL  Hdr;
     63        VMMDevHGCMCall          Call;
     64        VBoxSFParmInformation   Parms;
     65        SHFLVOLINFO             VolInfo;
     66    } *pReq = (struct MyEmbReq *)VbglR0PhysHeapAlloc(sizeof(*pReq));
     67    if (pReq)
     68    {
     69        RT_ZERO(pReq->VolInfo);
     70
     71        VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClientDarwin.idClient,
     72                                    SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, sizeof(*pReq));
     73        pReq->Parms.id32Root.type               = VMMDevHGCMParmType_32bit;
     74        pReq->Parms.id32Root.u.value32          = pThis->hHostFolder.root;
     75        pReq->Parms.u64Handle.type              = VMMDevHGCMParmType_64bit;
     76        pReq->Parms.u64Handle.u.value64         = 0;
     77        pReq->Parms.f32Flags.type               = VMMDevHGCMParmType_32bit;
     78        pReq->Parms.f32Flags.u.value32          = SHFL_INFO_VOLUME | SHFL_INFO_GET;
     79        pReq->Parms.cb32.type                   = VMMDevHGCMParmType_32bit;
     80        pReq->Parms.cb32.u.value32              = sizeof(pReq->VolInfo);
     81        pReq->Parms.pInfo.type                  = VMMDevHGCMParmType_Embedded;
     82        pReq->Parms.pInfo.u.Embedded.cbData     = sizeof(pReq->VolInfo);
     83        pReq->Parms.pInfo.u.Embedded.offData    = RT_UOFFSETOF(struct MyEmbReq, VolInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
     84        pReq->Parms.pInfo.u.Embedded.fFlags     = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
     85
     86        int vrc = VbglR0HGCMFastCall(g_SfClientDarwin.handle, &pReq->Hdr, sizeof(*pReq));
     87        if (RT_SUCCESS(vrc))
     88            vrc = pReq->Call.header.result;
     89        if (RT_SUCCESS(vrc))
    12290        {
    123             pMount->pLockGroupAttr = pGrpAttr;
    124             pMount->pLockGroup      = pGrp;
    125 
    126             return 0;
    127         }
    128         else
    129             PERROR("Unable to allocate locking group");
    130 
    131         lck_grp_attr_free(pGrpAttr);
    132     }
    133     else
    134         PERROR("Unable to allocate locking group attribute");
    135 
    136     return ENOMEM;
    137 }
    138 
    139 
    140 /**
    141  * Mount and unmount helper: destroy locking group attribute and locking group itself.
    142  *
    143  * @param pMount   VBoxVFS global data for which locking
    144  *                          group and attribute will be deallocated and set to NULL.
    145  */
    146 static void
    147 vboxvfs_destroy_locking(vboxvfs_mount_t *pMount)
    148 {
    149     AssertReturnVoid(pMount);
    150 
    151     if (pMount->pLockGroup)
    152     {
    153         lck_grp_free(pMount->pLockGroup);
    154         pMount->pLockGroup = NULL;
    155     }
    156 
    157     if (pMount->pLockGroupAttr)
    158     {
    159         lck_grp_attr_free(pMount->pLockGroupAttr);
    160         pMount->pLockGroupAttr = NULL;
    161     }
    162 }
    163 
    164 /**
    165  * Mount helper: Allocate and init VBoxVFS global data.
    166  *
    167  * @param mp            Mount data provided by VFS layer.
    168  * @param pUserData     Mounting parameters provided by user space mount tool.
    169  *
    170  * @return VBoxVFS global data or NULL.
    171  */
    172 static vboxvfs_mount_t *
    173 vboxvfs_alloc_internal_data(struct mount *mp, user_addr_t pUserData)
    174 {
    175     vboxvfs_mount_t             *pMount;
    176     struct vboxvfs_mount_info    mountInfo;
    177     struct vfsstatfs            *pVfsInfo;
    178     size_t                       cbShareName;
    179 
    180     int rc;
    181 
    182     AssertReturn(mp,        NULL);
    183     AssertReturn(pUserData, NULL);
    184 
    185     pVfsInfo = vfs_statfs(mp);
    186     AssertReturn(pVfsInfo, NULL);
    187 
    188     /* Allocate memory for VBoxVFS internal data */
    189     pMount = (vboxvfs_mount_t *)RTMemAllocZ(sizeof(vboxvfs_mount_t));
    190     if (pMount)
    191     {
    192         rc = vboxvfs_get_mount_info(pUserData, &mountInfo);
    193         if (rc == 0)
    194         {
    195             PDEBUG("Mounting shared folder '%s'", mountInfo.szFolder);
    196 
    197             /* Prepare for locking. We prepare locking group and attr data here,
    198              * but allocate and initialize real lock in vboxvfs_create_vnode_internal().
    199              * We use the same pLockGroup and pLockAttr for all vnodes related to this mount point. */
    200             rc = vboxvfs_prepare_locking(pMount);
    201             if (rc == 0)
     91            /*
     92             * Fill in stuff.
     93             */
     94            /* Copy over the results we got from the host. */
     95            uint32_t cbUnit = pReq->VolInfo.ulBytesPerSector * pReq->VolInfo.ulBytesPerAllocationUnit;
     96            VFSATTR_RETURN(pFsAttr, f_bsize, cbUnit);
     97            VFSATTR_RETURN(pFsAttr, f_iosize, _64K); /** @todo what's a good block size...  */
     98            VFSATTR_RETURN(pFsAttr, f_blocks, (uint64_t)pReq->VolInfo.ullTotalAllocationBytes / cbUnit);
     99            VFSATTR_RETURN(pFsAttr, f_bavail, (uint64_t)pReq->VolInfo.ullAvailableAllocationBytes / cbUnit);
     100            VFSATTR_RETURN(pFsAttr, f_bfree,  (uint64_t)pReq->VolInfo.ullAvailableAllocationBytes / cbUnit);
     101            VFSATTR_RETURN(pFsAttr, f_bused,
     102                           ((uint64_t)pReq->VolInfo.ullTotalAllocationBytes - (uint64_t)pReq->VolInfo.ullAvailableAllocationBytes) / cbUnit);
     103            fsid_t const fsid = { { vfs_statfs(pMount)->f_fsid.val[0], vfs_typenum(pMount) } };
     104            VFSATTR_RETURN(pFsAttr, f_fsid, fsid);
     105
     106            /* f_owner is handled by caller. */
     107            /* f_signature is handled by caller. */
     108
     109            struct timespec TmpTv = { 1084190406, 0 };
     110            VFSATTR_RETURN(pFsAttr, f_create_time, TmpTv);
     111
     112            /*
     113             * Unsupported bits.
     114             */
     115            /* Dummies for some values we don't support. */
     116            VFSATTR_RETURN(pFsAttr, f_objcount, 0);
     117            VFSATTR_RETURN(pFsAttr, f_filecount, 0);
     118            VFSATTR_RETURN(pFsAttr, f_dircount, 0);
     119            VFSATTR_RETURN(pFsAttr, f_maxobjcount, UINT32_MAX);
     120            VFSATTR_RETURN(pFsAttr, f_files, UINT32_MAX);
     121            VFSATTR_RETURN(pFsAttr, f_ffree, UINT32_MAX);
     122            VFSATTR_RETURN(pFsAttr, f_fssubtype, 0);
     123            VFSATTR_RETURN(pFsAttr, f_carbon_fsid, 0);
     124
     125            /* Totally not supported: */
     126            VFSATTR_CLEAR_ACTIVE(pFsAttr, f_modify_time);
     127            VFSATTR_CLEAR_ACTIVE(pFsAttr, f_access_time);
     128            VFSATTR_CLEAR_ACTIVE(pFsAttr, f_backup_time);
     129
     130            /*
     131             * Annoying capability stuff.
     132             * The 'valid' bits are only supposed to be set when we know for sure.
     133             */
     134            if (VFSATTR_IS_ACTIVE(pFsAttr, f_capabilities))
    202135            {
    203                 rc = vboxvfs_set_share_name(mp, (char *)mountInfo.szFolder, &cbShareName);
    204                 if (rc == 0)
    205                 {
    206                     pMount->pShareName = vboxvfs_construct_shflstring(mountInfo.szFolder, cbShareName);
    207                     if (pMount->pShareName)
    208                     {
    209                         /* Remember user who mounted this share */
    210                         pMount->owner = pVfsInfo->f_owner;
    211 
    212                         /* Mark root vnode as uninitialized */
    213                         ASMAtomicWriteU8(&pMount->fRootVnodeState, VBOXVFS_OBJECT_UNINITIALIZED);
    214 
    215                         return pMount;
    216                     }
    217                 }
     136                vol_capabilities_attr_t *pCaps = &pFsAttr->f_capabilities;
     137
     138                pCaps->valid[VOL_CAPABILITIES_FORMAT]            = VOL_CAP_FMT_PERSISTENTOBJECTIDS
     139                                                                 | VOL_CAP_FMT_SYMBOLICLINKS
     140                                                                 | VOL_CAP_FMT_HARDLINKS
     141                                                                 | VOL_CAP_FMT_JOURNAL
     142                                                                 | VOL_CAP_FMT_JOURNAL_ACTIVE
     143                                                                 | VOL_CAP_FMT_NO_ROOT_TIMES
     144                                                                 | VOL_CAP_FMT_SPARSE_FILES
     145                                                                 | VOL_CAP_FMT_ZERO_RUNS
     146                                                                 | VOL_CAP_FMT_CASE_SENSITIVE
     147                                                                 | VOL_CAP_FMT_CASE_PRESERVING
     148                                                                 | VOL_CAP_FMT_FAST_STATFS
     149                                                                 | VOL_CAP_FMT_2TB_FILESIZE
     150                                                                 | VOL_CAP_FMT_OPENDENYMODES
     151                                                                 | VOL_CAP_FMT_HIDDEN_FILES
     152                                                                 | VOL_CAP_FMT_PATH_FROM_ID
     153                                                                 | VOL_CAP_FMT_NO_VOLUME_SIZES
     154                                                                 | VOL_CAP_FMT_DECMPFS_COMPRESSION
     155                                                                 | VOL_CAP_FMT_64BIT_OBJECT_IDS;
     156                pCaps->capabilities[VOL_CAPABILITIES_FORMAT]     = VOL_CAP_FMT_2TB_FILESIZE
     157                                                                 ///@todo | VOL_CAP_FMT_SYMBOLICLINKS - later
     158                                                                 ///@todo | VOL_CAP_FMT_SPARSE_FILES - probably, needs testing.
     159                                                                 /*| VOL_CAP_FMT_CASE_SENSITIVE - case-insensitive */
     160                                                                 | VOL_CAP_FMT_CASE_PRESERVING
     161                                                                 ///@todo | VOL_CAP_FMT_HIDDEN_FILES - if windows host.
     162                                                                 ///@todo | VOL_CAP_FMT_OPENDENYMODES - if windows host.
     163                                                                 ;
     164                pCaps->valid[VOL_CAPABILITIES_INTERFACES]        = VOL_CAP_INT_SEARCHFS
     165                                                                 | VOL_CAP_INT_ATTRLIST
     166                                                                 | VOL_CAP_INT_NFSEXPORT
     167                                                                 | VOL_CAP_INT_READDIRATTR
     168                                                                 | VOL_CAP_INT_EXCHANGEDATA
     169                                                                 | VOL_CAP_INT_COPYFILE
     170                                                                 | VOL_CAP_INT_ALLOCATE
     171                                                                 | VOL_CAP_INT_VOL_RENAME
     172                                                                 | VOL_CAP_INT_ADVLOCK
     173                                                                 | VOL_CAP_INT_FLOCK
     174                                                                 | VOL_CAP_INT_EXTENDED_SECURITY
     175                                                                 | VOL_CAP_INT_USERACCESS
     176                                                                 | VOL_CAP_INT_MANLOCK
     177                                                                 | VOL_CAP_INT_NAMEDSTREAMS
     178                                                                 | VOL_CAP_INT_EXTENDED_ATTR;
     179                pCaps->capabilities[VOL_CAPABILITIES_INTERFACES] = 0
     180                                                                 ///@todo | VOL_CAP_INT_SEARCHFS
     181                                                                 ///@todo | VOL_CAP_INT_COPYFILE
     182                                                                 ///@todo | VOL_CAP_INT_READDIRATTR
     183                                                                 ;
     184
     185                pCaps->valid[VOL_CAPABILITIES_RESERVED1]         = 0;
     186                pCaps->capabilities[VOL_CAPABILITIES_RESERVED1]  = 0;
     187
     188                pCaps->valid[VOL_CAPABILITIES_RESERVED2]         = 0;
     189                pCaps->capabilities[VOL_CAPABILITIES_RESERVED2]  = 0;
     190
     191                VFSATTR_SET_SUPPORTED(pFsAttr, f_capabilities);
    218192            }
    219193
    220             vboxvfs_destroy_locking(pMount);
    221         }
    222 
    223         RTMemFree(pMount);
    224     }
    225 
    226     return NULL;
    227 }
    228 
    229 
    230 /**
    231  * Mount and unmount helper: Release VBoxVFS internal resources.
    232  * Deallocates ppMount as well.
    233  *
    234  * @param ppMount      Pointer to reference of VBoxVFS internal data.
    235  */
    236 static void
    237 vboxvfs_destroy_internal_data(vboxvfs_mount_t **ppMount)
    238 {
    239     AssertReturnVoid(ppMount);
    240     AssertReturnVoid(*ppMount);
    241     AssertReturnVoid((*ppMount)->pShareName);
    242 
    243     RTMemFree((*ppMount)->pShareName);
    244     (*ppMount)->pShareName = NULL;
    245 
    246     vboxvfs_destroy_locking(*ppMount);
    247     RTMemFree(*ppMount);
    248     *ppMount = NULL;
    249 }
    250 
    251 
    252 /**
    253  * Mount VBoxVFS.
    254  *
    255  * @param mp        Mount data provided by VFS layer.
    256  * @param pDev      Device structure provided by VFS layer.
    257  * @param pUserData Mounting parameters provided by user space mount tool.
    258  * @param pContext  kAuth context needed in order to authentificate mount operation.
    259  *
    260  * @return 0 on success or BSD error code otherwise.
    261  */
    262 static int
    263 vboxvfs_mount(struct mount *mp, vnode_t pDev, user_addr_t pUserData, vfs_context_t pContext)
    264 {
    265     NOREF(pDev);
    266     NOREF(pContext);
    267 
    268     vboxvfs_mount_t *pMount;
    269 
    270     int rc = ENOMEM;
    271 
    272     PDEBUG("Mounting...");
    273 
    274     pMount = vboxvfs_alloc_internal_data(mp, pUserData);
    275     if (pMount)
    276     {
    277         rc = VbglR0SfMapFolder(&g_SfClient, pMount->pShareName, &pMount->pMap);
    278         if (RT_SUCCESS(rc))
    279         {
    280             /* Private data should be set before vboxvfs_create_vnode_internal() call
    281              * because we need it in order to create vnode. */
    282             vfs_setfsprivate(mp, pMount);
    283 
    284             /* Reset root vnode */
    285             pMount->pRootVnode = NULL;
    286 
    287             vfs_setflags(mp, MNT_RDONLY | MNT_SYNCHRONOUS | MNT_NOEXEC | MNT_NOSUID | MNT_NODEV);
    288 
    289             PDEBUG("VirtualBox shared folder successfully mounted");
    290 
    291             return 0;
    292         }
    293 
    294         PDEBUG("Unable to map shared folder");
    295         vboxvfs_destroy_internal_data(&pMount);
    296     }
    297     else
    298         PDEBUG("Unable to allocate internal data");
    299 
    300     return rc;
    301 }
    302 
    303 
    304 /**
    305  * Unmount VBoxVFS.
    306  *
    307  * @param mp        Mount data provided by VFS layer.
    308  * @param fFlags    Unmounting flags.
    309  * @param pContext  kAuth context needed in order to authentificate mount operation.
    310  *
    311  * @return 0 on success or BSD error code otherwise.
    312  */
    313 static int
    314 vboxvfs_unmount(struct mount *mp, int fFlags, vfs_context_t pContext)
    315 {
    316     NOREF(pContext);
    317 
    318     vboxvfs_mount_t *pMount;
    319     int                  rc = EBUSY;
    320     int                  fFlush = (fFlags & MNT_FORCE) ? FORCECLOSE : 0;
    321 
    322     PDEBUG("Attempting to %s unmount a shared folder", (fFlags & MNT_FORCE) ? "forcibly" : "normally");
    323 
    324     AssertReturn(mp, EINVAL);
    325 
    326     pMount = (vboxvfs_mount_t *)vfs_fsprivate(mp);
    327 
    328     AssertReturn(pMount,             EINVAL);
    329     AssertReturn(pMount->pRootVnode, EINVAL);
    330 
    331     /* Check if we can do unmount at the moment */
    332     if (!vnode_isinuse(pMount->pRootVnode, 1))
    333     {
    334         /* Flush child vnodes first */
    335         rc = vflush(mp, pMount->pRootVnode, fFlush);
    336         if (rc == 0)
    337         {
    338             /* Flush root vnode */
    339             rc = vflush(mp, NULL, fFlush);
    340             if (rc == 0)
     194
     195            /*
     196             * Annoying attribute stuff.
     197             * The 'valid' bits are only supposed to be set when we know for sure.
     198             */
     199            if (VFSATTR_IS_ACTIVE(pFsAttr, f_attributes))
    341200            {
    342                 vfs_setfsprivate(mp, NULL);
    343 
    344                 rc = VbglR0SfUnmapFolder(&g_SfClient, &pMount->pMap);
    345                 if (RT_SUCCESS(rc))
    346                 {
    347                     vboxvfs_destroy_internal_data(&pMount);
    348                     PDEBUG("A shared folder has been successfully unmounted");
    349                     return 0;
    350                 }
    351 
    352                 PDEBUG("Unable to unmount shared folder");
    353                 rc = EPROTO;
     201                vol_attributes_attr_t *pAt = &pFsAttr->f_attributes;
     202
     203                pAt->validattr.commonattr  = ATTR_CMN_NAME
     204                                           | ATTR_CMN_DEVID
     205                                           | ATTR_CMN_FSID
     206                                           | ATTR_CMN_OBJTYPE
     207                                           | ATTR_CMN_OBJTAG
     208                                           | ATTR_CMN_OBJID
     209                                           | ATTR_CMN_OBJPERMANENTID
     210                                           | ATTR_CMN_PAROBJID
     211                                           | ATTR_CMN_SCRIPT
     212                                           | ATTR_CMN_CRTIME
     213                                           | ATTR_CMN_MODTIME
     214                                           | ATTR_CMN_CHGTIME
     215                                           | ATTR_CMN_ACCTIME
     216                                           | ATTR_CMN_BKUPTIME
     217                                           | ATTR_CMN_FNDRINFO
     218                                           | ATTR_CMN_OWNERID
     219                                           | ATTR_CMN_GRPID
     220                                           | ATTR_CMN_ACCESSMASK
     221                                           | ATTR_CMN_FLAGS
     222                                           | ATTR_CMN_USERACCESS
     223                                           | ATTR_CMN_EXTENDED_SECURITY
     224                                           | ATTR_CMN_UUID
     225                                           | ATTR_CMN_GRPUUID
     226                                           | ATTR_CMN_FILEID
     227                                           | ATTR_CMN_PARENTID
     228                                           | ATTR_CMN_FULLPATH
     229                                           | ATTR_CMN_ADDEDTIME;
     230                pAt->nativeattr.commonattr = ATTR_CMN_NAME
     231                                           | ATTR_CMN_DEVID
     232                                           | ATTR_CMN_FSID
     233                                           | ATTR_CMN_OBJTYPE
     234                                           | ATTR_CMN_OBJTAG
     235                                           | ATTR_CMN_OBJID
     236                                           //| ATTR_CMN_OBJPERMANENTID
     237                                           | ATTR_CMN_PAROBJID
     238                                           //| ATTR_CMN_SCRIPT
     239                                           | ATTR_CMN_CRTIME
     240                                           | ATTR_CMN_MODTIME
     241                                           | ATTR_CMN_CHGTIME
     242                                           | ATTR_CMN_ACCTIME
     243                                           //| ATTR_CMN_BKUPTIME
     244                                           //| ATTR_CMN_FNDRINFO
     245                                           //| ATTR_CMN_OWNERID
     246                                           //| ATTR_CMN_GRPID
     247                                           | ATTR_CMN_ACCESSMASK
     248                                           //| ATTR_CMN_FLAGS
     249                                           //| ATTR_CMN_USERACCESS
     250                                           //| ATTR_CMN_EXTENDED_SECURITY
     251                                           //| ATTR_CMN_UUID
     252                                           //| ATTR_CMN_GRPUUID
     253                                           | ATTR_CMN_FILEID
     254                                           | ATTR_CMN_PARENTID
     255                                           | ATTR_CMN_FULLPATH
     256                                           //| ATTR_CMN_ADDEDTIME
     257                                           ;
     258                pAt->validattr.volattr     = ATTR_VOL_FSTYPE
     259                                           | ATTR_VOL_SIGNATURE
     260                                           | ATTR_VOL_SIZE
     261                                           | ATTR_VOL_SPACEFREE
     262                                           | ATTR_VOL_SPACEAVAIL
     263                                           | ATTR_VOL_MINALLOCATION
     264                                           | ATTR_VOL_ALLOCATIONCLUMP
     265                                           | ATTR_VOL_IOBLOCKSIZE
     266                                           | ATTR_VOL_OBJCOUNT
     267                                           | ATTR_VOL_FILECOUNT
     268                                           | ATTR_VOL_DIRCOUNT
     269                                           | ATTR_VOL_MAXOBJCOUNT
     270                                           | ATTR_VOL_MOUNTPOINT
     271                                           | ATTR_VOL_NAME
     272                                           | ATTR_VOL_MOUNTFLAGS
     273                                           | ATTR_VOL_MOUNTEDDEVICE
     274                                           | ATTR_VOL_ENCODINGSUSED
     275                                           | ATTR_VOL_CAPABILITIES
     276                                           | ATTR_VOL_UUID
     277                                           | ATTR_VOL_ATTRIBUTES
     278                                           | ATTR_VOL_INFO;
     279                pAt->nativeattr.volattr     = ATTR_VOL_FSTYPE
     280                                            //| ATTR_VOL_SIGNATURE
     281                                            | ATTR_VOL_SIZE
     282                                            | ATTR_VOL_SPACEFREE
     283                                            | ATTR_VOL_SPACEAVAIL
     284                                            | ATTR_VOL_MINALLOCATION
     285                                            | ATTR_VOL_ALLOCATIONCLUMP
     286                                            | ATTR_VOL_IOBLOCKSIZE
     287                                            //| ATTR_VOL_OBJCOUNT
     288                                            //| ATTR_VOL_FILECOUNT
     289                                            //| ATTR_VOL_DIRCOUNT
     290                                            //| ATTR_VOL_MAXOBJCOUNT
     291                                            //| ATTR_VOL_MOUNTPOINT - ??
     292                                            | ATTR_VOL_NAME
     293                                            | ATTR_VOL_MOUNTFLAGS
     294                                            | ATTR_VOL_MOUNTEDDEVICE
     295                                            //| ATTR_VOL_ENCODINGSUSED
     296                                            | ATTR_VOL_CAPABILITIES
     297                                            //| ATTR_VOL_UUID
     298                                            | ATTR_VOL_ATTRIBUTES
     299                                            //| ATTR_VOL_INFO
     300                                            ;
     301                pAt->validattr.dirattr      = ATTR_DIR_LINKCOUNT
     302                                            | ATTR_DIR_ENTRYCOUNT
     303                                            | ATTR_DIR_MOUNTSTATUS;
     304                pAt->nativeattr.dirattr     = 0 //ATTR_DIR_LINKCOUNT
     305                                            | ATTR_DIR_ENTRYCOUNT
     306                                            | ATTR_DIR_MOUNTSTATUS
     307                                            ;
     308                pAt->validattr.fileattr     = ATTR_FILE_LINKCOUNT
     309                                            | ATTR_FILE_TOTALSIZE
     310                                            | ATTR_FILE_ALLOCSIZE
     311                                            | ATTR_FILE_IOBLOCKSIZE
     312                                            | ATTR_FILE_DEVTYPE
     313                                            | ATTR_FILE_FORKCOUNT
     314                                            | ATTR_FILE_FORKLIST
     315                                            | ATTR_FILE_DATALENGTH
     316                                            | ATTR_FILE_DATAALLOCSIZE
     317                                            | ATTR_FILE_RSRCLENGTH
     318                                            | ATTR_FILE_RSRCALLOCSIZE;
     319                pAt->nativeattr.fileattr    = 0
     320                                            //|ATTR_FILE_LINKCOUNT
     321                                            | ATTR_FILE_TOTALSIZE
     322                                            | ATTR_FILE_ALLOCSIZE
     323                                            //| ATTR_FILE_IOBLOCKSIZE
     324                                            | ATTR_FILE_DEVTYPE
     325                                            //| ATTR_FILE_FORKCOUNT
     326                                            //| ATTR_FILE_FORKLIST
     327                                            | ATTR_FILE_DATALENGTH
     328                                            | ATTR_FILE_DATAALLOCSIZE
     329                                            | ATTR_FILE_RSRCLENGTH
     330                                            | ATTR_FILE_RSRCALLOCSIZE
     331                                            ;
     332                pAt->validattr.forkattr     = ATTR_FORK_TOTALSIZE
     333                                            | ATTR_FORK_ALLOCSIZE;
     334                pAt->nativeattr.forkattr    = 0
     335                                            //| ATTR_FORK_TOTALSIZE
     336                                            //| ATTR_FORK_ALLOCSIZE
     337                                            ;
     338                VFSATTR_SET_SUPPORTED(pFsAttr, f_attributes);
    354339            }
    355             else
    356                 PDEBUG("Unable to flush filesystem before unmount, some data might be lost");
    357         }
    358         else
    359             PDEBUG("Unable to flush child vnodes");
    360 
    361     }
    362     else
    363         PDEBUG("Root vnode is in use, can't unmount");
    364 
    365     vnode_put(pMount->pRootVnode);
    366 
    367     return rc;
    368 }
    369 
    370 
    371 /**
    372  * Get VBoxVFS root vnode.
    373  *
    374  * Handle three cases here:
    375  *  - vnode does not exist yet: create a new one
    376  *  - currently creating vnode: wait till the end, increment usage count and return existing one
    377  *  - vnode already created: increment usage count and return existing one
    378  *  - vnode was failed to create: give a chance to try to re-create it later
    379  *
    380  * @param mp        Mount data provided by VFS layer.
    381  * @param ppVnode   vnode to return.
    382  * @param pContext  kAuth context needed in order to authentificate mount operation.
    383  *
    384  * @return 0 on success or BSD error code otherwise.
    385  */
    386 static int
    387 vboxvfs_root(struct mount *mp, struct vnode **ppVnode, vfs_context_t pContext)
    388 {
    389     NOREF(pContext);
    390 
    391     vboxvfs_mount_t *pMount;
    392     int rc = 0;
    393     uint32_t vid;
    394 
    395     PDEBUG("Getting root vnode...");
    396 
    397     AssertReturn(mp,      EINVAL);
    398     AssertReturn(ppVnode, EINVAL);
    399 
    400     pMount = (vboxvfs_mount_t *)vfs_fsprivate(mp);
    401     AssertReturn(pMount, EINVAL);
    402 
    403     /* Check case when vnode does not exist yet */
    404     if (ASMAtomicCmpXchgU8(&pMount->fRootVnodeState, VBOXVFS_OBJECT_INITIALIZING, VBOXVFS_OBJECT_UNINITIALIZED))
    405     {
    406         PDEBUG("Create new root vnode");
    407 
    408         /* Allocate empty SHFLSTRING to indicate path to root vnode within Shared Folder */
    409         char        szEmpty[1];
    410         SHFLSTRING *pSFVnodePath;
    411 
    412         pSFVnodePath = vboxvfs_construct_shflstring((char *)szEmpty, 0);
    413         if (pSFVnodePath)
    414         {
    415             int rc2;
    416             rc2 = vboxvfs_create_vnode_internal(mp, VDIR, NULL, TRUE, pSFVnodePath, &pMount->pRootVnode);
    417             if (rc2 != 0)
     340
     341            if (VFSATTR_IS_ACTIVE(pFsAttr, f_vol_name))
    418342            {
    419                 RTMemFree(pSFVnodePath);
    420                 rc = ENOTSUP;
     343                RTStrCopy(pFsAttr->f_vol_name, MAXPATHLEN, pThis->MntInfo.szFolder);
     344                VFSATTR_SET_SUPPORTED(pFsAttr, f_vol_name);
    421345            }
    422         }
    423         else
    424             rc = ENOMEM;
    425 
    426         /* Notify other threads about result */
    427         if (rc == 0)
    428             ASMAtomicWriteU8(&pMount->fRootVnodeState, VBOXVFS_OBJECT_INITIALIZED);
    429         else
    430             ASMAtomicWriteU8(&pMount->fRootVnodeState, VBOXVFS_OBJECT_INVALID);
    431     }
    432     else
    433     {
    434         /* Check case if we are currently creating vnode. Wait while other thread to finish allocation. */
    435         uint8_t fRootVnodeState = VBOXVFS_OBJECT_UNINITIALIZED;
    436         while (fRootVnodeState != VBOXVFS_OBJECT_INITIALIZED
    437             && fRootVnodeState != VBOXVFS_OBJECT_INVALID)
    438         {
    439             /** @todo Currently, we are burning CPU cycles while waiting. This is for a short
    440              * time but we should relax here! */
    441             fRootVnodeState = ASMAtomicReadU8(&pMount->fRootVnodeState);
    442 
    443         }
    444 
    445         /* Check if the other thread initialized root vnode and it is ready to be returned */
    446         if (fRootVnodeState == VBOXVFS_OBJECT_INITIALIZED)
    447         {
    448             /* Take care about iocount */
    449             vid = vnode_vid(pMount->pRootVnode);
    450             rc = vnode_getwithvid(pMount->pRootVnode, vid);
     346
     347            rc = 0;
    451348        }
    452349        else
    453350        {
    454             /* Other thread reported initialization failure.
    455              * Set vnode state VBOXVFS_OBJECT_UNINITIALIZED in order to try recreate root
    456              * vnode in other attempt */
    457             ASMAtomicWriteU8(&pMount->fRootVnodeState, VBOXVFS_OBJECT_UNINITIALIZED);
     351            Log(("vboxSfOs2QueryFileInfo: VbglR0SfFsInfo failed: %Rrc\n", vrc));
     352            rc = RTErrConvertToErrno(vrc);
    458353        }
    459354
    460     }
    461 
    462     /* Only return vnode if we got success */
    463     if (rc == 0)
    464     {
    465         PDEBUG("Root vnode can be returned");
    466         *ppVnode = pMount->pRootVnode;
     355        VbglR0PhysHeapFree(pReq);
    467356    }
    468357    else
    469         PDEBUG("Root vnode cannot be returned: 0x%X", rc);
    470 
     358        rc = ENOMEM;
    471359    return rc;
    472360}
    473361
     362
    474363/**
    475  * VBoxVFS get VFS layer object attribute callback.
     364 * vfsops::vfs_root implementation.
    476365 *
    477  * @param mp        Mount data provided by VFS layer.
    478  * @param pAttr     Output buffer to return attributes.
    479  * @param pContext  kAuth context needed in order to authentificate mount operation.
     366 * @returns 0 on success or errno.h value on failure.
     367 * @param   pMount      The mount data structure.
     368 * @param   ppVnode     Where to return the referenced root node on success.
     369 * @param   pContext    Unused kAuth parameter.
     370 */
     371static int vboxSfDwnVfsRoot(mount_t pMount, vnode_t *ppVnode, vfs_context_t pContext)
     372{
     373    PVBOXSFMNT pThis = (PVBOXSFMNT)vfs_fsprivate(pMount);
     374    AssertReturn(pThis, EBADMSG);
     375    LogFlow(("vboxSfDwnVfsRoot: pThis=%p:{%s}\n", pThis, pThis->MntInfo.szFolder));
     376
     377    /*
     378     * We shouldn't be callable during unmount, should we?
     379     */
     380    AssertReturn(vfs_isunmount(pMount), EBUSY);
     381
     382    /*
     383     * There should always be a root node around.
     384     */
     385    if (pThis->pVnRoot)
     386    {
     387        int rc = vnode_get(pThis->pVnRoot);
     388        if (rc == 0)
     389        {
     390            *ppVnode = pThis->pVnRoot;
     391            LogFlow(("vboxSfDwnVfsRoot: return %p\n", *ppVnode));
     392            return 0;
     393        }
     394        Log(("vboxSfDwnVfsRoot: vnode_get failed! %d\n", rc));
     395        return rc;
     396    }
     397
     398    LogRel(("vboxSfDwnVfsRoot: pVnRoot is NULL!\n"));
     399    return EILSEQ;
     400}
     401
     402
     403/**
     404 * vfsops::vfs_umount implementation.
    480405 *
    481  * @returns     0 for success, else an error code.
    482  */
    483 static int
    484 vboxvfs_getattr(struct mount *mp, struct vfs_attr *pAttr, vfs_context_t pContext)
     406 * @returns 0 on success or errno.h value on failure.
     407 * @param   pMount      The mount data.
     408 * @param   fFlags      Unmount flags.
     409 * @param   pContext    kAuth context which we don't care much about.
     410 *
     411 */
     412static int vboxSfDwnVfsUnmount(mount_t pMount, int fFlags, vfs_context_t pContext)
    485413{
    486     NOREF(pContext);
    487 
    488     vboxvfs_mount_t     *pMount;
    489     SHFLVOLINFO          SHFLVolumeInfo;
    490 
    491     int      rc;
    492     uint32_t cbBuffer = sizeof(SHFLVolumeInfo);
    493 
    494     uint32_t u32bsize;
    495     uint64_t u64blocks;
    496     uint64_t u64bfree;
    497 
    498     PDEBUG("Getting attribute...\n");
    499 
    500     AssertReturn(mp, EINVAL);
    501 
    502     pMount = (vboxvfs_mount_t *)vfs_fsprivate(mp);
    503     AssertReturn(pMount, EINVAL);
    504     AssertReturn(pMount->pShareName, EINVAL);
    505 
    506     rc = VbglR0SfFsInfo(&g_SfClient, &pMount->pMap, 0, SHFL_INFO_GET | SHFL_INFO_VOLUME,
    507                         &cbBuffer, (PSHFLDIRINFO)&SHFLVolumeInfo);
    508     AssertReturn(rc == 0, EPROTO);
    509 
    510     u32bsize  = (uint32_t)SHFLVolumeInfo.ulBytesPerAllocationUnit;
    511     AssertReturn(u32bsize > 0, ENOTSUP);
    512 
    513     u64blocks = (uint64_t)SHFLVolumeInfo.ullTotalAllocationBytes / (uint64_t)u32bsize;
    514     u64bfree  = (uint64_t)SHFLVolumeInfo.ullAvailableAllocationBytes / (uint64_t)u32bsize;
    515 
    516     VFSATTR_RETURN(pAttr, f_bsize,  u32bsize);
    517     VFSATTR_RETURN(pAttr, f_blocks, u64blocks);
    518     VFSATTR_RETURN(pAttr, f_bfree,  u64bfree);
    519     VFSATTR_RETURN(pAttr, f_bavail, u64bfree);
    520     VFSATTR_RETURN(pAttr, f_bused,  u64blocks - u64bfree);
    521 
    522     VFSATTR_RETURN(pAttr, f_owner,  pMount->owner);
    523 
    524     VFSATTR_CLEAR_ACTIVE(pAttr, f_iosize);
    525     VFSATTR_CLEAR_ACTIVE(pAttr, f_files);
    526     VFSATTR_CLEAR_ACTIVE(pAttr, f_ffree);
    527     VFSATTR_CLEAR_ACTIVE(pAttr, f_fssubtype);
    528 
    529     /** @todo take care about f_capabilities and f_attributes, f_fsid */
    530     VFSATTR_CLEAR_ACTIVE(pAttr, f_capabilities);
    531     VFSATTR_CLEAR_ACTIVE(pAttr, f_attributes);
    532     VFSATTR_CLEAR_ACTIVE(pAttr, f_fsid);
    533 
    534     /** @todo take care about f_create_time, f_modify_time, f_access_time, f_backup_time */
    535     VFSATTR_CLEAR_ACTIVE(pAttr, f_create_time);
    536     VFSATTR_CLEAR_ACTIVE(pAttr, f_modify_time);
    537     VFSATTR_CLEAR_ACTIVE(pAttr, f_access_time);
    538     VFSATTR_CLEAR_ACTIVE(pAttr, f_backup_time);
    539 
    540     VFSATTR_CLEAR_ACTIVE(pAttr, f_signature);
    541     VFSATTR_CLEAR_ACTIVE(pAttr, f_carbon_fsid);
    542     VFSATTR_CLEAR_ACTIVE(pAttr, f_uuid);
    543 
    544     if (VFSATTR_IS_ACTIVE(pAttr, f_vol_name))
    545     {
    546         strlcpy(pAttr->f_vol_name, (char*)pMount->pShareName->String.utf8, MAXPATHLEN);
    547         VFSATTR_SET_SUPPORTED(pAttr, f_vol_name);
    548     }
    549 
    550     VFSATTR_ALL_SUPPORTED(pAttr);
    551 
     414    PVBOXSFMNT pThis = (PVBOXSFMNT)vfs_fsprivate(pMount);
     415    AssertReturn(pThis, 0);
     416    LogFlowFunc(("pThis=%p:{%s} fFlags=%#x\n", pThis, pThis->MntInfo.szFolder, fFlags));
     417
     418    /*
     419     * Flush vnodes.
     420     */
     421    int rc = vflush(pMount, pThis->pVnRoot, fFlags & MNT_FORCE ? FORCECLOSE : 0);
     422    if (rc == 0)
     423    {
     424        /*
     425         * Is the file system still busy?
     426         *
     427         * Until we find a way of killing any active host calls, we cannot properly
     428         * respect the MNT_FORCE flag here. So, MNT_FORCE is ignored here.
     429         */
     430        if (   !pThis->pVnRoot
     431            || !vnode_isinuse(pThis->pVnRoot, 1))
     432        {
     433            /*
     434             * Release our root vnode reference and do another flush.
     435             */
     436            if (pThis->pVnRoot)
     437            {
     438                vnode_put(pThis->pVnRoot);
     439                pThis->pVnRoot = NULL;
     440            }
     441            vflush(pMount, NULLVP, FORCECLOSE);
     442
     443            /*
     444             * Unmap the shared folder and destroy our mount info structure.
     445             */
     446            vfs_setfsprivate(pMount, NULL);
     447
     448            rc = VbglR0SfUnmapFolder(&g_SfClientDarwin, &pThis->hHostFolder);
     449            AssertRC(rc);
     450
     451            RT_ZERO(*pThis);
     452            RTMemFree(pThis);
     453
     454            vfs_clearflags(pMount, MNT_LOCAL); /* ?? */
     455            rc = 0;
     456
     457            g_cVBoxSfMounts--;
     458        }
     459        else
     460        {
     461            Log(("VBoxSF: umount failed: file system busy! (%s)\n", pThis->MntInfo.szFolder));
     462            rc = EBUSY;
     463        }
     464    }
     465    return rc;
     466}
     467
     468
     469/**
     470 * vfsops::vfs_start implementation.
     471 */
     472static int vboxSfDwnVfsStart(mount_t pMount, int fFlags, vfs_context_t pContext)
     473{
     474    RT_NOREF(pMount, fFlags, pContext);
    552475    return 0;
    553476}
    554477
     478
     479/**
     480 * vfsops::vfs_mount implementation.
     481 *
     482 * @returns 0 on success or errno.h value on failure.
     483 * @param   pMount      The mount data structure.
     484 * @param   pDevVp      The device to mount.  Not used by us.
     485 * @param   pUserData   User space address of parameters supplied to mount().
     486 *                      We expect a VBOXSFDRWNMOUNTINFO structure.
     487 * @param   pContext    kAuth context needed in order to authentificate mount
     488 *                      operation.
     489 */
     490static int vboxSfDwnVfsMount(mount_t pMount, vnode_t pDevVp, user_addr_t pUserData, vfs_context_t pContext)
     491{
     492    RT_NOREF(pDevVp)
     493
     494    /*
     495     * We don't support mount updating.
     496     */
     497    if (vfs_isupdate(pMount))
     498    {
     499        LogRel(("VBoxSF: mount: MNT_UPDATE is not supported.\n"));
     500        return ENOTSUP;
     501    }
     502    if (pUserData == USER_ADDR_NULL)
     503    {
     504        LogRel(("VBoxSF: mount: pUserData is NULL.\n"));
     505        return EINVAL;
     506    }
     507    struct vfsstatfs *pFsStats = vfs_statfs(pMount);
     508    AssertReturn(pFsStats, EINVAL);
     509
     510    /*
     511     * Get the mount information from userland.
     512     */
     513    PVBOXSFMNT pThis = (PVBOXSFMNT)RTMemAllocZ(sizeof(*pThis));
     514    if (!pThis)
     515        return ENOMEM;
     516    pThis->uidMounter = pFsStats->f_owner;
     517
     518    int rc = RTR0MemUserCopyFrom(&pThis->MntInfo, (RTR3PTR)pUserData, sizeof(pThis->MntInfo));
     519    if (RT_FAILURE(rc))
     520    {
     521        LogRel(("VBoxSF: mount: Failed to copy in mount user data: %Rrc\n", rc));
     522        rc = EFAULT;
     523    }
     524    else if (pThis->MntInfo.u32Magic != VBOXSFDRWNMOUNTINFO_MAGIC)
     525    {
     526        LogRel(("VBoxSF: mount: Invalid user data magic (%#x)\n", pThis->MntInfo.u32Magic));
     527        rc = EINVAL;
     528    }
     529    else if (   (rc = RTStrValidateEncodingEx(pThis->MntInfo.szFolder, sizeof(pThis->MntInfo.szFolder),
     530                                              RTSTR_VALIDATE_ENCODING_ZERO_TERMINATED)) != VINF_SUCCESS
     531             || pThis->MntInfo.szFolder[0] == '\0')
     532    {
     533        LogRel(("VBoxSF: mount: Invalid or empty share name!\n"));
     534        rc = EINVAL;
     535    }
     536    else
     537    {
     538        /*
     539         * Try map the shared folder.
     540         */
     541        if (vboxSfDwnConnect())
     542        {
     543            PSHFLSTRING pName = ShflStringDupUtf8(pThis->MntInfo.szFolder);
     544            if (pName)
     545            {
     546                rc = VbglR0SfMapFolder(&g_SfClientDarwin, pName, &pThis->hHostFolder);
     547                RTMemFree(pName);
     548                if (RT_SUCCESS(rc))
     549                {
     550
     551                    /*
     552                     * Create a root node, that avoid races later.
     553                     */
     554                    pThis->pVnRoot = vboxSfDwnVnAlloc(pMount, VDIR, NULL /*pParent*/, 0);
     555                    if (pThis->pVnRoot)
     556                    {
     557                        /*
     558                         * Fill file system stats with dummy data.
     559                         */
     560                        pFsStats->f_bsize  = 512;
     561                        pFsStats->f_iosize = _64K;
     562                        pFsStats->f_blocks = _1M;
     563                        pFsStats->f_bavail = _1M / 4 * 3;
     564                        pFsStats->f_bused  = _1M / 4;
     565                        pFsStats->f_files  = 1024;
     566                        pFsStats->f_ffree  = _64K;
     567                        vfs_getnewfsid(pMount); /* f_fsid */
     568                        /* pFsStats->f_fowner - don't touch */
     569                        /* pFsStats->f_fstypename - don't touch */
     570                        /* pFsStats->f_mntonname - don't touch */
     571                        RTStrCopy(pFsStats->f_mntfromname, sizeof(pFsStats->f_mntfromname), pThis->MntInfo.szFolder);
     572                        /* pFsStats->f_fssubtype - don't touch? */
     573                        /* pFsStats->f_reserved[0] - don't touch? */
     574                        /* pFsStats->f_reserved[1] - don't touch? */
     575
     576                        /*
     577                         * We're good. Set private data and flags.
     578                         */
     579                        vfs_setfsprivate(pMount, pThis);
     580                        vfs_setflags(pMount, MNT_SYNCHRONOUS | MNT_NOSUID | MNT_NODEV);
     581                        /** @todo Consider flags like MNT_NOEXEC ? */
     582
     583                        /// @todo vfs_setauthopaque(pMount)?
     584                        /// @todo vfs_clearauthopaqueaccess(pMount)?
     585                        /// @todo vfs_clearextendedsecurity(pMount)?
     586
     587                        LogRel(("VBoxSF: mount: Successfully mounted '%s' (uidMounter=%u).\n",
     588                                pThis->MntInfo.szFolder, pThis->uidMounter));
     589                        return 0;
     590                    }
     591
     592                    LogRel(("VBoxSF: mount: Failed to allocate root node!\n"));
     593                    rc = ENOMEM;
     594                }
     595                else
     596                {
     597                    LogRel(("VBoxSF: mount: VbglR0SfMapFolder failed on '%s': %Rrc\n", pThis->MntInfo.szFolder, rc));
     598                    rc = ENOENT;
     599                }
     600            }
     601            else
     602                rc = ENOMEM;
     603        }
     604        else
     605        {
     606            LogRel(("VBoxSF: mount: Not connected to shared folders service!\n"));
     607            rc = ENOTCONN;
     608        }
     609    }
     610    RTMemFree(pThis);
     611    return rc;
     612}
     613
     614
    555615/**
    556616 * VFS operations
     
    558618struct vfsops g_VBoxSfVfsOps =
    559619{
    560     /* Standard operations */
    561     &vboxvfs_mount,
    562     NULL,               /* Skipped: vfs_start() */
    563     &vboxvfs_unmount,
    564     &vboxvfs_root,
     620    vboxSfDwnVfsMount,
     621    vboxSfDwnVfsStart,
     622    vboxSfDwnVfsUnmount,
     623    vboxSfDwnVfsRoot,
    565624    NULL,               /* Skipped: vfs_quotactl */
    566     &vboxvfs_getattr,
     625    vboxSfDwnVfsGetAttr,
    567626    NULL,               /* Skipped: vfs_sync */
    568627    NULL,               /* Skipped: vfs_vget */
  • trunk/src/VBox/Additions/darwin/VBoxSF/VBoxSF.cpp

    r75666 r75675  
    2020*   Header Files                                                                                                                 *
    2121*********************************************************************************************************************************/
    22 #define LOG_GROUP LOG_GROUP_DEFAULT
     22#define LOG_GROUP LOG_GROUP_SHARED_FOLDERS
    2323#include "VBoxSFInternal.h"
    2424
    2525#include <iprt/asm.h>
    2626#include <iprt/assert.h>
     27#include <iprt/initterm.h>
    2728#include <VBox/version.h>
    2829#include <VBox/log.h>
     
    3031
    3132/*********************************************************************************************************************************
    32 *   Structures and Typedefs                                                                                                      *
     33*   Internal Functions                                                                                                           *
    3334*********************************************************************************************************************************/
    34 /**
    35  * The service class for this driver.
    36  *
    37  * This has one purpose: Use waitForMatchingService() to find VBoxGuest.
    38  */
    39 class org_virtualbox_VBoxSF : public IOService
    40 {
    41     OSDeclareDefaultStructors(org_virtualbox_VBoxSF);
    42 
    43 private:
    44     IOService *waitForCoreService(void);
    45 
    46     IOService *m_pCoreService;
    47 
    48 public:
    49     virtual bool start(IOService *pProvider);
    50     virtual void stop(IOService *pProvider);
    51 };
    52 
    53 OSDefineMetaClassAndStructors(org_virtualbox_VBoxSF, IOService);
     35static kern_return_t vboxSfDwnModuleLoad(struct kmod_info *pKModInfo, void *pvData);
     36static kern_return_t vboxSfDwnModuleUnload(struct kmod_info *pKModInfo, void *pvData);
    5437
    5538
     
    5740*   Global Variables                                                                                                             *
    5841*********************************************************************************************************************************/
    59 /**
    60  * Declare the module stuff.
    61  */
    62 RT_C_DECLS_BEGIN
    63 static kern_return_t VBoxSfModuleLoad(struct kmod_info *pKModInfo, void *pvData);
    64 static kern_return_t VBoxSfModuleUnload(struct kmod_info *pKModInfo, void *pvData);
    65 extern kern_return_t _start(struct kmod_info *pKModInfo, void *pvData);
    66 extern kern_return_t _stop(struct kmod_info *pKModInfo, void *pvData);
    67 KMOD_EXPLICIT_DECL(VBoxVFS, VBOX_VERSION_STRING, _start, _stop)
    68 DECLHIDDEN(kmod_start_func_t *) _realmain      = VBoxSfModuleLoad;
    69 DECLHIDDEN(kmod_stop_func_t *)  _antimain      = VBoxSfModuleUnload;
    70 DECLHIDDEN(int)                 _kext_apple_cc = __APPLE_CC__;
    71 RT_C_DECLS_END
    72 
    73 /** The org_virtualbox_VBoxSF instance.
    74  * Used for preventing multiple instantiations. */
    75 static org_virtualbox_VBoxSF   *g_pService = NULL;
    76 
     42/** The VBoxGuest service if we've managed to connect to it already. */
     43static IOService               *g_pVBoxGuest = NULL;
    7744/** The shared folder service client structure. */
    78 VBGLSFCLIENT                    g_SfClient;
     45VBGLSFCLIENT                    g_SfClientDarwin = { UINT32_MAX, NULL };
     46/** Number of active mounts.  Used for unload prevention. */
     47uint32_t volatile               g_cVBoxSfMounts = 0;
     48
    7949/* VBoxVFS filesystem handle. Needed for FS unregistering. */
    8050static vfstable_t               g_pVBoxSfVfsTableEntry;
    81 
    8251/** For vfs_fsentry. */
    8352static struct vnodeopv_desc    *g_apVBoxSfVnodeOpDescList[] =
     
    8554    &g_VBoxSfVnodeOpvDesc,
    8655};
    87 
    88 
    8956/** VFS registration structure. */
    90 static struct vfs_fsentry g_VBoxSfFsEntry =
     57static struct vfs_fsentry       g_VBoxSfFsEntry =
    9158{
    9259    .vfe_vfsops     = &g_VBoxSfVfsOps,
     
    10572
    10673/**
    107  * KEXT Module BSD entry point
    108  */
    109 static kern_return_t VBoxSfModuleLoad(struct kmod_info *pKModInfo, void *pvData)
    110 {
    111     /* Initialize the R0 guest library. */
    112 #if 0
    113     rc = VbglR0SfInit();
    114     if (RT_FAILURE(rc))
    115         return KERN_FAILURE;
     74 * Declare the module stuff.
     75 */
     76RT_C_DECLS_BEGIN
     77extern kern_return_t _start(struct kmod_info *pKModInfo, void *pvData);
     78extern kern_return_t _stop(struct kmod_info *pKModInfo, void *pvData);
     79
     80KMOD_EXPLICIT_DECL(VBoxVFS, VBOX_VERSION_STRING, _start, _stop)
     81DECLHIDDEN(kmod_start_func_t *) _realmain      = vboxSfDwnModuleLoad;
     82DECLHIDDEN(kmod_stop_func_t *)  _antimain      = vboxSfDwnModuleUnload;
     83DECLHIDDEN(int)                 _kext_apple_cc = __APPLE_CC__;
     84RT_C_DECLS_END
     85
     86
     87/**
     88 * Connect to VBoxGuest and host shared folders service.
     89 *
     90 * @returns true if connected, false if not.
     91 */
     92bool vboxSfDwnConnect(void)
     93{
     94    /*
     95     * Grab VBoxGuest - since it's a dependency of this module, it shouldn't be hard.
     96     */
     97    if (!g_pVBoxGuest)
     98    {
     99        OSDictionary *pServiceMatcher = IOService::serviceMatching("org_virtualbox_VBoxGuest");
     100        if (pServiceMatcher)
     101        {
     102            IOService *pVBoxGuest = IOService::waitForMatchingService(pServiceMatcher, 10 * RT_NS_1SEC);
     103            if (pVBoxGuest)
     104                g_pVBoxGuest = pVBoxGuest;
     105            else
     106                LogRel(("vboxSfDwnConnect: IOService::waitForMatchingService failed!!\n"));
     107        }
     108        else
     109            LogRel(("vboxSfDwnConnect: serviceMatching failed\n"));
     110    }
     111
     112    if (g_pVBoxGuest)
     113    {
     114        /*
     115         * Get hold of the shared folders service if we haven't already.
     116         */
     117        if (g_SfClientDarwin.handle != NULL)
     118            return true;
     119
     120        int rc = VbglR0SfConnect(&g_SfClientDarwin);
     121        if (RT_SUCCESS(rc))
     122        {
     123            rc = VbglR0SfSetUtf8(&g_SfClientDarwin);
     124            if (RT_SUCCESS(rc))
     125                return true;
     126
     127            LogRel(("VBoxSF: VbglR0SfSetUtf8 failed: %Rrc\n", rc));
     128
     129            VbglR0SfDisconnect(&g_SfClientDarwin);
     130            g_SfClientDarwin.handle = NULL;
     131        }
     132        else
     133            LogRel(("VBoxSF: VbglR0SfConnect failed: %Rrc\n", rc));
     134    }
     135
     136    return false;
     137}
     138
     139
     140/**
     141 * Start the kernel module.
     142 */
     143static kern_return_t vboxSfDwnModuleLoad(struct kmod_info *pKModInfo, void *pvData)
     144{
     145    RT_NOREF(pKModInfo, pvData);
     146#ifdef DEBUG
     147    printf("vboxSfDwnModuleLoad\n");
     148    RTLogBackdoorPrintf("vboxSfDwnModuleLoad\n");
    116149#endif
    117150
    118     PINFO("VirtualBox " VBOX_VERSION_STRING " shared folders "
    119           "driver is loaded");
    120 
     151    /*
     152     * Initialize IPRT and the ring-0 guest library.
     153     */
     154    int rc = RTR0Init(0);
     155    if (RT_SUCCESS(rc))
     156    {
     157        rc = VbglR0SfInit();
     158        if (RT_SUCCESS(rc))
     159        {
     160            /*
     161             * Register the file system.
     162             */
     163            rc = vfs_fsadd(&g_VBoxSfFsEntry, &g_pVBoxSfVfsTableEntry);
     164            if (rc == 0)
     165            {
     166                /*
     167                 * Try find VBoxGuest and connect to the shared folders service on the host.
     168                 */
     169                /** @todo should we just ignore the error here and retry at mount time?
     170                 * Technically, VBoxGuest should be available since it's one of our
     171                 * dependencies... */
     172                vboxSfDwnConnect();
     173
     174                /*
     175                 * We're done for now.  We'll deal with
     176                 */
     177                LogRel(("VBoxSF: loaded\n"));
     178                return KERN_SUCCESS;
     179            }
     180
     181            printf("VBoxSF: vfs_fsadd failed: %d\n", rc);
     182            RTLogBackdoorPrintf("VBoxSF: vfs_fsadd failed: %d\n", rc);
     183            VbglR0SfTerm();
     184        }
     185        else
     186        {
     187            printf("VBoxSF: VbglR0SfInit failed: %d\n", rc);
     188            RTLogBackdoorPrintf("VBoxSF: VbglR0SfInit failed: %Rrc\n", rc);
     189        }
     190        RTR0Term();
     191    }
     192    else
     193    {
     194        printf("VBoxSF: RTR0Init failed: %d\n", rc);
     195        RTLogBackdoorPrintf("VBoxSF: RTR0Init failed: %Rrc\n", rc);
     196    }
     197    return KERN_FAILURE;
     198}
     199
     200
     201/**
     202 * Stop the kernel module.
     203 */
     204static kern_return_t vboxSfDwnModuleUnload(struct kmod_info *pKModInfo, void *pvData)
     205{
     206#ifdef DEBUG
     207    printf("vboxSfDwnModuleUnload\n");
     208    RTLogBackdoorPrintf("vboxSfDwnModuleUnload\n");
     209#endif
     210
     211    /*
     212     * Are we busy?  If so fail.
     213     */
     214    if (g_cVBoxSfMounts > 0)
     215    {
     216        LogRel(("VBoxSF: Refusing to unload with %u active mounts\n", g_cVBoxSfMounts));
     217        return KERN_NO_ACCESS;
     218    }
     219
     220    /*
     221     * Disconnect and terminate libraries we're using.
     222     */
     223
     224    if (g_SfClientDarwin.handle != NULL)
     225    {
     226        VbglR0SfDisconnect(&g_SfClientDarwin);
     227        g_SfClientDarwin.handle = NULL;
     228    }
     229
     230    if (g_pVBoxGuest)
     231    {
     232        g_pVBoxGuest->release();
     233        g_pVBoxGuest = NULL;
     234    }
     235
     236    VbglR0SfTerm();
     237    RTR0Term();
    121238    return KERN_SUCCESS;
    122239}
    123240
    124 
    125 /**
    126  * KEXT Module BSD exit point
    127  */
    128 static kern_return_t VBoxSfModuleUnload(struct kmod_info *pKModInfo, void *pvData)
    129 {
    130 #if 0
    131    VbglR0SfTerm();
    132 #endif
    133 
    134     PINFO("VirtualBox " VBOX_VERSION_STRING " shared folders driver is unloaded");
    135 
    136     return KERN_SUCCESS;
    137 }
    138 
    139 /**
    140  * Wait for VBoxGuest.kext to be started
    141  */
    142 IOService *org_virtualbox_VBoxSF::waitForCoreService(void)
    143 {
    144     OSDictionary *pServiceToMatach = serviceMatching("org_virtualbox_VBoxGuest");
    145     if (pServiceToMatach)
    146     {
    147         /* Wait 15 seconds for VBoxGuest to be started */
    148         IOService *pService = waitForMatchingService(pServiceToMatach, 15 * RT_NS_1SEC_64);
    149         pServiceToMatach->release();
    150         return pService;
    151     }
    152     PINFO("unable to create matching dictionary");
    153     return NULL;
    154 }
    155 
    156 
    157 /**
    158  * Start this service.
    159  */
    160 bool org_virtualbox_VBoxSF::start(IOService *pProvider)
    161 {
    162     if (g_pService == NULL)
    163         g_pService = this;
    164     else
    165     {
    166         printf("org_virtualbox_VBoxSF::start: g_pService=%p this=%p -> false\n", g_pService, this);
    167         return false;
    168     }
    169 
    170     if (IOService::start(pProvider))
    171     {
    172         /*
    173          * Get hold of VBoxGuest.
    174          */
    175         m_pCoreService = waitForCoreService();
    176         if (m_pCoreService)
    177         {
    178             int rc = VbglR0SfInit();
    179             if (RT_SUCCESS(rc))
    180             {
    181                 /*
    182                  * Connect to the host service and set UTF-8 as the string encoding to use.
    183                  */
    184                 rc = VbglR0SfConnect(&g_SfClient);
    185                 if (RT_SUCCESS(rc))
    186                 {
    187                     rc = VbglR0SfSetUtf8(&g_SfClient);
    188                     if (RT_SUCCESS(rc))
    189                     {
    190                         /*
    191                          * Register the file system.
    192                          */
    193                         rc = vfs_fsadd(&g_VBoxSfFsEntry, &g_pVBoxSfVfsTableEntry);
    194                         if (rc == 0)
    195                         {
    196                             registerService();
    197 
    198                             LogRel(("VBoxSF: ready\n"));
    199                             return true;
    200                         }
    201 
    202                         LogRel(("VBoxSF: vfs_fsadd failed: %d\n", rc));
    203                     }
    204                     else
    205                         LogRel(("VBoxSF: VbglR0SfSetUtf8 failed: %Rrc\n", rc));
    206                     VbglR0SfDisconnect(&g_SfClient);
    207                 }
    208                 else
    209                     LogRel(("VBoxSF: VbglR0SfConnect failed: %Rrc\n", rc));
    210                 VbglR0SfTerm();
    211             }
    212             else
    213                 LogRel(("VBoxSF: VbglR0SfInit failed: %Rrc\n", rc));
    214             m_pCoreService->release();
    215         }
    216         else
    217             LogRel(("VBoxSF: Failed to find VBoxGuest!\n"));
    218 
    219         IOService::stop(pProvider);
    220     }
    221     g_pService = NULL;
    222     return false;
    223 }
    224 
    225 
    226 /**
    227  * Stop this service.
    228  */
    229 void org_virtualbox_VBoxSF::stop(IOService *pProvider)
    230 {
    231     if (m_pCoreService == this)
    232     {
    233         /*
    234          * Unregister the filesystem.
    235          */
    236         if (g_pVBoxSfVfsTableEntry != NULL)
    237         {
    238             int rc = vfs_fsremove(g_pVBoxSfVfsTableEntry);
    239             if (rc == 0)
    240             {
    241                 g_pVBoxSfVfsTableEntry = NULL;
    242                 PINFO("VBoxVFS filesystem successfully unregistered");
    243             }
    244             else
    245             {
    246                 PINFO("Unable to unregister the VBoxSF filesystem (%d)", rc);
    247                 /** @todo how on earth do we deal with this...  Gues we shouldn't be using
    248                  *        IOService at all here. sigh.  */
    249             }
    250         }
    251         VbglR0SfDisconnect(&g_SfClient);
    252         VbglR0SfTerm();
    253         if (m_pCoreService)
    254             m_pCoreService->release();
    255 
    256     }
    257     IOService::stop(pProvider);
    258 }
    259 
  • trunk/src/VBox/Additions/darwin/VBoxSF/VBoxSFInternal.h

    r75666 r75675  
    3939#include <sys/param.h>
    4040#include <sys/vnode.h>
     41#include <vfs/vfs_support.h>
    4142#undef PVM
    4243
     44#include <iprt/mem.h>
     45#include <VBox/VBoxGuest.h>
    4346#include <VBox/VBoxGuestLibSharedFolders.h>
    4447
     
    5962typedef struct vboxvfs_mount_data
    6063{
    61     VBGLSFMAP           pMap;               /** Shared folder mapping */
    62     SHFLSTRING         *pShareName;         /** VBoxVFS share name */
    63     uint64_t            cFileIdCounter;     /** Counter that used in order to assign unique ID to each vnode within mounted share */
    64     vnode_t             pRootVnode;         /** VFS object: vnode that corresponds shared folder root */
    65     uint8_t volatile    fRootVnodeState;    /** Sync flag that used in order to safely allocate pRootVnode */
    66     uid_t               owner;              /** User ID tha mounted shared folder */
    67     lck_grp_t          *pLockGroup;         /** BSD locking stuff */
    68     lck_grp_attr_t     *pLockGroupAttr;     /** BSD locking stuff */
    69 } vboxvfs_mount_t;
     64    /** The shared folder mapping */
     65    VBGLSFMAP           hHostFolder;
     66    /** The root VNode. */
     67    vnode_t             pVnRoot;
     68    /** User that mounted shared folder (anyone but root?). */
     69    uid_t               uidMounter;
     70    /** The mount info from the mount() call. */
     71    VBOXSFDRWNMOUNTINFO MntInfo;
     72} vboxvfs_mount_t, VBOXSFMNT;
     73typedef VBOXSFMNT *PVBOXSFMNT;
    7074
    7175/** Private data assigned to each vnode object. */
    7276typedef struct vboxvfs_vnode_data
    7377{
    74     SHFLHANDLE      pHandle;                /** VBoxVFS object handle. */
    75     PSHFLSTRING     pPath;                  /** Path within shared folder */
    76     lck_attr_t     *pLockAttr;              /** BSD locking stuff */
    77     lck_rw_t       *pLock;                  /** BSD locking stuff */
    78 } vboxvfs_vnode_t;
     78    SHFLHANDLE      hHandle;                /** VBoxVFS object handle. */
     79    ///PSHFLSTRING     pPath;                  /** Path within shared folder */
     80    ///lck_attr_t     *pLockAttr;              /** BSD locking stuff */
     81    ///lck_rw_t       *pLock;                  /** BSD locking stuff */
     82} vboxvfs_vnode_t, VBOXSFDWNVNDATA;
     83/** Private vnode data. */
     84typedef VBOXSFDWNVNDATA *PVBOXSFDWNVNDATA;
     85
    7986
    8087
     
    8289*   Global Variables                                                                                                             *
    8390*********************************************************************************************************************************/
    84 extern VBGLSFCLIENT         g_SfClient;
     91extern VBGLSFCLIENT         g_SfClientDarwin;
     92extern uint32_t volatile    g_cVBoxSfMounts;
    8593extern struct vfsops        g_VBoxSfVfsOps;
    8694extern struct vnodeopv_desc g_VBoxSfVnodeOpvDesc;
     
    9199*   Functions                                                                                                                    *
    92100*********************************************************************************************************************************/
     101bool    vboxSfDwnConnect(void);
     102vnode_t vboxSfDwnVnAlloc(mount_t pMount, enum vtype enmType, vnode_t pParent, uint64_t cbFile);
     103
     104
     105
    93106
    94107/**
     
    228241extern SHFLSTRING *vboxvfs_construct_shflstring(const char *pszName, size_t cchName);
    229242
    230 extern int vboxvfs_register_filesystem(void);
    231 extern int vboxvfs_unregister_filesystem(void);
    232 
    233243
    234244#endif
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