* [PATCH 1/3] dm-pcache: advance slot index before writing slot
@ 2025-12-04 2:53 Dongsheng Yang
2025-12-04 2:53 ` [PATCH 2/3] dm pcache: fix cache info indexing Dongsheng Yang
` (3 more replies)
0 siblings, 4 replies; 13+ messages in thread
From: Dongsheng Yang @ 2025-12-04 2:53 UTC (permalink / raw)
To: cengku, dm-devel, chenl311, mpatocka; +Cc: Dongsheng Yang
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 <dongsheng.yang@linux.dev>
---
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
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 2/3] dm pcache: fix cache info indexing
2025-12-04 2:53 [PATCH 1/3] dm-pcache: advance slot index before writing slot Dongsheng Yang
@ 2025-12-04 2:53 ` Dongsheng Yang
2025-12-04 3:09 ` Zheng Gu
2025-12-04 16:01 ` Mikulas Patocka
2025-12-04 2:53 ` [PATCH 3/3] dm pcache: fix segment " Dongsheng Yang
` (2 subsequent siblings)
3 siblings, 2 replies; 13+ messages in thread
From: Dongsheng Yang @ 2025-12-04 2:53 UTC (permalink / raw)
To: cengku, dm-devel, chenl311, mpatocka; +Cc: Dongsheng Yang
From: Li Chen <chenl311@chinatelecom.cn>
The on-media cache_info index used sizeof(struct) instead of the
4K metadata stride, so gc_percent updates from dmsetup message
were written between slots and lost after reboot. Use
PCACHE_CACHE_INFO_SIZE in get_cache_info_addr() and align
info_index with the slot returned by pcache_meta_find_latest().
Signed-off-by: Li Chen <chenl311@chinatelecom.cn>
Signed-off-by: Dongsheng Yang <dongsheng.yang@linux.dev>
---
drivers/md/dm-pcache/cache.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/md/dm-pcache/cache.c b/drivers/md/dm-pcache/cache.c
index 9289c016b7c9..bcc4e509aa69 100644
--- a/drivers/md/dm-pcache/cache.c
+++ b/drivers/md/dm-pcache/cache.c
@@ -8,9 +8,11 @@
struct kmem_cache *key_cache;
-static inline struct pcache_cache_info *get_cache_info_addr(struct pcache_cache *cache)
+static inline struct pcache_cache_info *
+get_cache_info_addr(struct pcache_cache *cache)
{
- return cache->cache_info_addr + cache->info_index;
+ return (struct pcache_cache_info *)((char *)cache->cache_info_addr +
+ (size_t)cache->info_index * PCACHE_CACHE_INFO_SIZE);
}
static void cache_info_write(struct pcache_cache *cache)
@@ -49,6 +51,8 @@ static int cache_info_init(struct pcache_cache *cache, struct pcache_cache_optio
return -EINVAL;
}
+ cache->info_index = ((char *)cache_info_addr - (char *)cache->cache_info_addr) / PCACHE_CACHE_INFO_SIZE;
+
return 0;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 3/3] dm pcache: fix segment info indexing
2025-12-04 2:53 [PATCH 1/3] dm-pcache: advance slot index before writing slot Dongsheng Yang
2025-12-04 2:53 ` [PATCH 2/3] dm pcache: fix cache info indexing Dongsheng Yang
@ 2025-12-04 2:53 ` Dongsheng Yang
2025-12-04 3:10 ` Zheng Gu
2025-12-04 15:59 ` Mikulas Patocka
2025-12-04 3:08 ` [PATCH 1/3] dm-pcache: advance slot index before writing slot Zheng Gu
2025-12-04 16:13 ` Mikulas Patocka
3 siblings, 2 replies; 13+ messages in thread
From: Dongsheng Yang @ 2025-12-04 2:53 UTC (permalink / raw)
To: cengku, dm-devel, chenl311, mpatocka; +Cc: Dongsheng Yang
From: Li Chen <chenl311@chinatelecom.cn>
Segment info indexing also used sizeof(struct) instead of the
4K metadata stride, so info_index could point between slots and
subsequent writes would advance incorrectly. Derive info_index
from the pointer returned by the segment meta search using
PCACHE_SEG_INFO_SIZE and advance to the next slot for future
updates.
Signed-off-by: Li Chen <chenl311@chinatelecom.cn>
Signed-off-by: Dongsheng Yang <dongsheng.yang@linux.dev>
---
drivers/md/dm-pcache/cache_segment.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/md/dm-pcache/cache_segment.c b/drivers/md/dm-pcache/cache_segment.c
index ae57cc261422..9d92e2b067ed 100644
--- a/drivers/md/dm-pcache/cache_segment.c
+++ b/drivers/md/dm-pcache/cache_segment.c
@@ -56,7 +56,10 @@ static int cache_seg_info_load(struct pcache_cache_segment *cache_seg)
ret = -EIO;
goto out;
}
- cache_seg->info_index = cache_seg_info_addr - cache_seg_info_addr_base;
+
+ cache_seg->info_index =
+ ((char *)cache_seg_info_addr - (char *)cache_seg_info_addr_base) /
+ PCACHE_SEG_INFO_SIZE;
out:
mutex_unlock(&cache_seg->info_lock);
--
2.43.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 1/3] dm-pcache: advance slot index before writing slot
2025-12-04 2:53 [PATCH 1/3] dm-pcache: advance slot index before writing slot Dongsheng Yang
2025-12-04 2:53 ` [PATCH 2/3] dm pcache: fix cache info indexing Dongsheng Yang
2025-12-04 2:53 ` [PATCH 3/3] dm pcache: fix segment " Dongsheng Yang
@ 2025-12-04 3:08 ` Zheng Gu
2025-12-04 16:13 ` Mikulas Patocka
3 siblings, 0 replies; 13+ messages in thread
From: Zheng Gu @ 2025-12-04 3:08 UTC (permalink / raw)
To: Dongsheng Yang; +Cc: dm-devel, chenl311, mpatocka
On Thu, Dec 4, 2025 at 10:57 AM Dongsheng Yang <dongsheng.yang@linux.dev> 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 <dongsheng.yang@linux.dev>
> ---
> 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 <cengku@gmail.com>
Regards,
Gu
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/3] dm pcache: fix cache info indexing
2025-12-04 2:53 ` [PATCH 2/3] dm pcache: fix cache info indexing Dongsheng Yang
@ 2025-12-04 3:09 ` Zheng Gu
2025-12-04 16:01 ` Mikulas Patocka
1 sibling, 0 replies; 13+ messages in thread
From: Zheng Gu @ 2025-12-04 3:09 UTC (permalink / raw)
To: Dongsheng Yang; +Cc: dm-devel, chenl311, mpatocka
On Thu, Dec 4, 2025 at 10:57 AM Dongsheng Yang <dongsheng.yang@linux.dev> wrote:
>
> From: Li Chen <chenl311@chinatelecom.cn>
>
> The on-media cache_info index used sizeof(struct) instead of the
> 4K metadata stride, so gc_percent updates from dmsetup message
> were written between slots and lost after reboot. Use
> PCACHE_CACHE_INFO_SIZE in get_cache_info_addr() and align
> info_index with the slot returned by pcache_meta_find_latest().
>
> Signed-off-by: Li Chen <chenl311@chinatelecom.cn>
> Signed-off-by: Dongsheng Yang <dongsheng.yang@linux.dev>
> ---
> drivers/md/dm-pcache/cache.c | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/md/dm-pcache/cache.c b/drivers/md/dm-pcache/cache.c
> index 9289c016b7c9..bcc4e509aa69 100644
> --- a/drivers/md/dm-pcache/cache.c
> +++ b/drivers/md/dm-pcache/cache.c
> @@ -8,9 +8,11 @@
>
> struct kmem_cache *key_cache;
>
> -static inline struct pcache_cache_info *get_cache_info_addr(struct pcache_cache *cache)
> +static inline struct pcache_cache_info *
> +get_cache_info_addr(struct pcache_cache *cache)
> {
> - return cache->cache_info_addr + cache->info_index;
> + return (struct pcache_cache_info *)((char *)cache->cache_info_addr +
> + (size_t)cache->info_index * PCACHE_CACHE_INFO_SIZE);
> }
>
> static void cache_info_write(struct pcache_cache *cache)
> @@ -49,6 +51,8 @@ static int cache_info_init(struct pcache_cache *cache, struct pcache_cache_optio
> return -EINVAL;
> }
>
> + cache->info_index = ((char *)cache_info_addr - (char *)cache->cache_info_addr) / PCACHE_CACHE_INFO_SIZE;
> +
> return 0;
> }
>
> --
> 2.43.0
>
Reviewed-by: Zheng Gu <cengku@gmail.com>
Regards,
Gu
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 3/3] dm pcache: fix segment info indexing
2025-12-04 2:53 ` [PATCH 3/3] dm pcache: fix segment " Dongsheng Yang
@ 2025-12-04 3:10 ` Zheng Gu
2025-12-04 15:59 ` Mikulas Patocka
1 sibling, 0 replies; 13+ messages in thread
From: Zheng Gu @ 2025-12-04 3:10 UTC (permalink / raw)
To: Dongsheng Yang; +Cc: dm-devel, chenl311, mpatocka
On Thu, Dec 4, 2025 at 10:57 AM Dongsheng Yang <dongsheng.yang@linux.dev> wrote:
>
> From: Li Chen <chenl311@chinatelecom.cn>
>
> Segment info indexing also used sizeof(struct) instead of the
> 4K metadata stride, so info_index could point between slots and
> subsequent writes would advance incorrectly. Derive info_index
> from the pointer returned by the segment meta search using
> PCACHE_SEG_INFO_SIZE and advance to the next slot for future
> updates.
>
> Signed-off-by: Li Chen <chenl311@chinatelecom.cn>
> Signed-off-by: Dongsheng Yang <dongsheng.yang@linux.dev>
> ---
> drivers/md/dm-pcache/cache_segment.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/md/dm-pcache/cache_segment.c b/drivers/md/dm-pcache/cache_segment.c
> index ae57cc261422..9d92e2b067ed 100644
> --- a/drivers/md/dm-pcache/cache_segment.c
> +++ b/drivers/md/dm-pcache/cache_segment.c
> @@ -56,7 +56,10 @@ static int cache_seg_info_load(struct pcache_cache_segment *cache_seg)
> ret = -EIO;
> goto out;
> }
> - cache_seg->info_index = cache_seg_info_addr - cache_seg_info_addr_base;
> +
> + cache_seg->info_index =
> + ((char *)cache_seg_info_addr - (char *)cache_seg_info_addr_base) /
> + PCACHE_SEG_INFO_SIZE;
> out:
> mutex_unlock(&cache_seg->info_lock);
>
> --
> 2.43.0
>
Reviewed-by: Zheng Gu <cengku@gmail.com>
Regards,
Gu
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 3/3] dm pcache: fix segment info indexing
2025-12-04 2:53 ` [PATCH 3/3] dm pcache: fix segment " Dongsheng Yang
2025-12-04 3:10 ` Zheng Gu
@ 2025-12-04 15:59 ` Mikulas Patocka
2025-12-05 3:05 ` Dongsheng Yang
1 sibling, 1 reply; 13+ messages in thread
From: Mikulas Patocka @ 2025-12-04 15:59 UTC (permalink / raw)
To: Dongsheng Yang; +Cc: cengku, dm-devel, chenl311
On Thu, 4 Dec 2025, Dongsheng Yang wrote:
> From: Li Chen <chenl311@chinatelecom.cn>
>
> Segment info indexing also used sizeof(struct) instead of the
> 4K metadata stride, so info_index could point between slots and
> subsequent writes would advance incorrectly. Derive info_index
> from the pointer returned by the segment meta search using
> PCACHE_SEG_INFO_SIZE and advance to the next slot for future
> updates.
>
> Signed-off-by: Li Chen <chenl311@chinatelecom.cn>
> Signed-off-by: Dongsheng Yang <dongsheng.yang@linux.dev>
> ---
> drivers/md/dm-pcache/cache_segment.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/md/dm-pcache/cache_segment.c b/drivers/md/dm-pcache/cache_segment.c
> index ae57cc261422..9d92e2b067ed 100644
> --- a/drivers/md/dm-pcache/cache_segment.c
> +++ b/drivers/md/dm-pcache/cache_segment.c
> @@ -56,7 +56,10 @@ static int cache_seg_info_load(struct pcache_cache_segment *cache_seg)
> ret = -EIO;
> goto out;
> }
> - cache_seg->info_index = cache_seg_info_addr - cache_seg_info_addr_base;
> +
> + cache_seg->info_index =
> + ((char *)cache_seg_info_addr - (char *)cache_seg_info_addr_base) /
> + PCACHE_SEG_INFO_SIZE;
> out:
> mutex_unlock(&cache_seg->info_lock);
>
Hi
I already staged the patch below. Which patch is valid? Your new patch or
the patch that I staged?
Mikulas
diff --git a/drivers/md/dm-pcache/cache_segment.c
b/drivers/md/dm-pcache/cache_segment.c
index f0b58980806e..0b4bb08011ce 100644
--- a/drivers/md/dm-pcache/cache_segment.c
+++ b/drivers/md/dm-pcache/cache_segment.c
@@ -56,7 +56,11 @@ static int cache_seg_info_load(struct
pcache_cache_segment *cache_seg)
ret = -EIO;
goto out;
}
- cache_seg->info_index = cache_seg_info_addr - cache_seg_info_addr_base;
+
+ cache_seg->info_index =
+ ((char *)cache_seg_info_addr - (char *)cache_seg_info_addr_base) /
+ PCACHE_SEG_INFO_SIZE;
+ cache_seg->info_index = (cache_seg->info_index + 1) % PCACHE_META_INDEX_MAX;
out:
mutex_unlock(&cache_seg->info_lock);
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 2/3] dm pcache: fix cache info indexing
2025-12-04 2:53 ` [PATCH 2/3] dm pcache: fix cache info indexing Dongsheng Yang
2025-12-04 3:09 ` Zheng Gu
@ 2025-12-04 16:01 ` Mikulas Patocka
2025-12-05 3:05 ` Dongsheng Yang
1 sibling, 1 reply; 13+ messages in thread
From: Mikulas Patocka @ 2025-12-04 16:01 UTC (permalink / raw)
To: Dongsheng Yang; +Cc: cengku, dm-devel, chenl311
On Thu, 4 Dec 2025, Dongsheng Yang wrote:
> From: Li Chen <chenl311@chinatelecom.cn>
>
> The on-media cache_info index used sizeof(struct) instead of the
> 4K metadata stride, so gc_percent updates from dmsetup message
> were written between slots and lost after reboot. Use
> PCACHE_CACHE_INFO_SIZE in get_cache_info_addr() and align
> info_index with the slot returned by pcache_meta_find_latest().
>
> Signed-off-by: Li Chen <chenl311@chinatelecom.cn>
> Signed-off-by: Dongsheng Yang <dongsheng.yang@linux.dev>
> ---
> drivers/md/dm-pcache/cache.c | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/md/dm-pcache/cache.c b/drivers/md/dm-pcache/cache.c
> index 9289c016b7c9..bcc4e509aa69 100644
> --- a/drivers/md/dm-pcache/cache.c
> +++ b/drivers/md/dm-pcache/cache.c
> @@ -8,9 +8,11 @@
>
> struct kmem_cache *key_cache;
>
> -static inline struct pcache_cache_info *get_cache_info_addr(struct pcache_cache *cache)
> +static inline struct pcache_cache_info *
> +get_cache_info_addr(struct pcache_cache *cache)
> {
> - return cache->cache_info_addr + cache->info_index;
> + return (struct pcache_cache_info *)((char *)cache->cache_info_addr +
> + (size_t)cache->info_index * PCACHE_CACHE_INFO_SIZE);
> }
>
> static void cache_info_write(struct pcache_cache *cache)
> @@ -49,6 +51,8 @@ static int cache_info_init(struct pcache_cache *cache, struct pcache_cache_optio
> return -EINVAL;
> }
>
> + cache->info_index = ((char *)cache_info_addr - (char *)cache->cache_info_addr) / PCACHE_CACHE_INFO_SIZE;
> +
> return 0;
> }
>
> --
> 2.43.0
I already staged the patch below? Should I revert it and stage your new
patch?
Mikulas
diff --git a/drivers/md/dm-pcache/cache.c b/drivers/md/dm-pcache/cache.c
index d8e92367d947..9554d1158450 100644
--- a/drivers/md/dm-pcache/cache.c
+++ b/drivers/md/dm-pcache/cache.c
@@ -8,9 +8,11 @@
struct kmem_cache *key_cache;
-static inline struct pcache_cache_info *get_cache_info_addr(struct pcache_cache *cache)
+static inline struct pcache_cache_info *
+get_cache_info_addr(struct pcache_cache *cache)
{
- return cache->cache_info_addr + cache->info_index;
+ return (struct pcache_cache_info *)((char *)cache->cache_info_addr
+
+ (size_t)cache->info_index * PCACHE_CACHE_INFO_SIZE);
}
static void cache_info_write(struct pcache_cache *cache)
@@ -40,7 +42,12 @@ static int cache_info_init(struct pcache_cache *cache,
struct pcache_cache_optio
if (IS_ERR(cache_info_addr))
return PTR_ERR(cache_info_addr);
- if (cache_info_addr) {
+ if (cache_info_addr) {
+ int index = ((char *)cache_info_addr - (char *)cache->cache_info_addr) /
+ PCACHE_CACHE_INFO_SIZE;
+
+ cache->info_index = (index + 1) % PCACHE_META_INDEX_MAX;
+
if (opts->data_crc !=
(cache->cache_info.flags & PCACHE_CACHE_FLAGS_DATA_CRC)) {
pcache_dev_err(pcache, "invalid option for data_crc: %s, expected: %s",
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 1/3] dm-pcache: advance slot index before writing slot
2025-12-04 2:53 [PATCH 1/3] dm-pcache: advance slot index before writing slot Dongsheng Yang
` (2 preceding siblings ...)
2025-12-04 3:08 ` [PATCH 1/3] dm-pcache: advance slot index before writing slot Zheng Gu
@ 2025-12-04 16:13 ` Mikulas Patocka
2025-12-05 3:01 ` Dongsheng Yang
3 siblings, 1 reply; 13+ messages in thread
From: Mikulas Patocka @ 2025-12-04 16:13 UTC (permalink / raw)
To: Dongsheng Yang; +Cc: cengku, dm-devel, chenl311
[-- Attachment #1: Type: text/plain, Size: 1743 bytes --]
On Thu, 4 Dec 2025, Dongsheng Yang 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 <dongsheng.yang@linux.dev>
> ---
> 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);
I'm not sure whether this is bug or not - but memcpy_flushcache doesn't
guarantee that the cache will be flushed (despite it's name) or that
writes would be ordered.
You need pmem_wmb(). I see that you are using it at other places.
Mikulas
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/3] dm-pcache: advance slot index before writing slot
2025-12-04 16:13 ` Mikulas Patocka
@ 2025-12-05 3:01 ` Dongsheng Yang
2025-12-06 11:36 ` Mikulas Patocka
0 siblings, 1 reply; 13+ messages in thread
From: Dongsheng Yang @ 2025-12-05 3:01 UTC (permalink / raw)
To: Mikulas Patocka; +Cc: cengku, dm-devel, chenl311
在 12/5/2025 12:13 AM, Mikulas Patocka 写道:
>
> On Thu, 4 Dec 2025, Dongsheng Yang 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 <dongsheng.yang@linux.dev>
>> ---
>> 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);
> I'm not sure whether this is bug or not
It's a bug, if in-place updating for slot happen, there is a potential
metadata corruption while powercut happening at the same time.
so I will add
Cc: stable@vger.kernel.org # 6.18
in V2.
> - but memcpy_flushcache doesn't
> guarantee that the cache will be flushed (despite it's name) or that
> writes would be ordered.
>
> You need pmem_wmb(). I see that you are using it at other places.
Good catch, I will send v2 to add the missing pmem_wmb().
Thanx
>
> Mikulas
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/3] dm pcache: fix cache info indexing
2025-12-04 16:01 ` Mikulas Patocka
@ 2025-12-05 3:05 ` Dongsheng Yang
0 siblings, 0 replies; 13+ messages in thread
From: Dongsheng Yang @ 2025-12-05 3:05 UTC (permalink / raw)
To: Mikulas Patocka; +Cc: cengku, dm-devel, chenl311
在 12/5/2025 12:01 AM, Mikulas Patocka 写道:
>
> On Thu, 4 Dec 2025, Dongsheng Yang wrote:
>
>> From: Li Chen <chenl311@chinatelecom.cn>
>>
>> The on-media cache_info index used sizeof(struct) instead of the
>> 4K metadata stride, so gc_percent updates from dmsetup message
>> were written between slots and lost after reboot. Use
>> PCACHE_CACHE_INFO_SIZE in get_cache_info_addr() and align
>> info_index with the slot returned by pcache_meta_find_latest().
>>
>> Signed-off-by: Li Chen <chenl311@chinatelecom.cn>
>> Signed-off-by: Dongsheng Yang <dongsheng.yang@linux.dev>
>> ---
>> drivers/md/dm-pcache/cache.c | 8 ++++++--
>> 1 file changed, 6 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/md/dm-pcache/cache.c b/drivers/md/dm-pcache/cache.c
>> index 9289c016b7c9..bcc4e509aa69 100644
>> --- a/drivers/md/dm-pcache/cache.c
>> +++ b/drivers/md/dm-pcache/cache.c
>> @@ -8,9 +8,11 @@
>>
>> struct kmem_cache *key_cache;
>>
>> -static inline struct pcache_cache_info *get_cache_info_addr(struct pcache_cache *cache)
>> +static inline struct pcache_cache_info *
>> +get_cache_info_addr(struct pcache_cache *cache)
>> {
>> - return cache->cache_info_addr + cache->info_index;
>> + return (struct pcache_cache_info *)((char *)cache->cache_info_addr +
>> + (size_t)cache->info_index * PCACHE_CACHE_INFO_SIZE);
>> }
>>
>> static void cache_info_write(struct pcache_cache *cache)
>> @@ -49,6 +51,8 @@ static int cache_info_init(struct pcache_cache *cache, struct pcache_cache_optio
>> return -EINVAL;
>> }
>>
>> + cache->info_index = ((char *)cache_info_addr - (char *)cache->cache_info_addr) / PCACHE_CACHE_INFO_SIZE;
>> +
>> return 0;
>> }
>>
>> --
>> 2.43.0
> I already staged the patch below? Should I revert it and stage your new
> patch?
Yes, please revert it, I will send a v2 patchset, please pick the v2 patch.
Thanx
>
> Mikulas
>
>
> diff --git a/drivers/md/dm-pcache/cache.c b/drivers/md/dm-pcache/cache.c
> index d8e92367d947..9554d1158450 100644
> --- a/drivers/md/dm-pcache/cache.c
> +++ b/drivers/md/dm-pcache/cache.c
> @@ -8,9 +8,11 @@
>
> struct kmem_cache *key_cache;
>
> -static inline struct pcache_cache_info *get_cache_info_addr(struct pcache_cache *cache)
> +static inline struct pcache_cache_info *
> +get_cache_info_addr(struct pcache_cache *cache)
> {
> - return cache->cache_info_addr + cache->info_index;
> + return (struct pcache_cache_info *)((char *)cache->cache_info_addr
> +
> + (size_t)cache->info_index * PCACHE_CACHE_INFO_SIZE);
> }
>
> static void cache_info_write(struct pcache_cache *cache)
> @@ -40,7 +42,12 @@ static int cache_info_init(struct pcache_cache *cache,
> struct pcache_cache_optio
> if (IS_ERR(cache_info_addr))
> return PTR_ERR(cache_info_addr);
>
> - if (cache_info_addr) {
> + if (cache_info_addr) {
> + int index = ((char *)cache_info_addr - (char *)cache->cache_info_addr) /
> + PCACHE_CACHE_INFO_SIZE;
> +
> + cache->info_index = (index + 1) % PCACHE_META_INDEX_MAX;
> +
> if (opts->data_crc !=
> (cache->cache_info.flags & PCACHE_CACHE_FLAGS_DATA_CRC)) {
> pcache_dev_err(pcache, "invalid option for data_crc: %s, expected: %s",
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 3/3] dm pcache: fix segment info indexing
2025-12-04 15:59 ` Mikulas Patocka
@ 2025-12-05 3:05 ` Dongsheng Yang
0 siblings, 0 replies; 13+ messages in thread
From: Dongsheng Yang @ 2025-12-05 3:05 UTC (permalink / raw)
To: Mikulas Patocka; +Cc: cengku, dm-devel, chenl311
在 12/4/2025 11:59 PM, Mikulas Patocka 写道:
>
> On Thu, 4 Dec 2025, Dongsheng Yang wrote:
>
>> From: Li Chen <chenl311@chinatelecom.cn>
>>
>> Segment info indexing also used sizeof(struct) instead of the
>> 4K metadata stride, so info_index could point between slots and
>> subsequent writes would advance incorrectly. Derive info_index
>> from the pointer returned by the segment meta search using
>> PCACHE_SEG_INFO_SIZE and advance to the next slot for future
>> updates.
>>
>> Signed-off-by: Li Chen <chenl311@chinatelecom.cn>
>> Signed-off-by: Dongsheng Yang <dongsheng.yang@linux.dev>
>> ---
>> drivers/md/dm-pcache/cache_segment.c | 5 ++++-
>> 1 file changed, 4 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/md/dm-pcache/cache_segment.c b/drivers/md/dm-pcache/cache_segment.c
>> index ae57cc261422..9d92e2b067ed 100644
>> --- a/drivers/md/dm-pcache/cache_segment.c
>> +++ b/drivers/md/dm-pcache/cache_segment.c
>> @@ -56,7 +56,10 @@ static int cache_seg_info_load(struct pcache_cache_segment *cache_seg)
>> ret = -EIO;
>> goto out;
>> }
>> - cache_seg->info_index = cache_seg_info_addr - cache_seg_info_addr_base;
>> +
>> + cache_seg->info_index =
>> + ((char *)cache_seg_info_addr - (char *)cache_seg_info_addr_base) /
>> + PCACHE_SEG_INFO_SIZE;
>> out:
>> mutex_unlock(&cache_seg->info_lock);
>>
> Hi
>
> I already staged the patch below. Which patch is valid? Your new patch or
> the patch that I staged?
Yes, please revert it, I will send a v2 patchset, please pick the v2 patch.
Thanx
>
> Mikulas
>
>
>
> diff --git a/drivers/md/dm-pcache/cache_segment.c
> b/drivers/md/dm-pcache/cache_segment.c
> index f0b58980806e..0b4bb08011ce 100644
> --- a/drivers/md/dm-pcache/cache_segment.c
> +++ b/drivers/md/dm-pcache/cache_segment.c
> @@ -56,7 +56,11 @@ static int cache_seg_info_load(struct
> pcache_cache_segment *cache_seg)
> ret = -EIO;
> goto out;
> }
> - cache_seg->info_index = cache_seg_info_addr - cache_seg_info_addr_base;
> +
> + cache_seg->info_index =
> + ((char *)cache_seg_info_addr - (char *)cache_seg_info_addr_base) /
> + PCACHE_SEG_INFO_SIZE;
> + cache_seg->info_index = (cache_seg->info_index + 1) % PCACHE_META_INDEX_MAX;
> out:
> mutex_unlock(&cache_seg->info_lock);
>
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/3] dm-pcache: advance slot index before writing slot
2025-12-05 3:01 ` Dongsheng Yang
@ 2025-12-06 11:36 ` Mikulas Patocka
0 siblings, 0 replies; 13+ messages in thread
From: Mikulas Patocka @ 2025-12-06 11:36 UTC (permalink / raw)
To: Dongsheng Yang; +Cc: cengku, dm-devel, chenl311
[-- Attachment #1: Type: text/plain, Size: 2379 bytes --]
On Fri, 5 Dec 2025, Dongsheng Yang wrote:
>
> 在 12/5/2025 12:13 AM, Mikulas Patocka 写道:
> >
> > On Thu, 4 Dec 2025, Dongsheng Yang 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 <dongsheng.yang@linux.dev>
> > > ---
> > > 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);
> > I'm not sure whether this is bug or not
>
>
> It's a bug, if in-place updating for slot happen, there is a potential
> metadata corruption while powercut happening at the same time.
>
>
> so I will add
>
> Cc: stable@vger.kernel.org # 6.18
>
> in V2.
>
> > - but memcpy_flushcache doesn't
> > guarantee that the cache will be flushed (despite it's name) or that
> > writes would be ordered.
> >
> > You need pmem_wmb(). I see that you are using it at other places.
>
>
> Good catch, I will send v2 to add the missing pmem_wmb().
>
>
> Thanx
OK. I staged all 3 patches and I'll send to Linus soon.
Mikulas
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2025-12-06 11:36 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-04 2:53 [PATCH 1/3] dm-pcache: advance slot index before writing slot Dongsheng Yang
2025-12-04 2:53 ` [PATCH 2/3] dm pcache: fix cache info indexing Dongsheng Yang
2025-12-04 3:09 ` Zheng Gu
2025-12-04 16:01 ` Mikulas Patocka
2025-12-05 3:05 ` Dongsheng Yang
2025-12-04 2:53 ` [PATCH 3/3] dm pcache: fix segment " Dongsheng Yang
2025-12-04 3:10 ` Zheng Gu
2025-12-04 15:59 ` Mikulas Patocka
2025-12-05 3:05 ` Dongsheng Yang
2025-12-04 3:08 ` [PATCH 1/3] dm-pcache: advance slot index before writing slot Zheng Gu
2025-12-04 16:13 ` Mikulas Patocka
2025-12-05 3:01 ` Dongsheng Yang
2025-12-06 11:36 ` Mikulas Patocka
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox