/* $Id: VDInternal.h 98103 2023-01-17 14:15:46Z vboxsync $ */ /** @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 . * * 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 #include #include #include #include #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 */