Blame source/vdo/base/blockMapEntry.h

Packit Service 310c69
/*
Packit Service 310c69
 * Copyright (c) 2020 Red Hat, Inc.
Packit Service 310c69
 *
Packit Service 310c69
 * This program is free software; you can redistribute it and/or
Packit Service 310c69
 * modify it under the terms of the GNU General Public License
Packit Service 310c69
 * as published by the Free Software Foundation; either version 2
Packit Service 310c69
 * of the License, or (at your option) any later version.
Packit Service 310c69
 * 
Packit Service 310c69
 * This program is distributed in the hope that it will be useful,
Packit Service 310c69
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 310c69
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 310c69
 * GNU General Public License for more details.
Packit Service 310c69
 * 
Packit Service 310c69
 * You should have received a copy of the GNU General Public License
Packit Service 310c69
 * along with this program; if not, write to the Free Software
Packit Service 310c69
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit Service 310c69
 * 02110-1301, USA. 
Packit Service 310c69
 *
Packit Service 310c69
 * $Id: //eng/vdo-releases/aluminum/src/c++/vdo/base/blockMapEntry.h#4 $
Packit Service 310c69
 */
Packit Service 310c69
Packit Service 310c69
#ifndef BLOCK_MAP_ENTRY_H
Packit Service 310c69
#define BLOCK_MAP_ENTRY_H
Packit Service 310c69
Packit Service 310c69
#include "blockMappingState.h"
Packit Service 310c69
#include "constants.h"
Packit Service 310c69
#include "numeric.h"
Packit Service 310c69
#include "types.h"
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * The entry for each logical block in the block map is encoded into five
Packit Service 310c69
 * bytes, which saves space in both the on-disk and in-memory layouts. It
Packit Service 310c69
 * consists of the 36 low-order bits of a PhysicalBlockNumber (addressing 256
Packit Service 310c69
 * terabytes with a 4KB block size) and a 4-bit encoding of a
Packit Service 310c69
 * BlockMappingState.
Packit Service 310c69
 **/
Packit Service 310c69
typedef union __attribute__((packed)) blockMapEntry {
Packit Service 310c69
  struct __attribute__((packed)) {
Packit Service 310c69
    /**
Packit Service 310c69
     * Bits 7..4: The four highest bits of the 36-bit physical block number
Packit Service 310c69
     * Bits 3..0: The 4-bit BlockMappingState
Packit Service 310c69
     **/
Packit Service 310c69
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
Packit Service 310c69
    unsigned mappingState  : 4;
Packit Service 310c69
    unsigned pbnHighNibble : 4;
Packit Service 310c69
#else
Packit Service 310c69
    unsigned pbnHighNibble : 4;
Packit Service 310c69
    unsigned mappingState  : 4;
Packit Service 310c69
#endif
Packit Service 310c69
Packit Service 310c69
    /** 32 low-order bits of the 36-bit PBN, in little-endian byte order */
Packit Service 310c69
    byte pbnLowWord[4];
Packit Service 310c69
  } fields;
Packit Service 310c69
Packit Service 310c69
  // A raw view of the packed encoding.
Packit Service 310c69
  uint8_t raw[5];
Packit Service 310c69
Packit Service 310c69
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
Packit Service 310c69
  // This view is only valid on little-endian machines and is only present for
Packit Service 310c69
  // ease of directly examining packed entries in GDB.
Packit Service 310c69
  struct __attribute__((packed)) {
Packit Service 310c69
    unsigned mappingState  : 4;
Packit Service 310c69
    unsigned pbnHighNibble : 4;
Packit Service 310c69
    uint32_t pbnLowWord;
Packit Service 310c69
  } littleEndian;
Packit Service 310c69
#endif
Packit Service 310c69
} BlockMapEntry;
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Unpack the fields of a BlockMapEntry, returning them as a DataLocation.
Packit Service 310c69
 *
Packit Service 310c69
 * @param entry   A pointer to the entry to unpack
Packit Service 310c69
 *
Packit Service 310c69
 * @return the location of the data mapped by the block map entry
Packit Service 310c69
 **/
Packit Service 310c69
static inline DataLocation unpackBlockMapEntry(const BlockMapEntry *entry)
Packit Service 310c69
{
Packit Service 310c69
  PhysicalBlockNumber low32 = getUInt32LE(entry->fields.pbnLowWord);
Packit Service 310c69
  PhysicalBlockNumber high4 = entry->fields.pbnHighNibble;
Packit Service 310c69
  return (DataLocation) {
Packit Service 310c69
    .pbn   = ((high4 << 32) | low32),
Packit Service 310c69
    .state = entry->fields.mappingState,
Packit Service 310c69
  };
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/**********************************************************************/
Packit Service 310c69
static inline bool isMappedLocation(const DataLocation *location)
Packit Service 310c69
{
Packit Service 310c69
  return (location->state != MAPPING_STATE_UNMAPPED);
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/**********************************************************************/
Packit Service 310c69
static inline bool isValidLocation(const DataLocation *location)
Packit Service 310c69
{
Packit Service 310c69
  if (location->pbn == ZERO_BLOCK) {
Packit Service 310c69
    return !isCompressed(location->state);
Packit Service 310c69
  } else {
Packit Service 310c69
    return isMappedLocation(location);
Packit Service 310c69
  }
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Pack a PhysicalBlockNumber into a BlockMapEntry.
Packit Service 310c69
 *
Packit Service 310c69
 * @param pbn            The physical block number to convert to its
Packit Service 310c69
 *                       packed five-byte representation
Packit Service 310c69
 * @param mappingState   The mapping state of the block
Packit Service 310c69
 *
Packit Service 310c69
 * @return the packed representation of the block number and mapping state
Packit Service 310c69
 *
Packit Service 310c69
 * @note unrepresentable high bits of the unpacked PBN are silently truncated
Packit Service 310c69
 **/
Packit Service 310c69
static inline BlockMapEntry packPBN(PhysicalBlockNumber pbn,
Packit Service 310c69
                                    BlockMappingState   mappingState)
Packit Service 310c69
{
Packit Service 310c69
  BlockMapEntry entry;
Packit Service 310c69
  entry.fields.mappingState  = (mappingState & 0x0F);
Packit Service 310c69
  entry.fields.pbnHighNibble = ((pbn >> 32) & 0x0F),
Packit Service 310c69
  storeUInt32LE(entry.fields.pbnLowWord, pbn & UINT_MAX);
Packit Service 310c69
  return entry;
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
#endif // BLOCK_MAP_ENTRY_H