dm cache: policy ignore hints if generated by different version
When reading the dm cache metadata from disk, ignore the policy hints unless they were generated by the same major version number of the same policy module. The hints are considered to be private data belonging to the specific module that generated them and there is no requirement for them to make sense to different versions of the policy that generated them. Policy modules are all required to work fine if no previous hints are supplied (or if existing hints are lost). Signed-off-by: Mike Snitzer <snitzer@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
This commit is contained in:
parent
4e7f506f64
commit
ea2dd8c1ed
|
@ -863,18 +863,43 @@ struct thunk {
|
|||
bool hints_valid;
|
||||
};
|
||||
|
||||
static bool policy_unchanged(struct dm_cache_metadata *cmd,
|
||||
struct dm_cache_policy *policy)
|
||||
{
|
||||
const char *policy_name = dm_cache_policy_get_name(policy);
|
||||
const unsigned *policy_version = dm_cache_policy_get_version(policy);
|
||||
size_t policy_hint_size = dm_cache_policy_get_hint_size(policy);
|
||||
|
||||
/*
|
||||
* Ensure policy names match.
|
||||
*/
|
||||
if (strncmp(cmd->policy_name, policy_name, sizeof(cmd->policy_name)))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Ensure policy major versions match.
|
||||
*/
|
||||
if (cmd->policy_version[0] != policy_version[0])
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Ensure policy hint sizes match.
|
||||
*/
|
||||
if (cmd->policy_hint_size != policy_hint_size)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool hints_array_initialized(struct dm_cache_metadata *cmd)
|
||||
{
|
||||
return cmd->hint_root && cmd->policy_hint_size;
|
||||
}
|
||||
|
||||
static bool hints_array_available(struct dm_cache_metadata *cmd,
|
||||
const char *policy_name)
|
||||
struct dm_cache_policy *policy)
|
||||
{
|
||||
bool policy_names_match = !strncmp(cmd->policy_name, policy_name,
|
||||
sizeof(cmd->policy_name));
|
||||
|
||||
return cmd->clean_when_opened && policy_names_match &&
|
||||
return cmd->clean_when_opened && policy_unchanged(cmd, policy) &&
|
||||
hints_array_initialized(cmd);
|
||||
}
|
||||
|
||||
|
@ -908,7 +933,8 @@ static int __load_mapping(void *context, uint64_t cblock, void *leaf)
|
|||
return r;
|
||||
}
|
||||
|
||||
static int __load_mappings(struct dm_cache_metadata *cmd, const char *policy_name,
|
||||
static int __load_mappings(struct dm_cache_metadata *cmd,
|
||||
struct dm_cache_policy *policy,
|
||||
load_mapping_fn fn, void *context)
|
||||
{
|
||||
struct thunk thunk;
|
||||
|
@ -918,18 +944,19 @@ static int __load_mappings(struct dm_cache_metadata *cmd, const char *policy_nam
|
|||
|
||||
thunk.cmd = cmd;
|
||||
thunk.respect_dirty_flags = cmd->clean_when_opened;
|
||||
thunk.hints_valid = hints_array_available(cmd, policy_name);
|
||||
thunk.hints_valid = hints_array_available(cmd, policy);
|
||||
|
||||
return dm_array_walk(&cmd->info, cmd->root, __load_mapping, &thunk);
|
||||
}
|
||||
|
||||
int dm_cache_load_mappings(struct dm_cache_metadata *cmd, const char *policy_name,
|
||||
int dm_cache_load_mappings(struct dm_cache_metadata *cmd,
|
||||
struct dm_cache_policy *policy,
|
||||
load_mapping_fn fn, void *context)
|
||||
{
|
||||
int r;
|
||||
|
||||
down_read(&cmd->root_lock);
|
||||
r = __load_mappings(cmd, policy_name, fn, context);
|
||||
r = __load_mappings(cmd, policy, fn, context);
|
||||
up_read(&cmd->root_lock);
|
||||
|
||||
return r;
|
||||
|
@ -1085,7 +1112,7 @@ static int begin_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *po
|
|||
(strlen(policy_name) > sizeof(cmd->policy_name) - 1))
|
||||
return -EINVAL;
|
||||
|
||||
if (strcmp(cmd->policy_name, policy_name)) {
|
||||
if (!policy_unchanged(cmd, policy)) {
|
||||
strncpy(cmd->policy_name, policy_name, sizeof(cmd->policy_name));
|
||||
memcpy(cmd->policy_version, policy_version, sizeof(cmd->policy_version));
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ typedef int (*load_mapping_fn)(void *context, dm_oblock_t oblock,
|
|||
dm_cblock_t cblock, bool dirty,
|
||||
uint32_t hint, bool hint_valid);
|
||||
int dm_cache_load_mappings(struct dm_cache_metadata *cmd,
|
||||
const char *policy_name,
|
||||
struct dm_cache_policy *policy,
|
||||
load_mapping_fn fn,
|
||||
void *context);
|
||||
|
||||
|
|
|
@ -2369,8 +2369,7 @@ static int cache_preresume(struct dm_target *ti)
|
|||
}
|
||||
|
||||
if (!cache->loaded_mappings) {
|
||||
r = dm_cache_load_mappings(cache->cmd,
|
||||
dm_cache_policy_get_name(cache->policy),
|
||||
r = dm_cache_load_mappings(cache->cmd, cache->policy,
|
||||
load_mapping, cache);
|
||||
if (r) {
|
||||
DMERR("could not load cache mappings");
|
||||
|
|
Loading…
Reference in New Issue