Пример #1
0
int sf_get_volume_info(struct super_block *sb, STRUCT_STATFS *stat)
{
    struct sf_glob_info *sf_g;
    SHFLVOLINFO SHFLVolumeInfo;
    uint32_t cbBuffer;
    int rc;

    sf_g = GET_GLOB_INFO(sb);
    cbBuffer = sizeof(SHFLVolumeInfo);
    rc = VbglR0SfFsInfo(&client_handle, &sf_g->map, 0, SHFL_INFO_GET | SHFL_INFO_VOLUME,
                        &cbBuffer, (PSHFLDIRINFO)&SHFLVolumeInfo);
    if (RT_FAILURE(rc))
        return -RTErrConvertToErrno(rc);

    stat->f_type        = NFS_SUPER_MAGIC; /* XXX vboxsf type? */
    stat->f_bsize       = SHFLVolumeInfo.ulBytesPerAllocationUnit;
    stat->f_blocks      = SHFLVolumeInfo.ullTotalAllocationBytes
                        / SHFLVolumeInfo.ulBytesPerAllocationUnit;
    stat->f_bfree       = SHFLVolumeInfo.ullAvailableAllocationBytes
                        / SHFLVolumeInfo.ulBytesPerAllocationUnit;
    stat->f_bavail      = SHFLVolumeInfo.ullAvailableAllocationBytes
                        / SHFLVolumeInfo.ulBytesPerAllocationUnit;
    stat->f_files       = 1000;
    stat->f_ffree       = 1000; /* don't return 0 here since the guest may think
                                 * that it is not possible to create any more files */
    stat->f_fsid.val[0] = 0;
    stat->f_fsid.val[1] = 0;
    stat->f_namelen     = 255;
    return 0;
}
Пример #2
0
int sf_setattr(struct dentry *dentry, struct iattr *iattr)
{
    struct sf_glob_info *sf_g;
    struct sf_inode_info *sf_i;
    SHFLCREATEPARMS params;
    SHFLFSOBJINFO info;
    uint32_t cbBuffer;
    int rc, err;

    TRACE();

    sf_g = GET_GLOB_INFO(dentry->d_inode->i_sb);
    sf_i = GET_INODE_INFO(dentry->d_inode);
    err  = 0;

    RT_ZERO(params);
    params.Handle = SHFL_HANDLE_NIL;
    params.CreateFlags = SHFL_CF_ACT_OPEN_IF_EXISTS
                       | SHFL_CF_ACT_FAIL_IF_NEW
                       | SHFL_CF_ACCESS_ATTR_WRITE;

    /* this is at least required for Posix hosts */
    if (iattr->ia_valid & ATTR_SIZE)
        params.CreateFlags |= SHFL_CF_ACCESS_WRITE;

    rc = VbglR0SfCreate(&client_handle, &sf_g->map, sf_i->path, &params);
    if (RT_FAILURE(rc))
    {
        LogFunc(("VbglR0SfCreate(%s) failed rc=%Rrc\n",
                 sf_i->path->String.utf8, rc));
        err = -RTErrConvertToErrno(rc);
        goto fail2;
    }
    if (params.Result != SHFL_FILE_EXISTS)
    {
        LogFunc(("file %s does not exist\n", sf_i->path->String.utf8));
        err = -ENOENT;
        goto fail1;
    }

    /* Setting the file size and setting the other attributes has to be
     * handled separately, see implementation of vbsfSetFSInfo() in
     * vbsf.cpp */
    if (iattr->ia_valid & (ATTR_MODE | ATTR_ATIME | ATTR_MTIME))
    {
#define mode_set(r) ((iattr->ia_mode & (S_##r)) ? RTFS_UNIX_##r : 0)

        RT_ZERO(info);
        if (iattr->ia_valid & ATTR_MODE)
        {
            info.Attr.fMode  = mode_set(ISUID);
            info.Attr.fMode |= mode_set(ISGID);
            info.Attr.fMode |= mode_set(IRUSR);
            info.Attr.fMode |= mode_set(IWUSR);
            info.Attr.fMode |= mode_set(IXUSR);
            info.Attr.fMode |= mode_set(IRGRP);
            info.Attr.fMode |= mode_set(IWGRP);
            info.Attr.fMode |= mode_set(IXGRP);
            info.Attr.fMode |= mode_set(IROTH);
            info.Attr.fMode |= mode_set(IWOTH);
            info.Attr.fMode |= mode_set(IXOTH);

            if (iattr->ia_mode & S_IFDIR)
                info.Attr.fMode |= RTFS_TYPE_DIRECTORY;
            else
                info.Attr.fMode |= RTFS_TYPE_FILE;
        }

        if (iattr->ia_valid & ATTR_ATIME)
            sf_timespec_from_ftime(&info.AccessTime, &iattr->ia_atime);
        if (iattr->ia_valid & ATTR_MTIME)
            sf_timespec_from_ftime(&info.ModificationTime, &iattr->ia_mtime);
        /* ignore ctime (inode change time) as it can't be set from userland anyway */

        cbBuffer = sizeof(info);
        rc = VbglR0SfFsInfo(&client_handle, &sf_g->map, params.Handle,
                            SHFL_INFO_SET | SHFL_INFO_FILE, &cbBuffer,
                            (PSHFLDIRINFO)&info);
        if (RT_FAILURE(rc))
        {
            LogFunc(("VbglR0SfFsInfo(%s, FILE) failed rc=%Rrc\n",
                        sf_i->path->String.utf8, rc));
            err = -RTErrConvertToErrno(rc);
            goto fail1;
        }
    }

    if (iattr->ia_valid & ATTR_SIZE)
    {
        RT_ZERO(info);
        info.cbObject = iattr->ia_size;
        cbBuffer = sizeof(info);
        rc = VbglR0SfFsInfo(&client_handle, &sf_g->map, params.Handle,
                            SHFL_INFO_SET | SHFL_INFO_SIZE, &cbBuffer,
                            (PSHFLDIRINFO)&info);
        if (RT_FAILURE(rc))
        {
            LogFunc(("VbglR0SfFsInfo(%s, SIZE) failed rc=%Rrc\n",
                        sf_i->path->String.utf8, rc));
            err = -RTErrConvertToErrno(rc);
            goto fail1;
        }
    }

    rc = VbglR0SfClose(&client_handle, &sf_g->map, params.Handle);
    if (RT_FAILURE(rc))
        LogFunc(("VbglR0SfClose(%s) failed rc=%Rrc\n", sf_i->path->String.utf8, rc));

    return sf_inode_revalidate(dentry);

fail1:
    rc = VbglR0SfClose(&client_handle, &sf_g->map, params.Handle);
    if (RT_FAILURE(rc))
        LogFunc(("VbglR0SfClose(%s) failed rc=%Rrc\n", sf_i->path->String.utf8, rc));

fail2:
    return err;
}
Пример #3
0
/**
 * VBoxVFS get VFS layer object attribute callback.
 *
 * @param mp        Mount data provided by VFS layer.
 * @param pAttr     Output buffer to return attributes.
 * @param pContext  kAuth context needed in order to authentificate mount operation.
 *
 * @returns     0 for success, else an error code.
 */
static int
vboxvfs_getattr(struct mount *mp, struct vfs_attr *pAttr, vfs_context_t pContext)
{
    NOREF(pContext);

    vboxvfs_mount_t     *pMount;
    SHFLVOLINFO          SHFLVolumeInfo;

    int      rc;
    uint32_t cbBuffer = sizeof(SHFLVolumeInfo);

    uint32_t u32bsize;
    uint64_t u64blocks;
    uint64_t u64bfree;

    PDEBUG("Getting attribute...\n");

    AssertReturn(mp, EINVAL);

    pMount = (vboxvfs_mount_t *)vfs_fsprivate(mp);
    AssertReturn(pMount, EINVAL);
    AssertReturn(pMount->pShareName, EINVAL);

    rc = VbglR0SfFsInfo(&g_vboxSFClient, &pMount->pMap, 0, SHFL_INFO_GET | SHFL_INFO_VOLUME,
                        &cbBuffer, (PSHFLDIRINFO)&SHFLVolumeInfo);
    AssertReturn(rc == 0, EPROTO);

    u32bsize  = (uint32_t)SHFLVolumeInfo.ulBytesPerAllocationUnit;
    AssertReturn(u32bsize > 0, ENOTSUP);

    u64blocks = (uint64_t)SHFLVolumeInfo.ullTotalAllocationBytes / (uint64_t)u32bsize;
    u64bfree  = (uint64_t)SHFLVolumeInfo.ullAvailableAllocationBytes / (uint64_t)u32bsize;

    VFSATTR_RETURN(pAttr, f_bsize,  u32bsize);
    VFSATTR_RETURN(pAttr, f_blocks, u64blocks);
    VFSATTR_RETURN(pAttr, f_bfree,  u64bfree);
    VFSATTR_RETURN(pAttr, f_bavail, u64bfree);
    VFSATTR_RETURN(pAttr, f_bused,  u64blocks - u64bfree);

    VFSATTR_RETURN(pAttr, f_owner,  pMount->owner);

    VFSATTR_CLEAR_ACTIVE(pAttr, f_iosize);
    VFSATTR_CLEAR_ACTIVE(pAttr, f_files);
    VFSATTR_CLEAR_ACTIVE(pAttr, f_ffree);
    VFSATTR_CLEAR_ACTIVE(pAttr, f_fssubtype);

    /* todo: take care about f_capabilities and f_attributes, f_fsid */
    VFSATTR_CLEAR_ACTIVE(pAttr, f_capabilities);
    VFSATTR_CLEAR_ACTIVE(pAttr, f_attributes);
    VFSATTR_CLEAR_ACTIVE(pAttr, f_fsid);

    /* todo: take care about f_create_time, f_modify_time, f_access_time, f_backup_time */
    VFSATTR_CLEAR_ACTIVE(pAttr, f_create_time);
    VFSATTR_CLEAR_ACTIVE(pAttr, f_modify_time);
    VFSATTR_CLEAR_ACTIVE(pAttr, f_access_time);
    VFSATTR_CLEAR_ACTIVE(pAttr, f_backup_time);

    VFSATTR_CLEAR_ACTIVE(pAttr, f_signature);
    VFSATTR_CLEAR_ACTIVE(pAttr, f_carbon_fsid);
    VFSATTR_CLEAR_ACTIVE(pAttr, f_uuid);

    if (VFSATTR_IS_ACTIVE(pAttr, f_vol_name))
    {
        strlcpy(pAttr->f_vol_name, (char*)pMount->pShareName->String.utf8, MAXPATHLEN);
        VFSATTR_SET_SUPPORTED(pAttr, f_vol_name);
    }

    VFSATTR_ALL_SUPPORTED(pAttr);

    return 0;
}