|
Packit Service |
cbade1 |
/*
|
|
Packit Service |
cbade1 |
* Copyright (c) 2020 Red Hat, Inc.
|
|
Packit Service |
cbade1 |
*
|
|
Packit Service |
cbade1 |
* This program is free software; you can redistribute it and/or
|
|
Packit Service |
cbade1 |
* modify it under the terms of the GNU General Public License
|
|
Packit Service |
cbade1 |
* as published by the Free Software Foundation; either version 2
|
|
Packit Service |
cbade1 |
* of the License, or (at your option) any later version.
|
|
Packit Service |
cbade1 |
*
|
|
Packit Service |
cbade1 |
* This program is distributed in the hope that it will be useful,
|
|
Packit Service |
cbade1 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
cbade1 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
cbade1 |
* GNU General Public License for more details.
|
|
Packit Service |
cbade1 |
*
|
|
Packit Service |
cbade1 |
* You should have received a copy of the GNU General Public License
|
|
Packit Service |
cbade1 |
* along with this program; if not, write to the Free Software
|
|
Packit Service |
cbade1 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
Packit Service |
cbade1 |
* 02110-1301, USA.
|
|
Packit Service |
cbade1 |
*
|
|
Packit Service |
cbade1 |
* $Id: //eng/vdo-releases/aluminum/src/c++/vdo/base/recoveryUtils.h#5 $
|
|
Packit Service |
cbade1 |
*/
|
|
Packit Service |
cbade1 |
|
|
Packit Service |
cbade1 |
#ifndef RECOVERY_UTILS_H
|
|
Packit Service |
cbade1 |
#define RECOVERY_UTILS_H
|
|
Packit Service |
cbade1 |
|
|
Packit Service |
cbade1 |
#include "constants.h"
|
|
Packit Service |
cbade1 |
#include "packedRecoveryJournalBlock.h"
|
|
Packit Service |
cbade1 |
#include "recoveryJournalEntry.h"
|
|
Packit Service |
cbade1 |
#include "recoveryJournalInternals.h"
|
|
Packit Service |
cbade1 |
#include "types.h"
|
|
Packit Service |
cbade1 |
|
|
Packit Service |
cbade1 |
/**
|
|
Packit Service |
cbade1 |
* Get the block header for a block at a position in the journal data.
|
|
Packit Service |
cbade1 |
*
|
|
Packit Service |
cbade1 |
* @param journal The recovery journal
|
|
Packit Service |
cbade1 |
* @param journalData The recovery journal data
|
|
Packit Service |
cbade1 |
* @param sequence The sequence number
|
|
Packit Service |
cbade1 |
*
|
|
Packit Service |
cbade1 |
* @return A pointer to a packed recovery journal block header.
|
|
Packit Service |
cbade1 |
**/
|
|
Packit Service |
cbade1 |
__attribute__((warn_unused_result))
|
|
Packit Service |
cbade1 |
static inline
|
|
Packit Service |
cbade1 |
PackedJournalHeader *getJournalBlockHeader(RecoveryJournal *journal,
|
|
Packit Service |
cbade1 |
char *journalData,
|
|
Packit Service |
cbade1 |
SequenceNumber sequence)
|
|
Packit Service |
cbade1 |
{
|
|
Packit Service |
cbade1 |
off_t blockOffset = (getRecoveryJournalBlockNumber(journal, sequence)
|
|
Packit Service |
cbade1 |
* VDO_BLOCK_SIZE);
|
|
Packit Service |
cbade1 |
return (PackedJournalHeader *) &journalData[blockOffset];
|
|
Packit Service |
cbade1 |
}
|
|
Packit Service |
cbade1 |
|
|
Packit Service |
cbade1 |
/**
|
|
Packit Service |
cbade1 |
* Determine whether the given header describes a valid block for the
|
|
Packit Service |
cbade1 |
* given journal. A block is not valid if it is unformatted, or if it
|
|
Packit Service |
cbade1 |
* is older than the last successful recovery or reformat.
|
|
Packit Service |
cbade1 |
*
|
|
Packit Service |
cbade1 |
* @param journal The journal to use
|
|
Packit Service |
cbade1 |
* @param header The unpacked block header to check
|
|
Packit Service |
cbade1 |
*
|
|
Packit Service |
cbade1 |
* @return True if the header is valid
|
|
Packit Service |
cbade1 |
**/
|
|
Packit Service |
cbade1 |
__attribute__((warn_unused_result))
|
|
Packit Service |
cbade1 |
static inline
|
|
Packit Service |
cbade1 |
bool isValidRecoveryJournalBlock(const RecoveryJournal *journal,
|
|
Packit Service |
cbade1 |
const RecoveryBlockHeader *header)
|
|
Packit Service |
cbade1 |
{
|
|
Packit Service |
cbade1 |
return ((header->metadataType == VDO_METADATA_RECOVERY_JOURNAL)
|
|
Packit Service |
cbade1 |
&& (header->nonce == journal->nonce)
|
|
Packit Service |
cbade1 |
&& (header->recoveryCount == journal->recoveryCount));
|
|
Packit Service |
cbade1 |
}
|
|
Packit Service |
cbade1 |
|
|
Packit Service |
cbade1 |
/**
|
|
Packit Service |
cbade1 |
* Determine whether the given header describes the exact block indicated.
|
|
Packit Service |
cbade1 |
*
|
|
Packit Service |
cbade1 |
* @param journal The journal to use
|
|
Packit Service |
cbade1 |
* @param header The unpacked block header to check
|
|
Packit Service |
cbade1 |
* @param sequence The expected sequence number
|
|
Packit Service |
cbade1 |
*
|
|
Packit Service |
cbade1 |
* @return True if the block matches
|
|
Packit Service |
cbade1 |
**/
|
|
Packit Service |
cbade1 |
__attribute__((warn_unused_result))
|
|
Packit Service |
cbade1 |
static inline
|
|
Packit Service |
cbade1 |
bool isExactRecoveryJournalBlock(const RecoveryJournal *journal,
|
|
Packit Service |
cbade1 |
const RecoveryBlockHeader *header,
|
|
Packit Service |
cbade1 |
SequenceNumber sequence)
|
|
Packit Service |
cbade1 |
{
|
|
Packit Service |
cbade1 |
return ((header->sequenceNumber == sequence)
|
|
Packit Service |
cbade1 |
&& isValidRecoveryJournalBlock(journal, header));
|
|
Packit Service |
cbade1 |
}
|
|
Packit Service |
cbade1 |
|
|
Packit Service |
cbade1 |
/**
|
|
Packit Service |
cbade1 |
* Determine whether the header of the given sector could describe a
|
|
Packit Service |
cbade1 |
* valid sector for the given journal block header.
|
|
Packit Service |
cbade1 |
*
|
|
Packit Service |
cbade1 |
* @param header The unpacked block header to compare against
|
|
Packit Service |
cbade1 |
* @param sector The packed sector to check
|
|
Packit Service |
cbade1 |
*
|
|
Packit Service |
cbade1 |
* @return True if the sector matches the block header
|
|
Packit Service |
cbade1 |
**/
|
|
Packit Service |
cbade1 |
__attribute__((warn_unused_result))
|
|
Packit Service |
cbade1 |
static inline
|
|
Packit Service |
cbade1 |
bool isValidRecoveryJournalSector(const RecoveryBlockHeader *header,
|
|
Packit Service |
cbade1 |
const PackedJournalSector *sector)
|
|
Packit Service |
cbade1 |
{
|
|
Packit Service |
cbade1 |
return ((header->checkByte == sector->checkByte)
|
|
Packit Service |
cbade1 |
&& (header->recoveryCount == sector->recoveryCount));
|
|
Packit Service |
cbade1 |
}
|
|
Packit Service |
cbade1 |
|
|
Packit Service |
cbade1 |
/**
|
|
Packit Service |
cbade1 |
* Load the journal data off the disk.
|
|
Packit Service |
cbade1 |
*
|
|
Packit Service |
cbade1 |
* @param [in] journal The recovery journal to load
|
|
Packit Service |
cbade1 |
* @param [in] parent The completion to notify when the load is
|
|
Packit Service |
cbade1 |
* complete
|
|
Packit Service |
cbade1 |
* @param [out] journalDataPtr A pointer to the journal data buffer (it is the
|
|
Packit Service |
cbade1 |
* caller's responsibility to free this buffer)
|
|
Packit Service |
cbade1 |
**/
|
|
Packit Service |
cbade1 |
void loadJournalAsync(RecoveryJournal *journal,
|
|
Packit Service |
cbade1 |
VDOCompletion *parent,
|
|
Packit Service |
cbade1 |
char **journalDataPtr);
|
|
Packit Service |
cbade1 |
|
|
Packit Service |
cbade1 |
/**
|
|
Packit Service |
cbade1 |
* Find the tail and the head of the journal by searching for the highest
|
|
Packit Service |
cbade1 |
* sequence number in a block with a valid nonce, and the highest head value
|
|
Packit Service |
cbade1 |
* among the blocks with valid nonces.
|
|
Packit Service |
cbade1 |
*
|
|
Packit Service |
cbade1 |
* @param [in] journal The recovery journal
|
|
Packit Service |
cbade1 |
* @param [in] journalData The journal data read from disk
|
|
Packit Service |
cbade1 |
* @param [out] tailPtr A pointer to return the tail found, or if
|
|
Packit Service |
cbade1 |
* no higher block is found, the value
|
|
Packit Service |
cbade1 |
* currently in the journal
|
|
Packit Service |
cbade1 |
* @param [out] blockMapHeadPtr A pointer to return the block map head
|
|
Packit Service |
cbade1 |
* @param [out] slabJournalHeadPtr An optional pointer to return the slab
|
|
Packit Service |
cbade1 |
* journal head
|
|
Packit Service |
cbade1 |
*
|
|
Packit Service |
cbade1 |
* @return True if there were valid journal blocks
|
|
Packit Service |
cbade1 |
**/
|
|
Packit Service |
cbade1 |
bool findHeadAndTail(RecoveryJournal *journal,
|
|
Packit Service |
cbade1 |
char *journalData,
|
|
Packit Service |
cbade1 |
SequenceNumber *tailPtr,
|
|
Packit Service |
cbade1 |
SequenceNumber *blockMapHeadPtr,
|
|
Packit Service |
cbade1 |
SequenceNumber *slabJournalHeadPtr);
|
|
Packit Service |
cbade1 |
|
|
Packit Service |
cbade1 |
/**
|
|
Packit Service |
cbade1 |
* Validate a recovery journal entry.
|
|
Packit Service |
cbade1 |
*
|
|
Packit Service |
cbade1 |
* @param vdo The VDO
|
|
Packit Service |
cbade1 |
* @param entry The entry to validate
|
|
Packit Service |
cbade1 |
*
|
|
Packit Service |
cbade1 |
* @return VDO_SUCCESS or an error
|
|
Packit Service |
cbade1 |
**/
|
|
Packit Service |
cbade1 |
int validateRecoveryJournalEntry(const VDO *vdo,
|
|
Packit Service |
cbade1 |
const RecoveryJournalEntry *entry)
|
|
Packit Service |
cbade1 |
__attribute__((warn_unused_result));
|
|
Packit Service |
cbade1 |
|
|
Packit Service |
cbade1 |
#endif // RECOVERY_UTILS_H
|