dm cache: policy change version from string to integer set
Separate dm cache policy version string into 3 unsigned numbers corresponding to major, minor and patchlevel and store them at the end of the on-disk metadata so we know which version of the policy generated the hints in case a future version wants to use them differently. Signed-off-by: Mike Snitzer <snitzer@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
This commit is contained in:
parent
e2e74d617e
commit
4e7f506f64
|
@ -83,6 +83,8 @@ struct cache_disk_superblock {
|
||||||
__le32 read_misses;
|
__le32 read_misses;
|
||||||
__le32 write_hits;
|
__le32 write_hits;
|
||||||
__le32 write_misses;
|
__le32 write_misses;
|
||||||
|
|
||||||
|
__le32 policy_version[CACHE_POLICY_VERSION_SIZE];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
struct dm_cache_metadata {
|
struct dm_cache_metadata {
|
||||||
|
@ -109,6 +111,7 @@ struct dm_cache_metadata {
|
||||||
bool clean_when_opened:1;
|
bool clean_when_opened:1;
|
||||||
|
|
||||||
char policy_name[CACHE_POLICY_NAME_SIZE];
|
char policy_name[CACHE_POLICY_NAME_SIZE];
|
||||||
|
unsigned policy_version[CACHE_POLICY_VERSION_SIZE];
|
||||||
size_t policy_hint_size;
|
size_t policy_hint_size;
|
||||||
struct dm_cache_statistics stats;
|
struct dm_cache_statistics stats;
|
||||||
};
|
};
|
||||||
|
@ -268,7 +271,8 @@ static int __write_initial_superblock(struct dm_cache_metadata *cmd)
|
||||||
memset(disk_super->uuid, 0, sizeof(disk_super->uuid));
|
memset(disk_super->uuid, 0, sizeof(disk_super->uuid));
|
||||||
disk_super->magic = cpu_to_le64(CACHE_SUPERBLOCK_MAGIC);
|
disk_super->magic = cpu_to_le64(CACHE_SUPERBLOCK_MAGIC);
|
||||||
disk_super->version = cpu_to_le32(CACHE_VERSION);
|
disk_super->version = cpu_to_le32(CACHE_VERSION);
|
||||||
memset(disk_super->policy_name, 0, CACHE_POLICY_NAME_SIZE);
|
memset(disk_super->policy_name, 0, sizeof(disk_super->policy_name));
|
||||||
|
memset(disk_super->policy_version, 0, sizeof(disk_super->policy_version));
|
||||||
disk_super->policy_hint_size = 0;
|
disk_super->policy_hint_size = 0;
|
||||||
|
|
||||||
r = dm_sm_copy_root(cmd->metadata_sm, &disk_super->metadata_space_map_root,
|
r = dm_sm_copy_root(cmd->metadata_sm, &disk_super->metadata_space_map_root,
|
||||||
|
@ -284,7 +288,6 @@ static int __write_initial_superblock(struct dm_cache_metadata *cmd)
|
||||||
disk_super->metadata_block_size = cpu_to_le32(DM_CACHE_METADATA_BLOCK_SIZE >> SECTOR_SHIFT);
|
disk_super->metadata_block_size = cpu_to_le32(DM_CACHE_METADATA_BLOCK_SIZE >> SECTOR_SHIFT);
|
||||||
disk_super->data_block_size = cpu_to_le32(cmd->data_block_size);
|
disk_super->data_block_size = cpu_to_le32(cmd->data_block_size);
|
||||||
disk_super->cache_blocks = cpu_to_le32(0);
|
disk_super->cache_blocks = cpu_to_le32(0);
|
||||||
memset(disk_super->policy_name, 0, sizeof(disk_super->policy_name));
|
|
||||||
|
|
||||||
disk_super->read_hits = cpu_to_le32(0);
|
disk_super->read_hits = cpu_to_le32(0);
|
||||||
disk_super->read_misses = cpu_to_le32(0);
|
disk_super->read_misses = cpu_to_le32(0);
|
||||||
|
@ -478,6 +481,9 @@ static void read_superblock_fields(struct dm_cache_metadata *cmd,
|
||||||
cmd->data_block_size = le32_to_cpu(disk_super->data_block_size);
|
cmd->data_block_size = le32_to_cpu(disk_super->data_block_size);
|
||||||
cmd->cache_blocks = to_cblock(le32_to_cpu(disk_super->cache_blocks));
|
cmd->cache_blocks = to_cblock(le32_to_cpu(disk_super->cache_blocks));
|
||||||
strncpy(cmd->policy_name, disk_super->policy_name, sizeof(cmd->policy_name));
|
strncpy(cmd->policy_name, disk_super->policy_name, sizeof(cmd->policy_name));
|
||||||
|
cmd->policy_version[0] = le32_to_cpu(disk_super->policy_version[0]);
|
||||||
|
cmd->policy_version[1] = le32_to_cpu(disk_super->policy_version[1]);
|
||||||
|
cmd->policy_version[2] = le32_to_cpu(disk_super->policy_version[2]);
|
||||||
cmd->policy_hint_size = le32_to_cpu(disk_super->policy_hint_size);
|
cmd->policy_hint_size = le32_to_cpu(disk_super->policy_hint_size);
|
||||||
|
|
||||||
cmd->stats.read_hits = le32_to_cpu(disk_super->read_hits);
|
cmd->stats.read_hits = le32_to_cpu(disk_super->read_hits);
|
||||||
|
@ -572,6 +578,9 @@ static int __commit_transaction(struct dm_cache_metadata *cmd,
|
||||||
disk_super->discard_nr_blocks = cpu_to_le64(from_dblock(cmd->discard_nr_blocks));
|
disk_super->discard_nr_blocks = cpu_to_le64(from_dblock(cmd->discard_nr_blocks));
|
||||||
disk_super->cache_blocks = cpu_to_le32(from_cblock(cmd->cache_blocks));
|
disk_super->cache_blocks = cpu_to_le32(from_cblock(cmd->cache_blocks));
|
||||||
strncpy(disk_super->policy_name, cmd->policy_name, sizeof(disk_super->policy_name));
|
strncpy(disk_super->policy_name, cmd->policy_name, sizeof(disk_super->policy_name));
|
||||||
|
disk_super->policy_version[0] = cpu_to_le32(cmd->policy_version[0]);
|
||||||
|
disk_super->policy_version[1] = cpu_to_le32(cmd->policy_version[1]);
|
||||||
|
disk_super->policy_version[2] = cpu_to_le32(cmd->policy_version[2]);
|
||||||
|
|
||||||
disk_super->read_hits = cpu_to_le32(cmd->stats.read_hits);
|
disk_super->read_hits = cpu_to_le32(cmd->stats.read_hits);
|
||||||
disk_super->read_misses = cpu_to_le32(cmd->stats.read_misses);
|
disk_super->read_misses = cpu_to_le32(cmd->stats.read_misses);
|
||||||
|
@ -1070,6 +1079,7 @@ static int begin_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *po
|
||||||
__le32 value;
|
__le32 value;
|
||||||
size_t hint_size;
|
size_t hint_size;
|
||||||
const char *policy_name = dm_cache_policy_get_name(policy);
|
const char *policy_name = dm_cache_policy_get_name(policy);
|
||||||
|
const unsigned *policy_version = dm_cache_policy_get_version(policy);
|
||||||
|
|
||||||
if (!policy_name[0] ||
|
if (!policy_name[0] ||
|
||||||
(strlen(policy_name) > sizeof(cmd->policy_name) - 1))
|
(strlen(policy_name) > sizeof(cmd->policy_name) - 1))
|
||||||
|
@ -1077,6 +1087,7 @@ static int begin_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *po
|
||||||
|
|
||||||
if (strcmp(cmd->policy_name, policy_name)) {
|
if (strcmp(cmd->policy_name, policy_name)) {
|
||||||
strncpy(cmd->policy_name, policy_name, sizeof(cmd->policy_name));
|
strncpy(cmd->policy_name, policy_name, sizeof(cmd->policy_name));
|
||||||
|
memcpy(cmd->policy_version, policy_version, sizeof(cmd->policy_version));
|
||||||
|
|
||||||
hint_size = dm_cache_policy_get_hint_size(policy);
|
hint_size = dm_cache_policy_get_hint_size(policy);
|
||||||
if (!hint_size)
|
if (!hint_size)
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
/*----------------------------------------------------------------*/
|
/*----------------------------------------------------------------*/
|
||||||
|
|
||||||
#define DM_MSG_PREFIX "cache cleaner"
|
#define DM_MSG_PREFIX "cache cleaner"
|
||||||
#define CLEANER_VERSION "1.0.0"
|
|
||||||
|
|
||||||
/* Cache entry struct. */
|
/* Cache entry struct. */
|
||||||
struct wb_cache_entry {
|
struct wb_cache_entry {
|
||||||
|
@ -434,6 +433,7 @@ static struct dm_cache_policy *wb_create(dm_cblock_t cache_size,
|
||||||
|
|
||||||
static struct dm_cache_policy_type wb_policy_type = {
|
static struct dm_cache_policy_type wb_policy_type = {
|
||||||
.name = "cleaner",
|
.name = "cleaner",
|
||||||
|
.version = {1, 0, 0},
|
||||||
.hint_size = 0,
|
.hint_size = 0,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.create = wb_create
|
.create = wb_create
|
||||||
|
@ -446,7 +446,10 @@ static int __init wb_init(void)
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
DMERR("register failed %d", r);
|
DMERR("register failed %d", r);
|
||||||
else
|
else
|
||||||
DMINFO("version " CLEANER_VERSION " loaded");
|
DMINFO("version %u.%u.%u loaded",
|
||||||
|
wb_policy_type.version[0],
|
||||||
|
wb_policy_type.version[1],
|
||||||
|
wb_policy_type.version[2]);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,6 +117,8 @@ void dm_cache_policy_destroy(struct dm_cache_policy *p);
|
||||||
*/
|
*/
|
||||||
const char *dm_cache_policy_get_name(struct dm_cache_policy *p);
|
const char *dm_cache_policy_get_name(struct dm_cache_policy *p);
|
||||||
|
|
||||||
|
const unsigned *dm_cache_policy_get_version(struct dm_cache_policy *p);
|
||||||
|
|
||||||
size_t dm_cache_policy_get_hint_size(struct dm_cache_policy *p);
|
size_t dm_cache_policy_get_hint_size(struct dm_cache_policy *p);
|
||||||
|
|
||||||
/*----------------------------------------------------------------*/
|
/*----------------------------------------------------------------*/
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
#include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
|
|
||||||
#define DM_MSG_PREFIX "cache-policy-mq"
|
#define DM_MSG_PREFIX "cache-policy-mq"
|
||||||
#define MQ_VERSION "1.0.0"
|
|
||||||
|
|
||||||
static struct kmem_cache *mq_entry_cache;
|
static struct kmem_cache *mq_entry_cache;
|
||||||
|
|
||||||
|
@ -1133,6 +1132,7 @@ bad_cache_alloc:
|
||||||
|
|
||||||
static struct dm_cache_policy_type mq_policy_type = {
|
static struct dm_cache_policy_type mq_policy_type = {
|
||||||
.name = "mq",
|
.name = "mq",
|
||||||
|
.version = {1, 0, 0},
|
||||||
.hint_size = 4,
|
.hint_size = 4,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.create = mq_create
|
.create = mq_create
|
||||||
|
@ -1140,6 +1140,7 @@ static struct dm_cache_policy_type mq_policy_type = {
|
||||||
|
|
||||||
static struct dm_cache_policy_type default_policy_type = {
|
static struct dm_cache_policy_type default_policy_type = {
|
||||||
.name = "default",
|
.name = "default",
|
||||||
|
.version = {1, 0, 0},
|
||||||
.hint_size = 4,
|
.hint_size = 4,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.create = mq_create
|
.create = mq_create
|
||||||
|
@ -1164,7 +1165,10 @@ static int __init mq_init(void)
|
||||||
|
|
||||||
r = dm_cache_policy_register(&default_policy_type);
|
r = dm_cache_policy_register(&default_policy_type);
|
||||||
if (!r) {
|
if (!r) {
|
||||||
DMINFO("version " MQ_VERSION " loaded");
|
DMINFO("version %u.%u.%u loaded",
|
||||||
|
mq_policy_type.version[0],
|
||||||
|
mq_policy_type.version[1],
|
||||||
|
mq_policy_type.version[2]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -150,6 +150,14 @@ const char *dm_cache_policy_get_name(struct dm_cache_policy *p)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(dm_cache_policy_get_name);
|
EXPORT_SYMBOL_GPL(dm_cache_policy_get_name);
|
||||||
|
|
||||||
|
const unsigned *dm_cache_policy_get_version(struct dm_cache_policy *p)
|
||||||
|
{
|
||||||
|
struct dm_cache_policy_type *t = p->private;
|
||||||
|
|
||||||
|
return t->version;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(dm_cache_policy_get_version);
|
||||||
|
|
||||||
size_t dm_cache_policy_get_hint_size(struct dm_cache_policy *p)
|
size_t dm_cache_policy_get_hint_size(struct dm_cache_policy *p)
|
||||||
{
|
{
|
||||||
struct dm_cache_policy_type *t = p->private;
|
struct dm_cache_policy_type *t = p->private;
|
||||||
|
|
|
@ -196,6 +196,7 @@ struct dm_cache_policy {
|
||||||
* We maintain a little register of the different policy types.
|
* We maintain a little register of the different policy types.
|
||||||
*/
|
*/
|
||||||
#define CACHE_POLICY_NAME_SIZE 16
|
#define CACHE_POLICY_NAME_SIZE 16
|
||||||
|
#define CACHE_POLICY_VERSION_SIZE 3
|
||||||
|
|
||||||
struct dm_cache_policy_type {
|
struct dm_cache_policy_type {
|
||||||
/* For use by the register code only. */
|
/* For use by the register code only. */
|
||||||
|
@ -206,6 +207,7 @@ struct dm_cache_policy_type {
|
||||||
* what gets passed on the target line to select your policy.
|
* what gets passed on the target line to select your policy.
|
||||||
*/
|
*/
|
||||||
char name[CACHE_POLICY_NAME_SIZE];
|
char name[CACHE_POLICY_NAME_SIZE];
|
||||||
|
unsigned version[CACHE_POLICY_VERSION_SIZE];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Policies may store a hint for each each cache block.
|
* Policies may store a hint for each each cache block.
|
||||||
|
|
Loading…
Reference in New Issue