VirtualBox

Changeset 39270 in vbox for trunk/src/VBox/Additions/solaris


Ignore:
Timestamp:
Nov 11, 2011 1:18:27 PM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
74815
Message:

Additions/solaris/SharedFolders: symlink support.

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

Legend:

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

    r39263 r39270  
    528528}
    529529
     530static void
     531sfprov_stat_from_info(sffs_stat_t *stat, SHFLFSOBJINFO *info)
     532{
     533        sfprov_mode_from_fmode(&stat->sf_mode, info->Attr.fMode);
     534        stat->sf_size  = info->cbObject;
     535        stat->sf_alloc = info->cbAllocated;
     536        sfprov_ftime_from_timespec(&stat->sf_atime, &info->AccessTime);
     537        sfprov_ftime_from_timespec(&stat->sf_mtime, &info->ModificationTime);
     538        sfprov_ftime_from_timespec(&stat->sf_ctime, &info->ChangeTime);
     539}
     540
    530541int
    531542sfprov_get_atime(sfp_mount_t *mnt, char *path, timestruc_t *time)
     
    568579
    569580int
    570 sfprov_get_attr(
    571         sfp_mount_t *mnt,
    572         char *path,
    573         mode_t *mode,
    574         uint64_t *size,
    575         timestruc_t *atime,
    576         timestruc_t *mtime,
    577         timestruc_t *ctime)
     581sfprov_get_attr(sfp_mount_t *mnt, char *path, sffs_stat_t *attr)
    578582{
    579583        int rc;
     
    583587        if (rc)
    584588                return (rc);
    585 
    586         if (mode)
    587                 sfprov_mode_from_fmode(mode, info.Attr.fMode);
    588         if (size != NULL)
    589                 *size = info.cbObject;
    590         if (atime != NULL)
    591                 sfprov_ftime_from_timespec(atime, &info.AccessTime);
    592         if (mtime != NULL)
    593                 sfprov_ftime_from_timespec(mtime, &info.ModificationTime);
    594         if (ctime != NULL)
    595                 sfprov_ftime_from_timespec(ctime, &info.ChangeTime);
    596 
     589        sfprov_stat_from_info(attr, &info);
    597590        return (0);
    598591}
     
    800793
    801794int
    802 sfprov_remove(sfp_mount_t *mnt, char *path)
     795sfprov_set_show_symlinks(void)
     796{
     797        int rc;
     798
     799        rc = vboxCallSetSymlinks(&vbox_client);
     800        if (RT_FAILURE(rc))
     801                return (sfprov_vbox2errno(rc));
     802
     803        return (0);
     804}
     805
     806int
     807sfprov_remove(sfp_mount_t *mnt, char *path, uint_t is_link)
    803808{
    804809        int rc;
     
    807812
    808813        str = sfprov_string(path, &size);
    809         rc = vboxCallRemove(&vbox_client, &mnt->map, str, SHFL_REMOVE_FILE);
     814        rc = vboxCallRemove(&vbox_client, &mnt->map, str,
     815                SHFL_REMOVE_FILE | (is_link ? SHFL_REMOVE_SYMLINK : 0));
    810816        kmem_free(str, size);
    811817        if (RT_FAILURE(rc))
    812818                return (sfprov_vbox2errno(rc));
    813819        return (0);
     820}
     821
     822int
     823sfprov_readlink(
     824        sfp_mount_t *mnt,
     825        char *path,
     826        char *target,
     827        size_t tgt_size)
     828{
     829        int rc;
     830        SHFLSTRING *str;
     831        int size;
     832
     833        str = sfprov_string(path, &size);
     834
     835        rc = vboxReadLink(&vbox_client, &mnt->map, str, (uint32_t) tgt_size,
     836            target);
     837        if (RT_FAILURE(rc))
     838                rc = sfprov_vbox2errno(rc);
     839
     840        kmem_free(str, size);
     841        return (rc);
     842}
     843
     844int
     845sfprov_symlink(
     846        sfp_mount_t *mnt,
     847        char *linkname,
     848        char *target,
     849        sffs_stat_t *stat)
     850{
     851        int rc;
     852        SHFLSTRING *lnk, *tgt;
     853        int lnk_size, tgt_size;
     854        SHFLFSOBJINFO info;
     855
     856        lnk = sfprov_string(linkname, &lnk_size);
     857        tgt = sfprov_string(target, &tgt_size);
     858
     859        rc = vboxCallSymlink(&vbox_client, &mnt->map, lnk, tgt, &info);
     860        if (RT_FAILURE(rc)) {
     861                rc = sfprov_vbox2errno(rc);
     862                goto done;
     863        }
     864
     865        if (stat != NULL)
     866                sfprov_stat_from_info(stat, &info);
     867
     868done:
     869        kmem_free(lnk, lnk_size);
     870        kmem_free(tgt, tgt_size);
     871
     872        return (rc);
    814873}
    815874
     
    880939        sffs_dirents_t *cur_buf;
    881940        struct sffs_dirent *dirent;
    882         sffs_stat_t *stat;
    883941        unsigned short reclen;
    884942        unsigned short entlen;
     
    9741032
    9751033                        /* save the stats */
    976                         stat = &dirent->sf_stat;
    977 
    978                         sfprov_mode_from_fmode(&stat->sf_mode, info->Info.Attr.fMode);
    979                         stat->sf_size = info->Info.cbObject;
    980                         stat->sf_alloc = info->Info.cbAllocated;
    981                         sfprov_ftime_from_timespec(&stat->sf_atime, &info->Info.AccessTime);
    982                         sfprov_ftime_from_timespec(&stat->sf_mtime, &info->Info.ModificationTime);
    983                         sfprov_ftime_from_timespec(&stat->sf_ctime, &info->Info.ChangeTime);
     1034                        sfprov_stat_from_info(&dirent->sf_stat, &info->Info);
    9841035
    9851036                        /* next info */
  • trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.h

    r39263 r39270  
    9999 * get/set information about a file (or directory) using pathname
    100100 */
     101typedef struct sffs_stat {
     102        mode_t          sf_mode;
     103        off_t           sf_size;
     104        off_t           sf_alloc;
     105        timestruc_t     sf_atime;
     106        timestruc_t     sf_mtime;
     107        timestruc_t     sf_ctime;
     108} sffs_stat_t;
     109
    101110extern int sfprov_get_mode(sfp_mount_t *, char *, mode_t *);
    102111extern int sfprov_get_size(sfp_mount_t *, char *, uint64_t *);
     
    104113extern int sfprov_get_mtime(sfp_mount_t *, char *, timestruc_t *);
    105114extern int sfprov_get_ctime(sfp_mount_t *, char *, timestruc_t *);
    106 extern int sfprov_get_attr(sfp_mount_t *, char *, mode_t *, uint64_t *,
    107    timestruc_t *, timestruc_t *, timestruc_t *);
     115extern int sfprov_get_attr(sfp_mount_t *, char *, sffs_stat_t *);
    108116extern int sfprov_set_attr(sfp_mount_t *, char *, uint_t, mode_t,
    109117   timestruc_t, timestruc_t, timestruc_t);
     
    115123 */
    116124extern int sfprov_trunc(sfp_mount_t *, char *);
    117 extern int sfprov_remove(sfp_mount_t *, char *path);
     125extern int sfprov_remove(sfp_mount_t *, char *path, uint_t is_link);
    118126extern int sfprov_mkdir(sfp_mount_t *, char *path, sfp_file_t **fp);
    119127extern int sfprov_rmdir(sfp_mount_t *, char *path);
    120128extern int sfprov_rename(sfp_mount_t *, char *from, char *to, uint_t is_dir);
    121129
    122 typedef struct sffs_stat {
    123         mode_t          sf_mode;
    124         off_t           sf_size;
    125         off_t       sf_alloc;
    126         timestruc_t     sf_atime;
    127         timestruc_t     sf_mtime;
    128         timestruc_t     sf_ctime;
    129 } sffs_stat_t;
     130
     131/*
     132 * Symbolic link operations
     133 */
     134extern int sfprov_set_show_symlinks(void);
     135extern int sfprov_readlink(sfp_mount_t *, char *path, char *target,
     136    size_t tgt_size);
     137extern int sfprov_symlink(sfp_mount_t *, char *linkname, char *target,
     138    sffs_stat_t *stat);
     139
    130140
    131141/*
  • trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_vfs.c

    r39249 r39270  
    187187        sfprov = sfprov_connect(SFPROV_VERSION);
    188188        if (sfprov == NULL) {
    189                 cmn_err(CE_WARN, "sffs_init(): couldn't init sffs provider");
     189                cmn_err(CE_WARN, "sffs_init: couldn't init sffs provider");
    190190                return (ENODEV);
     191        }
     192
     193        error = sfprov_set_show_symlinks();
     194        if (error != 0) {
     195                cmn_err(CE_WARN,  "sffs_init: host unable to show symlinks, "
     196                                                  "rc=%d\n", error);
    191197        }
    192198
  • trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c

    r39267 r39270  
    405405}
    406406
    407 static int
    408 sfnode_get_stat(sfp_mount_t *mnt, char *path, sffs_stat_t *stat)
    409 {
    410         return sfprov_get_attr(mnt, path, &stat->sf_mode, &stat->sf_size,
    411             &stat->sf_atime, &stat->sf_mtime, &stat->sf_ctime);
    412 }
    413 
    414407static void
    415408sfnode_invalidate_stat_cache(sfnode_t *node)
     
    423416        int error;
    424417
    425         error = sfnode_get_stat(node->sf_sffs->sf_handle, node->sf_path,
     418        error = sfprov_get_attr(node->sf_sffs->sf_handle, node->sf_path,
    426419            &node->sf_stat);
    427420        if (error == ENOENT)
     
    604597                if (stat == NULL) {
    605598                        stat = &tmp_stat;
    606                         error = sfnode_get_stat(dir->sf_sffs->sf_handle,
     599                        error = sfprov_get_attr(dir->sf_sffs->sf_handle,
    607600                            fullpath, stat);
    608601                        stat_time = sfnode_cur_time_usec();
     
    617610                else if (S_ISREG(m))
    618611                        type = VREG;
     612                else if (S_ISLNK(m))
     613                        type = VLNK;
    619614        }
    620615
     
    18911886/*ARGSUSED*/
    18921887static int
     1888sffs_readlink(
     1889        vnode_t         *vp,
     1890        uio_t           *uiop,
     1891        cred_t          *cred
     1892#if !defined(VBOX_VFS_SOLARIS_10U6)
     1893        ,
     1894        caller_context_t *ct
     1895#endif
     1896        )
     1897{
     1898        sfnode_t        *node;
     1899        int                     error = 0;
     1900        char            *target = NULL;
     1901
     1902        if (uiop->uio_iovcnt != 1)
     1903                return (EINVAL);
     1904
     1905        if (vp->v_type != VLNK)
     1906                return (EINVAL);
     1907
     1908        mutex_enter(&sffs_lock);
     1909        node = VN2SFN(vp);
     1910
     1911        target = kmem_alloc(MAXPATHLEN, KM_SLEEP);
     1912
     1913        error = sfprov_readlink(node->sf_sffs->sf_handle, node->sf_path, target,
     1914            MAXPATHLEN);
     1915        if (error)
     1916                goto done;
     1917
     1918        error = uiomove(target, strlen(target), UIO_READ, uiop);
     1919
     1920done:
     1921        mutex_exit(&sffs_lock);
     1922        if (target)
     1923                kmem_free(target, MAXPATHLEN);
     1924        return (error);
     1925}
     1926
     1927
     1928/*ARGSUSED*/
     1929static int
     1930sffs_symlink(
     1931        vnode_t         *dvp,
     1932        char            *linkname,
     1933        vattr_t         *vap,
     1934        char            *target,
     1935        cred_t          *cred
     1936#if !defined(VBOX_VFS_SOLARIS_10U6)
     1937        ,
     1938        caller_context_t *ct,
     1939        int             flags
     1940#endif
     1941        )
     1942{
     1943        sfnode_t        *dir;
     1944        sfnode_t        *node;
     1945        sffs_stat_t  stat;
     1946        int                      error = 0;
     1947        char            *fullpath;
     1948
     1949        /*
     1950         * These should never happen
     1951         */
     1952        ASSERT(linkname != NULL);
     1953        ASSERT(strcmp(linkname, "") != 0);
     1954        ASSERT(strcmp(linkname, ".") != 0);
     1955        ASSERT(strcmp(linkname, "..") != 0);
     1956
     1957        /*
     1958         * Basic checks.
     1959         */
     1960        if (vap->va_type != VLNK)
     1961                return (EINVAL);
     1962
     1963        mutex_enter(&sffs_lock);
     1964
     1965        if (sfnode_lookup(VN2SFN(dvp), linkname, VNON, NULL, 0, NULL) != NULL) {
     1966                error = EEXIST;
     1967                goto done;
     1968        }
     1969
     1970        dir = VN2SFN(dvp);
     1971        error = sfnode_access(dir, VWRITE, cred);
     1972        if (error)
     1973                goto done;
     1974
     1975        /*
     1976         * Create symlink. Note that we ignore vap->va_mode because generally
     1977         * we can't change the attributes of the symlink itself.
     1978         */
     1979        fullpath = sfnode_construct_path(dir, linkname);
     1980        error = sfprov_symlink(dir->sf_sffs->sf_handle, fullpath, target,
     1981            &stat);
     1982        kmem_free(fullpath, strlen(fullpath) + 1);
     1983        if (error)
     1984                goto done;
     1985
     1986        node = sfnode_lookup(dir, linkname, VLNK, &stat, sfnode_cur_time_usec(),
     1987            NULL);
     1988
     1989        sfnode_invalidate_stat_cache(dir);
     1990        sfnode_clear_dir_list(dir);
     1991
     1992done:
     1993        mutex_exit(&sffs_lock);
     1994        return (error);
     1995}
     1996
     1997
     1998/*ARGSUSED*/
     1999static int
    18932000sffs_remove(
    18942001        vnode_t         *dvp,
     
    19402047        sfnode_invalidate_stat_cache(VN2SFN(dvp));
    19412048
    1942         error = sfprov_remove(node->sf_sffs->sf_handle, node->sf_path);
     2049        error = sfprov_remove(node->sf_sffs->sf_handle, node->sf_path,
     2050                node->sf_type == VLNK);
    19432051        if (error == ENOENT || error == 0)
    19442052                sfnode_make_stale(node);
     
    22292337        VOPNAME_READ,           sffs_read,
    22302338        VOPNAME_READDIR,        sffs_readdir,
     2339        VOPNAME_READLINK,       sffs_readlink,
    22312340        VOPNAME_REMOVE,         sffs_remove,
    22322341        VOPNAME_RENAME,         sffs_rename,
     
    22352344        VOPNAME_SETATTR,        sffs_setattr,
    22362345        VOPNAME_SPACE,          sffs_space,
     2346        VOPNAME_SYMLINK,        sffs_symlink,
    22372347        VOPNAME_WRITE,          sffs_write,
    22382348
     
    22602370        VOPNAME_READ,           { .vop_read = sffs_read },
    22612371        VOPNAME_READDIR,        { .vop_readdir = sffs_readdir },
     2372        VOPNAME_READLINK,       { .vop_readlink = sffs_readlink },
    22622373        VOPNAME_REMOVE,         { .vop_remove = sffs_remove },
    22632374        VOPNAME_RENAME,         { .vop_rename = sffs_rename },
     
    22662377        VOPNAME_SETATTR,        { .vop_setattr = sffs_setattr },
    22672378        VOPNAME_SPACE,          { .vop_space = sffs_space },
     2379        VOPNAME_SYMLINK,        { .vop_symlink = sffs_symlink },
    22682380        VOPNAME_WRITE,          { .vop_write = sffs_write },
    22692381
     
    23782490            node->sf_type == VDIR ? "VDIR" :
    23792491            node->sf_type == VNON ? "VNON" :
     2492                node->sf_type == VLNK ? "VLNK" :
    23802493            node->sf_type == VREG ? "VREG" : "other", node->sf_type));
    23812494        Log((" ino=%d", (uint_t)node->sf_ino));
Note: See TracChangeset for help on using the changeset viewer.

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