Add the ability to set the era counter maintained by the dm-cache era policy shim to an arbitrary 32-bit value, to allow era rollback after the underlying device is restored from a snapshot. Signed-off-by: Morgan Mears <mmears@xxxxxxxxxx> --- drivers/md/dm-cache-policy-era.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/md/dm-cache-policy-era.c b/drivers/md/dm-cache-policy-era.c index d4fc0b0..c4cf2ba 100644 --- a/drivers/md/dm-cache-policy-era.c +++ b/drivers/md/dm-cache-policy-era.c @@ -155,6 +155,26 @@ static int incr_era_counter(struct era_policy *era, const char *curr_era_str, return r; } +static int set_era_counter(struct era_policy *era, const char *new_era_str, + era_match_fn_t dummy) +{ + era_t new_era_counter; + + /* + * Set the era counter to a user-provided value, as long as it is + * in range. + */ + + if (kstrtou32(new_era_str, 10, &new_era_counter)) + return -EINVAL; + if (new_era_counter > ERA_MAX_ERA) + return -EOVERFLOW; + era->era_counter = new_era_counter; + smp_wmb(); + + return 0; +} + static void *era_cblock_to_hint(struct shim_walk_map_ctx *ctx, dm_cblock_t cblock, dm_oblock_t oblock) { @@ -404,6 +424,7 @@ static int era_set_config_value(struct dm_cache_policy *p, const char *key, struct era_policy *era = to_era_policy(p); struct config_value_handler *vh, value_handlers[] = { { "increment_era_counter", incr_era_counter, NULL }, + { "set_era_counter", set_era_counter, NULL }, { "unmap_blocks_from_later_eras", cond_unmap_by_era, era_is_gt_value }, { "unmap_blocks_from_this_era_and_later", cond_unmap_by_era, era_is_gte_value }, { "unmap_blocks_from_this_era_and_earlier", cond_unmap_by_era, era_is_lte_value }, -- -- dm-devel mailing list dm-devel@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/dm-devel