summaryrefslogtreecommitdiff
path: root/lib/cache_segtype
diff options
context:
space:
mode:
authorZdenek Kabelac <zkabelac@redhat.com>2017-03-01 12:26:56 +0100
committerZdenek Kabelac <zkabelac@redhat.com>2017-03-10 19:33:01 +0100
commit518b814cdb806f70f99aaa168fca45495b18a4cf (patch)
treeb53cdf46f6ab47e397aa877463969ff63b3f71cc /lib/cache_segtype
parent4a394f410d571d8c8ef7c9f87df781df0f7988bd (diff)
downloadlvm2-518b814cdb806f70f99aaa168fca45495b18a4cf.tar.gz
cache: LV supports cache segs with metadata format
Cache pool read/writes metadata_format within its segment type.. For CachePoolLV unselected metadata format is NOT stored in metadata. For CacheLV when metadata format is not present/selected in lvm2 metadata, it's automatically assumed to be the version 1 (backward compatible). To ensure older lvm2 will not 'miss-read' metadata with new version 2, such LV is marked with METADATA_FORMAT status flag (segment is specifying metadata format). So when cache uses metadata format 2, it will become inaccesible on older system without such support. (kernel dm cache < 1.10, lvm2 < 2.02.169).
Diffstat (limited to 'lib/cache_segtype')
-rw-r--r--lib/cache_segtype/cache.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/lib/cache_segtype/cache.c b/lib/cache_segtype/cache.c
index c378edafb..985af6856 100644
--- a/lib/cache_segtype/cache.c
+++ b/lib/cache_segtype/cache.c
@@ -52,6 +52,12 @@ static void _fix_missing_defaults(struct lv_segment *cpool_seg)
cpool_seg->policy_name);
}
+ if (cpool_seg->cache_metadata_format == CACHE_METADATA_FORMAT_UNSELECTED) {
+ cpool_seg->cache_metadata_format = CACHE_METADATA_FORMAT_1;
+ log_verbose("Cache pool %s uses implicit metadata format %u.",
+ display_lvname(cpool_seg->lv), cpool_seg->cache_metadata_format);
+ }
+
if (cpool_seg->cache_mode == CACHE_MODE_UNSELECTED) {
cpool_seg->cache_mode = CACHE_MODE_WHEN_MISSING;
log_verbose("Cache pool %s is missing cache mode, using %s.",
@@ -107,6 +113,16 @@ static int _cache_pool_text_import(struct lv_segment *seg,
return SEG_LOG_ERROR("Failed to duplicate policy in");
}
+ if (dm_config_has_node(sn, "metadata_format")) {
+ if (!dm_config_get_uint32(sn, "metadata_format", &seg->cache_metadata_format) ||
+ ((seg->cache_metadata_format != CACHE_METADATA_FORMAT_1) &&
+ (seg->cache_metadata_format != CACHE_METADATA_FORMAT_2)))
+ return SEG_LOG_ERROR("Unknown cache metadata format %u number in",
+ seg->cache_metadata_format);
+ if (seg->cache_metadata_format == CACHE_METADATA_FORMAT_2)
+ seg->lv->status |= LV_METADATA_FORMAT;
+ }
+
/*
* Read in policy args:
* policy_settings {
@@ -164,6 +180,25 @@ static int _cache_pool_text_export(const struct lv_segment *seg,
outf(f, "metadata = \"%s\"", seg->metadata_lv->name);
outf(f, "chunk_size = %" PRIu32, seg->chunk_size);
+ switch (seg->cache_metadata_format) {
+ case CACHE_METADATA_FORMAT_UNSELECTED:
+ /* Unselected format is not printed */
+ break;
+ case CACHE_METADATA_FORMAT_1:
+ /* If format 1 was already specified with cache pool, store it,
+ * otherwise format gets stored when LV is cached.
+ * NB: format 1 could be lost anytime, it's a default format.
+ * Older lvm2 tool can easily drop it.
+ */
+ case CACHE_METADATA_FORMAT_2: /* more in future ? */
+ outf(f, "metadata_format = " FMTu32, seg->cache_metadata_format);
+ break;
+ default:
+ log_error(INTERNAL_ERROR "LV %s is using unknown cache metadada format %u.",
+ display_lvname(seg->lv), seg->cache_metadata_format);
+ return 0;
+ }
+
/*
* Cache pool used by a cache LV holds data. Not ideal,
* but not worth to break backward compatibility, by shifting