Blame source/vdo/base/blockMapPage.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/blockMapPage.h#8 $
Packit Service 310c69
 */
Packit Service 310c69
Packit Service 310c69
#ifndef BLOCK_MAP_PAGE_H
Packit Service 310c69
#define BLOCK_MAP_PAGE_H
Packit Service 310c69
Packit Service 310c69
#include "numeric.h"
Packit Service 310c69
Packit Service 310c69
#include "blockMapEntry.h"
Packit Service 310c69
#include "header.h"
Packit Service 310c69
#include "types.h"
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * The packed, on-disk representation of a block map page header.
Packit Service 310c69
 **/
Packit Service 310c69
typedef union __attribute__((packed)) {
Packit Service 310c69
  struct __attribute__((packed)) {
Packit Service 310c69
    /**
Packit Service 310c69
     * The 64-bit nonce of the current VDO, in little-endian byte order. Used
Packit Service 310c69
     * to determine whether or not a page has been formatted.
Packit Service 310c69
     **/
Packit Service 310c69
    byte nonce[8];
Packit Service 310c69
Packit Service 310c69
    /** The 64-bit PBN of this page, in little-endian byte order */
Packit Service 310c69
    byte pbn[8];
Packit Service 310c69
Packit Service 310c69
    /** Formerly recoverySequenceNumber; may be non-zero on disk */
Packit Service 310c69
    byte unusedLongWord[8];
Packit Service 310c69
Packit Service 310c69
    /** Whether this page has been initialized on disk (i.e. written twice) */
Packit Service 310c69
    bool initialized;
Packit Service 310c69
Packit Service 310c69
    /** Formerly entryOffset; now unused since it should always be zero */
Packit Service 310c69
    byte unusedByte1;
Packit Service 310c69
Packit Service 310c69
    /** Formerly interiorTreePageWriting; may be non-zero on disk */
Packit Service 310c69
    byte unusedByte2;
Packit Service 310c69
Packit Service 310c69
    /** Formerly generation (for dirty tree pages); may be non-zero on disk */
Packit Service 310c69
    byte unusedByte3;
Packit Service 310c69
  } fields;
Packit Service 310c69
Packit Service 310c69
  // A raw view of the packed encoding.
Packit Service 310c69
  uint8_t raw[8 + 8 + 8 + 1 + 1 + 1 + 1];
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
    uint64_t            nonce;
Packit Service 310c69
    PhysicalBlockNumber pbn;
Packit Service 310c69
    uint64_t            unusedLongWord;
Packit Service 310c69
    bool                initialized;
Packit Service 310c69
    uint8_t             unusedByte1;
Packit Service 310c69
    uint8_t             unusedByte2;
Packit Service 310c69
    uint8_t             unusedByte3;
Packit Service 310c69
  } littleEndian;
Packit Service 310c69
#endif
Packit Service 310c69
} PageHeader;
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * The format of a block map page.
Packit Service 310c69
 **/
Packit Service 310c69
typedef struct __attribute__((packed)) {
Packit Service 310c69
  PackedVersionNumber version;
Packit Service 310c69
  PageHeader          header;
Packit Service 310c69
  BlockMapEntry       entries[];
Packit Service 310c69
} BlockMapPage;
Packit Service 310c69
Packit Service 310c69
typedef enum {
Packit Service 310c69
  // A block map page is correctly initialized
Packit Service 310c69
  BLOCK_MAP_PAGE_VALID,
Packit Service 310c69
  // A block map page is uninitialized
Packit Service 310c69
  BLOCK_MAP_PAGE_INVALID,
Packit Service 310c69
  // A block map page is intialized, but is the wrong page
Packit Service 310c69
  BLOCK_MAP_PAGE_BAD,
Packit Service 310c69
} BlockMapPageValidity;
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Check whether a block map page has been initialized.
Packit Service 310c69
 *
Packit Service 310c69
 * @param page  The page to check
Packit Service 310c69
 *
Packit Service 310c69
 * @return true if the page has been initialized
Packit Service 310c69
 **/
Packit Service 310c69
__attribute__((warn_unused_result))
Packit Service 310c69
static inline bool isBlockMapPageInitialized(const BlockMapPage *page)
Packit Service 310c69
{
Packit Service 310c69
  return page->header.fields.initialized;
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Mark whether a block map page has been initialized.
Packit Service 310c69
 *
Packit Service 310c69
 * @param page         The page to mark
Packit Service 310c69
 * @param initialized  The state to set
Packit Service 310c69
 *
Packit Service 310c69
 * @return true if the initialized flag was modified
Packit Service 310c69
 **/
Packit Service 310c69
static inline bool markBlockMapPageInitialized(BlockMapPage *page,
Packit Service 310c69
                                               bool          initialized)
Packit Service 310c69
{
Packit Service 310c69
  if (initialized == page->header.fields.initialized) {
Packit Service 310c69
    return false;
Packit Service 310c69
  }
Packit Service 310c69
Packit Service 310c69
  page->header.fields.initialized = initialized;
Packit Service 310c69
  return true;
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Get the physical block number where a block map page is stored.
Packit Service 310c69
 *
Packit Service 310c69
 * @param page  The page to query
Packit Service 310c69
 *
Packit Service 310c69
 * @return the page's physical block number
Packit Service 310c69
 **/
Packit Service 310c69
__attribute__((warn_unused_result))
Packit Service 310c69
static inline PhysicalBlockNumber getBlockMapPagePBN(const BlockMapPage *page)
Packit Service 310c69
{
Packit Service 310c69
  return getUInt64LE(page->header.fields.pbn);
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Check whether a block map page is of the current version.
Packit Service 310c69
 *
Packit Service 310c69
 * @param page  The page to check
Packit Service 310c69
 *
Packit Service 310c69
 * @return true if the page has the current version
Packit Service 310c69
 **/
Packit Service 310c69
bool isCurrentBlockMapPage(const BlockMapPage *page)
Packit Service 310c69
  __attribute__((warn_unused_result));
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Format a block map page in memory.
Packit Service 310c69
 *
Packit Service 310c69
 * @param buffer       The buffer which holds the page
Packit Service 310c69
 * @param nonce        The VDO nonce
Packit Service 310c69
 * @param pbn          The absolute PBN of the page
Packit Service 310c69
 * @param initialized  Whether the page should be marked as initialized
Packit Service 310c69
 *
Packit Service 310c69
 * @return the buffer pointer, as a block map page (for convenience)
Packit Service 310c69
 **/
Packit Service 310c69
BlockMapPage *formatBlockMapPage(void                *buffer,
Packit Service 310c69
                                 Nonce                nonce,
Packit Service 310c69
                                 PhysicalBlockNumber  pbn,
Packit Service 310c69
                                 bool                 initialized);
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Check whether a newly read page is valid, upgrading its in-memory format if
Packit Service 310c69
 * possible and necessary. If the page is valid, clear fields which are not
Packit Service 310c69
 * meaningful on disk.
Packit Service 310c69
 *
Packit Service 310c69
 * @param page   The page to validate
Packit Service 310c69
 * @param nonce  The VDO nonce
Packit Service 310c69
 * @param pbn    The expected absolute PBN of the page
Packit Service 310c69
 *
Packit Service 310c69
 * @return The validity of the page
Packit Service 310c69
 **/
Packit Service 310c69
BlockMapPageValidity validateBlockMapPage(BlockMapPage        *page,
Packit Service 310c69
                                          Nonce                nonce,
Packit Service 310c69
                                          PhysicalBlockNumber  pbn)
Packit Service 310c69
  __attribute__((warn_unused_result));
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Update an entry on a block map page.
Packit Service 310c69
 *
Packit Service 310c69
 * @param [in]     page          The page to update
Packit Service 310c69
 * @param [in]     dataVIO       The DataVIO making the update
Packit Service 310c69
 * @param [in]     pbn           The new PBN for the entry
Packit Service 310c69
 * @param [in]     mappingState  The new mapping state for the entry
Packit Service 310c69
 * @param [in,out] recoveryLock  A reference to the current recovery sequence
Packit Service 310c69
 *                               number lock held by the page. Will be updated
Packit Service 310c69
 *                               if the lock changes to protect the new entry
Packit Service 310c69
 **/
Packit Service 310c69
void updateBlockMapPage(BlockMapPage        *page,
Packit Service 310c69
                        DataVIO             *dataVIO,
Packit Service 310c69
                        PhysicalBlockNumber  pbn,
Packit Service 310c69
                        BlockMappingState    mappingState,
Packit Service 310c69
                        SequenceNumber      *recoveryLock);
Packit Service 310c69
Packit Service 310c69
#endif // BLOCK_MAP_PAGE_H