|
Packit Service |
d40955 |
/*
|
|
Packit Service |
d40955 |
* Copyright (c) 2020 Red Hat, Inc.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* This program is free software; you can redistribute it and/or
|
|
Packit Service |
d40955 |
* modify it under the terms of the GNU General Public License
|
|
Packit Service |
d40955 |
* as published by the Free Software Foundation; either version 2
|
|
Packit Service |
d40955 |
* of the License, or (at your option) any later version.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* This program is distributed in the hope that it will be useful,
|
|
Packit Service |
d40955 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
d40955 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
d40955 |
* GNU General Public License for more details.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* You should have received a copy of the GNU General Public License
|
|
Packit Service |
d40955 |
* along with this program; if not, write to the Free Software
|
|
Packit Service |
d40955 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
Packit Service |
d40955 |
* 02110-1301, USA.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* $Id: //eng/vdo-releases/aluminum/src/c++/vdo/base/header.h#4 $
|
|
Packit Service |
d40955 |
*/
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
#ifndef HEADER_H
|
|
Packit Service |
d40955 |
#define HEADER_H
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
#include "buffer.h"
|
|
Packit Service |
d40955 |
#include "numeric.h"
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
#include "types.h"
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**
|
|
Packit Service |
d40955 |
* An in-memory representation of a version number for versioned structures on
|
|
Packit Service |
d40955 |
* disk.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* A version number consists of two portions, a major version and a
|
|
Packit Service |
d40955 |
* minor version. Any format change which does not require an explicit
|
|
Packit Service |
d40955 |
* upgrade step from the previous version should increment the minor
|
|
Packit Service |
d40955 |
* version. Any format change which either requires an explicit
|
|
Packit Service |
d40955 |
* upgrade step, or is wholly incompatible (i.e. can not be upgraded
|
|
Packit Service |
d40955 |
* to), should increment the major version, and set the minor version
|
|
Packit Service |
d40955 |
* to 0.
|
|
Packit Service |
d40955 |
**/
|
|
Packit Service |
d40955 |
typedef struct {
|
|
Packit Service |
d40955 |
uint32_t majorVersion;
|
|
Packit Service |
d40955 |
uint32_t minorVersion;
|
|
Packit Service |
d40955 |
} __attribute__((packed)) VersionNumber;
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**
|
|
Packit Service |
d40955 |
* A packed, machine-independent, on-disk representation of a VersionNumber.
|
|
Packit Service |
d40955 |
* Both fields are stored in little-endian byte order.
|
|
Packit Service |
d40955 |
**/
|
|
Packit Service |
d40955 |
typedef struct {
|
|
Packit Service |
d40955 |
byte majorVersion[4];
|
|
Packit Service |
d40955 |
byte minorVersion[4];
|
|
Packit Service |
d40955 |
} __attribute__((packed)) PackedVersionNumber;
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**
|
|
Packit Service |
d40955 |
* The registry of component ids for use in headers
|
|
Packit Service |
d40955 |
**/
|
|
Packit Service |
d40955 |
typedef enum {
|
|
Packit Service |
d40955 |
SUPER_BLOCK = 0,
|
|
Packit Service |
d40955 |
FIXED_LAYOUT = 1,
|
|
Packit Service |
d40955 |
RECOVERY_JOURNAL = 2,
|
|
Packit Service |
d40955 |
SLAB_DEPOT = 3,
|
|
Packit Service |
d40955 |
BLOCK_MAP = 4,
|
|
Packit Service |
d40955 |
GEOMETRY_BLOCK = 5,
|
|
Packit Service |
d40955 |
} ComponentID;
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**
|
|
Packit Service |
d40955 |
* The header for versioned data stored on disk.
|
|
Packit Service |
d40955 |
**/
|
|
Packit Service |
d40955 |
typedef struct {
|
|
Packit Service |
d40955 |
ComponentID id; // The component this is a header for
|
|
Packit Service |
d40955 |
VersionNumber version; // The version of the data format
|
|
Packit Service |
d40955 |
size_t size; // The size of the data following this header
|
|
Packit Service |
d40955 |
} __attribute__((packed)) Header;
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
enum {
|
|
Packit Service |
d40955 |
ENCODED_HEADER_SIZE = sizeof(Header),
|
|
Packit Service |
d40955 |
};
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**
|
|
Packit Service |
d40955 |
* Check whether two version numbers are the same.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @param versionA The first version
|
|
Packit Service |
d40955 |
* @param versionB The second version
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @return true if the two versions are the same
|
|
Packit Service |
d40955 |
**/
|
|
Packit Service |
d40955 |
static inline bool areSameVersion(VersionNumber versionA,
|
|
Packit Service |
d40955 |
VersionNumber versionB)
|
|
Packit Service |
d40955 |
{
|
|
Packit Service |
d40955 |
return ((versionA.majorVersion == versionB.majorVersion)
|
|
Packit Service |
d40955 |
&& (versionA.minorVersion == versionB.minorVersion));
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**
|
|
Packit Service |
d40955 |
* Check whether an actual version is upgradable to an expected version.
|
|
Packit Service |
d40955 |
* An actual version is upgradable if its major number is expected but
|
|
Packit Service |
d40955 |
* its minor number differs, and the expected version's minor number
|
|
Packit Service |
d40955 |
* is greater than the actual version's minor number.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @param expectedVersion The expected version
|
|
Packit Service |
d40955 |
* @param actualVersion The version being validated
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @return true if the actual version is upgradable
|
|
Packit Service |
d40955 |
**/
|
|
Packit Service |
d40955 |
static inline bool isUpgradableVersion(VersionNumber expectedVersion,
|
|
Packit Service |
d40955 |
VersionNumber actualVersion)
|
|
Packit Service |
d40955 |
{
|
|
Packit Service |
d40955 |
return ((expectedVersion.majorVersion == actualVersion.majorVersion)
|
|
Packit Service |
d40955 |
&& (expectedVersion.minorVersion > actualVersion.minorVersion));
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**
|
|
Packit Service |
d40955 |
* Check whether a version matches an expected version. Logs an error
|
|
Packit Service |
d40955 |
* describing a mismatch.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @param expectedVersion The expected version
|
|
Packit Service |
d40955 |
* @param actualVersion The version being validated
|
|
Packit Service |
d40955 |
* @param componentName The name of the component or the calling function
|
|
Packit Service |
d40955 |
* (for error logging)
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @return VDO_SUCCESS if the versions are the same
|
|
Packit Service |
d40955 |
* VDO_UNSUPPORTED_VERSION if the versions don't match
|
|
Packit Service |
d40955 |
**/
|
|
Packit Service |
d40955 |
int validateVersion(VersionNumber expectedVersion,
|
|
Packit Service |
d40955 |
VersionNumber actualVersion,
|
|
Packit Service |
d40955 |
const char *componentName)
|
|
Packit Service |
d40955 |
__attribute__((warn_unused_result));
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**
|
|
Packit Service |
d40955 |
* Check whether a header matches expectations. Logs an error describing the
|
|
Packit Service |
d40955 |
* first mismatch found.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @param expectedHeader The expected header
|
|
Packit Service |
d40955 |
* @param actualHeader The header being validated
|
|
Packit Service |
d40955 |
* @param exactSize If true, the size fields of the two headers must be
|
|
Packit Service |
d40955 |
* the same, otherwise actualSize >= expectedSize is OK
|
|
Packit Service |
d40955 |
* @param componentName The name of the component or the calling function
|
|
Packit Service |
d40955 |
* (for error logging)
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @return VDO_SUCCESS if the header meets expectations
|
|
Packit Service |
d40955 |
* VDO_INCORRECT_COMPONENT if the component ids don't match
|
|
Packit Service |
d40955 |
* VDO_UNSUPPORTED_VERSION if the versions or sizes don't match
|
|
Packit Service |
d40955 |
**/
|
|
Packit Service |
d40955 |
int validateHeader(const Header *expectedHeader,
|
|
Packit Service |
d40955 |
const Header *actualHeader,
|
|
Packit Service |
d40955 |
bool exactSize,
|
|
Packit Service |
d40955 |
const char *componentName)
|
|
Packit Service |
d40955 |
__attribute__((warn_unused_result));
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**
|
|
Packit Service |
d40955 |
* Encode a header into a buffer.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @param header The header to encode
|
|
Packit Service |
d40955 |
* @param buffer The buffer in which to encode the header
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @return UDS_SUCCESS or an error
|
|
Packit Service |
d40955 |
**/
|
|
Packit Service |
d40955 |
int encodeHeader(const Header *header, Buffer *buffer)
|
|
Packit Service |
d40955 |
__attribute__((warn_unused_result));
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**
|
|
Packit Service |
d40955 |
* Encode a version number into a buffer.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @param version The version to encode
|
|
Packit Service |
d40955 |
* @param buffer The buffer in which to encode the version
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @return UDS_SUCCESS or an error
|
|
Packit Service |
d40955 |
**/
|
|
Packit Service |
d40955 |
int encodeVersionNumber(VersionNumber version, Buffer *buffer)
|
|
Packit Service |
d40955 |
__attribute__((warn_unused_result));
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**
|
|
Packit Service |
d40955 |
* Decode a header from a buffer.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @param [in] buffer The buffer from which to decode the header
|
|
Packit Service |
d40955 |
* @param [out] header The header to decode
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @return UDS_SUCCESS or an error
|
|
Packit Service |
d40955 |
**/
|
|
Packit Service |
d40955 |
int decodeHeader(Buffer *buffer, Header *header)
|
|
Packit Service |
d40955 |
__attribute__((warn_unused_result));
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**
|
|
Packit Service |
d40955 |
* Decode a version number from a buffer.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @param buffer The buffer from which to decode the version
|
|
Packit Service |
d40955 |
* @param version The version structure to decode into
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @return UDS_SUCCESS or an error
|
|
Packit Service |
d40955 |
**/
|
|
Packit Service |
d40955 |
int decodeVersionNumber(Buffer *buffer, VersionNumber *version)
|
|
Packit Service |
d40955 |
__attribute__((warn_unused_result));
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**
|
|
Packit Service |
d40955 |
* Convert a VersionNumber to its packed on-disk representation.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @param version The version number to convert
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @return the platform-independent representation of the version
|
|
Packit Service |
d40955 |
**/
|
|
Packit Service |
d40955 |
static inline PackedVersionNumber packVersionNumber(VersionNumber version)
|
|
Packit Service |
d40955 |
{
|
|
Packit Service |
d40955 |
PackedVersionNumber packed;
|
|
Packit Service |
d40955 |
storeUInt32LE(packed.majorVersion, version.majorVersion);
|
|
Packit Service |
d40955 |
storeUInt32LE(packed.minorVersion, version.minorVersion);
|
|
Packit Service |
d40955 |
return packed;
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**
|
|
Packit Service |
d40955 |
* Convert a PackedVersionNumber to its native in-memory representation.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @param version The version number to convert
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @return the platform-independent representation of the version
|
|
Packit Service |
d40955 |
**/
|
|
Packit Service |
d40955 |
static inline VersionNumber unpackVersionNumber(PackedVersionNumber version)
|
|
Packit Service |
d40955 |
{
|
|
Packit Service |
d40955 |
return (VersionNumber) {
|
|
Packit Service |
d40955 |
.majorVersion = getUInt32LE(version.majorVersion),
|
|
Packit Service |
d40955 |
.minorVersion = getUInt32LE(version.minorVersion),
|
|
Packit Service |
d40955 |
};
|
|
Packit Service |
d40955 |
}
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
#endif // HEADER_H
|