VirtualBox

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

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

VDIfVfs.cpp: Try return VINF_EOF in read when we should since vdIfIoFileReadSync probably doesn't do this like the VFS code expects it to.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.9 KB
Line 
1/* $Id: VDIfVfs.cpp 48176 2013-08-30 02:23:46Z 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 {
93 size_t cbAdvance = (pcbRead ? *pcbRead : pSgBuf->paSegs[0].cbSeg);
94 pThis->offCurPos = off + cbAdvance;
95 if (pcbRead && !cbAdvance)
96 rc = VINF_EOF;
97 }
98 return rc;
99}
100
101
102/**
103 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnWrite}
104 */
105static DECLCALLBACK(int) vdIfVfsIos_Write(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten)
106{
107 PVDIFVFSIOS pThis = (PVDIFVFSIOS)pvThis;
108 Assert(pSgBuf->cSegs == 1); NOREF(fBlocking);
109
110 /*
111 * This may end up being a little more complicated, esp. wrt VERR_EOF.
112 */
113 if (off == -1)
114 off = pThis->offCurPos;
115 int rc = vdIfIoFileWriteSync(pThis->pVDIfsIo, pThis->pvStorage, off, pSgBuf[0].pvSegCur, pSgBuf->paSegs[0].cbSeg, pcbWritten);
116 if (RT_SUCCESS(rc))
117 pThis->offCurPos = off + (pcbWritten ? *pcbWritten : pSgBuf->paSegs[0].cbSeg);
118 return rc;
119}
120
121
122/**
123 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnFlush}
124 */
125static DECLCALLBACK(int) vdIfVfsIos_Flush(void *pvThis)
126{
127 PVDIFVFSIOS pThis = (PVDIFVFSIOS)pvThis;
128 return vdIfIoFileFlushSync(pThis->pVDIfsIo, pThis->pvStorage);
129}
130
131
132/**
133 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnPollOne}
134 */
135static DECLCALLBACK(int) vdIfVfsIos_PollOne(void *pvThis, uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr,
136 uint32_t *pfRetEvents)
137{
138 NOREF(pvThis);
139 int rc;
140 if (fEvents != RTPOLL_EVT_ERROR)
141 {
142 *pfRetEvents = fEvents & ~RTPOLL_EVT_ERROR;
143 rc = VINF_SUCCESS;
144 }
145 else
146 rc = RTVfsUtilDummyPollOne(fEvents, cMillies, fIntr, pfRetEvents);
147 return rc;
148}
149
150
151/**
152 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnTell}
153 */
154static DECLCALLBACK(int) vdIfVfsIos_Tell(void *pvThis, PRTFOFF poffActual)
155{
156 PVDIFVFSIOS pThis = (PVDIFVFSIOS)pvThis;
157 *poffActual = pThis->offCurPos;
158 return VINF_SUCCESS;
159}
160
161/**
162 * Standard file operations.
163 */
164DECL_HIDDEN_CONST(const RTVFSIOSTREAMOPS) g_vdIfVfsStdIosOps =
165{
166 { /* Obj */
167 RTVFSOBJOPS_VERSION,
168 RTVFSOBJTYPE_IO_STREAM,
169 "VDIfIos",
170 vdIfVfsIos_Close,
171 vdIfVfsIos_QueryInfo,
172 RTVFSOBJOPS_VERSION
173 },
174 RTVFSIOSTREAMOPS_VERSION,
175 RTVFSIOSTREAMOPS_FEAT_NO_SG,
176 vdIfVfsIos_Read,
177 vdIfVfsIos_Write,
178 vdIfVfsIos_Flush,
179 vdIfVfsIos_PollOne,
180 vdIfVfsIos_Tell,
181 NULL /*Skip*/,
182 NULL /*ZeroFill*/,
183 RTVFSIOSTREAMOPS_VERSION,
184
185};
186
187VBOXDDU_DECL(int) VDIfCreateVfsStream(PVDINTERFACEIO pVDIfsIo, void *pvStorage, uint32_t fFlags, PRTVFSIOSTREAM phVfsIos)
188{
189 AssertPtrReturn(pVDIfsIo, VERR_INVALID_HANDLE);
190 AssertPtrReturn(phVfsIos, VERR_INVALID_POINTER);
191
192 /*
193 * Create the volume file.
194 */
195 RTVFSIOSTREAM hVfsIos;
196 PVDIFVFSIOS pThis;
197 int rc = RTVfsNewIoStream(&g_vdIfVfsStdIosOps, sizeof(*pThis), fFlags,
198 NIL_RTVFS, NIL_RTVFSLOCK, &hVfsIos, (void **)&pThis);
199 if (RT_SUCCESS(rc))
200 {
201 pThis->pVDIfsIo = pVDIfsIo;
202 pThis->pvStorage = pvStorage;
203 pThis->offCurPos = 0;
204
205 *phVfsIos = hVfsIos;
206 return VINF_SUCCESS;
207 }
208
209 return rc;
210}
211
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