|
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
|