VirtualBox

source: vbox/trunk/include/VBox/vd-ifs-internal.h@ 44233

Last change on this file since 44233 was 44233, checked in by vboxsync, 12 years ago

Storage: Preparations for the sync/async I/O unification

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.3 KB
Line 
1/** @file
2 * VD Container API - internal interfaces.
3 */
4
5/*
6 * Copyright (C) 2011 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef ___VBox_VD_Interfaces_Internal_h
27#define ___VBox_VD_Interfaces_Internal_h
28
29#include <iprt/sg.h>
30#include <VBox/vd-ifs.h>
31
32RT_C_DECLS_BEGIN
33
34/**
35 * Interface to get the parent state.
36 *
37 * Per-operation interface. Optional, present only if there is a parent, and
38 * used only internally for compacting.
39 */
40typedef struct VDINTERFACEPARENTSTATE
41{
42 /**
43 * Common interface header.
44 */
45 VDINTERFACE Core;
46
47 /**
48 * Read data callback.
49 *
50 * @return VBox status code.
51 * @return VERR_VD_NOT_OPENED if no image is opened in HDD container.
52 * @param pvUser The opaque data passed for the operation.
53 * @param uOffset Offset of first reading byte from start of disk.
54 * Must be aligned to a sector boundary.
55 * @param pvBuffer Pointer to buffer for reading data.
56 * @param cbBuffer Number of bytes to read.
57 * Must be aligned to a sector boundary.
58 */
59 DECLR3CALLBACKMEMBER(int, pfnParentRead, (void *pvUser, uint64_t uOffset, void *pvBuffer, size_t cbBuffer));
60
61} VDINTERFACEPARENTSTATE, *PVDINTERFACEPARENTSTATE;
62
63
64/**
65 * Get parent state interface from interface list.
66 *
67 * @return Pointer to the first parent state interface in the list.
68 * @param pVDIfs Pointer to the interface list.
69 */
70DECLINLINE(PVDINTERFACEPARENTSTATE) VDIfParentStateGet(PVDINTERFACE pVDIfs)
71{
72 PVDINTERFACE pIf = VDInterfaceGet(pVDIfs, VDINTERFACETYPE_PARENTSTATE);
73
74 /* Check that the interface descriptor is a progress interface. */
75 AssertMsgReturn( !pIf
76 || ( (pIf->enmInterface == VDINTERFACETYPE_PARENTSTATE)
77 && (pIf->cbSize == sizeof(VDINTERFACEPARENTSTATE))),
78 ("Not a parent state interface"), NULL);
79
80 return (PVDINTERFACEPARENTSTATE)pIf;
81}
82
83/** Forward declaration. Only visible in the VBoxHDD module. */
84/** I/O context */
85typedef struct VDIOCTX *PVDIOCTX;
86/** Storage backend handle. */
87typedef struct VDIOSTORAGE *PVDIOSTORAGE;
88/** Pointer to a storage backend handle. */
89typedef PVDIOSTORAGE *PPVDIOSTORAGE;
90
91/**
92 * Completion callback for meta/userdata reads or writes.
93 *
94 * @return VBox status code.
95 * VINF_SUCCESS if everything was successful and the transfer can continue.
96 * VERR_VD_ASYNC_IO_IN_PROGRESS if there is another data transfer pending.
97 * @param pBackendData The opaque backend data.
98 * @param pIoCtx I/O context associated with this request.
99 * @param pvUser Opaque user data passed during a read/write request.
100 * @param rcReq Status code for the completed request.
101 */
102typedef DECLCALLBACK(int) FNVDXFERCOMPLETED(void *pBackendData, PVDIOCTX pIoCtx, void *pvUser, int rcReq);
103/** Pointer to FNVDXFERCOMPLETED() */
104typedef FNVDXFERCOMPLETED *PFNVDXFERCOMPLETED;
105
106/** Metadata transfer handle. */
107typedef struct VDMETAXFER *PVDMETAXFER;
108/** Pointer to a metadata transfer handle. */
109typedef PVDMETAXFER *PPVDMETAXFER;
110
111
112/**
113 * Internal I/O interface between the generic VD layer and the backends.
114 *
115 * Per-image. Always passed to backends.
116 */
117typedef struct VDINTERFACEIOINT
118{
119 /**
120 * Common interface header.
121 */
122 VDINTERFACE Core;
123
124 /**
125 * Open callback
126 *
127 * @return VBox status code.
128 * @param pvUser The opaque data passed on container creation.
129 * @param pszLocation Name of the location to open.
130 * @param fOpen Flags for opening the backend.
131 * See RTFILE_O_* #defines, inventing another set
132 * of open flags is not worth the mapping effort.
133 * @param ppStorage Where to store the storage handle.
134 */
135 DECLR3CALLBACKMEMBER(int, pfnOpen, (void *pvUser, const char *pszLocation,
136 uint32_t fOpen, PPVDIOSTORAGE ppStorage));
137
138 /**
139 * Close callback.
140 *
141 * @return VBox status code.
142 * @param pvUser The opaque data passed on container creation.
143 * @param pStorage The storage handle to close.
144 */
145 DECLR3CALLBACKMEMBER(int, pfnClose, (void *pvUser, PVDIOSTORAGE pStorage));
146
147 /**
148 * Delete callback.
149 *
150 * @return VBox status code.
151 * @param pvUser The opaque data passed on container creation.
152 * @param pcszFilename Name of the file to delete.
153 */
154 DECLR3CALLBACKMEMBER(int, pfnDelete, (void *pvUser, const char *pcszFilename));
155
156 /**
157 * Move callback.
158 *
159 * @return VBox status code.
160 * @param pvUser The opaque data passed on container creation.
161 * @param pcszSrc The path to the source file.
162 * @param pcszDst The path to the destination file.
163 * This file will be created.
164 * @param fMove A combination of the RTFILEMOVE_* flags.
165 */
166 DECLR3CALLBACKMEMBER(int, pfnMove, (void *pvUser, const char *pcszSrc, const char *pcszDst, unsigned fMove));
167
168 /**
169 * Returns the free space on a disk.
170 *
171 * @return VBox status code.
172 * @param pvUser The opaque data passed on container creation.
173 * @param pcszFilename Name of a file to identify the disk.
174 * @param pcbFreeSpace Where to store the free space of the disk.
175 */
176 DECLR3CALLBACKMEMBER(int, pfnGetFreeSpace, (void *pvUser, const char *pcszFilename, int64_t *pcbFreeSpace));
177
178 /**
179 * Returns the last modification timestamp of a file.
180 *
181 * @return VBox status code.
182 * @param pvUser The opaque data passed on container creation.
183 * @param pcszFilename Name of a file to identify the disk.
184 * @param pModificationTime Where to store the timestamp of the file.
185 */
186 DECLR3CALLBACKMEMBER(int, pfnGetModificationTime, (void *pvUser, const char *pcszFilename, PRTTIMESPEC pModificationTime));
187
188 /**
189 * Returns the size of the opened storage backend.
190 *
191 * @return VBox status code.
192 * @param pvUser The opaque data passed on container creation.
193 * @param pStorage The storage handle to get the size from.
194 * @param pcbSize Where to store the size of the storage backend.
195 */
196 DECLR3CALLBACKMEMBER(int, pfnGetSize, (void *pvUser, PVDIOSTORAGE pStorage,
197 uint64_t *pcbSize));
198
199 /**
200 * Sets the size of the opened storage backend if possible.
201 *
202 * @return VBox status code.
203 * @retval VERR_NOT_SUPPORTED if the backend does not support this operation.
204 * @param pvUser The opaque data passed on container creation.
205 * @param pStorage The storage handle.
206 * @param cbSize The new size of the image.
207 */
208 DECLR3CALLBACKMEMBER(int, pfnSetSize, (void *pvUser, PVDIOSTORAGE pStorage,
209 uint64_t cbSize));
210
211 /**
212 * Initiate a read request for user data.
213 *
214 * @return VBox status code.
215 * @param pvUser The opaque user data passed on container creation.
216 * @param pStorage The storage handle.
217 * @param uOffset The offset to start reading from.
218 * @param pIoCtx I/O context passed in the read/write callback.
219 * @param cbRead How many bytes to read.
220 */
221 DECLR3CALLBACKMEMBER(int, pfnReadUser, (void *pvUser, PVDIOSTORAGE pStorage,
222 uint64_t uOffset, PVDIOCTX pIoCtx,
223 size_t cbRead));
224
225 /**
226 * Initiate a write request for user data.
227 *
228 * @return VBox status code.
229 * @param pvUser The opaque user data passed on container creation.
230 * @param pStorage The storage handle.
231 * @param uOffset The offset to start writing to.
232 * @param pIoCtx I/O context passed in the read/write callback.
233 * @param cbWrite How many bytes to write.
234 * @param pfnCompleted Completion callback.
235 * @param pvCompleteUser Opaque user data passed in the completion callback.
236 */
237 DECLR3CALLBACKMEMBER(int, pfnWriteUser, (void *pvUser, PVDIOSTORAGE pStorage,
238 uint64_t uOffset, PVDIOCTX pIoCtx,
239 size_t cbWrite,
240 PFNVDXFERCOMPLETED pfnComplete,
241 void *pvCompleteUser));
242
243 /**
244 * Reads metadata from storage.
245 * The current I/O context will be halted.
246 *
247 * @returns VBox status code.
248 * @param pvUser The opaque user data passed on container creation.
249 * @param pStorage The storage handle.
250 * @param uOffset Offset to start reading from.
251 * @param pvBuffer Where to store the data.
252 * @param cbBuffer How many bytes to read.
253 * @param pIoCtx The I/O context which triggered the read.
254 * @param ppMetaXfer Where to store the metadata transfer handle on success.
255 * @param pfnCompleted Completion callback.
256 * @param pvCompleteUser Opaque user data passed in the completion callback.
257 *
258 * @notes If pIoCtx is NULL the metadata read is handled synchronously
259 * i.e. the call returns only if the data is available in the given
260 * buffer. ppMetaXfer, pfnCompleted and pvCompleteUser are ignored in that case.
261 * Use the synchronous version only when opening/closing the image
262 * or when doing certain operations like resizing, compacting or repairing
263 * the disk.
264 */
265 DECLR3CALLBACKMEMBER(int, pfnReadMeta, (void *pvUser, PVDIOSTORAGE pStorage,
266 uint64_t uOffset, void *pvBuffer,
267 size_t cbBuffer, PVDIOCTX pIoCtx,
268 PPVDMETAXFER ppMetaXfer,
269 PFNVDXFERCOMPLETED pfnComplete,
270 void *pvCompleteUser));
271
272 /**
273 * Writes metadata to storage.
274 *
275 * @returns VBox status code.
276 * @param pvUser The opaque user data passed on container creation.
277 * @param pStorage The storage handle.
278 * @param uOffset Offset to start writing to.
279 * @param pvBuffer Written data.
280 * @param cbBuffer How many bytes to write.
281 * @param pIoCtx The I/O context which triggered the write.
282 * @param pfnCompleted Completion callback.
283 * @param pvCompleteUser Opaque user data passed in the completion callback.
284 *
285 * @notes See pfnReadMeta().
286 */
287 DECLR3CALLBACKMEMBER(int, pfnWriteMeta, (void *pvUser, PVDIOSTORAGE pStorage,
288 uint64_t uOffset, const void *pvBuffer,
289 size_t cbBuffer, PVDIOCTX pIoCtx,
290 PFNVDXFERCOMPLETED pfnComplete,
291 void *pvCompleteUser));
292
293 /**
294 * Releases a metadata transfer handle.
295 * The free space can be used for another transfer.
296 *
297 * @returns nothing.
298 * @param pvUser The opaque user data passed on container creation.
299 * @param pMetaXfer The metadata transfer handle to release.
300 */
301 DECLR3CALLBACKMEMBER(void, pfnMetaXferRelease, (void *pvUser, PVDMETAXFER pMetaXfer));
302
303 /**
304 * Initiates a flush request.
305 *
306 * @return VBox status code.
307 * @param pvUser The opaque data passed on container creation.
308 * @param pStorage The storage handle to flush.
309 * @param pIoCtx I/O context which triggered the flush.
310 * @param pfnCompleted Completion callback.
311 * @param pvCompleteUser Opaque user data passed in the completion callback.
312 *
313 * @notes See pfnReadMeta().
314 */
315 DECLR3CALLBACKMEMBER(int, pfnFlush, (void *pvUser, PVDIOSTORAGE pStorage,
316 PVDIOCTX pIoCtx,
317 PFNVDXFERCOMPLETED pfnComplete,
318 void *pvCompleteUser));
319
320 /**
321 * Copies a buffer into the I/O context.
322 *
323 * @return Number of bytes copied.
324 * @param pvUser The opaque user data passed on container creation.
325 * @param pIoCtx I/O context to copy the data to.
326 * @param pvBuffer Buffer to copy.
327 * @param cbBuffer Number of bytes to copy.
328 */
329 DECLR3CALLBACKMEMBER(size_t, pfnIoCtxCopyTo, (void *pvUser, PVDIOCTX pIoCtx,
330 void *pvBuffer, size_t cbBuffer));
331
332 /**
333 * Copies data from the I/O context into a buffer.
334 *
335 * @return Number of bytes copied.
336 * @param pvUser The opaque user data passed on container creation.
337 * @param pIoCtx I/O context to copy the data from.
338 * @param pvBuffer Destination buffer.
339 * @param cbBuffer Number of bytes to copy.
340 */
341 DECLR3CALLBACKMEMBER(size_t, pfnIoCtxCopyFrom, (void *pvUser, PVDIOCTX pIoCtx,
342 void *pvBuffer, size_t cbBuffer));
343
344 /**
345 * Sets the buffer of the given context to a specific byte.
346 *
347 * @return Number of bytes set.
348 * @param pvUser The opaque user data passed on container creation.
349 * @param pIoCtx I/O context to copy the data from.
350 * @param ch The byte to set.
351 * @param cbSet Number of bytes to set.
352 */
353 DECLR3CALLBACKMEMBER(size_t, pfnIoCtxSet, (void *pvUser, PVDIOCTX pIoCtx,
354 int ch, size_t cbSet));
355
356 /**
357 * Creates a segment array from the I/O context data buffer.
358 *
359 * @returns Number of bytes the array describes.
360 * @param pvUser The opaque user data passed on container creation.
361 * @param pIoCtx I/O context to copy the data from.
362 * @param paSeg The uninitialized segment array.
363 * If NULL pcSeg will contain the number of segments needed
364 * to describe the requested amount of data.
365 * @param pcSeg The number of segments the given array has.
366 * This will hold the actual number of entries needed upon return.
367 * @param cbData Number of bytes the new array should describe.
368 */
369 DECLR3CALLBACKMEMBER(size_t, pfnIoCtxSegArrayCreate, (void *pvUser, PVDIOCTX pIoCtx,
370 PRTSGSEG paSeg, unsigned *pcSeg,
371 size_t cbData));
372 /**
373 * Marks the given number of bytes as completed and continues the I/O context.
374 *
375 * @returns nothing.
376 * @param pvUser The opaque user data passed on container creation.
377 * @param pIoCtx The I/O context.
378 * @param rcReq Status code the request completed with.
379 * @param cbCompleted Number of bytes completed.
380 */
381 DECLR3CALLBACKMEMBER(void, pfnIoCtxCompleted, (void *pvUser, PVDIOCTX pIoCtx,
382 int rcReq, size_t cbCompleted));
383} VDINTERFACEIOINT, *PVDINTERFACEIOINT;
384
385/**
386 * Get internal I/O interface from interface list.
387 *
388 * @return Pointer to the first internal I/O interface in the list.
389 * @param pVDIfs Pointer to the interface list.
390 */
391DECLINLINE(PVDINTERFACEIOINT) VDIfIoIntGet(PVDINTERFACE pVDIfs)
392{
393 PVDINTERFACE pIf = VDInterfaceGet(pVDIfs, VDINTERFACETYPE_IOINT);
394
395 /* Check that the interface descriptor is a progress interface. */
396 AssertMsgReturn( !pIf
397 || ( (pIf->enmInterface == VDINTERFACETYPE_IOINT)
398 && (pIf->cbSize == sizeof(VDINTERFACEIOINT))),
399 ("Not an internal I/O interface"), NULL);
400
401 return (PVDINTERFACEIOINT)pIf;
402}
403
404DECLINLINE(int) vdIfIoIntFileOpen(PVDINTERFACEIOINT pIfIoInt, const char *pszFilename,
405 uint32_t fOpen, PPVDIOSTORAGE ppStorage)
406{
407 return pIfIoInt->pfnOpen(pIfIoInt->Core.pvUser, pszFilename, fOpen, ppStorage);
408}
409
410DECLINLINE(int) vdIfIoIntFileClose(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage)
411{
412 return pIfIoInt->pfnClose(pIfIoInt->Core.pvUser, pStorage);
413}
414
415DECLINLINE(int) vdIfIoIntFileDelete(PVDINTERFACEIOINT pIfIoInt, const char *pszFilename)
416{
417 return pIfIoInt->pfnDelete(pIfIoInt->Core.pvUser, pszFilename);
418}
419
420DECLINLINE(int) vdIfIoIntFileMove(PVDINTERFACEIOINT pIfIoInt, const char *pszSrc,
421 const char *pszDst, unsigned fMove)
422{
423 return pIfIoInt->pfnMove(pIfIoInt->Core.pvUser, pszSrc, pszDst, fMove);
424}
425
426DECLINLINE(int) vdIfIoIntFileGetFreeSpace(PVDINTERFACEIOINT pIfIoInt, const char *pszFilename,
427 int64_t *pcbFree)
428{
429 return pIfIoInt->pfnGetFreeSpace(pIfIoInt->Core.pvUser, pszFilename, pcbFree);
430}
431
432DECLINLINE(int) vdIfIoIntFileGetModificationTime(PVDINTERFACEIOINT pIfIoInt, const char *pcszFilename,
433 PRTTIMESPEC pModificationTime)
434{
435 return pIfIoInt->pfnGetModificationTime(pIfIoInt->Core.pvUser, pcszFilename,
436 pModificationTime);
437}
438
439DECLINLINE(int) vdIfIoIntFileGetSize(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage,
440 uint64_t *pcbSize)
441{
442 return pIfIoInt->pfnGetSize(pIfIoInt->Core.pvUser, pStorage, pcbSize);
443}
444
445DECLINLINE(int) vdIfIoIntFileSetSize(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage,
446 uint64_t cbSize)
447{
448 return pIfIoInt->pfnSetSize(pIfIoInt->Core.pvUser, pStorage, cbSize);
449}
450
451DECLINLINE(int) vdIfIoIntFileWriteSync(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage,
452 uint64_t uOffset, const void *pvBuffer, size_t cbBuffer)
453{
454 return pIfIoInt->pfnWriteMeta(pIfIoInt->Core.pvUser, pStorage,
455 uOffset, pvBuffer, cbBuffer, NULL,
456 NULL, NULL);
457}
458
459DECLINLINE(int) vdIfIoIntFileReadSync(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage,
460 uint64_t uOffset, void *pvBuffer, size_t cbBuffer)
461{
462 return pIfIoInt->pfnReadMeta(pIfIoInt->Core.pvUser, pStorage,
463 uOffset, pvBuffer, cbBuffer, NULL,
464 NULL, NULL, NULL);
465}
466
467DECLINLINE(int) vdIfIoIntFileFlushSync(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage)
468{
469 return pIfIoInt->pfnFlush(pIfIoInt->Core.pvUser, pStorage, NULL, NULL, NULL);
470}
471
472DECLINLINE(int) vdIfIoIntFileReadUser(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage,
473 uint64_t uOffset, PVDIOCTX pIoCtx, size_t cbRead)
474{
475 return pIfIoInt->pfnReadUser(pIfIoInt->Core.pvUser, pStorage,
476 uOffset, pIoCtx, cbRead);
477}
478
479DECLINLINE(int) vdIfIoIntFileWriteUser(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage,
480 uint64_t uOffset, PVDIOCTX pIoCtx, size_t cbWrite,
481 PFNVDXFERCOMPLETED pfnComplete,
482 void *pvCompleteUser)
483{
484 return pIfIoInt->pfnWriteUser(pIfIoInt->Core.pvUser, pStorage,
485 uOffset, pIoCtx, cbWrite, pfnComplete,
486 pvCompleteUser);
487}
488
489DECLINLINE(int) vdIfIoIntFileReadMeta(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage,
490 uint64_t uOffset, void *pvBuffer,
491 size_t cbBuffer, PVDIOCTX pIoCtx,
492 PPVDMETAXFER ppMetaXfer,
493 PFNVDXFERCOMPLETED pfnComplete,
494 void *pvCompleteUser)
495{
496 return pIfIoInt->pfnReadMeta(pIfIoInt->Core.pvUser, pStorage,
497 uOffset, pvBuffer, cbBuffer, pIoCtx,
498 ppMetaXfer, pfnComplete, pvCompleteUser);
499}
500
501DECLINLINE(int) vdIfIoIntFileWriteMeta(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage,
502 uint64_t uOffset, void *pvBuffer,
503 size_t cbBuffer, PVDIOCTX pIoCtx,
504 PFNVDXFERCOMPLETED pfnComplete,
505 void *pvCompleteUser)
506{
507 return pIfIoInt->pfnWriteMeta(pIfIoInt->Core.pvUser, pStorage,
508 uOffset, pvBuffer, cbBuffer, pIoCtx,
509 pfnComplete, pvCompleteUser);
510}
511
512DECLINLINE(void) vdIfIoIntMetaXferRelease(PVDINTERFACEIOINT pIfIoInt, PVDMETAXFER pMetaXfer)
513{
514 pIfIoInt->pfnMetaXferRelease(pIfIoInt->Core.pvUser, pMetaXfer);
515}
516
517DECLINLINE(int) vdIfIoIntFileFlush(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage,
518 PVDIOCTX pIoCtx, PFNVDXFERCOMPLETED pfnComplete,
519 void *pvCompleteUser)
520{
521 return pIfIoInt->pfnFlush(pIfIoInt->Core.pvUser, pStorage, pIoCtx, pfnComplete,
522 pvCompleteUser);
523}
524
525DECLINLINE(size_t) vdIfIoIntIoCtxSet(PVDINTERFACEIOINT pIfIoInt, PVDIOCTX pIoCtx,
526 int ch, size_t cbSet)
527{
528 return pIfIoInt->pfnIoCtxSet(pIfIoInt->Core.pvUser, pIoCtx, ch, cbSet);
529}
530
531RT_C_DECLS_END
532
533/** @} */
534
535#endif
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