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