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