Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions env/posix/ocf_env_headers.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright(c) 2019-2021 Intel Corporation
* Copyright(c) 2026 Unvertical
* SPDX-License-Identifier: BSD-3-Clause
*/

Expand All @@ -15,8 +16,9 @@
#define OCF_PREFIX_SHORT "[" OCF_LOGO "] "
#define OCF_PREFIX_LONG "Open CAS Framework"

#define OCF_VERSION_MAIN 20
#define OCF_VERSION_MAJOR 3
#define OCF_VERSION_MINOR 0
#define ENV_ADAPTER_NAME "OCF Posix"
#define ENV_ADAPTER_VERSION_MAIN 20
#define ENV_ADAPTER_VERSION_MAJOR 3
#define ENV_ADAPTER_VERSION_MINOR 0

#endif /* __OCF_ENV_HEADERS_H__ */
8 changes: 8 additions & 0 deletions inc/ocf_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
* @brief OCF definitions
*/

#define OCF_VERSION_MAIN 26
#define OCF_VERSION_MAJOR 9
#define OCF_VERSION_MINOR 0

/**
* Enabling debug statistics
*/
Expand Down Expand Up @@ -64,6 +68,10 @@
* Size of cache name
*/
#define OCF_CACHE_NAME_SIZE 32
/**
* Size of adapter name
*/
#define OCF_ADAPTER_NAME_SIZE 32
/**
* Value to turn off fallback pass through
*/
Expand Down
11 changes: 10 additions & 1 deletion inc/ocf_err.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,16 @@ typedef enum {
/** Operation not allowed when cleaner is disabled **/
OCF_ERR_CLEANER_DISABLED,

OCF_ERR_MAX = OCF_ERR_CLEANER_DISABLED,
/** Metadata was created by a different adapter */
OCF_ERR_ADAPTER_MISMATCH,

/** Adapter version mismatch */
OCF_ERR_ADAPTER_VER,

/** Metadata was created in different block mode */
OCF_ERR_BLOCK_MODE_MISMATCH,

OCF_ERR_MAX = OCF_ERR_BLOCK_MODE_MISMATCH,

} ocf_error_t;

Expand Down
15 changes: 15 additions & 0 deletions src/metadata/metadata.c
Original file line number Diff line number Diff line change
Expand Up @@ -1954,8 +1954,23 @@ static void ocf_metadata_probe_cmpl(struct ocf_metadata_read_sb_ctx *context)
if (METADATA_VERSION() != superblock->metadata_version)
OCF_CMPL_RET(priv, -OCF_ERR_METADATA_VER, &status);

/*
* Following fields presence and offset is dependent on metadata
* version, so they can be safely accessed only after positive
* metadata version verification.
*/

if (env_strncmp(superblock->adapter_name, OCF_ADAPTER_NAME_SIZE,
ENV_ADAPTER_NAME, OCF_ADAPTER_NAME_SIZE)) {
OCF_CMPL_RET(priv, -OCF_ERR_ADAPTER_MISMATCH, &status);
}

if (superblock->adapter_version != ADAPTER_VERSION())
OCF_CMPL_RET(priv, -OCF_ERR_ADAPTER_VER, &status);

env_strncpy(status.cache_name, OCF_CACHE_NAME_SIZE, superblock->name,
OCF_CACHE_NAME_SIZE);

status.cache_mode = superblock->cache_mode;
status.cache_line_size = superblock->line_size;

Expand Down
46 changes: 45 additions & 1 deletion src/metadata/metadata_superblock.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,15 @@ int ocf_metadata_validate_superblock(ocf_ctx_t ctx,
}

if (METADATA_VERSION() != superblock->metadata_version) {
ocf_log(ctx, log_err, "Metadata version mismatch!\n");
ocf_log(ctx, log_err, "Loading %s: metadata version mismatch! "
"Metadata was created by OCF %u.%u.%u, but "
"current version is %u.%u.%u\n", segment_name,
(superblock->metadata_version >> 16) & 0xff,
(superblock->metadata_version >> 8) & 0xff,
superblock->adapter_version & 0xff,
OCF_VERSION_MAIN,
OCF_VERSION_MAJOR,
OCF_VERSION_MINOR);
return -OCF_ERR_METADATA_VER;
}

Expand All @@ -128,6 +136,42 @@ int ocf_metadata_validate_superblock(ocf_ctx_t ctx,
return -OCF_ERR_CRC_MISMATCH;
}

if (env_strncmp(superblock->adapter_name, OCF_ADAPTER_NAME_SIZE,
ENV_ADAPTER_NAME, OCF_ADAPTER_NAME_SIZE)) {
/* Field comes off disk and need not be terminated - bound
* the print to its size instead of running past it.
*/
ocf_log(ctx, log_err, "Loading %s: metadata was created by "
"adapter '%.*s', but OCF is running as '%s'!\n",
segment_name, OCF_ADAPTER_NAME_SIZE,
superblock->adapter_name, ENV_ADAPTER_NAME);
return -OCF_ERR_ADAPTER_MISMATCH;
}

if (superblock->adapter_version != ADAPTER_VERSION()) {
ocf_log(ctx, log_err, "Loading %s: adapter version mismatch! "
"Metadata was created by %s %u.%u.%u, but OCF "
"is running under %s %u.%u.%u\n", segment_name,
ENV_ADAPTER_NAME,
(superblock->adapter_version >> 16) & 0xff,
(superblock->adapter_version >> 8) & 0xff,
superblock->adapter_version & 0xff,
ENV_ADAPTER_NAME,
ENV_ADAPTER_VERSION_MAIN,
ENV_ADAPTER_VERSION_MAJOR,
ENV_ADAPTER_VERSION_MINOR);
return -OCF_ERR_ADAPTER_VER;
}

if (superblock->metadata_4k_mode != METADATA_4K_MODE()) {
ocf_log(ctx, log_err, "Loading %s: metadata was created in %s "
"block mode, but OCF is running in %s block "
"mode!\n", segment_name,
superblock->metadata_4k_mode ? "4KiB" : "512B",
METADATA_4K_MODE() ? "4KiB" : "512B");
return -OCF_ERR_BLOCK_MODE_MISMATCH;
}

if (superblock->clean_shutdown > ocf_metadata_clean_shutdown) {
ocf_log_invalid_superblock("shutdown status");
return -OCF_ERR_INVAL;
Expand Down
38 changes: 28 additions & 10 deletions src/metadata/metadata_superblock.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,35 @@

/**
* @brief OCF cache metadata configuration superblock
*
* The first 12 bytes of superblock do not change between verions.
* These fields are used by metadata probe to recognize OCF metadata
* and identify metadata version and status.
* The layout is following:
* 0:7 | clean shutdown status
* 8:15 | dirty metadata present
* 16:31 | padding; kept for historic reasons; zeroed
* 32:63 | OCF magic number; must be 0x187E1CA6
* 64:95 | OCF metadata version
*
* The remaining fields can should be accessed only after confirming
* correct magic and metadata version.
*/
struct ocf_superblock_config {
/** WARNING: Metadata probe disregards metadata version when
* checking if the cache is dirty - position of next two fields
* shouldn't change!! */
uint8_t clean_shutdown;
uint8_t dirty_flushed;
/* Superblock header */
struct {
uint8_t clean_shutdown;
uint8_t dirty_flushed;
uint16_t _padding;
uint32_t magic_number;
uint32_t metadata_version;
};

/* Current core sequence number */
ocf_core_id_t curr_core_seq_no;

uint32_t magic_number;
/* Identity of the adapter */
char adapter_name[OCF_ADAPTER_NAME_SIZE];
uint32_t adapter_version;

uint32_t metadata_version;
bool metadata_4k_mode;

unsigned flapping_idx;

Expand All @@ -46,6 +61,9 @@ struct ocf_superblock_config {
ocf_cache_line_size_t line_size;
uint32_t core_count;

/* Current core sequence number */
ocf_core_id_t curr_core_seq_no;

unsigned long valid_core_bitmap[OCF_DIV_ROUND_UP_STATIC(OCF_CORE_NUM,
sizeof(unsigned long) * 8)];

Expand Down
22 changes: 17 additions & 5 deletions src/mngt/ocf_mngt_cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,9 +297,21 @@ static void __init_cores(ocf_cache_t cache)
sizeof(cache->conf_meta->valid_core_bitmap), 0));
}

static void __init_metadata_version(ocf_cache_t cache)
static void __init_superblock_header(ocf_cache_t cache)
{
cache->conf_meta->metadata_version = METADATA_VERSION();
cache->conf_meta->adapter_version = ADAPTER_VERSION();
cache->conf_meta->metadata_4k_mode = METADATA_4K_MODE();

/*
* Zero the whole field first - the name is covered by the superblock
* checksum, so the bytes past the terminator have to be deterministic.
*/
ENV_BUG_ON(env_memset(cache->conf_meta->adapter_name,
OCF_ADAPTER_NAME_SIZE, 0));
ENV_BUG_ON(env_strncpy(cache->conf_meta->adapter_name,
OCF_ADAPTER_NAME_SIZE, ENV_ADAPTER_NAME,
OCF_ADAPTER_NAME_SIZE - 1));
}

static void _reset_stats(ocf_pipeline_t pipeline, void *priv,
Expand Down Expand Up @@ -327,13 +339,13 @@ static void _reset_stats(ocf_pipeline_t pipeline, void *priv,
ocf_pipeline_next(pipeline);
}

static void _init_metadata_version(ocf_pipeline_t pipeline, void *priv,
static void _init_superblock_header(ocf_pipeline_t pipeline, void *priv,
ocf_pipeline_arg_t arg)
{
struct ocf_init_metadata_context *context = priv;
ocf_cache_t cache = context->cache;

__init_metadata_version(cache);
__init_superblock_header(cache);

ocf_pipeline_next(pipeline);
}
Expand All @@ -356,7 +368,7 @@ struct ocf_pipeline_properties ocf_init_attached_recovery_props = {
OCF_PL_STEP(ocf_metadata_init_collision),
OCF_PL_STEP(_init_parts_attached),
OCF_PL_STEP(_reset_stats),
OCF_PL_STEP(_init_metadata_version),
OCF_PL_STEP(_init_superblock_header),
OCF_PL_STEP_TERMINATOR(),
},
};
Expand Down Expand Up @@ -1598,7 +1610,7 @@ static void _ocf_mngt_cache_init(ocf_cache_t cache,
__init_free(cache);

__init_cores(cache);
__init_metadata_version(cache);
__init_superblock_header(cache);
__init_partitions(cache);
}

Expand Down
9 changes: 9 additions & 0 deletions src/ocf_def_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,15 @@
#define METADATA_VERSION() ((OCF_VERSION_MAIN << 16) + \
(OCF_VERSION_MAJOR << 8) + OCF_VERSION_MINOR)

#define ADAPTER_VERSION() ((ENV_ADAPTER_VERSION_MAIN << 16) + \
(ENV_ADAPTER_VERSION_MAJOR << 8) + ENV_ADAPTER_VERSION_MINOR)

#ifdef OCF_BLOCK_SIZE_4K
#define METADATA_4K_MODE() true
#else
#define METADATA_4K_MODE() false
#endif

/* call conditional reschedule every 'iterations' calls */
#define OCF_COND_RESCHED(cnt, iterations) \
if (unlikely(++(cnt) == (iterations))) { \
Expand Down
3 changes: 3 additions & 0 deletions tests/functional/pyocf/types/shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ class OcfErrorCode(IntEnum):
OCF_ERR_CORE_NOT_REMOVED = auto()
OCF_ERR_CACHE_NOT_STANDBY = auto()
OCF_ERR_CLEANER_DISABLED = auto()
OCF_ERR_ADAPTER_MISMATCH = auto()
OCF_ERR_ADAPTER_VER = auto()
OCF_ERR_BLOCK_MODE_MISMATCH = auto()


class OcfCompletion:
Expand Down
Loading