VirtualBox

source: vbox/trunk/src/VBox/Storage/VDIfVfs.cpp@ 47665

Last change on this file since 47665 was 47665, checked in by vboxsync, 11 years ago

Seems vdIfIoFileReadSync/vdIfIoFileWriteSync want real actual offsets.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.7 KB
Line 
1/* $Id: VDIfVfs.cpp 47665 2013-08-12 10:11:42Z vboxsync $ */
2/** @file
3 * Virtual Disk Image (VDI), I/O interface to IPRT VFS I/O stream glue.
4 */
5
6/*
7 * Copyright (C) 2012-2013 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#include <iprt/types.h>
23#include <iprt/assert.h>
24#include <iprt/mem.h>
25#include <iprt/err.h>
26#include <iprt/asm.h>
27#include <iprt/string.h>
28#include <iprt/file.h>
29#include <iprt/sg.h>
30#include <iprt/vfslowlevel.h>
31#include <iprt/poll.h>
32#include <VBox/vd.h>
33
34/*******************************************************************************
35* Structures and Typedefs *
36*******************************************************************************/
37
38/**
39 * The internal data of a DVM volume I/O stream.
40 */
41typedef struct VDIFVFSIOS
42{
43 /** The VD I/O interface we wrap. */
44 PVDINTERFACEIO pVDIfsIo;
45 /** User pointer to pass to the VD I/O interface methods. */
46 void *pvStorage;
47 /** The current stream position relative to the VDIfCreateVfsStream call. */
48 uint64_t offCurPos;
49} VDIFVFSIOS;
50/** Pointer to a the internal data of a DVM volume file. */
51typedef VDIFVFSIOS *PVDIFVFSIOS;
52
53
54
55/**
56 * @interface_method_impl{RTVFSOBJOPS,pfnClose}
57 */
58static DECLCALLBACK(int) vdIfVfsIos_Close(void *pvThis)
59{
60 /* We don't close anything. */
61 return VINF_SUCCESS;
62}
63
64
65/**
66 * @interface_method_impl{RTVFSOBJOPS,pfnQueryInfo}
67 */
68static DECLCALLBACK(int) vdIfVfsIos_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
69{
70 NOREF(pvThis);
71 NOREF(pObjInfo);
72 NOREF(enmAddAttr);
73 return VERR_NOT_SUPPORTED;
74}
75
76
77/**
78 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnRead}
79 */
80static DECLCALLBACK(int) vdIfVfsIos_Read(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead)
81{
82 PVDIFVFSIOS pThis = (PVDIFVFSIOS)pvThis;
83 Assert(pSgBuf->cSegs == 1); NOREF(fBlocking);
84
85 /*
86 * This may end up being a little more complicated, esp. wrt VERR_EOF.
87 */
88 if (off == -1)
89 off = pThis->offCurPos;
90 int rc = vdIfIoFileReadSync(pThis->pVDIfsIo, pThis->pvStorage, off, pSgBuf[0].pvSegCur, pSgBuf->paSegs[0].cbSeg, pcbRead);
91 if (RT_SUCCESS(rc))
92 pThis->offCurPos = off + (pcbRead ? *pcbRead : pSgBuf->paSegs[0].cbSeg);
93 return rc;
94}
95
96
97/**
98 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnWrite}
99 */
100static DECLCALLBACK(int) vdIfVfsIos_Write(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten)
101{
102 PVDIFVFSIOS pThis = (PVDIFVFSIOS)pvThis;
103 Assert(pSgBuf->cSegs == 1); NOREF(fBlocking);
104
105 /*
106 * This may end up being a little more complicated, esp. wrt VERR_EOF.
107 */
108 if (off == -1)
109 off = pThis->offCurPos;
110 int rc = vdIfIoFileWriteSync(pThis->pVDIfsIo, pThis->pvStorage, off, pSgBuf[0].pvSegCur, pSgBuf->paSegs[0].cbSeg, pcbWritten);
111 if (RT_SUCCESS(rc))
112 pThis->offCurPos = off + (pcbWritten ? *pcbWritten : pSgBuf->paSegs[0].cbSeg);
113 return rc;
114}
115
116
117/**
118 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnFlush}
119 */
120static DECLCALLBACK(int) vdIfVfsIos_Flush(void *pvThis)
121{
122 PVDIFVFSIOS pThis = (PVDIFVFSIOS)pvThis;
123 return vdIfIoFileFlushSync(pThis->pVDIfsIo, pThis->pvStorage);
124}
125
126
127/**
128 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnPollOne}
129 */
130static DECLCALLBACK(int) vdIfVfsIos_PollOne(void *pvThis, uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr,
131 uint32_t *pfRetEvents)
132{
133 NOREF(pvThis);
134 int rc;
135 if (fEvents != RTPOLL_EVT_ERROR)
136 {
137 *pfRetEvents = fEvents & ~RTPOLL_EVT_ERROR;
138 rc = VINF_SUCCESS;
139 }
140 else
141 rc = RTVfsUtilDummyPollOne(fEvents, cMillies, fIntr, pfRetEvents);
142 return rc;
143}
144
145
146/**
147 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnTell}
148 */
149static DECLCALLBACK(int) vdIfVfsIos_Tell(void *pvThis, PRTFOFF poffActual)
150{
151 PVDIFVFSIOS pThis = (PVDIFVFSIOS)pvThis;
152 *poffActual = pThis->offCurPos;
153 return VINF_SUCCESS;
154}
155
156
157
158
159/**
160 * Standard file operations.
161 */
162DECL_HIDDEN_CONST(const RTVFSIOSTREAMOPS) g_vdIfVfsStdIosOps =
163{
164 { /* Obj */
165 RTVFSOBJOPS_VERSION,
166 RTVFSOBJTYPE_FILE,
167 "VDIfIos",
168 vdIfVfsIos_Close,
169 vdIfVfsIos_QueryInfo,
170 RTVFSOBJOPS_VERSION
171 },
172 RTVFSIOSTREAMOPS_VERSION,
173 RTVFSIOSTREAMOPS_FEAT_NO_SG,
174 vdIfVfsIos_Read,
175 vdIfVfsIos_Write,
176 vdIfVfsIos_Flush,
177 vdIfVfsIos_PollOne,
178 vdIfVfsIos_Tell,
179 NULL /*Skip*/,
180 NULL /*ZeroFill*/,
181 RTVFSIOSTREAMOPS_VERSION,
182};
183
184
185VBOXDDU_DECL(int) VDIfCreateVfsStream(PVDINTERFACEIO pVDIfsIo, void *pvStorage, uint32_t fFlags, PRTVFSIOSTREAM phVfsIos)
186{
187 AssertPtrReturn(pVDIfsIo, VERR_INVALID_HANDLE);
188 AssertPtrReturn(phVfsIos, VERR_INVALID_POINTER);
189
190 /*
191 * Create the volume file.
192 */
193 RTVFSIOSTREAM hVfsIos;
194 PVDIFVFSIOS pThis;
195 int rc = RTVfsNewIoStream(&g_vdIfVfsStdIosOps, sizeof(*pThis), fFlags,
196 NIL_RTVFS, NIL_RTVFSLOCK, &hVfsIos, (void **)&pThis);
197 if (RT_SUCCESS(rc))
198 {
199 pThis->pVDIfsIo = pVDIfsIo;
200 pThis->pvStorage = pvStorage;
201 pThis->offCurPos = 0;
202
203 *phVfsIos = hVfsIos;
204 return VINF_SUCCESS;
205 }
206
207 return rc;
208}
209
Note: See TracBrowser for help on using the repository browser.

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