VirtualBox

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

Last change on this file since 106579 was 106061, checked in by vboxsync, 2 months 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.9 KB
Line 
1/* $Id: VDIoBackend.cpp 106061 2024-09-16 14:03:52Z vboxsync $ */
2/** @file
3 * VBox HDD container test utility, I/O backend API
4 */
5
6/*
7 * Copyright (C) 2013-2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27#define LOGGROUP LOGGROUP_DEFAULT /** @todo Log group */
28#include <iprt/errcore.h>
29#include <iprt/log.h>
30#include <iprt/assert.h>
31#include <iprt/asm.h>
32#include <iprt/mem.h>
33#include <iprt/file.h>
34#include <iprt/string.h>
35
36#include "VDIoBackend.h"
37#include "VDMemDisk.h"
38#include "VDIoBackendMem.h"
39
40typedef struct VDIOBACKEND
41{
42 /** Memory I/O backend handle. */
43 PVDIOBACKENDMEM pIoMem;
44 /** Users of the memory backend. */
45 volatile uint32_t cRefsIoMem;
46 /** Users of the file backend. */
47 volatile uint32_t cRefsFile;
48} VDIOBACKEND;
49
50typedef struct VDIOSTORAGE
51{
52 /** Pointer to the I/O backend parent. */
53 PVDIOBACKEND pIoBackend;
54 /** Completion callback. */
55 PFNVDIOCOMPLETE pfnComplete;
56 /** Flag whether this storage is backed by a file or memory.disk. */
57 bool fMemory;
58 /** Type dependent data. */
59 union
60 {
61 /** Memory disk handle. */
62 PVDMEMDISK pMemDisk;
63 /** file handle. */
64 RTFILE hFile;
65 } u;
66} VDIOSTORAGE;
67
68
69int VDIoBackendCreate(PPVDIOBACKEND ppIoBackend)
70{
71 int rc = VINF_SUCCESS;
72 PVDIOBACKEND pIoBackend;
73
74 pIoBackend = (PVDIOBACKEND)RTMemAllocZ(sizeof(VDIOBACKEND));
75 if (pIoBackend)
76 *ppIoBackend = pIoBackend;
77 else
78 rc = VERR_NO_MEMORY;
79
80 return rc;
81}
82
83void VDIoBackendDestroy(PVDIOBACKEND pIoBackend)
84{
85 if (pIoBackend->pIoMem)
86 VDIoBackendMemDestroy(pIoBackend->pIoMem);
87 RTMemFree(pIoBackend);
88}
89
90int VDIoBackendStorageCreate(PVDIOBACKEND pIoBackend, const char *pszBackend,
91 const char *pszName, PFNVDIOCOMPLETE pfnComplete,
92 PPVDIOSTORAGE ppIoStorage)
93{
94 int rc = VINF_SUCCESS;
95 PVDIOSTORAGE pIoStorage = (PVDIOSTORAGE)RTMemAllocZ(sizeof(VDIOSTORAGE));
96
97 if (pIoStorage)
98 {
99 pIoStorage->pIoBackend = pIoBackend;
100 pIoStorage->pfnComplete = pfnComplete;
101 if (!strcmp(pszBackend, "memory"))
102 {
103 pIoStorage->fMemory = true;
104 rc = VDMemDiskCreate(&pIoStorage->u.pMemDisk, 0 /* Growing */);
105 if (RT_SUCCESS(rc))
106 {
107 uint32_t cRefs = ASMAtomicIncU32(&pIoBackend->cRefsIoMem);
108 if ( cRefs == 1
109 && !pIoBackend->pIoMem)
110 {
111 rc = VDIoBackendMemCreate(&pIoBackend->pIoMem);
112 if (RT_FAILURE(rc))
113 VDMemDiskDestroy(pIoStorage->u.pMemDisk);
114 }
115 }
116 }
117 else if (!strcmp(pszBackend, "file"))
118 {
119 /* Create file. */
120 rc = RTFileOpen(&pIoStorage->u.hFile, pszName,
121 RTFILE_O_READWRITE | RTFILE_O_CREATE | RTFILE_O_ASYNC_IO | RTFILE_O_NO_CACHE | RTFILE_O_DENY_NONE);
122
123 if (RT_FAILURE(rc))
124 ASMAtomicDecU32(&pIoBackend->cRefsFile);
125 }
126 else
127 rc = VERR_NOT_SUPPORTED;
128
129 if (RT_FAILURE(rc))
130 RTMemFree(pIoStorage);
131 else
132 *ppIoStorage = pIoStorage;
133 }
134 else
135 rc = VERR_NO_MEMORY;
136
137 return rc;
138}
139
140void VDIoBackendStorageDestroy(PVDIOSTORAGE pIoStorage)
141{
142 if (pIoStorage->fMemory)
143 {
144 VDMemDiskDestroy(pIoStorage->u.pMemDisk);
145 ASMAtomicDecU32(&pIoStorage->pIoBackend->cRefsIoMem);
146 }
147 else
148 {
149 RTFileClose(pIoStorage->u.hFile);
150 ASMAtomicDecU32(&pIoStorage->pIoBackend->cRefsFile);
151 }
152 RTMemFree(pIoStorage);
153}
154
155int VDIoBackendTransfer(PVDIOSTORAGE pIoStorage, VDIOTXDIR enmTxDir, uint64_t off,
156 size_t cbTransfer, PRTSGBUF pSgBuf, void *pvUser, bool fSync)
157{
158 int rc = VINF_SUCCESS;
159
160 if (pIoStorage->fMemory)
161 {
162 if (!fSync)
163 {
164 rc = VDIoBackendMemTransfer(pIoStorage->pIoBackend->pIoMem, pIoStorage->u.pMemDisk,
165 enmTxDir, off, cbTransfer, pSgBuf, pIoStorage->pfnComplete,
166 pvUser);
167 }
168 else
169 {
170 switch (enmTxDir)
171 {
172 case VDIOTXDIR_READ:
173 rc = VDMemDiskRead(pIoStorage->u.pMemDisk, off, cbTransfer, pSgBuf);
174 break;
175 case VDIOTXDIR_WRITE:
176 rc = VDMemDiskWrite(pIoStorage->u.pMemDisk, off, cbTransfer, pSgBuf);
177 break;
178 case VDIOTXDIR_FLUSH:
179 break;
180 default:
181 AssertMsgFailed(("Invalid transfer type %d\n", enmTxDir));
182 }
183 }
184 }
185 else
186 {
187 if (!fSync)
188 rc = VERR_NOT_IMPLEMENTED;
189 else
190 {
191 switch (enmTxDir)
192 {
193 case VDIOTXDIR_READ:
194 rc = RTFileSgReadAt(pIoStorage->u.hFile, off, pSgBuf, cbTransfer, NULL);
195 break;
196 case VDIOTXDIR_WRITE:
197 rc = RTFileSgWriteAt(pIoStorage->u.hFile, off, pSgBuf, cbTransfer, NULL);
198 break;
199 case VDIOTXDIR_FLUSH:
200 rc = RTFileFlush(pIoStorage->u.hFile);
201 break;
202 default:
203 AssertMsgFailed(("Invalid transfer type %d\n", enmTxDir));
204 }
205 }
206 }
207
208 return rc;
209}
210
211int VDIoBackendStorageSetSize(PVDIOSTORAGE pIoStorage, uint64_t cbSize)
212{
213 int rc = VINF_SUCCESS;
214
215 if (pIoStorage->fMemory)
216 {
217 rc = VDMemDiskSetSize(pIoStorage->u.pMemDisk, cbSize);
218 }
219 else
220 rc = RTFileSetSize(pIoStorage->u.hFile, cbSize);
221
222 return rc;
223}
224
225int VDIoBackendStorageGetSize(PVDIOSTORAGE pIoStorage, uint64_t *pcbSize)
226{
227 int rc = VINF_SUCCESS;
228
229 if (pIoStorage->fMemory)
230 {
231 rc = VDMemDiskGetSize(pIoStorage->u.pMemDisk, pcbSize);
232 }
233 else
234 rc = RTFileQuerySize(pIoStorage->u.hFile, pcbSize);
235
236 return rc;
237}
238
239DECLHIDDEN(int) VDIoBackendDumpToFile(PVDIOSTORAGE pIoStorage, const char *pszPath)
240{
241 int rc = VINF_SUCCESS;
242
243 if (pIoStorage->fMemory)
244 rc = VDMemDiskWriteToFile(pIoStorage->u.pMemDisk, pszPath);
245 else
246 rc = VERR_NOT_IMPLEMENTED;
247
248 return rc;
249}
250
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