VirtualBox

Ticket #6512: vbox.sf.sol.setattr.patch

File vbox.sf.sol.setattr.patch, 7.9 KB (added by foobar42, 14 years ago)

Added support for setting file attributes (times and mode) and file-length.

  • src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.c

    diff a/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.c b/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.c
    a b sfprov_get_ctime(sfp_mount_t *mnt, char *path, timestruc_t *time)  
    519519        return (0);
    520520}
    521521
     522static void
     523sfprov_timespec_from_ftime(RTTIMESPEC *ts, timestruc_t time)
     524{
     525        uint64_t nanosec = 1000000000 * time.tv_sec + time.tv_nsec;
     526        RTTimeSpecSetNano(ts, nanosec);
     527}
     528
     529int
     530sfprov_set_attr(
     531        sfp_mount_t *mnt,
     532        char *path,
     533        uint_t mask,
     534        mode_t mode,
     535        timestruc_t atime,
     536        timestruc_t mtime,
     537        timestruc_t ctime)
     538{
     539        int rc, err;
     540        SHFLCREATEPARMS parms;
     541        SHFLSTRING *str;
     542        RTFSOBJINFO info;
     543        uint32_t bytes;
     544        int str_size;
     545
     546        str = sfprov_string(path, &str_size);
     547        parms.Handle = 0;
     548        parms.Info.cbObject = 0;
     549        parms.CreateFlags = SHFL_CF_ACT_OPEN_IF_EXISTS
     550                          | SHFL_CF_ACT_FAIL_IF_NEW
     551                          | SHFL_CF_ACCESS_ATTR_WRITE;
     552
     553        rc = vboxCallCreate(&vbox_client, &mnt->map, str, &parms);
     554
     555        if (RT_FAILURE(rc)) {
     556                cmn_err(CE_WARN, "sfprov_set_attr: vboxCallCreate(%s) failed rc=%d",
     557                        path, rc);
     558                err = EINVAL;
     559                goto fail2;
     560        }
     561        if (parms.Result != SHFL_FILE_EXISTS) {
     562                err = ENOENT;
     563                goto fail1;
     564        }
     565
     566        RT_ZERO(info);
     567        if (mask & AT_MODE)
     568        {
     569#define mode_set(r) ((mode & (S_##r)) ? RTFS_UNIX_##r : 0)
     570
     571                info.Attr.fMode  = mode_set (ISUID);
     572                info.Attr.fMode |= mode_set (ISGID);
     573                info.Attr.fMode |= (mode & S_ISVTX) ? RTFS_UNIX_ISTXT : 0;
     574                info.Attr.fMode |= mode_set (IRUSR);
     575                info.Attr.fMode |= mode_set (IWUSR);
     576                info.Attr.fMode |= mode_set (IXUSR);
     577                info.Attr.fMode |= mode_set (IRGRP);
     578                info.Attr.fMode |= mode_set (IWGRP);
     579                info.Attr.fMode |= mode_set (IXGRP);
     580                info.Attr.fMode |= mode_set (IROTH);
     581                info.Attr.fMode |= mode_set (IWOTH);
     582                info.Attr.fMode |= mode_set (IXOTH);
     583
     584                if (S_ISDIR(mode))
     585                        info.Attr.fMode |= RTFS_TYPE_DIRECTORY;
     586                else if (S_ISREG(mode))
     587                        info.Attr.fMode |= RTFS_TYPE_FILE;
     588                else if (S_ISFIFO(mode))
     589                        info.Attr.fMode |= RTFS_TYPE_FIFO;
     590                else if (S_ISCHR(mode))
     591                        info.Attr.fMode |= RTFS_TYPE_DEV_CHAR;
     592                else if (S_ISBLK(mode))
     593                        info.Attr.fMode |= RTFS_TYPE_DEV_BLOCK;
     594                else if (S_ISLNK(mode))
     595                        info.Attr.fMode |= RTFS_TYPE_SYMLINK;
     596                else if (S_ISSOCK(mode))
     597                        info.Attr.fMode |= RTFS_TYPE_SOCKET;
     598                else
     599                        info.Attr.fMode |= RTFS_TYPE_FILE;
     600        }
     601
     602        if (mask & AT_ATIME)
     603                sfprov_timespec_from_ftime(&info.AccessTime, atime);
     604        if (mask & AT_MTIME)
     605                sfprov_timespec_from_ftime(&info.ModificationTime, mtime);
     606        if (mask & AT_CTIME)
     607                sfprov_timespec_from_ftime(&info.ChangeTime, ctime);
     608
     609        bytes = sizeof(info);
     610        rc = vboxCallFSInfo(&vbox_client, &mnt->map, parms.Handle,
     611                            (SHFL_INFO_SET | SHFL_INFO_FILE), &bytes,
     612                            (SHFLDIRINFO *)&info);
     613        if (RT_FAILURE (rc)) {
     614                cmn_err(CE_WARN, "sfprov_set_attr: vboxCallFSInfo(%s, FILE) failed rc=%d",
     615                        path, rc);
     616                err = RTErrConvertToErrno(rc);
     617                goto fail1;
     618        }
     619
     620        err = 0;
     621
     622fail1:
     623        rc = vboxCallClose(&vbox_client, &mnt->map, parms.Handle);
     624        if (RT_FAILURE (rc))
     625        {
     626                cmn_err(CE_WARN, "sfprov_set_attr: vboxCallClose(%s) failed rc=%d",
     627                        path, rc);
     628        }
     629fail2:
     630        kmem_free(str, str_size);
     631        return err;
     632}
     633
     634int
     635sfprov_set_size(sfp_mount_t *mnt, char *path, uint64_t size)
     636{
     637        int rc, err;
     638        SHFLCREATEPARMS parms;
     639        SHFLSTRING *str;
     640        RTFSOBJINFO info;
     641        uint32_t bytes;
     642        int str_size;
     643
     644        str = sfprov_string(path, &str_size);
     645        parms.Handle = 0;
     646        parms.Info.cbObject = 0;
     647        parms.CreateFlags = SHFL_CF_ACT_OPEN_IF_EXISTS
     648                          | SHFL_CF_ACT_FAIL_IF_NEW
     649                          | SHFL_CF_ACCESS_WRITE;
     650
     651        rc = vboxCallCreate(&vbox_client, &mnt->map, str, &parms);
     652
     653        if (RT_FAILURE(rc)) {
     654                cmn_err(CE_WARN, "sfprov_set_size: vboxCallCreate(%s) failed rc=%d",
     655                        path, rc);
     656                err = EINVAL;
     657                goto fail2;
     658        }
     659        if (parms.Result != SHFL_FILE_EXISTS) {
     660                err = ENOENT;
     661                goto fail1;
     662        }
     663
     664        RT_ZERO(info);
     665        info.cbObject = size;
     666        bytes = sizeof(info);
     667        rc = vboxCallFSInfo(&vbox_client, &mnt->map, parms.Handle,
     668                            (SHFL_INFO_SET | SHFL_INFO_SIZE), &bytes,
     669                            (SHFLDIRINFO *)&info);
     670        if (RT_FAILURE (rc)) {
     671                cmn_err(CE_WARN, "sfprov_set_size: vboxCallFSInfo(%s, SIZE) failed rc=%d",
     672                        path, rc);
     673                err = RTErrConvertToErrno(rc);
     674                goto fail1;
     675        }
     676
     677        err = 0;
     678
     679fail1:
     680        rc = vboxCallClose(&vbox_client, &mnt->map, parms.Handle);
     681        if (RT_FAILURE (rc))
     682        {
     683                cmn_err(CE_WARN, "sfprov_set_size: vboxCallClose(%s) failed rc=%d",
     684                        path, rc);
     685        }
     686fail2:
     687        kmem_free(str, str_size);
     688        return err;
     689}
     690
    522691/*
    523692 * Directory operations
    524693 */
  • src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.h

    diff a/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.h b/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.h
    a b extern int sfprov_write(sfp_file_t *, char * buffer, uint64_t offset,  
    8585
    8686
    8787/*
    88  * get information about a file (or directory) using pathname
     88 * get/set information about a file (or directory) using pathname
    8989 */
    9090extern int sfprov_get_mode(sfp_mount_t *, char *, mode_t *);
    9191extern int sfprov_get_size(sfp_mount_t *, char *, uint64_t *);
    9292extern int sfprov_get_atime(sfp_mount_t *, char *, timestruc_t *);
    9393extern int sfprov_get_mtime(sfp_mount_t *, char *, timestruc_t *);
    9494extern int sfprov_get_ctime(sfp_mount_t *, char *, timestruc_t *);
     95extern int sfprov_set_attr(sfp_mount_t *, char *, uint_t, mode_t,
     96                           timestruc_t, timestruc_t, timestruc_t);
     97extern int sfprov_set_size(sfp_mount_t *, char *, uint64_t);
    9598
    9699
    97100/*
  • src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c

    diff a/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c b/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c
    a b  
    5858
    5959#include <VBox/log.h>
    6060
     61#include <unistd.h>
    6162#include <sys/types.h>
    6263#include <sys/stat.h>
    6364#include <sys/mntent.h>
    done:  
    779780        return (error);
    780781}
    781782
     783static int
     784sffs_setattr(
     785        vnode_t         *vp,
     786        vattr_t         *vap,
     787        int             flags,
     788        cred_t          *cred,
     789        caller_context_t *ct)
     790{
     791        sfnode_t        *node = VN2SFN(vp);
     792        int             error;
     793        mode_t          mode;
     794
     795        mode = vap->va_mode;
     796        if (vp->v_type == VREG)
     797                mode |= S_IFREG;
     798        else if (vp->v_type == VDIR)
     799                mode |= S_IFDIR;
     800        else if (vp->v_type == VBLK)
     801                mode |= S_IFBLK;
     802        else if (vp->v_type == VCHR)
     803                mode |= S_IFCHR;
     804        else if (vp->v_type == VLNK)
     805                mode |= S_IFLNK;
     806        else if (vp->v_type == VFIFO)
     807                mode |= S_IFIFO;
     808        else if (vp->v_type == VSOCK)
     809                mode |= S_IFSOCK;
     810
     811        mutex_enter(&sffs_lock);
     812
     813        error = sfprov_set_attr(node->sf_sffs->sf_handle, node->sf_path,
     814                                vap->va_mask, mode,
     815                                vap->va_atime, vap->va_mtime, vap->va_ctime);
     816        if (error == ENOENT)
     817                sfnode_make_stale(node);
     818
     819done:
     820        mutex_exit(&sffs_lock);
     821        return (error);
     822}
     823
     824static int
     825sffs_space(
     826        vnode_t         *vp,
     827        int             cmd,
     828        struct flock64  *bfp,
     829        int             flags,
     830        offset_t        off,
     831        cred_t          *cred,
     832        caller_context_t *ct)
     833{
     834        sfnode_t        *node = VN2SFN(vp);
     835        int             error;
     836
     837        /* we only support changing the length of the file */
     838        if (bfp->l_whence != SEEK_SET || bfp->l_len != 0)
     839            return ENOSYS;
     840
     841        mutex_enter(&sffs_lock);
     842
     843        error = sfprov_set_size(node->sf_sffs->sf_handle, node->sf_path,
     844                                bfp->l_start);
     845        if (error == ENOENT)
     846                sfnode_make_stale(node);
     847
     848done:
     849        mutex_exit(&sffs_lock);
     850        return (error);
     851}
     852
    782853/*ARGSUSED*/
    783854static int
    784855sffs_read(
    const fs_operation_def_t sffs_ops_template[] = {  
    15111582        VOPNAME_RENAME,         sffs_rename,
    15121583        VOPNAME_RMDIR,          sffs_rmdir,
    15131584        VOPNAME_SEEK,           sffs_seek,
     1585        VOPNAME_SETATTR,        sffs_setattr,
     1586        VOPNAME_SPACE,          sffs_space,
    15141587        VOPNAME_WRITE,          sffs_write,
    15151588        NULL,                   NULL
    15161589#else
    const fs_operation_def_t sffs_ops_template[] = {  
    15311604        VOPNAME_RENAME,         { .vop_rename = sffs_rename },
    15321605        VOPNAME_RMDIR,          { .vop_rmdir = sffs_rmdir },
    15331606        VOPNAME_SEEK,           { .vop_seek = sffs_seek },
     1607        VOPNAME_SETATTR,        { .vop_setattr = sffs_setattr },
     1608        VOPNAME_SPACE,          { .vop_space = sffs_space },
    15341609        VOPNAME_WRITE,          { .vop_write = sffs_write },
    15351610        NULL,                   NULL
    15361611#endif

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