VirtualBox

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

Last change on this file since 84372 was 82968, checked in by vboxsync, 5 years ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.6 KB
Line 
1/* $Id: VDIoBackend.cpp 82968 2020-02-04 10:35:17Z vboxsync $ */
2/** @file
3 * VBox HDD container test utility, I/O backend API
4 */
5
6/*
7 * Copyright (C) 2013-2020 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/errcore.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/string.h>
25
26#include "VDIoBackend.h"
27#include "VDMemDisk.h"
28#include "VDIoBackendMem.h"
29
30typedef struct VDIOBACKEND
31{
32 /** Memory I/O backend handle. */
33 PVDIOBACKENDMEM pIoMem;
34 /** Users of the memory backend. */
35 volatile uint32_t cRefsIoMem;
36 /** Users of the file backend. */
37 volatile uint32_t cRefsFile;
38} VDIOBACKEND;
39
40typedef struct VDIOSTORAGE
41{
42 /** Pointer to the I/O backend parent. */
43 PVDIOBACKEND pIoBackend;
44 /** Completion callback. */
45 PFNVDIOCOMPLETE pfnComplete;
46 /** Flag whether this storage is backed by a file or memory.disk. */
47 bool fMemory;
48 /** Type dependent data. */
49 union
50 {
51 /** Memory disk handle. */
52 PVDMEMDISK pMemDisk;
53 /** file handle. */
54 RTFILE hFile;
55 } u;
56} VDIOSTORAGE;
57
58
59int VDIoBackendCreate(PPVDIOBACKEND ppIoBackend)
60{
61 int rc = VINF_SUCCESS;
62 PVDIOBACKEND pIoBackend;
63
64 pIoBackend = (PVDIOBACKEND)RTMemAllocZ(sizeof(VDIOBACKEND));
65 if (pIoBackend)
66 *ppIoBackend = pIoBackend;
67 else
68 rc = VERR_NO_MEMORY;
69
70 return rc;
71}
72
73void VDIoBackendDestroy(PVDIOBACKEND pIoBackend)
74{
75 if (pIoBackend->pIoMem)
76 VDIoBackendMemDestroy(pIoBackend->pIoMem);
77 RTMemFree(pIoBackend);
78}
79
80int VDIoBackendStorageCreate(PVDIOBACKEND pIoBackend, const char *pszBackend,
81 const char *pszName, PFNVDIOCOMPLETE pfnComplete,
82 PPVDIOSTORAGE ppIoStorage)
83{
84 int rc = VINF_SUCCESS;
85 PVDIOSTORAGE pIoStorage = (PVDIOSTORAGE)RTMemAllocZ(sizeof(VDIOSTORAGE));
86
87 if (pIoStorage)
88 {
89 pIoStorage->pIoBackend = pIoBackend;
90 pIoStorage->pfnComplete = pfnComplete;
91 if (!strcmp(pszBackend, "memory"))
92 {
93 pIoStorage->fMemory = true;
94 rc = VDMemDiskCreate(&pIoStorage->u.pMemDisk, 0 /* Growing */);
95 if (RT_SUCCESS(rc))
96 {
97 uint32_t cRefs = ASMAtomicIncU32(&pIoBackend->cRefsIoMem);
98 if ( cRefs == 1
99 && !pIoBackend->pIoMem)
100 {
101 rc = VDIoBackendMemCreate(&pIoBackend->pIoMem);
102 if (RT_FAILURE(rc))
103 VDMemDiskDestroy(pIoStorage->u.pMemDisk);
104 }
105 }
106 }
107 else if (!strcmp(pszBackend, "file"))
108 {
109 /* Create file. */
110 rc = RTFileOpen(&pIoStorage->u.hFile, pszName,
111 RTFILE_O_READWRITE | RTFILE_O_CREATE | RTFILE_O_ASYNC_IO | RTFILE_O_NO_CACHE | RTFILE_O_DENY_NONE);
112
113 if (RT_FAILURE(rc))
114 ASMAtomicDecU32(&pIoBackend->cRefsFile);
115 }
116 else
117 rc = VERR_NOT_SUPPORTED;
118
119 if (RT_FAILURE(rc))
120 RTMemFree(pIoStorage);
121 else
122 *ppIoStorage = pIoStorage;
123 }
124 else
125 rc = VERR_NO_MEMORY;
126
127 return rc;
128}
129
130void VDIoBackendStorageDestroy(PVDIOSTORAGE pIoStorage)
131{
132 if (pIoStorage->fMemory)
133 {
134 VDMemDiskDestroy(pIoStorage->u.pMemDisk);
135 ASMAtomicDecU32(&pIoStorage->pIoBackend->cRefsIoMem);
136 }
137 else
138 {
139 RTFileClose(pIoStorage->u.hFile);
140 ASMAtomicDecU32(&pIoStorage->pIoBackend->cRefsFile);
141 }
142 RTMemFree(pIoStorage);
143}
144
145int VDIoBackendTransfer(PVDIOSTORAGE pIoStorage, VDIOTXDIR enmTxDir, uint64_t off,
146 size_t cbTransfer, PRTSGBUF pSgBuf, void *pvUser, bool fSync)
147{
148 int rc = VINF_SUCCESS;
149
150 if (pIoStorage->fMemory)
151 {
152 if (!fSync)
153 {
154 rc = VDIoBackendMemTransfer(pIoStorage->pIoBackend->pIoMem, pIoStorage->u.pMemDisk,
155 enmTxDir, off, cbTransfer, pSgBuf, pIoStorage->pfnComplete,
156 pvUser);
157 }
158 else
159 {
160 switch (enmTxDir)
161 {
162 case VDIOTXDIR_READ:
163 rc = VDMemDiskRead(pIoStorage->u.pMemDisk, off, cbTransfer, pSgBuf);
164 break;
165 case VDIOTXDIR_WRITE:
166 rc = VDMemDiskWrite(pIoStorage->u.pMemDisk, off, cbTransfer, pSgBuf);
167 break;
168 case VDIOTXDIR_FLUSH:
169 break;
170 default:
171 AssertMsgFailed(("Invalid transfer type %d\n", enmTxDir));
172 }
173 }
174 }
175 else
176 {
177 if (!fSync)
178 rc = VERR_NOT_IMPLEMENTED;
179 else
180 {
181 switch (enmTxDir)
182 {
183 case VDIOTXDIR_READ:
184 rc = RTFileSgReadAt(pIoStorage->u.hFile, off, pSgBuf, cbTransfer, NULL);
185 break;
186 case VDIOTXDIR_WRITE:
187 rc = RTFileSgWriteAt(pIoStorage->u.hFile, off, pSgBuf, cbTransfer, NULL);
188 break;
189 case VDIOTXDIR_FLUSH:
190 rc = RTFileFlush(pIoStorage->u.hFile);
191 break;
192 default:
193 AssertMsgFailed(("Invalid transfer type %d\n", enmTxDir));
194 }
195 }
196 }
197
198 return rc;
199}
200
201int VDIoBackendStorageSetSize(PVDIOSTORAGE pIoStorage, uint64_t cbSize)
202{
203 int rc = VINF_SUCCESS;
204
205 if (pIoStorage->fMemory)
206 {
207 rc = VDMemDiskSetSize(pIoStorage->u.pMemDisk, cbSize);
208 }
209 else
210 rc = RTFileSetSize(pIoStorage->u.hFile, cbSize);
211
212 return rc;
213}
214
215int VDIoBackendStorageGetSize(PVDIOSTORAGE pIoStorage, uint64_t *pcbSize)
216{
217 int rc = VINF_SUCCESS;
218
219 if (pIoStorage->fMemory)
220 {
221 rc = VDMemDiskGetSize(pIoStorage->u.pMemDisk, pcbSize);
222 }
223 else
224 rc = RTFileQuerySize(pIoStorage->u.hFile, pcbSize);
225
226 return rc;
227}
228
229DECLHIDDEN(int) VDIoBackendDumpToFile(PVDIOSTORAGE pIoStorage, const char *pszPath)
230{
231 int rc = VINF_SUCCESS;
232
233 if (pIoStorage->fMemory)
234 rc = VDMemDiskWriteToFile(pIoStorage->u.pMemDisk, pszPath);
235 else
236 rc = VERR_NOT_IMPLEMENTED;
237
238 return rc;
239}
240
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