/* * 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/compressedBlock.h#3 $ */ #ifndef COMPRESSED_BLOCK_H #define COMPRESSED_BLOCK_H #include "blockMappingState.h" #include "header.h" /** * The header of a compressed block. **/ typedef union __attribute__((packed)) { struct __attribute__((packed)) { /** Unsigned 32-bit major and minor versions, in little-endian byte order */ PackedVersionNumber version; /** List of unsigned 16-bit compressed block sizes, in little-endian order */ byte sizes[MAX_COMPRESSION_SLOTS][2]; } fields; // A raw view of the packed encoding. byte raw[4 + 4 + (2 * MAX_COMPRESSION_SLOTS)]; #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ // This view is only valid on little-endian machines and is only present for // ease of directly examining compressed block headers in GDB. struct __attribute__((packed)) { VersionNumber version; uint16_t sizes[MAX_COMPRESSION_SLOTS]; } littleEndian; #endif } CompressedBlockHeader; /** * The compressed block overlay. **/ typedef struct { CompressedBlockHeader header; char data[]; } __attribute__((packed)) CompressedBlock; /** * Initializes/resets a compressed block header. * * @param header the header * * When done, the version number is set to the current version, and all * fragments are empty. **/ void resetCompressedBlockHeader(CompressedBlockHeader *header); /** * Get a reference to a compressed fragment from a compression block. * * @param [in] mappingState the mapping state for the look up * @param [in] buffer buffer that contains compressed data * @param [in] blockSize size of a data block * @param [out] fragmentOffset the offset of the fragment within a * compressed block * @param [out] fragmentSize the size of the fragment * * @return If a valid compressed fragment is found, VDO_SUCCESS; * otherwise, VDO_INVALID_FRAGMENT if the fragment is invalid. **/ int getCompressedBlockFragment(BlockMappingState mappingState, char *buffer, BlockSize blockSize, uint16_t *fragmentOffset, uint16_t *fragmentSize); /** * Copy a fragment into the compressed block. * * @param block the compressed block * @param fragment the number of the fragment * @param offset the byte offset of the fragment in the data area * @param data a pointer to the compressed data * @param size the size of the data * * @note no bounds checking -- the data better fit without smashing other stuff **/ void putCompressedBlockFragment(CompressedBlock *block, unsigned int fragment, uint16_t offset, const char *data, uint16_t size); #endif // COMPRESSED_BLOCK_H