VirtualBox

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

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

pr6022. 3rd variant (using VFS streaming feature) of GZIP support for reading the gzipped storage images from OVA/OVF package has been added.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.8 KB
Line 
1/* $Id: VDIfVfs.cpp 47716 2013-08-14 05:33:22Z 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 * Standard file operations.
158 */
159DECL_HIDDEN_CONST(const RTVFSIOSTREAMOPS) g_vdIfVfsStdIosOps =
160{
161 { /* Obj */
162 RTVFSOBJOPS_VERSION,
163 RTVFSOBJTYPE_IO_STREAM,
164 "VDIfIos",
165 vdIfVfsIos_Close,
166 vdIfVfsIos_QueryInfo,
167 RTVFSOBJOPS_VERSION
168 },
169 RTVFSIOSTREAMOPS_VERSION,
170 RTVFSIOSTREAMOPS_FEAT_NO_SG,
171 vdIfVfsIos_Read,
172 vdIfVfsIos_Write,
173 vdIfVfsIos_Flush,
174 vdIfVfsIos_PollOne,
175 vdIfVfsIos_Tell,
176 NULL /*Skip*/,
177 NULL /*ZeroFill*/,
178 RTVFSIOSTREAMOPS_VERSION,
179
180};
181
182VBOXDDU_DECL(int) VDIfCreateVfsStream(PVDINTERFACEIO pVDIfsIo, void *pvStorage, uint32_t fFlags, PRTVFSIOSTREAM phVfsIos)
183{
184 AssertPtrReturn(pVDIfsIo, VERR_INVALID_HANDLE);
185 AssertPtrReturn(phVfsIos, VERR_INVALID_POINTER);
186
187 /*
188 * Create the volume file.
189 */
190 RTVFSIOSTREAM hVfsIos;
191 PVDIFVFSIOS pThis;
192 int rc = RTVfsNewIoStream(&g_vdIfVfsStdIosOps, sizeof(*pThis), fFlags,
193 NIL_RTVFS, NIL_RTVFSLOCK, &hVfsIos, (void **)&pThis);
194 if (RT_SUCCESS(rc))
195 {
196 pThis->pVDIfsIo = pVDIfsIo;
197 pThis->pvStorage = pvStorage;
198 pThis->offCurPos = 0;
199
200 *phVfsIos = hVfsIos;
201 return VINF_SUCCESS;
202 }
203
204 return rc;
205}
206
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