VirtualBox

Ignore:
Timestamp:
Jun 5, 2009 3:36:59 PM (16 years ago)
Author:
vboxsync
Message:

Linux shared folders: make chmod work on hosts which support file mode setting and follow the file mode when creating new files / directories

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

Legend:

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

    r20298 r20342  
    392392
    393393static int
    394 sf_create_aux (struct inode *parent, struct dentry *dentry, int dirop)
     394sf_create_aux (struct inode *parent, struct dentry *dentry, int mode, int dirop)
    395395{
    396396        int rc, err;
     
    410410
    411411        memset(&params, 0, sizeof(params));
     412        /* Ensure that the shared folders host service is using our fMode
     413         * paramter */
     414        params.Handle = SHFL_HANDLE_NIL;
    412415
    413416        params.CreateFlags = 0
     
    420423        params.Info.Attr.fMode = 0
    421424                | (dirop ? RTFS_TYPE_DIRECTORY : RTFS_TYPE_FILE)
    422                 | RTFS_UNIX_IRUSR
    423                 | RTFS_UNIX_IWUSR
    424                 | RTFS_UNIX_IXUSR
     425                | (mode & S_IRWXUGO)
    425426                ;
    426427
     
    487488{
    488489        TRACE ();
    489         return sf_create_aux (parent, dentry, 0);
     490        return sf_create_aux (parent, dentry, mode, 0);
    490491}
    491492
     
    494495{
    495496        TRACE ();
    496         return sf_create_aux (parent, dentry, 1);
     497        return sf_create_aux (parent, dentry, mode, 1);
    497498}
    498499
     
    607608        .revalidate = sf_inode_revalidate
    608609#else
    609         .getattr    = sf_getattr
     610        .getattr    = sf_getattr,
     611        .setattr    = sf_setattr
    610612#endif
    611613};
  • trunk/src/VBox/Additions/linux/sharedfolders/regops.c

    r20298 r20342  
    219219
    220220        memset(&params, 0, sizeof(params));
    221         /* params.Handle is now 0. We check this afterwards to find out if
     221        params.Handle = SHFL_HANDLE_NIL;
     222        /* We check the value of params.Handle afterwards to find out if
    222223         * the call succeeded or failed, as the API does not seem to cleanly
    223          * distinguish error and informational messages. */
     224         * distinguish error and informational messages.
     225         *
     226         * Furthermore, we must set params.Handle to SHFL_HANDLE_NIL to
     227         * make the shared folders host service use our fMode parameter */
    224228
    225229        if (file->f_flags & O_CREAT) {
     
    265269        }
    266270
     271        params.Info.Attr.fMode = inode->i_mode;
    267272        LogFunc(("sf_reg_open: calling vboxCallCreate, file %s, flags=%d, %#x\n",
    268273                 sf_i->path->String.utf8 , file->f_flags, params.CreateFlags));
     
    453458        .revalidate = sf_inode_revalidate
    454459#else
    455         .getattr    = sf_getattr
     460        .getattr    = sf_getattr,
     461        .setattr    = sf_setattr
    456462#endif
    457463};
  • trunk/src/VBox/Additions/linux/sharedfolders/utils.c

    r20298 r20342  
    6161        *time = t;
    6262}
    63 #else
     63
     64static void
     65sf_timespec_from_ftime (RTTIMESPEC *ts, time_t *time)
     66{
     67        int64_t t = 1000000000 * *time;
     68        RTTimeSpecSetNano (ts, t);
     69}
     70#else /* >= 2.6.0 */
    6471static void
    6572sf_ftime_from_timespec (struct timespec *tv, RTTIMESPEC *ts)
     
    7279        tv->tv_nsec = nsec;
    7380}
    74 #endif
     81
     82static void
     83sf_timespec_from_ftime (RTTIMESPEC *ts, struct timespec *tv)
     84{
     85        int64_t t = (int64_t)tv->tv_nsec + (int64_t)tv->tv_sec * 1000000000;
     86        RTTimeSpecSetNano (ts, t);
     87}
     88#endif /* >= 2.6.0 */
    7589
    7690/* set [inode] attributes based on [info], uid/gid based on [sf_g] */
     
    233247sf_dentry_revalidate (struct dentry *dentry, int flags)
    234248#else
    235         sf_dentry_revalidate (struct dentry *dentry, struct nameidata *nd)
     249sf_dentry_revalidate (struct dentry *dentry, struct nameidata *nd)
    236250#endif
    237251{
     
    260274
    261275        generic_fillattr (dentry->d_inode, kstat);
     276        printk("getattr %08x\n", kstat->mode);
    262277        return 0;
    263278}
    264 #endif
     279
     280int
     281sf_setattr (struct dentry *dentry, struct iattr *iattr)
     282{
     283        struct sf_glob_info *sf_g;
     284        struct sf_inode_info *sf_i;
     285        SHFLCREATEPARMS params;
     286        RTFSOBJINFO info;
     287        uint32_t cbBuffer;
     288        int rc, err;
     289
     290        TRACE ();
     291
     292        sf_g = GET_GLOB_INFO (dentry->d_inode->i_sb);
     293        sf_i = GET_INODE_INFO (dentry->d_inode);
     294        err  = 0;
     295
     296        memset(&params, 0, sizeof(params));
     297        memset(&info, 0, sizeof(info));
     298
     299        params.CreateFlags = SHFL_CF_ACT_OPEN_IF_EXISTS
     300                           | SHFL_CF_ACT_FAIL_IF_NEW;
     301
     302        rc = vboxCallCreate (&client_handle, &sf_g->map, sf_i->path, &params);
     303        if (VBOX_FAILURE (rc)) {
     304                LogFunc(("vboxCallCreate(%s) failed rc=%Rrc\n",
     305                        sf_i->path->String.utf8, rc));
     306                err = -RTErrConvertToErrno(rc);
     307                goto fail2;
     308        }
     309        if (params.Result != SHFL_FILE_EXISTS) {
     310                LogFunc(("file %s does not exist\n", sf_i->path->String.utf8));
     311                err = -ENOENT;
     312                goto fail1;
     313        }
     314
     315        cbBuffer = sizeof(info);
     316
     317#define mode_set(r) ((iattr->ia_mode & (S_##r)) ? RTFS_UNIX_##r : 0)
     318
     319        if (iattr->ia_valid & ATTR_MODE)
     320        {
     321            info.Attr.fMode  = mode_set (ISUID);
     322            info.Attr.fMode |= mode_set (ISGID);
     323            info.Attr.fMode |= mode_set (IRUSR);
     324            info.Attr.fMode |= mode_set (IWUSR);
     325            info.Attr.fMode |= mode_set (IXUSR);
     326            info.Attr.fMode |= mode_set (IRGRP);
     327            info.Attr.fMode |= mode_set (IWGRP);
     328            info.Attr.fMode |= mode_set (IXGRP);
     329            info.Attr.fMode |= mode_set (IROTH);
     330            info.Attr.fMode |= mode_set (IWOTH);
     331            info.Attr.fMode |= mode_set (IXOTH);
     332
     333            if (iattr->ia_mode & S_IFDIR)
     334                info.Attr.fMode |= RTFS_TYPE_DIRECTORY;
     335            else
     336                info.Attr.fMode |= RTFS_TYPE_FILE;
     337        }
     338
     339        if (iattr->ia_valid & ATTR_ATIME)
     340            sf_timespec_from_ftime (&info.AccessTime, &iattr->ia_atime);
     341        if (iattr->ia_valid & ATTR_MTIME)
     342            sf_timespec_from_ftime (&info.ModificationTime, &iattr->ia_mtime);
     343        /* ignore ctime (inode change time) as it can't be set from userland anyway */
     344
     345        rc = vboxCallFSInfo(&client_handle, &sf_g->map, params.Handle,
     346                            SHFL_INFO_SET | SHFL_INFO_FILE, &cbBuffer,
     347                            (PSHFLDIRINFO)&info);
     348        if (VBOX_FAILURE (rc)) {
     349                LogFunc(("vboxCallFSInfo(%s) failed rc=%Rrc\n",
     350                        sf_i->path->String.utf8, rc));
     351                err = -RTErrConvertToErrno(rc);
     352                goto fail1;
     353        }
     354       
     355        rc = vboxCallClose (&client_handle, &sf_g->map, params.Handle);
     356        if (VBOX_FAILURE (rc)) {
     357                LogFunc(("vboxCallClose(%s) failed rc=%Rrc\n",
     358                      sf_i->path->String.utf8, rc));
     359        }
     360
     361        return sf_inode_revalidate (dentry);
     362
     363fail1:
     364        rc = vboxCallClose (&client_handle, &sf_g->map, params.Handle);
     365        if (VBOX_FAILURE (rc)) {
     366                LogFunc(("vboxCallClose(%s) failed rc=%Rrc\n",
     367                      sf_i->path->String.utf8, rc));
     368        }
     369fail2:
     370        return err;
     371}
     372#endif /* >= 2.6.0 */
    265373
    266374static int
  • trunk/src/VBox/Additions/linux/sharedfolders/vfsmod.h

    r14345 r20342  
    8585extern int
    8686sf_getattr (struct vfsmount *mnt, struct dentry *dentry, struct kstat *kstat);
     87extern int
     88sf_setattr (struct dentry *dentry, struct iattr *iattr);
    8789#endif
    8890extern int
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