On Thu, Dec 4, 2025 at 10:57 AM Dongsheng Yang <[email protected]> wrote:
>
> In dm-pcache, in order to ensure crash-consistency, a dual-copy scheme
> is used to alternately update metadata, and there is a slot index that
> records the current slot. However, in the write path the current
> implementation writes directly to the current slot indexed by slot
> index, and then advances the slot — which ends up overwriting the
> existing slot, violating the crash-consistency guarantee.
>
> This patch fixes that behavior, preventing metadata from being
> overwritten incorrectly.
>
> Signed-off-by: Dongsheng Yang <[email protected]>
> ---
>  drivers/md/dm-pcache/cache.c         | 8 ++++----
>  drivers/md/dm-pcache/cache_segment.c | 8 ++++----
>  2 files changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/md/dm-pcache/cache.c b/drivers/md/dm-pcache/cache.c
> index 698697a7a73c..9289c016b7c9 100644
> --- a/drivers/md/dm-pcache/cache.c
> +++ b/drivers/md/dm-pcache/cache.c
> @@ -21,10 +21,10 @@ static void cache_info_write(struct pcache_cache *cache)
>         cache_info->header.crc = pcache_meta_crc(&cache_info->header,
>                                                 sizeof(struct 
> pcache_cache_info));
>
> +       cache->info_index = (cache->info_index + 1) % PCACHE_META_INDEX_MAX;
> +
>         memcpy_flushcache(get_cache_info_addr(cache), cache_info,
>                         sizeof(struct pcache_cache_info));
> -
> -       cache->info_index = (cache->info_index + 1) % PCACHE_META_INDEX_MAX;
>  }
>
>  static void cache_info_init_default(struct pcache_cache *cache);
> @@ -93,10 +93,10 @@ void cache_pos_encode(struct pcache_cache *cache,
>         pos_onmedia.header.seq = seq;
>         pos_onmedia.header.crc = cache_pos_onmedia_crc(&pos_onmedia);
>
> +       *index = (*index + 1) % PCACHE_META_INDEX_MAX;
> +
>         memcpy_flushcache(pos_onmedia_addr, &pos_onmedia, sizeof(struct 
> pcache_cache_pos_onmedia));
>         pmem_wmb();
> -
> -       *index = (*index + 1) % PCACHE_META_INDEX_MAX;
>  }
>
>  int cache_pos_decode(struct pcache_cache *cache,
> diff --git a/drivers/md/dm-pcache/cache_segment.c 
> b/drivers/md/dm-pcache/cache_segment.c
> index f0b58980806e..ae57cc261422 100644
> --- a/drivers/md/dm-pcache/cache_segment.c
> +++ b/drivers/md/dm-pcache/cache_segment.c
> @@ -26,11 +26,11 @@ static void cache_seg_info_write(struct 
> pcache_cache_segment *cache_seg)
>         seg_info->header.seq++;
>         seg_info->header.crc = pcache_meta_crc(&seg_info->header, 
> sizeof(struct pcache_segment_info));
>
> +       cache_seg->info_index = (cache_seg->info_index + 1) % 
> PCACHE_META_INDEX_MAX;
> +
>         seg_info_addr = get_seg_info_addr(cache_seg);
>         memcpy_flushcache(seg_info_addr, seg_info, sizeof(struct 
> pcache_segment_info));
>         pmem_wmb();
> -
> -       cache_seg->info_index = (cache_seg->info_index + 1) % 
> PCACHE_META_INDEX_MAX;
>         mutex_unlock(&cache_seg->info_lock);
>  }
>
> @@ -129,10 +129,10 @@ static void cache_seg_ctrl_write(struct 
> pcache_cache_segment *cache_seg)
>         cache_seg_gen.header.crc = pcache_meta_crc(&cache_seg_gen.header,
>                                                  sizeof(struct 
> pcache_cache_seg_gen));
>
> +       cache_seg->gen_index = (cache_seg->gen_index + 1) % 
> PCACHE_META_INDEX_MAX;
> +
>         memcpy_flushcache(get_cache_seg_gen_addr(cache_seg), &cache_seg_gen, 
> sizeof(struct pcache_cache_seg_gen));
>         pmem_wmb();
> -
> -       cache_seg->gen_index = (cache_seg->gen_index + 1) % 
> PCACHE_META_INDEX_MAX;
>  }
>
>  static void cache_seg_ctrl_init(struct pcache_cache_segment *cache_seg)
> --
> 2.43.0
>

Nice catch!

Reviewed-by:  Zheng Gu <[email protected]>

Regards,
Gu

Reply via email to