Skip to content

Commit

Permalink
dm cache: policy ignore hints if generated by different version
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
snitm authored and kergon committed Mar 20, 2013
1 parent 4e7f506 commit ea2dd8c
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 13 deletions.
47 changes: 37 additions & 10 deletions drivers/md/dm-cache-metadata.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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));

Expand Down
2 changes: 1 addition & 1 deletion drivers/md/dm-cache-metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
3 changes: 1 addition & 2 deletions drivers/md/dm-cache-target.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down

0 comments on commit ea2dd8c

Please sign in to comment.