1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
|
/* $Id: VDInternal.h $ */
/** @file
* VD - Virtual Disk container implementation, internal header file.
*/
/*
* Copyright (C) 2017-2023 Oracle and/or its affiliates.
*
* This file is part of VirtualBox base platform packages, as
* available from https://www.virtualbox.org.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, in version 3 of the
* License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses>.
*
* SPDX-License-Identifier: GPL-3.0-only
*/
/*********************************************************************************************************************************
* Header Files *
*********************************************************************************************************************************/
#ifndef VBOX_INCLUDED_SRC_Storage_VDInternal_h
#define VBOX_INCLUDED_SRC_Storage_VDInternal_h
#ifndef RT_WITHOUT_PRAGMA_ONCE
# pragma once
#endif
#include <VBox/vd.h>
#include <VBox/vd-plugin.h>
#include <iprt/avl.h>
#include <iprt/list.h>
#include <iprt/memcache.h>
#if 0 /* bird: this is nonsense */
/** Disable dynamic backends on non x86 architectures. This feature
* requires the SUPR3 library which is not available there.
*/
#if !defined(VBOX_HDD_NO_DYNAMIC_BACKENDS) && !defined(RT_ARCH_X86) && !defined(RT_ARCH_AMD64)
# define VBOX_HDD_NO_DYNAMIC_BACKENDS
#endif
#endif
/** Magic number contained in the VDISK instance data, used for checking that the passed
* pointer contains a valid instance in debug builds. */
#define VDISK_SIGNATURE 0x6f0e2a7d
/**
* Structure containing everything I/O related
* for the image and cache descriptors.
*/
typedef struct VDIO
{
/** I/O interface to the upper layer. */
PVDINTERFACEIO pInterfaceIo;
/** Per image internal I/O interface. */
VDINTERFACEIOINT VDIfIoInt;
/** Fallback I/O interface, only used if the caller doesn't provide it. */
VDINTERFACEIO VDIfIo;
/** Opaque backend data. */
void *pBackendData;
/** Disk this image is part of */
PVDISK pDisk;
/** Flag whether to ignore flush requests. */
bool fIgnoreFlush;
} VDIO, *PVDIO;
/** Forward declaration of an I/O task */
typedef struct VDIOTASK *PVDIOTASK;
/**
* Virtual disk container image descriptor.
*/
typedef struct VDIMAGE
{
/** Link to parent image descriptor, if any. */
struct VDIMAGE *pPrev;
/** Link to child image descriptor, if any. */
struct VDIMAGE *pNext;
/** Cached image size. */
uint64_t cbImage;
/** Container base filename. (UTF-8) */
char *pszFilename;
/** Data managed by the backend which keeps the actual info. */
void *pBackendData;
/** Cached sanitized image flags. */
unsigned uImageFlags;
/** Image open flags (only those handled generically in this code and which
* the backends will never ever see). */
unsigned uOpenFlags;
/** Function pointers for the various backend methods. */
PCVDIMAGEBACKEND Backend;
/** Pointer to list of VD interfaces, per-image. */
PVDINTERFACE pVDIfsImage;
/** I/O related things. */
VDIO VDIo;
} VDIMAGE, *PVDIMAGE;
/** The special uninitialized size value for he image. */
#define VD_IMAGE_SIZE_UNINITIALIZED UINT64_C(0)
/**
* Virtual disk cache image descriptor.
*/
typedef struct VDCACHE
{
/** Cache base filename. (UTF-8) */
char *pszFilename;
/** Data managed by the backend which keeps the actual info. */
void *pBackendData;
/** Cached sanitized image flags. */
unsigned uImageFlags;
/** Image open flags (only those handled generically in this code and which
* the backends will never ever see). */
unsigned uOpenFlags;
/** Function pointers for the various backend methods. */
PCVDCACHEBACKEND Backend;
/** Pointer to list of VD interfaces, per-cache. */
PVDINTERFACE pVDIfsCache;
/** I/O related things. */
VDIO VDIo;
} VDCACHE, *PVDCACHE;
/**
* A block waiting for a discard.
*/
typedef struct VDDISCARDBLOCK
{
/** AVL core. */
AVLRU64NODECORE Core;
/** LRU list node. */
RTLISTNODE NodeLru;
/** Number of bytes to discard. */
size_t cbDiscard;
/** Bitmap of allocated sectors. */
void *pbmAllocated;
} VDDISCARDBLOCK, *PVDDISCARDBLOCK;
/**
* VD discard state.
*/
typedef struct VDDISCARDSTATE
{
/** Number of bytes waiting for a discard. */
size_t cbDiscarding;
/** AVL tree with blocks waiting for a discard.
* The uOffset + cbDiscard range is the search key. */
PAVLRU64TREE pTreeBlocks;
/** LRU list of the least frequently discarded blocks.
* If there are to many blocks waiting the least frequently used
* will be removed and the range will be set to 0.
*/
RTLISTNODE ListLru;
} VDDISCARDSTATE, *PVDDISCARDSTATE;
/**
* VD filter instance.
*/
typedef struct VDFILTER
{
/** List node for the read filter chain. */
RTLISTNODE ListNodeChainRead;
/** List node for the write filter chain. */
RTLISTNODE ListNodeChainWrite;
/** Number of references to this filter. */
uint32_t cRefs;
/** Opaque VD filter backend instance data. */
void *pvBackendData;
/** Pointer to the filter backend interface. */
PCVDFILTERBACKEND pBackend;
/** Pointer to list of VD interfaces, per-filter. */
PVDINTERFACE pVDIfsFilter;
/** I/O related things. */
VDIO VDIo;
} VDFILTER;
/** Pointer to a VD filter instance. */
typedef VDFILTER *PVDFILTER;
/**
* Virtual disk container main structure, private part.
*/
struct VDISK
{
/** Structure signature (VDISK_SIGNATURE). */
uint32_t u32Signature;
/** Image type. */
VDTYPE enmType;
/** Number of opened images. */
unsigned cImages;
/** Base image. */
PVDIMAGE pBase;
/** Last opened image in the chain.
* The same as pBase if only one image is used. */
PVDIMAGE pLast;
/** If a merge to one of the parents is running this may be non-NULL
* to indicate to what image the writes should be additionally relayed. */
PVDIMAGE pImageRelay;
/** Flags representing the modification state. */
unsigned uModified;
/** Cached size of this disk. */
uint64_t cbSize;
/** Cached PCHS geometry for this disk. */
VDGEOMETRY PCHSGeometry;
/** Cached LCHS geometry for this disk. */
VDGEOMETRY LCHSGeometry;
/** Pointer to list of VD interfaces, per-disk. */
PVDINTERFACE pVDIfsDisk;
/** Pointer to the common interface structure for error reporting. */
PVDINTERFACEERROR pInterfaceError;
/** Pointer to the optional thread synchronization callbacks. */
PVDINTERFACETHREADSYNC pInterfaceThreadSync;
/** Memory cache for I/O contexts */
RTMEMCACHE hMemCacheIoCtx;
/** Memory cache for I/O tasks. */
RTMEMCACHE hMemCacheIoTask;
/** An I/O context is currently using the disk structures
* Every I/O context must be placed on one of the lists below. */
volatile bool fLocked;
/** Head of pending I/O tasks waiting for completion - LIFO order. */
volatile PVDIOTASK pIoTasksPendingHead;
/** Head of newly queued I/O contexts - LIFO order. */
volatile PVDIOCTX pIoCtxHead;
/** Head of halted I/O contexts which are given back to generic
* disk framework by the backend. - LIFO order. */
volatile PVDIOCTX pIoCtxHaltedHead;
/** Head of blocked I/O contexts, processed only
* after pIoCtxLockOwner was freed - LIFO order. */
volatile PVDIOCTX pIoCtxBlockedHead;
/** I/O context which locked the disk for a growing write or flush request.
* Other flush or growing write requests need to wait until
* the current one completes. - NIL_VDIOCTX if unlocked. */
volatile PVDIOCTX pIoCtxLockOwner;
/** If the disk was locked by a growing write, flush or discard request this
* contains the start offset to check for interfering I/O while it is in progress. */
uint64_t uOffsetStartLocked;
/** If the disk was locked by a growing write, flush or discard request this contains
* the first non affected offset to check for interfering I/O while it is in progress. */
uint64_t uOffsetEndLocked;
/** Pointer to the L2 disk cache if any. */
PVDCACHE pCache;
/** Pointer to the discard state if any. */
PVDDISCARDSTATE pDiscard;
/** Read filter chain - PVDFILTER. */
RTLISTANCHOR ListFilterChainRead;
/** Write filter chain - PVDFILTER. */
RTLISTANCHOR ListFilterChainWrite;
};
DECLHIDDEN(int) vdPluginInit(void);
DECLHIDDEN(int) vdPluginTerm(void);
DECLHIDDEN(bool) vdPluginIsInitialized(void);
DECLHIDDEN(int) vdPluginUnloadFromPath(const char *pszPath);
DECLHIDDEN(int) vdPluginUnloadFromFilename(const char *pszFilename);
DECLHIDDEN(int) vdPluginLoadFromPath(const char *pszPath);
DECLHIDDEN(int) vdPluginLoadFromFilename(const char *pszFilename);
DECLHIDDEN(uint32_t) vdGetImageBackendCount(void);
DECLHIDDEN(int) vdQueryImageBackend(uint32_t idx, PCVDIMAGEBACKEND *ppBackend);
DECLHIDDEN(int) vdFindImageBackend(const char *pszBackend, PCVDIMAGEBACKEND *ppBackend);
DECLHIDDEN(uint32_t) vdGetCacheBackendCount(void);
DECLHIDDEN(int) vdQueryCacheBackend(uint32_t idx, PCVDCACHEBACKEND *ppBackend);
DECLHIDDEN(int) vdFindCacheBackend(const char *pszBackend, PCVDCACHEBACKEND *ppBackend);
DECLHIDDEN(uint32_t) vdGetFilterBackendCount(void);
DECLHIDDEN(int) vdQueryFilterBackend(uint32_t idx, PCVDFILTERBACKEND *ppBackend);
DECLHIDDEN(int) vdFindFilterBackend(const char *pszFilter, PCVDFILTERBACKEND *ppBackend);
DECLHIDDEN(int) vdIoIterQueryStartNext(VDIOITER hVdIoIter, uint64_t *pu64Start);
DECLHIDDEN(int) vdIoIterQuerySegSizeByStart(VDIOITER hVdIoIter, uint64_t u64Start, size_t *pcRegSize);
DECLHIDDEN(int) vdIoIterAdvance(VDIOITER hVdIoIter, uint64_t cBlocksOrBytes);
#endif /* !VBOX_INCLUDED_SRC_Storage_VDInternal_h */
|