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