Add the RHEL 687.11.1..687.12.1 backports (1198-1252) sourced from centos-stream-9 and upstream stable, on top of 687.10.1. Bump to 5.14.0-687.12.1.
64 lines
2.3 KiB
Diff
64 lines
2.3 KiB
Diff
From 239cbf26626f77357ad7d15407fc24666e236138 Mon Sep 17 00:00:00 2001
|
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
|
Date: Wed, 22 Apr 2026 20:14:10 -0400
|
|
Subject: [PATCH] dm-thin: fix metadata refcount underflow
|
|
|
|
JIRA: https://issues.redhat.com/browse/RHEL-169624
|
|
Upstream Status: git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm.git
|
|
|
|
commit 09a65adc7d8bbfce06392cb6d375468e2728ead5
|
|
Author: Mikulas Patocka <mpatocka@redhat.com>
|
|
Date: Mon Apr 20 19:56:44 2026 +0200
|
|
|
|
dm-thin: fix metadata refcount underflow
|
|
|
|
There's a bug in dm-thin in the function rebalance_children. If the
|
|
internal btree node has one entry, the code tries to copy all btree
|
|
entries from the node's child to the node itself and then decrement the
|
|
child's reference count.
|
|
|
|
If the child node is shared (it has reference count > 1), we won't free
|
|
it, so there would be two pointers to each of the grandchildren nodes.
|
|
But the reference counts of the grandchildren is not increased, thus the
|
|
reference count doesn't match the number of pointers that point to the
|
|
grandchildren. This results in "device mapper: space map common: unable
|
|
to decrement block" errors.
|
|
|
|
Fix this bug by incrementing reference counts on the grandchildren if the
|
|
btree node is shared.
|
|
|
|
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
|
|
Fixes: 3241b1d3e0aa ("dm: add persistent data library")
|
|
Cc: stable@vger.kernel.org
|
|
|
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
|
|
|
diff --git a/drivers/md/persistent-data/dm-btree-remove.c b/drivers/md/persistent-data/dm-btree-remove.c
|
|
index 942cd47eb52d..aeec5b9a1dd5 100644
|
|
--- a/drivers/md/persistent-data/dm-btree-remove.c
|
|
+++ b/drivers/md/persistent-data/dm-btree-remove.c
|
|
@@ -490,12 +490,20 @@ static int rebalance_children(struct shadow_spine *s,
|
|
|
|
if (le32_to_cpu(n->header.nr_entries) == 1) {
|
|
struct dm_block *child;
|
|
+ int is_shared;
|
|
dm_block_t b = value64(n, 0);
|
|
|
|
+ r = dm_tm_block_is_shared(info->tm, b, &is_shared);
|
|
+ if (r)
|
|
+ return r;
|
|
+
|
|
r = dm_tm_read_lock(info->tm, b, &btree_node_validator, &child);
|
|
if (r)
|
|
return r;
|
|
|
|
+ if (is_shared)
|
|
+ inc_children(info->tm, dm_block_data(child), vt);
|
|
+
|
|
memcpy(n, dm_block_data(child),
|
|
dm_bm_block_size(dm_tm_get_bm(info->tm)));
|
|
|
|
--
|
|
2.50.1 (Apple Git-155)
|
|
|