mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
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).
This commit is contained in:
parent
4a394f410d
commit
518b814cdb
@ -1,5 +1,6 @@
|
||||
Version 2.02.169 -
|
||||
=====================================
|
||||
Support cache segment with configurable metadata format.
|
||||
Add allocation/cache_metadata_format profilable setttings.
|
||||
Use function cache_set_params() for both lvcreate and lvconvert.
|
||||
Skip rounding on cache chunk size boudary when create cache LV.
|
||||
|
@ -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
|
||||
|
@ -67,6 +67,7 @@ static const struct flag _lv_flags[] = {
|
||||
{LV_WRITEMOSTLY, "WRITEMOSTLY", STATUS_FLAG},
|
||||
{LV_ACTIVATION_SKIP, "ACTIVATION_SKIP", COMPATIBLE_FLAG},
|
||||
{LV_ERROR_WHEN_FULL, "ERROR_WHEN_FULL", COMPATIBLE_FLAG},
|
||||
{LV_METADATA_FORMAT, "METADATA_FORMAT", STATUS_FLAG},
|
||||
{LV_NOSCAN, NULL, 0},
|
||||
{LV_TEMPORARY, NULL, 0},
|
||||
{POOL_METADATA_SPARE, NULL, 0},
|
||||
|
@ -141,7 +141,8 @@
|
||||
#define LV_RESHAPE_DELTA_DISKS_MINUS UINT64_C(0x0200000000000000) /* LV reshape flag delta disks minus image(s) */
|
||||
|
||||
#define LV_REMOVE_AFTER_RESHAPE UINT64_C(0x0400000000000000) /* LV needs to be removed after a shrinking reshape */
|
||||
/* Next unused flag: UINT64_C(0x0800000000000000) */
|
||||
#define LV_METADATA_FORMAT UINT64_C(0x0800000000000000) /* LV has segments with metadata format */
|
||||
/* Next unused flag: UINT64_C(0x1000000000000000) */
|
||||
|
||||
/* Format features flags */
|
||||
#define FMT_SEGMENTS 0x00000001U /* Arbitrary segment params? */
|
||||
@ -503,6 +504,7 @@ struct lv_segment {
|
||||
struct logical_volume *pool_lv; /* For thin, cache */
|
||||
uint32_t device_id; /* For thin, 24bit */
|
||||
|
||||
cache_metadata_format_t cache_metadata_format;/* For cache_pool */
|
||||
cache_mode_t cache_mode; /* For cache_pool */
|
||||
const char *policy_name; /* For cache_pool */
|
||||
struct dm_config_node *policy_settings; /* For cache_pool */
|
||||
@ -964,6 +966,7 @@ struct lvcreate_params {
|
||||
uint32_t min_recovery_rate; /* RAID */
|
||||
uint32_t max_recovery_rate; /* RAID */
|
||||
|
||||
cache_metadata_format_t cache_metadata_format; /* cache */
|
||||
cache_mode_t cache_mode; /* cache */
|
||||
const char *policy_name; /* cache */
|
||||
struct dm_config_tree *policy_settings; /* cache */
|
||||
|
Loading…
Reference in New Issue
Block a user