VirtualBox

source: vbox/trunk/src/VBox/Storage/testcase/VDIoBackend.cpp@ 78392

Last change on this file since 78392 was 77232, checked in by vboxsync, 6 years ago

Storage/QED+QCOW: It is not allowed to mix RTStrDup, RTMemAlloc and RTStrFree, you must stick to one allocator type. Strings must be sanitized or coverted after loading.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.8 KB
Line 
1/* $Id: VDIoBackend.cpp 77232 2019-02-09 01:55:37Z vboxsync $ */
2/** @file
3 * VBox HDD container test utility, I/O backend API
4 */
5
6/*
7 * Copyright (C) 2013-2019 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#define LOGGROUP LOGGROUP_DEFAULT /** @todo Log group */
18#include <iprt/err.h>
19#include <iprt/log.h>
20#include <iprt/assert.h>
21#include <iprt/asm.h>
22#include <iprt/mem.h>
23#include <iprt/file.h>
24#include <iprt/aiomgr.h>
25#include <iprt/string.h>
26
27#include "VDIoBackend.h"
28#include "VDMemDisk.h"
29#include "VDIoBackendMem.h"
30
31typedef struct VDIOBACKEND
32{
33 /** Memory I/O backend handle. */
34 PVDIOBACKENDMEM pIoMem;
35 /** Async I/O manager. */
36 RTAIOMGR hAioMgr;
37 /** Users of the memory backend. */
38 volatile uint32_t cRefsIoMem;
39 /** Users of the file backend. */
40 volatile uint32_t cRefsFile;
41} VDIOBACKEND;
42
43typedef struct VDIOSTORAGE
44{
45 /** Pointer to the I/O backend parent. */
46 PVDIOBACKEND pIoBackend;
47 /** Completion callback. */
48 PFNVDIOCOMPLETE pfnComplete;
49 /** Flag whether this storage is backed by a file or memory.disk. */
50 bool fMemory;
51 /** Type dependent data. */
52 union
53 {
54 /** Memory disk handle. */
55 PVDMEMDISK pMemDisk;
56 struct
57 {
58 /** file handle. */
59 RTFILE hFile;
60 /** I/O manager file handle. */
61 RTAIOMGRFILE hAioMgrFile;
62 } File;
63 } u;
64} VDIOSTORAGE;
65
66static DECLCALLBACK(void) vdIoBackendFileIoComplete(RTAIOMGRFILE hAioMgrFile, int rcReq, void *pvUser)
67{
68 PVDIOSTORAGE pIoStorage = (PVDIOSTORAGE)RTAioMgrFileGetUser(hAioMgrFile);
69 pIoStorage->pfnComplete(pvUser, rcReq);
70}
71
72int VDIoBackendCreate(PPVDIOBACKEND ppIoBackend)
73{
74 int rc = VINF_SUCCESS;
75 PVDIOBACKEND pIoBackend;
76
77 pIoBackend = (PVDIOBACKEND)RTMemAllocZ(sizeof(VDIOBACKEND));
78 if (pIoBackend)
79 {
80 pIoBackend->hAioMgr = NIL_RTAIOMGR;
81 *ppIoBackend = pIoBackend;
82 }
83 else
84 rc = VERR_NO_MEMORY;
85
86 return rc;
87}
88
89void VDIoBackendDestroy(PVDIOBACKEND pIoBackend)
90{
91 if (pIoBackend->pIoMem)
92 VDIoBackendMemDestroy(pIoBackend->pIoMem);
93 if (pIoBackend->hAioMgr)
94 RTAioMgrRelease(pIoBackend->hAioMgr);
95 RTMemFree(pIoBackend);
96}
97
98int VDIoBackendStorageCreate(PVDIOBACKEND pIoBackend, const char *pszBackend,
99 const char *pszName, PFNVDIOCOMPLETE pfnComplete,
100 PPVDIOSTORAGE ppIoStorage)
101{
102 int rc = VINF_SUCCESS;
103 PVDIOSTORAGE pIoStorage = (PVDIOSTORAGE)RTMemAllocZ(sizeof(VDIOSTORAGE));
104
105 if (pIoStorage)
106 {
107 pIoStorage->pIoBackend = pIoBackend;
108 pIoStorage->pfnComplete = pfnComplete;
109 if (!strcmp(pszBackend, "memory"))
110 {
111 pIoStorage->fMemory = true;
112 rc = VDMemDiskCreate(&pIoStorage->u.pMemDisk, 0 /* Growing */);
113 if (RT_SUCCESS(rc))
114 {
115 uint32_t cRefs = ASMAtomicIncU32(&pIoBackend->cRefsIoMem);
116 if ( cRefs == 1
117 && !pIoBackend->pIoMem)
118 {
119 rc = VDIoBackendMemCreate(&pIoBackend->pIoMem);
120 if (RT_FAILURE(rc))
121 VDMemDiskDestroy(pIoStorage->u.pMemDisk);
122 }
123 }
124 }
125 else if (!strcmp(pszBackend, "file"))
126 {
127 pIoStorage->fMemory = false;
128 uint32_t cRefs = ASMAtomicIncU32(&pIoBackend->cRefsFile);
129 if ( cRefs == 1
130 && pIoBackend->hAioMgr == NIL_RTAIOMGR)
131 rc = RTAioMgrCreate(&pIoBackend->hAioMgr, 1024);
132
133 if (RT_SUCCESS(rc))
134 {
135 /* Create file. */
136 rc = RTFileOpen(&pIoStorage->u.File.hFile, pszName,
137 RTFILE_O_READWRITE | RTFILE_O_CREATE | RTFILE_O_ASYNC_IO | RTFILE_O_NO_CACHE | RTFILE_O_DENY_NONE);
138 if (RT_SUCCESS(rc))
139 {
140 /* Create file handle for I/O manager. */
141 rc = RTAioMgrFileCreate(pIoBackend->hAioMgr, pIoStorage->u.File.hFile,
142 vdIoBackendFileIoComplete, pIoStorage,
143 &pIoStorage->u.File.hAioMgrFile);
144 if (RT_FAILURE(rc))
145 RTFileClose(pIoStorage->u.File.hFile);
146 }
147 }
148
149 if (RT_FAILURE(rc))
150 ASMAtomicDecU32(&pIoBackend->cRefsFile);
151 }
152 else
153 rc = VERR_NOT_SUPPORTED;
154
155 if (RT_FAILURE(rc))
156 RTMemFree(pIoStorage);
157 else
158 *ppIoStorage = pIoStorage;
159 }
160 else
161 rc = VERR_NO_MEMORY;
162
163 return rc;
164}
165
166void VDIoBackendStorageDestroy(PVDIOSTORAGE pIoStorage)
167{
168 if (pIoStorage->fMemory)
169 {
170 VDMemDiskDestroy(pIoStorage->u.pMemDisk);
171 ASMAtomicDecU32(&pIoStorage->pIoBackend->cRefsIoMem);
172 }
173 else
174 {
175 RTAioMgrFileRelease(pIoStorage->u.File.hAioMgrFile);
176 RTFileClose(pIoStorage->u.File.hFile);
177 ASMAtomicDecU32(&pIoStorage->pIoBackend->cRefsFile);
178 }
179 RTMemFree(pIoStorage);
180}
181
182int VDIoBackendTransfer(PVDIOSTORAGE pIoStorage, VDIOTXDIR enmTxDir, uint64_t off,
183 size_t cbTransfer, PRTSGBUF pSgBuf, void *pvUser, bool fSync)
184{
185 int rc = VINF_SUCCESS;
186
187 if (pIoStorage->fMemory)
188 {
189 if (!fSync)
190 {
191 rc = VDIoBackendMemTransfer(pIoStorage->pIoBackend->pIoMem, pIoStorage->u.pMemDisk,
192 enmTxDir, off, cbTransfer, pSgBuf, pIoStorage->pfnComplete,
193 pvUser);
194 }
195 else
196 {
197 switch (enmTxDir)
198 {
199 case VDIOTXDIR_READ:
200 rc = VDMemDiskRead(pIoStorage->u.pMemDisk, off, cbTransfer, pSgBuf);
201 break;
202 case VDIOTXDIR_WRITE:
203 rc = VDMemDiskWrite(pIoStorage->u.pMemDisk, off, cbTransfer, pSgBuf);
204 break;
205 case VDIOTXDIR_FLUSH:
206 break;
207 default:
208 AssertMsgFailed(("Invalid transfer type %d\n", enmTxDir));
209 }
210 }
211 }
212 else
213 {
214 if (!fSync)
215 {
216 switch (enmTxDir)
217 {
218 case VDIOTXDIR_READ:
219 rc = RTAioMgrFileRead(pIoStorage->u.File.hAioMgrFile, off, pSgBuf, cbTransfer, pvUser);
220 break;
221 case VDIOTXDIR_WRITE:
222 rc = RTAioMgrFileWrite(pIoStorage->u.File.hAioMgrFile, off, pSgBuf, cbTransfer, pvUser);
223 break;
224 case VDIOTXDIR_FLUSH:
225 rc = RTAioMgrFileFlush(pIoStorage->u.File.hAioMgrFile, pvUser);
226 break;
227 default:
228 AssertMsgFailed(("Invalid transfer type %d\n", enmTxDir));
229 }
230 if (rc == VERR_FILE_AIO_IN_PROGRESS)
231 rc = VINF_SUCCESS;
232 }
233 else
234 {
235 switch (enmTxDir)
236 {
237 case VDIOTXDIR_READ:
238 rc = RTFileSgReadAt(pIoStorage->u.File.hFile, off, pSgBuf, cbTransfer, NULL);
239 break;
240 case VDIOTXDIR_WRITE:
241 rc = RTFileSgWriteAt(pIoStorage->u.File.hFile, off, pSgBuf, cbTransfer, NULL);
242 break;
243 case VDIOTXDIR_FLUSH:
244 rc = RTFileFlush(pIoStorage->u.File.hFile);
245 break;
246 default:
247 AssertMsgFailed(("Invalid transfer type %d\n", enmTxDir));
248 }
249 }
250 }
251
252 return rc;
253}
254
255int VDIoBackendStorageSetSize(PVDIOSTORAGE pIoStorage, uint64_t cbSize)
256{
257 int rc = VINF_SUCCESS;
258
259 if (pIoStorage->fMemory)
260 {
261 rc = VDMemDiskSetSize(pIoStorage->u.pMemDisk, cbSize);
262 }
263 else
264 rc = RTFileSetSize(pIoStorage->u.File.hFile, cbSize);
265
266 return rc;
267}
268
269int VDIoBackendStorageGetSize(PVDIOSTORAGE pIoStorage, uint64_t *pcbSize)
270{
271 int rc = VINF_SUCCESS;
272
273 if (pIoStorage->fMemory)
274 {
275 rc = VDMemDiskGetSize(pIoStorage->u.pMemDisk, pcbSize);
276 }
277 else
278 rc = RTFileGetSize(pIoStorage->u.File.hFile, pcbSize);
279
280 return rc;
281}
282
283DECLHIDDEN(int) VDIoBackendDumpToFile(PVDIOSTORAGE pIoStorage, const char *pszPath)
284{
285 int rc = VINF_SUCCESS;
286
287 if (pIoStorage->fMemory)
288 rc = VDMemDiskWriteToFile(pIoStorage->u.pMemDisk, pszPath);
289 else
290 rc = VERR_NOT_IMPLEMENTED;
291
292 return rc;
293}
294
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