/* * Copyright (c) 2020 Red Hat, Inc. * * 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; either version 2 * of the License, or (at your option) any later version. * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. * * $Id: //eng/vdo-releases/aluminum/src/c++/vdo/base/volumeGeometry.h#5 $ */ #ifndef VOLUME_GEOMETRY_H #define VOLUME_GEOMETRY_H #include "uds.h" #include "types.h" struct indexConfig { uint32_t mem; uint32_t checkpointFrequency; bool sparse; } __attribute__((packed)); typedef enum { INDEX_REGION = 0, DATA_REGION = 1, VOLUME_REGION_COUNT, } VolumeRegionID; typedef struct { /** The ID of the region */ VolumeRegionID id; /** * The absolute starting offset on the device. The region continues until * the next region begins. */ PhysicalBlockNumber startBlock; } __attribute__((packed)) VolumeRegion; /** A binary UUID is 16 bytes. */ typedef unsigned char UUID[16]; typedef struct { /** The release version number of this volume */ ReleaseVersionNumber releaseVersion; /** The nonce of this volume */ Nonce nonce; /** The UUID of this volume */ UUID uuid; /** The regions in ID order */ VolumeRegion regions[VOLUME_REGION_COUNT]; /** The index config */ IndexConfig indexConfig; } __attribute__((packed)) VolumeGeometry; /** * Get the start of the index region from a geometry. * * @param geometry The geometry * * @return The start of the index region **/ __attribute__((warn_unused_result)) static inline PhysicalBlockNumber getIndexRegionOffset(VolumeGeometry geometry) { return geometry.regions[INDEX_REGION].startBlock; } /** * Get the start of the data region from a geometry. * * @param geometry The geometry * * @return The start of the data region **/ __attribute__((warn_unused_result)) static inline PhysicalBlockNumber getDataRegionOffset(VolumeGeometry geometry) { return geometry.regions[DATA_REGION].startBlock; } /** * Get the size of the index region from a geometry. * * @param geometry The geometry * * @return the size of the index region **/ __attribute__((warn_unused_result)) static inline PhysicalBlockNumber getIndexRegionSize(VolumeGeometry geometry) { return getDataRegionOffset(geometry) - getIndexRegionOffset(geometry); } /** * Read the volume geometry from a layer. * * @param layer The layer to read and parse the geometry from * @param geometry The geometry to be loaded **/ int loadVolumeGeometry(PhysicalLayer *layer, VolumeGeometry *geometry) __attribute__((warn_unused_result)); /** * Initialize a VolumeGeometry for a VDO. * * @param nonce The nonce for the VDO * @param uuid The uuid for the VDO * @param indexConfig The index config of the VDO. * @param geometry The geometry being initialized * * @return VDO_SUCCESS or an error **/ int initializeVolumeGeometry(Nonce nonce, UUID uuid, IndexConfig *indexConfig, VolumeGeometry *geometry) __attribute__((warn_unused_result)); /** * Zero out the geometry on a layer. * * @param layer The layer to clear * * @return VDO_SUCCESS or an error **/ int clearVolumeGeometry(PhysicalLayer *layer) __attribute__((warn_unused_result)); /** * Write a geometry block for a VDO. * * @param layer The layer on which to write. * @param geometry The VolumeGeometry to be written * * @return VDO_SUCCESS or an error **/ int writeVolumeGeometry(PhysicalLayer *layer, VolumeGeometry *geometry) __attribute__((warn_unused_result)); /** * Convert a index config to a UDS configuration, which can be used by UDS. * * @param [in] indexConfig The index config to convert * @param [out] udsConfigPtr A pointer to return the UDS configuration * * @return VDO_SUCCESS or an error **/ int indexConfigToUdsConfiguration(IndexConfig *indexConfig, UdsConfiguration *udsConfigPtr) __attribute__((warn_unused_result)); /** * Modify the uds_parameters to match the requested index config. * * @param indexConfig The index config to convert * @param userParams The uds_parameters to modify **/ void indexConfigToUdsParameters(IndexConfig *indexConfig, struct uds_parameters *userParams); /** * Compute the index size in blocks from the IndexConfig. * * @param [in] indexConfig The index config * @param [out] indexBlocksPtr A pointer to return the index size in blocks * * @return VDO_SUCCESS or an error **/ int computeIndexBlocks(IndexConfig *indexConfig, BlockCount *indexBlocksPtr) __attribute__((warn_unused_result)); /** * Set load config fields from a volume geometry. * * @param [in] geometry The geometry to use * @param [out] loadConfig The load config to set **/ static inline void setLoadConfigFromGeometry(VolumeGeometry *geometry, VDOLoadConfig *loadConfig) { loadConfig->firstBlockOffset = getDataRegionOffset(*geometry); loadConfig->releaseVersion = geometry->releaseVersion; loadConfig->nonce = geometry->nonce; } #endif // VOLUME_GEOMETRY_H