Additional patches for 10.3 lvm2
Resolves: RHEL-188186 RHEL-164001
This commit is contained in:
parent
80e131be0b
commit
41a5f705f1
@ -0,0 +1,47 @@
|
||||
From b185eefe423ad4292edac96456c45fe3da3402a1 Mon Sep 17 00:00:00 2001
|
||||
From: David Teigland <teigland@redhat.com>
|
||||
Date: Thu, 4 Jun 2026 15:36:29 -0500
|
||||
Subject: [PATCH 06/16] fix lvmpersist WEAR/EAAR reserve race when multiple
|
||||
nodes start simultaneously
|
||||
|
||||
When multiple nodes run "vgchange --persist start" in parallel, the
|
||||
check-then-reserve sequence for WEAR/EAAR reservations can race: a node
|
||||
checks that no reservation exists, but by the time it calls resv-acquire,
|
||||
another node has already created the reservation. The acquire fails and
|
||||
lvmpersist treats it as fatal, undoing its registration and failing the
|
||||
start.
|
||||
|
||||
After a failed acquire, re-check whether the expected reservation type
|
||||
now exists. If another registrant completed the reservation, the node
|
||||
is already protected under the all-registrants scope, so treat it as
|
||||
success.
|
||||
|
||||
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
||||
(cherry picked from commit a01615872e5ba97fecb16c3c67d14186c1ef91ca)
|
||||
---
|
||||
scripts/lvmpersist.sh | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/scripts/lvmpersist.sh b/scripts/lvmpersist.sh
|
||||
index 4cc0ba300..02ab245f0 100755
|
||||
--- a/scripts/lvmpersist.sh
|
||||
+++ b/scripts/lvmpersist.sh
|
||||
@@ -766,6 +766,15 @@ do_start() {
|
||||
fi
|
||||
|
||||
if [[ "$?" -ne 0 ]]; then
|
||||
+ # For WEAR/EAAR, another host may have acquired the
|
||||
+ # reservation between our check and our acquire attempt.
|
||||
+ # Re-check: if the reservation now exists, that's fine.
|
||||
+ if [[ "$type_str" == "WEAR" || "$type_str" == "EAAR" ]]; then
|
||||
+ get_dev_reservation "$dev"
|
||||
+ if [[ "$DEV_PRDESC" == "$type_str" ]]; then
|
||||
+ continue
|
||||
+ fi
|
||||
+ fi
|
||||
logmsg "start $GROUP failed to reserve $dev."
|
||||
undo_register
|
||||
exit 1
|
||||
--
|
||||
2.54.0
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
From a186787a056bf0f4f424cfa1ce9dec4ee22492f2 Mon Sep 17 00:00:00 2001
|
||||
From: David Teigland <teigland@redhat.com>
|
||||
Date: Wed, 24 Jun 2026 13:17:07 -0500
|
||||
Subject: [PATCH 07/16] man lvmlockd: fix invalid vgchange --setpersist
|
||||
--setlockargs
|
||||
|
||||
(cherry picked from commit c19a1561e031e3633ffc83eeb9daf10a9d08e3aa)
|
||||
---
|
||||
man/lvmlockd.8_main | 8 ++++++--
|
||||
1 file changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/man/lvmlockd.8_main b/man/lvmlockd.8_main
|
||||
index dc8865a4c..a7a17c4df 100644
|
||||
--- a/man/lvmlockd.8_main
|
||||
+++ b/man/lvmlockd.8_main
|
||||
@@ -382,9 +382,13 @@ For more information on using PR with LVM in general, see
|
||||
.P
|
||||
The vgcreate options to enable PR-based lock recovery in a new VG are shown above.
|
||||
.P
|
||||
-To enable PR-based lock recovery in an existing VG:
|
||||
+To enable PR-based lock recovery in an existing VG, first enable PR (if
|
||||
+not already), then change the lock args:
|
||||
.br
|
||||
-.B $ vgchange --setpersist y --setlockargs persist,notimeout
|
||||
+.B $ vgchange --setpersist y
|
||||
+.I VG
|
||||
+.br
|
||||
+.B $ vgchange --setlockargs persist,notimeout
|
||||
.I VG
|
||||
.P
|
||||
Changing the PR or lockargs settings requires the VG to be stopped on all
|
||||
--
|
||||
2.54.0
|
||||
|
||||
@ -0,0 +1,46 @@
|
||||
From 559cb88b10214befbb786ba1a51f892a9a4c47bd Mon Sep 17 00:00:00 2001
|
||||
From: David Teigland <teigland@redhat.com>
|
||||
Date: Tue, 23 Jun 2026 14:01:48 -0500
|
||||
Subject: [PATCH 08/16] lvmpersist: settle udev between register and
|
||||
preempt-abort
|
||||
|
||||
sg_persist REGISTER triggers udev to re-probe the device (blkid,
|
||||
scsi_id), issuing ~50 reads over ~14ms. do_takeover() follows
|
||||
REGISTER with PREEMPT AND ABORT only ~3ms later, while probing
|
||||
reads are still in-flight on the same iSCSI connection.
|
||||
|
||||
On the LIO target, core_tmr_drain_state_list() finds those reads
|
||||
as in-flight commands and blocks, forming a deadlock with the TX
|
||||
thread's iscsit_close_connection().
|
||||
|
||||
Add udevadm settle between the register and preempt-abort loops
|
||||
so udev probing completes before the preempt-abort is issued.
|
||||
|
||||
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
||||
(cherry picked from commit 0080e310bf82f91d737f4ec4e4be8454bd7361af)
|
||||
---
|
||||
scripts/lvmpersist.sh | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/scripts/lvmpersist.sh b/scripts/lvmpersist.sh
|
||||
index 02ab245f0..b91f456f3 100755
|
||||
--- a/scripts/lvmpersist.sh
|
||||
+++ b/scripts/lvmpersist.sh
|
||||
@@ -682,6 +682,14 @@ do_takeover() {
|
||||
exit 1
|
||||
fi
|
||||
|
||||
+ # The register above triggers udev to re-probe the device (blkid,
|
||||
+ # scsi_id). Those probing reads share the iSCSI connection with
|
||||
+ # the preempt-abort below. If probing is still in-flight when the
|
||||
+ # preempt-abort arrives at the LIO target, the target deadlocks in
|
||||
+ # core_tmr_drain_state_list (waiting for in-flight reads) vs
|
||||
+ # iscsit_close_connection (waiting for RX thread exit).
|
||||
+ udevadm settle
|
||||
+
|
||||
# Reserve the device
|
||||
|
||||
for dev in "${DEVICES[@]}"; do
|
||||
--
|
||||
2.54.0
|
||||
|
||||
49
0009-man-lvmlockd-improve-setlockargs-description.patch
Normal file
49
0009-man-lvmlockd-improve-setlockargs-description.patch
Normal file
@ -0,0 +1,49 @@
|
||||
From a8871780844b22491314ab49b60cc10d802d9aa2 Mon Sep 17 00:00:00 2001
|
||||
From: David Teigland <teigland@redhat.com>
|
||||
Date: Thu, 25 Jun 2026 11:50:38 -0500
|
||||
Subject: [PATCH 09/16] man lvmlockd: improve setlockargs description
|
||||
|
||||
(cherry picked from commit 41cbab67e9e21ac736cfe4f25ecf8d72db508358)
|
||||
---
|
||||
man/lvmlockd.8_main | 19 +++++++++++++++----
|
||||
1 file changed, 15 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/man/lvmlockd.8_main b/man/lvmlockd.8_main
|
||||
index a7a17c4df..c86a0a130 100644
|
||||
--- a/man/lvmlockd.8_main
|
||||
+++ b/man/lvmlockd.8_main
|
||||
@@ -383,16 +383,27 @@ For more information on using PR with LVM in general, see
|
||||
The vgcreate options to enable PR-based lock recovery in a new VG are shown above.
|
||||
.P
|
||||
To enable PR-based lock recovery in an existing VG, first enable PR (if
|
||||
-not already), then change the lock args:
|
||||
+not already), then change the lock args. Changing lock args can involve
|
||||
+stopping/starting PR and locking at different stages. Changing the PR or
|
||||
+lock args settings requires the VG to be stopped on all other nodes.
|
||||
+.P
|
||||
+.I Example
|
||||
+.br
|
||||
+.B $ vgcreate --shared
|
||||
+.I VG
|
||||
+.I devices
|
||||
.br
|
||||
.B $ vgchange --setpersist y
|
||||
.I VG
|
||||
.br
|
||||
+.B $ vgchange --persist start
|
||||
+.I VG
|
||||
+.br
|
||||
.B $ vgchange --setlockargs persist,notimeout
|
||||
.I VG
|
||||
-.P
|
||||
-Changing the PR or lockargs settings requires the VG to be stopped on all
|
||||
-other nodes.
|
||||
+.br
|
||||
+.B $ vgchange --persist start --lockstart
|
||||
+.I VG
|
||||
.P
|
||||
Display the VG attributes configured by setpersist and setlockargs:
|
||||
.br
|
||||
--
|
||||
2.54.0
|
||||
|
||||
374
0010-vdo-add-pre-format-pool-geometry-computation.patch
Normal file
374
0010-vdo-add-pre-format-pool-geometry-computation.patch
Normal file
@ -0,0 +1,374 @@
|
||||
From fc77a2a50faa1d1e6b10310f84384d2ad18dec47 Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Sun, 26 Apr 2026 11:35:09 +0200
|
||||
Subject: [PATCH 10/16] vdo: add pre-format pool geometry computation
|
||||
|
||||
Add vdo_format.c with vdo_pool_info() that replicates the vdoformat
|
||||
pool layout calculation: given a pool's physical size and VDO
|
||||
parameters, compute UDS index size, slab count, per-slab data blocks,
|
||||
and usable data blocks (accounting for block map forest overhead).
|
||||
|
||||
Return results in struct vdo_pool_info so callers can both set
|
||||
the correct virtual size before kernel formatting and report pool
|
||||
geometry (slab count, addressable capacity, growth limits).
|
||||
|
||||
(cherry picked from commit d5298389476a869a7e650f0188d6830202986ac6)
|
||||
---
|
||||
lib/Makefile.in | 1 +
|
||||
lib/metadata/metadata-exported.h | 10 +
|
||||
lib/metadata/vdo_format.c | 310 +++++++++++++++++++++++++++++++
|
||||
3 files changed, 321 insertions(+)
|
||||
create mode 100644 lib/metadata/vdo_format.c
|
||||
|
||||
diff --git a/lib/Makefile.in b/lib/Makefile.in
|
||||
index bffe5dddc..667534967 100644
|
||||
--- a/lib/Makefile.in
|
||||
+++ b/lib/Makefile.in
|
||||
@@ -94,6 +94,7 @@ SOURCES =\
|
||||
metadata/segtype.c \
|
||||
metadata/snapshot_manip.c \
|
||||
metadata/thin_manip.c \
|
||||
+ metadata/vdo_format.c \
|
||||
metadata/vdo_manip.c \
|
||||
metadata/vg.c \
|
||||
mirror/mirrored.c \
|
||||
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
|
||||
index 4318477f4..1f78c7aac 100644
|
||||
--- a/lib/metadata/metadata-exported.h
|
||||
+++ b/lib/metadata/metadata-exported.h
|
||||
@@ -1388,6 +1388,16 @@ const char *get_vdo_index_state_name(enum dm_vdo_index_state state);
|
||||
const char *get_vdo_operating_mode_name(enum dm_vdo_operating_mode mode);
|
||||
const char *get_vdo_write_policy_name(enum dm_vdo_write_policy policy);
|
||||
uint64_t get_vdo_pool_virtual_size(const struct lv_segment *vdo_pool_seg);
|
||||
+struct vdo_pool_info {
|
||||
+ uint64_t data_blocks;
|
||||
+ uint64_t uds_blocks;
|
||||
+ unsigned slab_count;
|
||||
+ unsigned data_per_slab;
|
||||
+};
|
||||
+
|
||||
+int vdo_pool_info(uint64_t pool_size_sectors,
|
||||
+ const struct dm_vdo_target_params *vtp,
|
||||
+ struct vdo_pool_info *info);
|
||||
int update_vdo_pool_virtual_size(struct lv_segment *vdo_pool_seg);
|
||||
uint32_t get_vdo_pool_max_extents(const struct dm_vdo_target_params *vtp,
|
||||
uint32_t extent_size);
|
||||
diff --git a/lib/metadata/vdo_format.c b/lib/metadata/vdo_format.c
|
||||
new file mode 100644
|
||||
index 000000000..48b0e6a2c
|
||||
--- /dev/null
|
||||
+++ b/lib/metadata/vdo_format.c
|
||||
@@ -0,0 +1,310 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2026 Red Hat, Inc. All rights reserved.
|
||||
+ *
|
||||
+ * This file is part of LVM2.
|
||||
+ *
|
||||
+ * This copyrighted material is made available to anyone wishing to use,
|
||||
+ * modify, copy, or redistribute it subject to the terms and conditions
|
||||
+ * of the GNU Lesser General Public License v.2.1.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public License
|
||||
+ * along with this program; if not, write to the Free Software Foundation,
|
||||
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
+ */
|
||||
+
|
||||
+#include "lib/misc/lib.h"
|
||||
+#include "lib/metadata/metadata.h"
|
||||
+
|
||||
+#include <math.h>
|
||||
+
|
||||
+/*
|
||||
+ * Compute VDO data blocks available for storing compressed/deduplicated content.
|
||||
+ *
|
||||
+ * Replicates the vdoformat calculation: given a pool's physical size and
|
||||
+ * VDO parameters, compute the usable data blocks at 1:1 mapping
|
||||
+ * (accounting for UDS index, slab overhead, and block map forest).
|
||||
+ */
|
||||
+
|
||||
+/* UDS index geometry constants */
|
||||
+#define UDS_BLOCK_SIZE 4096U
|
||||
+#define UDS_BYTES_PER_RECORD 32U
|
||||
+#define UDS_BYTES_PER_PAGE 32768U
|
||||
+#define UDS_RECORDS_PER_PAGE (UDS_BYTES_PER_PAGE / UDS_BYTES_PER_RECORD) /* 1024 */
|
||||
+#define UDS_DEFAULT_CHAPTERS 1024U
|
||||
+#define UDS_SMALL_RPC 64U
|
||||
+#define UDS_DEFAULT_RPC 256U
|
||||
+#define UDS_DELTA_LIST_SIZE 256U
|
||||
+#define UDS_MAX_ZONES 16U
|
||||
+#define UDS_MAX_SAVES 2U
|
||||
+#define UDS_HEADER_SIZE 19U /* immutable delta index header */
|
||||
+#define UDS_CHAPTER_MEAN_DELTA_BITS 16U /* chapter mean_delta = 1<<16 */
|
||||
+#define UDS_VOLUME_INDEX_MEAN_DELTA 4096U
|
||||
+#define UDS_SPARSE_SAMPLE_RATE 32U
|
||||
+
|
||||
+/* UDS on-disk structure sizes */
|
||||
+#define UDS_SIZEOF_DI_HEADER 40U
|
||||
+#define UDS_SIZEOF_DL_SAVE_INFO 8U
|
||||
+#define UDS_SIZEOF_DP_HEADER 20U
|
||||
+#define UDS_SIZEOF_SUB_INDEX_DATA 40U
|
||||
+#define UDS_SIZEOF_VI_DATA 12U /* magic[8] + u32 sparse_sample_rate */
|
||||
+#define UDS_PAGE_MAP_MAGIC_LEN 8U
|
||||
+#define UDS_OPEN_CHAPTER_MAGIC_LEN (sizeof("ALBOC") - 1)
|
||||
+#define UDS_OPEN_CHAPTER_VER_LEN (sizeof("02.00") - 1)
|
||||
+
|
||||
+/* VDO layout constants */
|
||||
+#define VDO_BLOCK_MAP_TREE_HEIGHT 5U
|
||||
+#define VDO_BLOCK_MAP_ROOT_COUNT 60U
|
||||
+#define VDO_BLOCK_MAP_ENTRIES_PER_PAGE 812U
|
||||
+#define VDO_SLAB_JOURNAL_SIZE 224U /* blocks per slab for journal */
|
||||
+#define VDO_SLAB_SUMMARY_BLOCKS 64U
|
||||
+#define VDO_RECOVERY_JOURNAL_SIZE 32768U
|
||||
+#define VDO_COUNTS_PER_BLOCK 4032U /* reference counts per block */
|
||||
+
|
||||
+static unsigned _bits_per(unsigned n)
|
||||
+{
|
||||
+ if (!n)
|
||||
+ return 0;
|
||||
+
|
||||
+ return 32 - clz(n);
|
||||
+}
|
||||
+
|
||||
+static unsigned _delta_min_bits(unsigned mean_delta)
|
||||
+{
|
||||
+ unsigned incr_keys = (unsigned)round(log(2.0) * mean_delta);
|
||||
+
|
||||
+ return _bits_per(incr_keys + 1);
|
||||
+}
|
||||
+
|
||||
+/* Total bits for one chapter's delta index */
|
||||
+static uint64_t _delta_index_size(uint64_t entry_count, unsigned mean_delta,
|
||||
+ unsigned payload_bits)
|
||||
+{
|
||||
+ unsigned min_bits = _delta_min_bits(mean_delta);
|
||||
+
|
||||
+ return entry_count * (payload_bits + min_bits + 1) + entry_count / 2;
|
||||
+}
|
||||
+
|
||||
+/* Number of delta index pages needed for one chapter */
|
||||
+static unsigned _delta_index_pages(uint64_t entry_count, unsigned list_count,
|
||||
+ unsigned mean_delta, unsigned payload_bits)
|
||||
+{
|
||||
+ uint64_t total_bits = _delta_index_size(entry_count, mean_delta, payload_bits);
|
||||
+ unsigned bits_per_list = (unsigned)(total_bits / list_count);
|
||||
+ unsigned bits_per_page;
|
||||
+
|
||||
+ total_bits += (uint64_t)list_count * UDS_HEADER_SIZE;
|
||||
+ bits_per_page = (UDS_BYTES_PER_PAGE - UDS_SIZEOF_DP_HEADER) * 8 -
|
||||
+ UDS_HEADER_SIZE - bits_per_list;
|
||||
+
|
||||
+ return (unsigned)dm_div_up(total_bits, bits_per_page);
|
||||
+}
|
||||
+
|
||||
+/* Save bytes for one volume sub-index */
|
||||
+static uint64_t _sub_index_save_bytes(unsigned records_per_chapter,
|
||||
+ unsigned chapters, unsigned vi_mean)
|
||||
+{
|
||||
+ uint64_t delta_list_records = (uint64_t)records_per_chapter * chapters;
|
||||
+ unsigned list_count = (unsigned)(delta_list_records / UDS_DELTA_LIST_SIZE);
|
||||
+ unsigned addr_bits, chapter_bits, invalid_chapters;
|
||||
+ unsigned chapters_in_vi;
|
||||
+ uint64_t entries_in_vi, addr_span;
|
||||
+ unsigned mean_delta;
|
||||
+ uint64_t chapter_size_bits, index_size_bytes, memory_size;
|
||||
+ uint64_t zone_memory, di_save;
|
||||
+
|
||||
+ if (list_count < UDS_MAX_ZONES * UDS_MAX_ZONES)
|
||||
+ list_count = UDS_MAX_ZONES * UDS_MAX_ZONES;
|
||||
+
|
||||
+ addr_bits = _bits_per(vi_mean * UDS_DELTA_LIST_SIZE - 1);
|
||||
+ chapter_bits = _bits_per(chapters - 1);
|
||||
+ invalid_chapters = chapters / 256;
|
||||
+ if (invalid_chapters < 2)
|
||||
+ invalid_chapters = 2;
|
||||
+ chapters_in_vi = chapters + invalid_chapters;
|
||||
+ entries_in_vi = (uint64_t)records_per_chapter * chapters_in_vi;
|
||||
+ addr_span = (uint64_t)list_count << addr_bits;
|
||||
+ mean_delta = (unsigned)(addr_span / entries_in_vi);
|
||||
+
|
||||
+ chapter_size_bits = _delta_index_size(records_per_chapter, mean_delta,
|
||||
+ chapter_bits);
|
||||
+ index_size_bytes = (chapter_size_bits * chapters_in_vi) / 8;
|
||||
+ /* add 6% headroom to reduce delta list rebalancing when index is full */
|
||||
+ memory_size = index_size_bytes * 106 / 100;
|
||||
+
|
||||
+ /* zone_mem(1, memory_size): round up to 64K */
|
||||
+ zone_memory = dm_div_up(memory_size, 65536U) * 65536U;
|
||||
+
|
||||
+ /* delta_index save = header + list_count*(save_info+1) + zone_memory */
|
||||
+ di_save = UDS_SIZEOF_DI_HEADER + zone_memory +
|
||||
+ (uint64_t)list_count * (UDS_SIZEOF_DL_SAVE_INFO + 1);
|
||||
+
|
||||
+ /* sub_index save = sub_index_data + list_count*8 + di_save */
|
||||
+ return UDS_SIZEOF_SUB_INDEX_DATA + (uint64_t)list_count * 8 + di_save;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Compute total UDS index size in 4K blocks.
|
||||
+ *
|
||||
+ * index_memory_mb: UDS memory config (256, 512, 768, or N*1024)
|
||||
+ * use_sparse: nonzero for sparse index
|
||||
+ */
|
||||
+static uint64_t _uds_index_blocks(unsigned index_memory_mb, int use_sparse)
|
||||
+{
|
||||
+ unsigned base_chapters, rpc, chapters, sparse_chapters = 0;
|
||||
+ unsigned records_per_chapter, chapter_payload_bits;
|
||||
+ unsigned chapter_dl_bits, delta_lists_per_chapter;
|
||||
+ unsigned ippc, pages_per_chapter;
|
||||
+ uint64_t pages_per_volume, bytes_per_volume, volume_blocks;
|
||||
+ uint64_t vi_save_bytes, vi_blocks;
|
||||
+ unsigned page_map_blocks, open_chapter_blocks;
|
||||
+ unsigned save_blocks;
|
||||
+
|
||||
+ /* Map memory config to chapters and records-per-page */
|
||||
+ if (index_memory_mb <= 256) {
|
||||
+ base_chapters = UDS_DEFAULT_CHAPTERS;
|
||||
+ rpc = UDS_SMALL_RPC;
|
||||
+ } else if (index_memory_mb <= 512) {
|
||||
+ base_chapters = UDS_DEFAULT_CHAPTERS;
|
||||
+ rpc = 2 * UDS_SMALL_RPC;
|
||||
+ } else if (index_memory_mb <= 768) {
|
||||
+ base_chapters = UDS_DEFAULT_CHAPTERS;
|
||||
+ rpc = 3 * UDS_SMALL_RPC;
|
||||
+ } else {
|
||||
+ base_chapters = (index_memory_mb / 1024) * UDS_DEFAULT_CHAPTERS;
|
||||
+ rpc = UDS_DEFAULT_RPC;
|
||||
+ }
|
||||
+
|
||||
+ /* sparse index: 10x total chapters, 95% sparse (19/2 sparse per base chapter) */
|
||||
+ if (use_sparse) {
|
||||
+ sparse_chapters = (19 * base_chapters) / 2;
|
||||
+ chapters = base_chapters * 10;
|
||||
+ } else {
|
||||
+ chapters = base_chapters;
|
||||
+ }
|
||||
+
|
||||
+ /* Geometry */
|
||||
+ records_per_chapter = UDS_RECORDS_PER_PAGE * rpc;
|
||||
+ chapter_payload_bits = _bits_per(rpc - 1);
|
||||
+ chapter_dl_bits = _bits_per((records_per_chapter - 1) | 077) - 6;
|
||||
+ delta_lists_per_chapter = 1U << chapter_dl_bits;
|
||||
+ ippc = _delta_index_pages(records_per_chapter, delta_lists_per_chapter,
|
||||
+ 1U << UDS_CHAPTER_MEAN_DELTA_BITS,
|
||||
+ chapter_payload_bits);
|
||||
+ pages_per_chapter = ippc + rpc;
|
||||
+ pages_per_volume = (uint64_t)pages_per_chapter * chapters;
|
||||
+ bytes_per_volume = UDS_BYTES_PER_PAGE * (pages_per_volume + 1);
|
||||
+ volume_blocks = bytes_per_volume / UDS_BLOCK_SIZE;
|
||||
+
|
||||
+ /* Volume index save blocks */
|
||||
+ if (!use_sparse) {
|
||||
+ vi_save_bytes = _sub_index_save_bytes(records_per_chapter,
|
||||
+ chapters,
|
||||
+ UDS_VOLUME_INDEX_MEAN_DELTA);
|
||||
+ } else {
|
||||
+ unsigned hook_rec = records_per_chapter / UDS_SPARSE_SAMPLE_RATE;
|
||||
+ unsigned non_hook_rec = records_per_chapter - hook_rec;
|
||||
+ unsigned dense_chapters = chapters - sparse_chapters;
|
||||
+ uint64_t hook_bytes, non_hook_bytes;
|
||||
+
|
||||
+ hook_bytes = _sub_index_save_bytes(hook_rec, chapters,
|
||||
+ UDS_VOLUME_INDEX_MEAN_DELTA);
|
||||
+ non_hook_bytes = _sub_index_save_bytes(non_hook_rec,
|
||||
+ dense_chapters,
|
||||
+ UDS_VOLUME_INDEX_MEAN_DELTA);
|
||||
+ vi_save_bytes = UDS_SIZEOF_VI_DATA + hook_bytes + non_hook_bytes;
|
||||
+ }
|
||||
+ vi_blocks = dm_div_up(vi_save_bytes + UDS_SIZEOF_DL_SAVE_INFO,
|
||||
+ UDS_BLOCK_SIZE) + UDS_MAX_ZONES;
|
||||
+
|
||||
+ /* Page map and open chapter save blocks */
|
||||
+ page_map_blocks =
|
||||
+ (unsigned)dm_div_up(UDS_PAGE_MAP_MAGIC_LEN + 8 + (uint64_t)chapters * (ippc - 1) * 2,
|
||||
+ UDS_BLOCK_SIZE);
|
||||
+ open_chapter_blocks =
|
||||
+ (unsigned)dm_div_up(UDS_OPEN_CHAPTER_MAGIC_LEN + UDS_OPEN_CHAPTER_VER_LEN + 4 +
|
||||
+ (uint64_t)records_per_chapter * UDS_BYTES_PER_RECORD,
|
||||
+ UDS_BLOCK_SIZE);
|
||||
+
|
||||
+ save_blocks = 1 + vi_blocks + page_map_blocks + open_chapter_blocks;
|
||||
+
|
||||
+ /* total = header(3) + volume + MAX_SAVES * save */
|
||||
+ return 3 + volume_blocks + UDS_MAX_SAVES * save_blocks;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Compute block map forest overhead: the number of blocks consumed
|
||||
+ * by the 5-level block map tree when mapping data_blocks entries.
|
||||
+ * Tree roots (level 3) and super roots (level 4) are not allocated
|
||||
+ * from slabs, so they are excluded.
|
||||
+ */
|
||||
+static uint64_t _forest_overhead(uint64_t data_blocks)
|
||||
+{
|
||||
+ uint64_t leaf_pages, level_size, non_leaves, leaves;
|
||||
+ unsigned levels[VDO_BLOCK_MAP_TREE_HEIGHT];
|
||||
+ unsigned h;
|
||||
+
|
||||
+ leaf_pages = dm_div_up(data_blocks, VDO_BLOCK_MAP_ENTRIES_PER_PAGE);
|
||||
+ level_size = dm_div_up(leaf_pages, VDO_BLOCK_MAP_ROOT_COUNT);
|
||||
+
|
||||
+ for (h = 0; h < VDO_BLOCK_MAP_TREE_HEIGHT; h++) {
|
||||
+ level_size = dm_div_up(level_size, VDO_BLOCK_MAP_ENTRIES_PER_PAGE);
|
||||
+ levels[h] = (unsigned)level_size;
|
||||
+ }
|
||||
+
|
||||
+ non_leaves = 0;
|
||||
+ for (h = 0; h < VDO_BLOCK_MAP_TREE_HEIGHT; h++)
|
||||
+ non_leaves += (uint64_t)levels[h] * VDO_BLOCK_MAP_ROOT_COUNT;
|
||||
+
|
||||
+ /* Exclude tree roots and super roots (not from slabs) */
|
||||
+ non_leaves -= (levels[VDO_BLOCK_MAP_TREE_HEIGHT - 2] +
|
||||
+ levels[VDO_BLOCK_MAP_TREE_HEIGHT - 1]) *
|
||||
+ VDO_BLOCK_MAP_ROOT_COUNT;
|
||||
+
|
||||
+ leaves = dm_div_up(data_blocks - non_leaves,
|
||||
+ VDO_BLOCK_MAP_ENTRIES_PER_PAGE);
|
||||
+
|
||||
+ return non_leaves + leaves;
|
||||
+}
|
||||
+
|
||||
+int vdo_pool_info(uint64_t pool_size_sectors,
|
||||
+ const struct dm_vdo_target_params *vtp,
|
||||
+ struct vdo_pool_info *info)
|
||||
+{
|
||||
+ uint64_t pool_4k = pool_size_sectors / DM_VDO_BLOCK_SIZE;
|
||||
+ unsigned slab_4k = (unsigned)((uint64_t)vtp->slab_size_mb * (1048576 / UDS_BLOCK_SIZE));
|
||||
+ uint64_t offset, depot_blocks;
|
||||
+ unsigned ref_blocks;
|
||||
+ uint64_t total_data, forest;
|
||||
+
|
||||
+ memset(info, 0, sizeof(*info));
|
||||
+
|
||||
+ info->uds_blocks = _uds_index_blocks(vtp->index_memory_size_mb,
|
||||
+ vtp->use_sparse_index);
|
||||
+
|
||||
+ /* Layout: geometry(1) + UDS + super(1) + roots + slab_summary + recovery_journal */
|
||||
+ offset = info->uds_blocks + 2;
|
||||
+ if (pool_4k <= offset + VDO_BLOCK_MAP_ROOT_COUNT +
|
||||
+ VDO_SLAB_SUMMARY_BLOCKS + VDO_RECOVERY_JOURNAL_SIZE)
|
||||
+ return 0;
|
||||
+
|
||||
+ depot_blocks = pool_4k - offset - VDO_BLOCK_MAP_ROOT_COUNT -
|
||||
+ VDO_SLAB_SUMMARY_BLOCKS - VDO_RECOVERY_JOURNAL_SIZE;
|
||||
+
|
||||
+ info->slab_count = (unsigned)(depot_blocks / slab_4k);
|
||||
+ if (!info->slab_count)
|
||||
+ return 0;
|
||||
+
|
||||
+ /* Slab layout: journal(224) + ref_blocks + data_blocks = slab_4k */
|
||||
+ ref_blocks = (unsigned)dm_div_up(slab_4k - VDO_SLAB_JOURNAL_SIZE,
|
||||
+ VDO_COUNTS_PER_BLOCK + 1);
|
||||
+ info->data_per_slab = slab_4k - VDO_SLAB_JOURNAL_SIZE - ref_blocks;
|
||||
+ total_data = (uint64_t)info->data_per_slab * info->slab_count;
|
||||
+
|
||||
+ forest = _forest_overhead(total_data);
|
||||
+ if (forest >= total_data)
|
||||
+ return 0;
|
||||
+
|
||||
+ info->data_blocks = total_data - forest;
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
--
|
||||
2.54.0
|
||||
|
||||
239
0011-vdo-add-support-for-VDO-kernel-direct-formatting.patch
Normal file
239
0011-vdo-add-support-for-VDO-kernel-direct-formatting.patch
Normal file
@ -0,0 +1,239 @@
|
||||
From efdcd4b2f8c2f25e9db8e3b217de85d8cba54aab Mon Sep 17 00:00:00 2001
|
||||
From: Bruce Johnston <bjohnsto@redhat.com>
|
||||
Date: Wed, 17 Dec 2025 12:40:44 -0500
|
||||
Subject: [PATCH 11/16] vdo: add support for VDO kernel direct formatting
|
||||
|
||||
VDO has added a feature (dm-vdo 9.2.0+) to format devices directly
|
||||
in its kernel code vs using the vdoformat userspace tool. Add support
|
||||
for this via a new config parameter vdo_use_kernel_format.
|
||||
|
||||
When vdo_use_kernel_format=1, LVM zeroes the first 4KiB of the pool
|
||||
data LV and passes slabSize, indexMemory, and indexSparse parameters
|
||||
on the device-mapper table line so the kernel formats on activation.
|
||||
|
||||
The use_kernel_format flag is persisted in VDO pool metadata so it
|
||||
survives reactivation. Old metadata without the flag defaults to 0
|
||||
(userspace vdoformat), ensuring backward compatibility.
|
||||
|
||||
Signed-off-by: Bruce Johnston <bjohnsto@redhat.com>
|
||||
Made-with: Cursor
|
||||
(cherry picked from commit 7642c5b4ab0c87ed6dc31bcb56e2de40a45045ce)
|
||||
---
|
||||
lib/config/config_settings.h | 10 ++++++++--
|
||||
lib/config/defaults.h | 1 +
|
||||
lib/metadata/segtype.h | 1 +
|
||||
lib/metadata/vdo_manip.c | 32 +++++++++++++++++++++++++++++---
|
||||
lib/vdo/vdo.c | 6 ++++++
|
||||
libdm/libdevmapper.h | 2 ++
|
||||
libdm/libdm-deptree.c | 20 ++++++++++++++++++++
|
||||
tools/toollib.c | 1 +
|
||||
8 files changed, 68 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
|
||||
index 8a1872b62..92d5f9e40 100644
|
||||
--- a/lib/config/config_settings.h
|
||||
+++ b/lib/config/config_settings.h
|
||||
@@ -782,6 +782,12 @@ cfg(allocation_vdo_check_point_frequency_CFG, "vdo_check_point_frequency", alloc
|
||||
cfg(allocation_vdo_use_sparse_index_CFG, "vdo_use_sparse_index", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_VDO_USE_SPARSE_INDEX, VDO_1ST_VSN, NULL, 0, NULL,
|
||||
"Enables sparse indexing for VDO volume.\n")
|
||||
|
||||
+/* vdo format */
|
||||
+cfg(allocation_vdo_use_kernel_format_CFG, "vdo_use_kernel_format", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_VDO_USE_KERNEL_FORMAT, vsn(2, 3, 41), NULL, 0, NULL,
|
||||
+ "Use kernel direct formatting for VDO volume.\n"
|
||||
+ "When enabled (1), uses kernel direct formatting (requires dm-vdo 9.2.0+).\n"
|
||||
+ "When disabled (0), uses traditional userspace vdoformat tool.\n")
|
||||
+
|
||||
/* vdo format */
|
||||
cfg(allocation_vdo_index_memory_size_mb_CFG, "vdo_index_memory_size_mb", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_VDO_INDEX_MEMORY_SIZE_MB, VDO_1ST_VSN, NULL, 0, NULL,
|
||||
"Specifies the amount of index memory in MiB for VDO volume.\n"
|
||||
@@ -1336,10 +1342,10 @@ cfg_array(global_vdo_format_options_CFG, "vdo_format_options", global_CFG_SECTIO
|
||||
cfg_array(global_vdo_disabled_features_CFG, "vdo_disabled_features", global_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 3, 11), NULL, 0, NULL,
|
||||
"Features to not use in the vdo driver.\n"
|
||||
"This can be helpful for testing, or to avoid using a feature that is\n"
|
||||
- "causing problems. Features include: online_rename, version4\n"
|
||||
+ "causing problems. Features include: online_rename, version4, kernel_format\n"
|
||||
"#\n"
|
||||
"Example\n"
|
||||
- "vdo_disabled_features = [ \"online_rename\", \"version4\" ]\n"
|
||||
+ "vdo_disabled_features = [ \"online_rename\", \"version4\", \"kernel_format\" ]\n"
|
||||
"#\n")
|
||||
|
||||
cfg(global_fsadm_executable_CFG, "fsadm_executable", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_FSADM_PATH, vsn(2, 2, 170), "@FSADM_PATH@", 0, NULL,
|
||||
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
|
||||
index c9c19dcef..f0cbddf72 100644
|
||||
--- a/lib/config/defaults.h
|
||||
+++ b/lib/config/defaults.h
|
||||
@@ -169,6 +169,7 @@
|
||||
#define DEFAULT_VDO_BLOCK_MAP_CACHE_SIZE_MB (DM_VDO_BLOCK_MAP_CACHE_SIZE_MINIMUM_MB)
|
||||
#define DEFAULT_VDO_BLOCK_MAP_ERA_LENGTH (DM_VDO_BLOCK_MAP_ERA_LENGTH_MAXIMUM)
|
||||
#define DEFAULT_VDO_USE_SPARSE_INDEX 0
|
||||
+#define DEFAULT_VDO_USE_KERNEL_FORMAT 1
|
||||
#define DEFAULT_VDO_CHECK_POINT_FREQUENCY (0)
|
||||
#define DEFAULT_VDO_INDEX_MEMORY_SIZE_MB (DM_VDO_INDEX_MEMORY_SIZE_MINIMUM_MB)
|
||||
#define DEFAULT_VDO_SLAB_SIZE_MB (2 * 1024) /* 2GiB ... 19 slabbits */
|
||||
diff --git a/lib/metadata/segtype.h b/lib/metadata/segtype.h
|
||||
index b53859d9d..64650579b 100644
|
||||
--- a/lib/metadata/segtype.h
|
||||
+++ b/lib/metadata/segtype.h
|
||||
@@ -356,6 +356,7 @@ int init_vdo_segtypes(struct cmd_context *cmd, struct segtype_library *seglib);
|
||||
|
||||
#define VDO_FEATURE_ONLINE_RENAME (1U << 0) /* version 6.2.3 */
|
||||
#define VDO_FEATURE_VERSION4 (1U << 1) /* version 8.2.0 */
|
||||
+#define VDO_FEATURE_KERNEL_FORMAT (1U << 2) /* version 9.2.0 */
|
||||
|
||||
int init_writecache_segtypes(struct cmd_context *cmd, struct segtype_library *seglib);
|
||||
|
||||
diff --git a/lib/metadata/vdo_manip.c b/lib/metadata/vdo_manip.c
|
||||
index 9d1c7305e..0b4f2d3fe 100644
|
||||
--- a/lib/metadata/vdo_manip.c
|
||||
+++ b/lib/metadata/vdo_manip.c
|
||||
@@ -390,6 +390,8 @@ int convert_vdo_pool_lv(struct logical_volume *data_lv,
|
||||
struct lv_segment *vdo_pool_seg;
|
||||
uint64_t vdo_logical_size = 0;
|
||||
uint64_t adjust;
|
||||
+ unsigned attrs = 0;
|
||||
+ int use_kernel = format && vtp->use_kernel_format;
|
||||
|
||||
if (!(vdo_pool_segtype = get_segtype_from_string(cmd, SEG_TYPE_NAME_VDO_POOL)))
|
||||
return_0;
|
||||
@@ -412,9 +414,30 @@ int convert_vdo_pool_lv(struct logical_volume *data_lv,
|
||||
if (format) {
|
||||
if (test_mode()) {
|
||||
log_verbose("Test mode: Skipping formatting of VDO pool volume.");
|
||||
- } else if (!_format_vdo_pool_data_lv(data_lv, vtp, &vdo_logical_size)) {
|
||||
- log_error("Cannot format VDO pool volume %s.", display_lvname(data_lv));
|
||||
- return 0;
|
||||
+ } else if (use_kernel) {
|
||||
+ if (use_kernel &&
|
||||
+ (!vdo_pool_segtype->ops->target_present ||
|
||||
+ !vdo_pool_segtype->ops->target_present(cmd, NULL, &attrs) ||
|
||||
+ !(attrs & VDO_FEATURE_KERNEL_FORMAT))) {
|
||||
+ log_error("Kernel direct formatting (vdo_use_kernel_format=1) requires VDO target version 9.2.0 or newer.");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /* Kernel decides to format if the first 4k are zeroes */
|
||||
+ if (!activate_and_wipe_lv(data_lv, WIPE_MODE_DO_ZERO, 0, 0)) {
|
||||
+ log_error("Aborting. Failed to wipe first 4 KiB of VDO pool volume %s.",
|
||||
+ display_lvname(data_lv));
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (!*virtual_extents)
|
||||
+ vdo_logical_size = data_lv->size;
|
||||
+ } else {
|
||||
+ /* Traditional userspace vdoformat */
|
||||
+ if (!_format_vdo_pool_data_lv(data_lv, vtp, &vdo_logical_size)) {
|
||||
+ log_error("Cannot format VDO pool volume %s.", display_lvname(data_lv));
|
||||
+ return 0;
|
||||
+ }
|
||||
}
|
||||
} else {
|
||||
log_verbose("Skipping VDO formatting %s.", display_lvname(data_lv));
|
||||
@@ -455,6 +478,7 @@ int convert_vdo_pool_lv(struct logical_volume *data_lv,
|
||||
vdo_pool_seg = first_seg(vdo_pool_lv);
|
||||
vdo_pool_seg->segtype = vdo_pool_segtype;
|
||||
vdo_pool_seg->vdo_params = *vtp;
|
||||
+ vdo_pool_seg->vdo_params.use_kernel_format = use_kernel;
|
||||
vdo_pool_seg->vdo_pool_header_size = vdo_pool_header_size;
|
||||
vdo_pool_seg->vdo_pool_virtual_extents = *virtual_extents;
|
||||
|
||||
@@ -621,6 +645,8 @@ int fill_vdo_target_params(struct cmd_context *cmd,
|
||||
find_config_tree_int(cmd, allocation_vdo_block_map_era_length_CFG, profile);
|
||||
vtp->use_sparse_index =
|
||||
find_config_tree_bool(cmd, allocation_vdo_use_sparse_index_CFG, profile);
|
||||
+ vtp->use_kernel_format =
|
||||
+ find_config_tree_bool(cmd, allocation_vdo_use_kernel_format_CFG, profile);
|
||||
vtp->index_memory_size_mb =
|
||||
find_config_tree_int64(cmd, allocation_vdo_index_memory_size_mb_CFG, profile);
|
||||
vtp->slab_size_mb =
|
||||
diff --git a/lib/vdo/vdo.c b/lib/vdo/vdo.c
|
||||
index c3cb2b2a5..1e9d377b5 100644
|
||||
--- a/lib/vdo/vdo.c
|
||||
+++ b/lib/vdo/vdo.c
|
||||
@@ -254,6 +254,9 @@ static int _vdo_pool_text_import(struct lv_segment *seg,
|
||||
if (!_import_bool(n, "use_sparse_index", &vtp->use_sparse_index))
|
||||
return_0;
|
||||
|
||||
+ if (!_import_bool(n, "use_kernel_format", &vtp->use_kernel_format))
|
||||
+ return_0;
|
||||
+
|
||||
if (!dm_config_get_uint32(n, "index_memory_size_mb", &vtp->index_memory_size_mb))
|
||||
return _bad_field("index_memory_size_mb");
|
||||
|
||||
@@ -327,6 +330,8 @@ static int _vdo_pool_text_export(const struct lv_segment *seg, struct formatter
|
||||
|
||||
if (vtp->use_sparse_index)
|
||||
outf(f, "use_sparse_index = 1");
|
||||
+ if (vtp->use_kernel_format)
|
||||
+ outf(f, "use_kernel_format = 1");
|
||||
/* TODO - conditionally */
|
||||
outsize(f, vtp->index_memory_size_mb * UINT64_C(2 * 1024),
|
||||
"index_memory_size_mb = %u", vtp->index_memory_size_mb);
|
||||
@@ -430,6 +435,7 @@ static int _vdo_target_present(struct cmd_context *cmd,
|
||||
} _features[] = {
|
||||
{ 6, 2, 3, VDO_FEATURE_ONLINE_RENAME, "online_rename" },
|
||||
{ 8, 2, 0, VDO_FEATURE_VERSION4, "version4" },
|
||||
+ { 9, 2, 0, VDO_FEATURE_KERNEL_FORMAT, "kernel_format" },
|
||||
};
|
||||
static const char _lvmconf[] = "global/vdo_disabled_features";
|
||||
static int _vdo_checked = 0;
|
||||
diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
|
||||
index c393c217e..d5066fbda 100644
|
||||
--- a/libdm/libdevmapper.h
|
||||
+++ b/libdm/libdevmapper.h
|
||||
@@ -2167,6 +2167,8 @@ struct dm_vdo_target_params {
|
||||
|
||||
/* write policy */
|
||||
enum dm_vdo_write_policy write_policy;
|
||||
+
|
||||
+ int use_kernel_format; /* kernel direct format (added last for ABI compat) */
|
||||
};
|
||||
|
||||
int dm_vdo_validate_target_params(const struct dm_vdo_target_params *vtp,
|
||||
diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c
|
||||
index 0a246f272..02b730bb8 100644
|
||||
--- a/libdm/libdm-deptree.c
|
||||
+++ b/libdm/libdm-deptree.c
|
||||
@@ -3026,6 +3026,26 @@ static int _vdo_emit_segment_line(struct dm_task *dmt, uint32_t major, uint32_t
|
||||
seg->vdo_params.logical_threads,
|
||||
seg->vdo_params.physical_threads);
|
||||
|
||||
+ /* Add format parameters for kernel direct formatting */
|
||||
+ if (seg->vdo_params.use_kernel_format) {
|
||||
+ /* Convert slab size from MB to 4KiB blocks */
|
||||
+ EMIT_PARAMS(pos, " slabSize " FMTu64,
|
||||
+ seg->vdo_params.slab_size_mb * UINT64_C(256)); // 1MiB -> 256 * 4KiB blocks
|
||||
+
|
||||
+ /* Index memory size: format as GiB if >= 1024MB, otherwise as fraction */
|
||||
+ if (seg->vdo_params.index_memory_size_mb >= 1024)
|
||||
+ EMIT_PARAMS(pos, " indexMemory %u", seg->vdo_params.index_memory_size_mb / 1024);
|
||||
+ else if (seg->vdo_params.index_memory_size_mb >= 768)
|
||||
+ EMIT_PARAMS(pos, " indexMemory 0.75");
|
||||
+ else if (seg->vdo_params.index_memory_size_mb >= 512)
|
||||
+ EMIT_PARAMS(pos, " indexMemory 0.50");
|
||||
+ else
|
||||
+ EMIT_PARAMS(pos, " indexMemory 0.25");
|
||||
+
|
||||
+ /* Sparse index setting */
|
||||
+ EMIT_PARAMS(pos, " indexSparse %s", seg->vdo_params.use_sparse_index ? "on" : "off");
|
||||
+ }
|
||||
+
|
||||
return 1;
|
||||
}
|
||||
|
||||
diff --git a/tools/toollib.c b/tools/toollib.c
|
||||
index 0e6ce5d3a..f91fae701 100644
|
||||
--- a/tools/toollib.c
|
||||
+++ b/tools/toollib.c
|
||||
@@ -1369,6 +1369,7 @@ int get_vdo_settings(struct cmd_context *cmd,
|
||||
DO_OFFLINE(slab_size_mb);
|
||||
DO_OFFLINE(use_metadata_hints);
|
||||
DO_OFFLINE(use_sparse_index);
|
||||
+ DO_OFFLINE(use_kernel_format);
|
||||
|
||||
option = "write_policy";
|
||||
if (_compare_vdo_option(cn->key, option)) {
|
||||
--
|
||||
2.54.0
|
||||
|
||||
355
0012-vdo-add-kernel-formatting-path-with-LV_VDOFORMAT-met.patch
Normal file
355
0012-vdo-add-kernel-formatting-path-with-LV_VDOFORMAT-met.patch
Normal file
@ -0,0 +1,355 @@
|
||||
From cc3b0438480b7bdc140416010e077943543a305a Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Thu, 25 Jun 2026 17:17:32 +0200
|
||||
Subject: [PATCH 12/16] vdo: add kernel formatting path with LV_VDOFORMAT
|
||||
metadata flag
|
||||
|
||||
Introduce LV_VDOFORMAT status flag persisted in VG metadata so the
|
||||
VDO pool activation can pass use_kernel_format=1 to the dm-vdo target.
|
||||
The flag is set before activation and cleared after formatting completes.
|
||||
|
||||
Add _format_vdo_pool_kernel() which activates the VDO pool with the
|
||||
flag set, waits for the VDO index to come online, deactivates, clears
|
||||
LV_VDOFORMAT and commits metadata.
|
||||
|
||||
In convert_vdo_pool_lv(), gracefully fall back to userspace vdoformat
|
||||
when the VDO target is older than 9.2.0 instead of failing with an
|
||||
error. For the kernel path, compute pool geometry via vdo_pool_info()
|
||||
to determine virtual size and report slab layout after formatting.
|
||||
On failure, revert status flags and remove the data layer.
|
||||
|
||||
Correct versioning for dm_tree_node_add_vdo_target as DM_1_02_216 after
|
||||
adding use_kernel_format to dm_vdo_target_params.
|
||||
Add ABI compatibility wrapper for 1.02.213 callers whose struct lacks
|
||||
the new field -- the wrapper zero-initialises use_kernel_format so old
|
||||
binaries default to userspace vdoformat.
|
||||
|
||||
Use a local copy of vdo_params in _vdo_pool_add_target_line() to
|
||||
avoid mutating in-memory metadata when setting use_kernel_format
|
||||
|
||||
(cherry picked from commit 50355f35e5eaad7d44f82c7d2a4c3d39f23527e1)
|
||||
---
|
||||
lib/format_text/flags.c | 1 +
|
||||
lib/metadata/metadata-exported.h | 1 +
|
||||
lib/metadata/vdo_manip.c | 138 ++++++++++++++++++++++++----
|
||||
lib/vdo/vdo.c | 7 +-
|
||||
libdm/.exported_symbols.DM_1_02_216 | 1 +
|
||||
libdm/libdm-deptree.c | 53 +++++++++--
|
||||
6 files changed, 176 insertions(+), 25 deletions(-)
|
||||
create mode 100644 libdm/.exported_symbols.DM_1_02_216
|
||||
|
||||
diff --git a/lib/format_text/flags.c b/lib/format_text/flags.c
|
||||
index 1f81d063a..dde5aabc8 100644
|
||||
--- a/lib/format_text/flags.c
|
||||
+++ b/lib/format_text/flags.c
|
||||
@@ -77,6 +77,7 @@ static const struct flag _lv_flags[] = {
|
||||
{LV_CROP_METADATA, "CROP_METADATA", SEGTYPE_FLAG},
|
||||
{LV_CACHE_VOL, "CACHE_VOL", COMPATIBLE_FLAG},
|
||||
{LV_CACHE_USES_CACHEVOL, "CACHE_USES_CACHEVOL", SEGTYPE_FLAG},
|
||||
+ {LV_VDOFORMAT, "VDOFORMAT", SEGTYPE_FLAG},
|
||||
{LV_NOSCAN, NULL, 0},
|
||||
{LV_TEMPORARY, NULL, 0},
|
||||
{POOL_METADATA_SPARE, NULL, 0},
|
||||
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
|
||||
index 1f78c7aac..70a00d0bd 100644
|
||||
--- a/lib/metadata/metadata-exported.h
|
||||
+++ b/lib/metadata/metadata-exported.h
|
||||
@@ -156,6 +156,7 @@
|
||||
#define LV_VDO UINT64_C(0x0000000020000000) /* LV - Internal use only */
|
||||
#define LV_VDO_POOL UINT64_C(0x0000000040000000) /* LV - Internal use only */
|
||||
#define LV_VDO_POOL_DATA UINT64_C(0x8000000000000000) /* LV - Internal use only */
|
||||
+#define LV_VDOFORMAT UINT64_C(0x0000000000000800) /* LV - VDO pool passes format args */
|
||||
|
||||
#define LV_CACHE_VOL UINT64_C(0x0010000000000000) /* LV - also a PV flag */
|
||||
#define LV_CACHE_USES_CACHEVOL UINT64_C(0x4000000000000000) /* LV - also a PV flag */
|
||||
diff --git a/lib/metadata/vdo_manip.c b/lib/metadata/vdo_manip.c
|
||||
index 0b4f2d3fe..ca1c34331 100644
|
||||
--- a/lib/metadata/vdo_manip.c
|
||||
+++ b/lib/metadata/vdo_manip.c
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "lib/metadata/metadata.h"
|
||||
#include "lib/locking/locking.h"
|
||||
#include "lib/misc/lvm-string.h"
|
||||
+#include "lib/misc/lvm-signal.h"
|
||||
#include "lib/commands/toolcontext.h"
|
||||
#include "lib/display/display.h"
|
||||
#include "lib/metadata/segtype.h"
|
||||
@@ -367,6 +368,73 @@ static int _format_vdo_pool_data_lv(struct logical_volume *data_lv,
|
||||
return 1;
|
||||
}
|
||||
|
||||
+static int _format_vdo_pool_kernel(struct logical_volume *vdo_pool_lv)
|
||||
+{
|
||||
+ struct cmd_context *cmd = vdo_pool_lv->vg->cmd;
|
||||
+ struct lv_status_vdo *vdo_status;
|
||||
+ enum dm_vdo_index_state index_state;
|
||||
+ int r = 0;
|
||||
+
|
||||
+ if (!vg_write(vdo_pool_lv->vg) || !vg_commit(vdo_pool_lv->vg))
|
||||
+ return_0;
|
||||
+
|
||||
+ if (!activate_lv(cmd, vdo_pool_lv)) {
|
||||
+ log_error("Failed to activate VDO pool %s for kernel formatting.",
|
||||
+ display_lvname(vdo_pool_lv));
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ sync_local_dev_names(cmd);
|
||||
+
|
||||
+ /* Wait for the UDS index to finish initializing */
|
||||
+ for (;;) {
|
||||
+ if (!lv_vdo_pool_status(vdo_pool_lv, 0, &vdo_status)) {
|
||||
+ stack;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ index_state = vdo_status->vdo->index_state;
|
||||
+ dm_pool_destroy(vdo_status->mem);
|
||||
+
|
||||
+ if (index_state == DM_VDO_INDEX_ERROR) {
|
||||
+ log_error("Failed to format VDO pool %s, index error.",
|
||||
+ display_lvname(vdo_pool_lv));
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ log_verbose("VDO pool %s index state: %s.",
|
||||
+ display_lvname(vdo_pool_lv),
|
||||
+ get_vdo_index_state_name(index_state));
|
||||
+
|
||||
+ if (index_state != DM_VDO_INDEX_OPENING) {
|
||||
+ r = 1; /* Initialized */
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ /* 50ms: formatting is typically fast, avoid unnecessary delay */
|
||||
+ if (!sigint_usleep(50000)) {
|
||||
+ log_warn("WARNING: Interrupted waiting for VDO index on %s.",
|
||||
+ display_lvname(vdo_pool_lv));
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!deactivate_lv(cmd, vdo_pool_lv)) {
|
||||
+ log_error("Failed to deactivate VDO pool %s after kernel formatting.",
|
||||
+ display_lvname(vdo_pool_lv));
|
||||
+ r = 0;
|
||||
+ }
|
||||
+out:
|
||||
+ vdo_pool_lv->status &= ~LV_VDOFORMAT;
|
||||
+
|
||||
+ if (!vg_write(vdo_pool_lv->vg) || !vg_commit(vdo_pool_lv->vg))
|
||||
+ return_0;
|
||||
+
|
||||
+ sync_local_dev_names(cmd);
|
||||
+
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* convert_vdo_pool_lv
|
||||
* @data_lv
|
||||
@@ -388,6 +456,7 @@ int convert_vdo_pool_lv(struct logical_volume *data_lv,
|
||||
struct logical_volume *vdo_pool_lv = data_lv;
|
||||
const struct segment_type *vdo_pool_segtype;
|
||||
struct lv_segment *vdo_pool_seg;
|
||||
+ struct vdo_pool_info pinfo = { 0 };
|
||||
uint64_t vdo_logical_size = 0;
|
||||
uint64_t adjust;
|
||||
unsigned attrs = 0;
|
||||
@@ -414,29 +483,37 @@ int convert_vdo_pool_lv(struct logical_volume *data_lv,
|
||||
if (format) {
|
||||
if (test_mode()) {
|
||||
log_verbose("Test mode: Skipping formatting of VDO pool volume.");
|
||||
- } else if (use_kernel) {
|
||||
+ } else {
|
||||
if (use_kernel &&
|
||||
(!vdo_pool_segtype->ops->target_present ||
|
||||
!vdo_pool_segtype->ops->target_present(cmd, NULL, &attrs) ||
|
||||
!(attrs & VDO_FEATURE_KERNEL_FORMAT))) {
|
||||
- log_error("Kernel direct formatting (vdo_use_kernel_format=1) requires VDO target version 9.2.0 or newer.");
|
||||
- return 0;
|
||||
+ log_verbose("Kernel formatting requires VDO target version 9.2.0 or newer, using vdoformat.");
|
||||
+ use_kernel = 0;
|
||||
}
|
||||
|
||||
- /* Kernel decides to format if the first 4k are zeroes */
|
||||
- if (!activate_and_wipe_lv(data_lv, WIPE_MODE_DO_ZERO, 0, 0)) {
|
||||
- log_error("Aborting. Failed to wipe first 4 KiB of VDO pool volume %s.",
|
||||
- display_lvname(data_lv));
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
- if (!*virtual_extents)
|
||||
- vdo_logical_size = data_lv->size;
|
||||
- } else {
|
||||
- /* Traditional userspace vdoformat */
|
||||
- if (!_format_vdo_pool_data_lv(data_lv, vtp, &vdo_logical_size)) {
|
||||
- log_error("Cannot format VDO pool volume %s.", display_lvname(data_lv));
|
||||
- return 0;
|
||||
+ if (use_kernel) {
|
||||
+ /* Kernel decides to format if the first 4k are zeroes */
|
||||
+ if (!activate_and_wipe_lv(data_lv, WIPE_MODE_DO_ZERO, 0, 0)) {
|
||||
+ log_error("Aborting. Failed to wipe first 4 KiB of VDO pool volume %s.",
|
||||
+ display_lvname(data_lv));
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (!vdo_pool_info(data_lv->size, vtp, &pinfo)) {
|
||||
+ log_error("Pool %s is too small for the given VDO configuration.",
|
||||
+ display_lvname(data_lv));
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (!*virtual_extents)
|
||||
+ vdo_logical_size = pinfo.data_blocks * DM_VDO_BLOCK_SIZE;
|
||||
+ } else {
|
||||
+ /* Traditional userspace vdoformat */
|
||||
+ if (!_format_vdo_pool_data_lv(data_lv, vtp, &vdo_logical_size)) {
|
||||
+ log_error("Cannot format VDO pool volume %s.", display_lvname(data_lv));
|
||||
+ return 0;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -485,6 +562,33 @@ int convert_vdo_pool_lv(struct logical_volume *data_lv,
|
||||
vdo_pool_lv->status |= LV_VDO_POOL;
|
||||
data_lv->status |= LV_VDO_POOL_DATA;
|
||||
|
||||
+ if (use_kernel) {
|
||||
+ vdo_pool_lv->status |= LV_VDOFORMAT;
|
||||
+
|
||||
+ if (!_format_vdo_pool_kernel(vdo_pool_lv)) {
|
||||
+ log_error("Failed to kernel format VDO pool %s, reverting.",
|
||||
+ display_lvname(vdo_pool_lv));
|
||||
+ vdo_pool_lv->status &= ~LV_VDO_POOL;
|
||||
+ data_lv->status &= ~LV_VDO_POOL_DATA;
|
||||
+ if (!remove_layer_from_lv(vdo_pool_lv, data_lv))
|
||||
+ return_0;
|
||||
+ if (!lv_remove(data_lv))
|
||||
+ return_0;
|
||||
+ if (!vg_write(vdo_pool_lv->vg) || !vg_commit(vdo_pool_lv->vg))
|
||||
+ return_0;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ log_print_unless_silent(" The VDO volume can address %s in %u data slabs, each %s.",
|
||||
+ display_size(cmd, (uint64_t)pinfo.data_per_slab * pinfo.slab_count * DM_VDO_BLOCK_SIZE),
|
||||
+ pinfo.slab_count,
|
||||
+ display_mb_size(cmd, vtp->slab_size_mb));
|
||||
+ log_print_unless_silent(" It can grow to address at most %s of physical storage in %u slabs.",
|
||||
+ display_mb_size(cmd, (uint64_t)DM_VDO_SLABS_MAXIMUM * vtp->slab_size_mb),
|
||||
+ (unsigned)DM_VDO_SLABS_MAXIMUM);
|
||||
+ log_print_unless_silent(" If a larger maximum size might be needed, use bigger slabs.");
|
||||
+ }
|
||||
+
|
||||
return 1;
|
||||
}
|
||||
|
||||
diff --git a/lib/vdo/vdo.c b/lib/vdo/vdo.c
|
||||
index 1e9d377b5..e0a0c3079 100644
|
||||
--- a/lib/vdo/vdo.c
|
||||
+++ b/lib/vdo/vdo.c
|
||||
@@ -391,6 +391,7 @@ static int _vdo_pool_add_target_line(struct dev_manager *dm,
|
||||
struct dm_tree_node *node, uint64_t len,
|
||||
uint32_t *pvmove_mirror_count __attribute__((unused)))
|
||||
{
|
||||
+ struct dm_vdo_target_params vdo_params;
|
||||
char *vdo_pool_name, *data_uuid;
|
||||
unsigned attrs = 0;
|
||||
|
||||
@@ -411,11 +412,15 @@ static int _vdo_pool_add_target_line(struct dev_manager *dm,
|
||||
if (!(data_uuid = build_dm_uuid(mem, seg_lv(seg, 0), lv_layer(seg_lv(seg, 0)))))
|
||||
return_0;
|
||||
|
||||
+ /* Use local copy to avoid mutating in-memory metadata */
|
||||
+ vdo_params = seg->vdo_params;
|
||||
+ vdo_params.use_kernel_format = (seg->lv->status & LV_VDOFORMAT) ? 1 : 0;
|
||||
+
|
||||
/* VDO uses virtual size instead of its physical size */
|
||||
if (!dm_tree_node_add_vdo_target(node, get_vdo_pool_virtual_size(seg),
|
||||
!(attrs & VDO_FEATURE_VERSION4) ? 2 : 4,
|
||||
vdo_pool_name, data_uuid, seg_lv(seg, 0)->size,
|
||||
- &seg->vdo_params))
|
||||
+ &vdo_params))
|
||||
return_0;
|
||||
|
||||
return 1;
|
||||
diff --git a/libdm/.exported_symbols.DM_1_02_216 b/libdm/.exported_symbols.DM_1_02_216
|
||||
new file mode 100644
|
||||
index 000000000..f88fb03a7
|
||||
--- /dev/null
|
||||
+++ b/libdm/.exported_symbols.DM_1_02_216
|
||||
@@ -0,0 +1 @@
|
||||
+dm_tree_node_add_vdo_target
|
||||
diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c
|
||||
index 02b730bb8..4c420eeba 100644
|
||||
--- a/libdm/libdm-deptree.c
|
||||
+++ b/libdm/libdm-deptree.c
|
||||
@@ -4609,13 +4609,14 @@ void dm_tree_node_set_callback(struct dm_tree_node *dnode,
|
||||
dnode->callback_data = cb_data;
|
||||
}
|
||||
|
||||
-int dm_tree_node_add_vdo_target(struct dm_tree_node *node,
|
||||
- uint64_t size,
|
||||
- uint32_t vdo_version,
|
||||
- const char *vdo_pool_name,
|
||||
- const char *data_uuid,
|
||||
- uint64_t data_size,
|
||||
- const struct dm_vdo_target_params *vtp)
|
||||
+DM_EXPORT_NEW_SYMBOL(int, dm_tree_node_add_vdo_target, 1_02_216)
|
||||
+ (struct dm_tree_node *node,
|
||||
+ uint64_t size,
|
||||
+ uint32_t vdo_version,
|
||||
+ const char *vdo_pool_name,
|
||||
+ const char *data_uuid,
|
||||
+ uint64_t data_size,
|
||||
+ const struct dm_vdo_target_params *vtp)
|
||||
{
|
||||
struct load_segment *seg;
|
||||
|
||||
@@ -4699,4 +4700,42 @@ int dm_tree_node_add_cache_target_base(struct dm_tree_node *node,
|
||||
metadata_uuid, data_uuid, origin_uuid,
|
||||
policy_name, policy_settings, data_block_size);
|
||||
}
|
||||
+
|
||||
+/*
|
||||
+ * Retain ABI compatibility after adding use_kernel_format field
|
||||
+ * to dm_vdo_target_params in version 1.02.216.
|
||||
+ *
|
||||
+ * Old binaries compiled against 1.02.213 have struct dm_vdo_target_params
|
||||
+ * without the use_kernel_format field at the end. The wrapper copies only
|
||||
+ * the old fields and leaves use_kernel_format=0 (old apps use userspace
|
||||
+ * vdoformat).
|
||||
+ *
|
||||
+ * dm_vdo_validate_target_params does not need versioning as it never
|
||||
+ * accesses the use_kernel_format field.
|
||||
+ */
|
||||
+
|
||||
+DM_EXPORT_SYMBOL(dm_tree_node_add_vdo_target, 1_02_213)
|
||||
+int dm_tree_node_add_vdo_target_v1_02_213(struct dm_tree_node *node,
|
||||
+ uint64_t size,
|
||||
+ uint32_t vdo_version,
|
||||
+ const char *vdo_pool_name,
|
||||
+ const char *data_uuid,
|
||||
+ uint64_t data_size,
|
||||
+ const struct dm_vdo_target_params *vtp);
|
||||
+int dm_tree_node_add_vdo_target_v1_02_213(struct dm_tree_node *node,
|
||||
+ uint64_t size,
|
||||
+ uint32_t vdo_version,
|
||||
+ const char *vdo_pool_name,
|
||||
+ const char *data_uuid,
|
||||
+ uint64_t data_size,
|
||||
+ const struct dm_vdo_target_params *vtp)
|
||||
+{
|
||||
+ struct dm_vdo_target_params vtp_compat = { 0 };
|
||||
+
|
||||
+ /* Old callers pass struct without use_kernel_format at the end */
|
||||
+ memcpy(&vtp_compat, vtp, offsetof(struct dm_vdo_target_params, use_kernel_format));
|
||||
+
|
||||
+ return dm_tree_node_add_vdo_target(node, size, vdo_version, vdo_pool_name,
|
||||
+ data_uuid, data_size, &vtp_compat);
|
||||
+}
|
||||
#endif
|
||||
--
|
||||
2.54.0
|
||||
|
||||
44
0013-make-generate.patch
Normal file
44
0013-make-generate.patch
Normal file
@ -0,0 +1,44 @@
|
||||
From 60d971e910d8e1ffac7c4e5dafa9933ab0e3a767 Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Sun, 26 Apr 2026 16:29:42 +0200
|
||||
Subject: [PATCH 13/16] make: generate
|
||||
|
||||
(cherry picked from commit 9ec3d17d61a0a7bb5063129bbbf4b3144234ccc4)
|
||||
---
|
||||
conf/example.conf.in | 11 +++++++++--
|
||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/conf/example.conf.in b/conf/example.conf.in
|
||||
index 9a74feda5..ef8ca256f 100644
|
||||
--- a/conf/example.conf.in
|
||||
+++ b/conf/example.conf.in
|
||||
@@ -703,6 +703,13 @@ allocation {
|
||||
# This configuration option has an automatic default value.
|
||||
# vdo_use_sparse_index = 0
|
||||
|
||||
+ # Configuration option allocation/vdo_use_kernel_format.
|
||||
+ # Use kernel direct formatting for VDO volume.
|
||||
+ # When enabled (1), uses kernel direct formatting (requires dm-vdo 9.2.0+).
|
||||
+ # When disabled (0), uses traditional userspace vdoformat tool.
|
||||
+ # This configuration option has an automatic default value.
|
||||
+ # vdo_use_kernel_format = 1
|
||||
+
|
||||
# Configuration option allocation/vdo_index_memory_size_mb.
|
||||
# Specifies the amount of index memory in MiB for VDO volume.
|
||||
# The value must be at least 256MiB and at most 1TiB.
|
||||
@@ -1383,10 +1390,10 @@ global {
|
||||
# Configuration option global/vdo_disabled_features.
|
||||
# Features to not use in the vdo driver.
|
||||
# This can be helpful for testing, or to avoid using a feature that is
|
||||
- # causing problems. Features include: online_rename, version4
|
||||
+ # causing problems. Features include: online_rename, version4, kernel_format
|
||||
#
|
||||
# Example
|
||||
- # vdo_disabled_features = [ "online_rename", "version4" ]
|
||||
+ # vdo_disabled_features = [ "online_rename", "version4", "kernel_format" ]
|
||||
#
|
||||
# This configuration option does not have a default value defined.
|
||||
|
||||
--
|
||||
2.54.0
|
||||
|
||||
38
0014-WHATS_NEW-update.patch
Normal file
38
0014-WHATS_NEW-update.patch
Normal file
@ -0,0 +1,38 @@
|
||||
From d3bc31dc85f8890ccb14101703b8da4484040a5b Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Sun, 26 Apr 2026 11:36:45 +0200
|
||||
Subject: [PATCH 14/16] WHATS_NEW: update
|
||||
|
||||
(cherry picked from commit 4785084a64bbe6426dbc4adc43a4e181280713ab)
|
||||
---
|
||||
WHATS_NEW | 2 ++
|
||||
WHATS_NEW_DM | 4 ++++
|
||||
2 files changed, 6 insertions(+)
|
||||
|
||||
diff --git a/WHATS_NEW b/WHATS_NEW
|
||||
index e53280e10..56c565d9c 100644
|
||||
--- a/WHATS_NEW
|
||||
+++ b/WHATS_NEW
|
||||
@@ -1,5 +1,7 @@
|
||||
Version 2.03.42 -
|
||||
==================
|
||||
+ Support formatting vdo volumes with kernel vdo target (version >= 9.2).
|
||||
+ Add vdo_format.c with pre-format logical size computation for kernel format.
|
||||
Fix autoactivation on top of MD and loop devices if udev db records incomplete.
|
||||
Make MD device ready state check in udev to be in sync with MD udev rules.
|
||||
|
||||
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
|
||||
index b567591db..e58e4f86e 100644
|
||||
--- a/WHATS_NEW_DM
|
||||
+++ b/WHATS_NEW_DM
|
||||
@@ -1,3 +1,7 @@
|
||||
+Version 1.02.216 -
|
||||
+===================
|
||||
+ Add use_kernel_format to dm_vdo_target_params.
|
||||
+
|
||||
Version 1.02.215 - 15th May 2026
|
||||
================================
|
||||
Fix ttree insert/lookup depth mismatch in libdm.
|
||||
--
|
||||
2.54.0
|
||||
|
||||
16
lvm2.spec
16
lvm2.spec
@ -49,6 +49,18 @@ Patch2: 0002-lvmlockd-fix-adopt-failure-when-gl-is-not-found.patch
|
||||
Patch3: 0003-udev-check-MD-array_state-value-instead-of-just-file.patch
|
||||
Patch4: 0004-udev-MD-and-loop-fallback-handling-for-synthetic-ADD.patch
|
||||
Patch5: 0005-WHATS_NEW-update.patch
|
||||
# RHEL-188186:
|
||||
Patch6: 0006-fix-lvmpersist-WEAR-EAAR-reserve-race-when-multiple-.patch
|
||||
# Minor fixes
|
||||
Patch7: 0007-man-lvmlockd-fix-invalid-vgchange-setpersist-setlock.patch
|
||||
Patch8: 0008-lvmpersist-settle-udev-between-register-and-preempt-.patch
|
||||
Patch9: 0009-man-lvmlockd-improve-setlockargs-description.patch
|
||||
# RHEL-164001:
|
||||
Patch10: 0010-vdo-add-pre-format-pool-geometry-computation.patch
|
||||
Patch11: 0011-vdo-add-support-for-VDO-kernel-direct-formatting.patch
|
||||
Patch12: 0012-vdo-add-kernel-formatting-path-with-LV_VDOFORMAT-met.patch
|
||||
Patch13: 0013-make-generate.patch
|
||||
Patch14: 0014-WHATS_NEW-update.patch
|
||||
|
||||
BuildRequires: make
|
||||
BuildRequires: gcc
|
||||
@ -660,6 +672,10 @@ An extensive functional testsuite for LVM2.
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Thu Jul 02 2026 Marian Csontos <mcsontos@redhat.com> - 2.03.41-3
|
||||
- Fix concurrent PR start.
|
||||
- Use kernel vdoformat if present.
|
||||
|
||||
* Tue Jun 02 2026 Marian Csontos <mcsontos@redhat.com> - 2.03.41-2
|
||||
- Fix MD handling in udev rules.
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user