Blame source/vdo/base/recoveryJournalEntry.h

Packit Service 75d76b
/*
Packit Service 75d76b
 * Copyright (c) 2020 Red Hat, Inc.
Packit Service 75d76b
 *
Packit Service 75d76b
 * This program is free software; you can redistribute it and/or
Packit Service 75d76b
 * modify it under the terms of the GNU General Public License
Packit Service 75d76b
 * as published by the Free Software Foundation; either version 2
Packit Service 75d76b
 * of the License, or (at your option) any later version.
Packit Service 75d76b
 * 
Packit Service 75d76b
 * This program is distributed in the hope that it will be useful,
Packit Service 75d76b
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 75d76b
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 75d76b
 * GNU General Public License for more details.
Packit Service 75d76b
 * 
Packit Service 75d76b
 * You should have received a copy of the GNU General Public License
Packit Service 75d76b
 * along with this program; if not, write to the Free Software
Packit Service 75d76b
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit Service 75d76b
 * 02110-1301, USA. 
Packit Service 75d76b
 *
Packit Service 75d76b
 * $Id: //eng/vdo-releases/aluminum/src/c++/vdo/base/recoveryJournalEntry.h#1 $
Packit Service 75d76b
 */
Packit Service 75d76b
Packit Service 75d76b
#ifndef RECOVERY_JOURNAL_ENTRY_H
Packit Service 75d76b
#define RECOVERY_JOURNAL_ENTRY_H
Packit Service 75d76b
Packit Service 75d76b
#include "numeric.h"
Packit Service 75d76b
Packit Service 75d76b
#include "blockMapEntry.h"
Packit Service 75d76b
#include "journalPoint.h"
Packit Service 75d76b
#include "types.h"
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * A recovery journal entry stores two physical locations: a data location
Packit Service 75d76b
 * that is the value of a single mapping in the block map tree, and the
Packit Service 75d76b
 * location of the block map page and and slot that is either acquiring or
Packit Service 75d76b
 * releasing a reference to the data location. The journal entry also stores
Packit Service 75d76b
 * an operation code that says whether the reference is being acquired (an
Packit Service 75d76b
 * increment) or released (a decrement), and whether the mapping is for a
Packit Service 75d76b
 * logical block or for the block map tree itself.
Packit Service 75d76b
 **/
Packit Service 75d76b
typedef struct {
Packit Service 75d76b
  BlockMapSlot     slot;
Packit Service 75d76b
  DataLocation     mapping;
Packit Service 75d76b
  JournalOperation operation;
Packit Service 75d76b
} RecoveryJournalEntry;
Packit Service 75d76b
Packit Service 75d76b
/** The packed, on-disk representation of a recovery journal entry. */
Packit Service 75d76b
typedef union __attribute__((packed)) {
Packit Service 75d76b
  struct __attribute__((packed)) {
Packit Service 75d76b
    /**
Packit Service 75d76b
     * In little-endian bit order:
Packit Service 75d76b
     * Bits 15..12:  The four highest bits of the 36-bit physical block number
Packit Service 75d76b
     *               of the block map tree page
Packit Service 75d76b
     * Bits 11..2:   The 10-bit block map page slot number
Packit Service 75d76b
     * Bits 1..0:    The 2-bit JournalOperation of the entry
Packit Service 75d76b
     **/
Packit Service 75d76b
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
Packit Service 75d76b
    unsigned operation     : 2;
Packit Service 75d76b
    unsigned slotLow       : 6;
Packit Service 75d76b
    unsigned slotHigh      : 4;
Packit Service 75d76b
    unsigned pbnHighNibble : 4;
Packit Service 75d76b
#else
Packit Service 75d76b
    unsigned slotLow       : 6;
Packit Service 75d76b
    unsigned operation     : 2;
Packit Service 75d76b
    unsigned pbnHighNibble : 4;
Packit Service 75d76b
    unsigned slotHigh      : 4;
Packit Service 75d76b
#endif
Packit Service 75d76b
Packit Service 75d76b
    /**
Packit Service 75d76b
     * Bits 47..16:  The 32 low-order bits of the block map page PBN,
Packit Service 75d76b
     *               in little-endian byte order
Packit Service 75d76b
     **/
Packit Service 75d76b
    byte pbnLowWord[4];
Packit Service 75d76b
Packit Service 75d76b
    /**
Packit Service 75d76b
     * Bits 87..48:  The five-byte block map entry encoding the location that
Packit Service 75d76b
     *               was or will be stored in the block map page slot
Packit Service 75d76b
     **/
Packit Service 75d76b
    BlockMapEntry blockMapEntry;
Packit Service 75d76b
  } fields;
Packit Service 75d76b
Packit Service 75d76b
  // A raw view of the packed encoding.
Packit Service 75d76b
  uint8_t raw[11];
Packit Service 75d76b
Packit Service 75d76b
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
Packit Service 75d76b
  // This view is only valid on little-endian machines and is only present for
Packit Service 75d76b
  // ease of directly examining packed entries in GDB.
Packit Service 75d76b
  struct __attribute__((packed)) {
Packit Service 75d76b
    unsigned      operation     : 2;
Packit Service 75d76b
    unsigned      slot          : 10;
Packit Service 75d76b
    unsigned      pbnHighNibble : 4;
Packit Service 75d76b
    uint32_t      pbnLowWord;
Packit Service 75d76b
    BlockMapEntry blockMapEntry;
Packit Service 75d76b
  } littleEndian;
Packit Service 75d76b
#endif
Packit Service 75d76b
} PackedRecoveryJournalEntry;
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * Return the packed, on-disk representation of a recovery journal entry.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param entry   The journal entry to pack
Packit Service 75d76b
 *
Packit Service 75d76b
 * @return  The packed representation of the journal entry
Packit Service 75d76b
 **/
Packit Service 75d76b
static inline PackedRecoveryJournalEntry
Packit Service 75d76b
packRecoveryJournalEntry(const RecoveryJournalEntry *entry)
Packit Service 75d76b
{
Packit Service 75d76b
  PackedRecoveryJournalEntry packed = {
Packit Service 75d76b
    .fields = {
Packit Service 75d76b
      .operation     = entry->operation,
Packit Service 75d76b
      .slotLow       = entry->slot.slot & 0x3F,
Packit Service 75d76b
      .slotHigh      = (entry->slot.slot >> 6) & 0x0F,
Packit Service 75d76b
      .pbnHighNibble = (entry->slot.pbn >> 32) & 0x0F,
Packit Service 75d76b
      .blockMapEntry = packPBN(entry->mapping.pbn, entry->mapping.state),
Packit Service 75d76b
    }
Packit Service 75d76b
  };
Packit Service 75d76b
  storeUInt32LE(packed.fields.pbnLowWord, entry->slot.pbn & UINT_MAX);
Packit Service 75d76b
  return packed;
Packit Service 75d76b
}
Packit Service 75d76b
Packit Service 75d76b
/**
Packit Service 75d76b
 * Unpack the on-disk representation of a recovery journal entry.
Packit Service 75d76b
 *
Packit Service 75d76b
 * @param entry  The recovery journal entry to unpack
Packit Service 75d76b
 *
Packit Service 75d76b
 * @return  The unpacked entry
Packit Service 75d76b
 **/
Packit Service 75d76b
static inline RecoveryJournalEntry
Packit Service 75d76b
unpackRecoveryJournalEntry(const PackedRecoveryJournalEntry *entry)
Packit Service 75d76b
{
Packit Service 75d76b
  PhysicalBlockNumber low32 = getUInt32LE(entry->fields.pbnLowWord);
Packit Service 75d76b
  PhysicalBlockNumber high4 = entry->fields.pbnHighNibble;
Packit Service 75d76b
  return (RecoveryJournalEntry) {
Packit Service 75d76b
    .operation = entry->fields.operation,
Packit Service 75d76b
    .slot      = {
Packit Service 75d76b
      .pbn  = ((high4 << 32) | low32),
Packit Service 75d76b
      .slot = (entry->fields.slotLow | (entry->fields.slotHigh << 6)),
Packit Service 75d76b
    },
Packit Service 75d76b
    .mapping = unpackBlockMapEntry(&entry->fields.blockMapEntry),
Packit Service 75d76b
  };
Packit Service 75d76b
}
Packit Service 75d76b
Packit Service 75d76b
#endif // RECOVERY_JOURNAL_ENTRY_H