From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [45.144.208.40]) by lore.proxmox.com (Postfix) with ESMTPS id 4E7E71FF0E0 for ; Thu, 06 Aug 2026 10:02:17 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 1815D21506; Thu, 06 Aug 2026 10:02:17 +0200 (CEST) From: Erik Fastermann To: pve-devel@lists.proxmox.com Subject: [PATCH storage] fix #6915: lvmthin: leave room for repair Date: Thu, 6 Aug 2026 10:02:08 +0200 Message-ID: <20260806080208.41768-1-e.fastermann@proxmox.com> X-Mailer: git-send-email 2.47.3 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 1 AWL -0.584 Adjusted score from AWL reputation of From: address DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) KAM_LAZY_DOMAIN_SECURITY 1 Sending domain does not have any anti-forgery methods RDNS_NONE 1.274 Delivered to internal network by a host with no rDNS SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_NONE 0.001 SPF: sender does not publish an SPF Record Message-ID-Hash: VXPXDEORZUFJLQKWRDZGXRGRMQ66ANJN X-Message-ID-Hash: VXPXDEORZUFJLQKWRDZGXRGRMQ66ANJN X-MailFrom: efastermann@ruth.proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Erik Fastermann X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: The pool is sized to fill the volume group, leaving a flat 128M free regardless of device size. That is not enough to repair damaged pool metadata. As described in lvmthin(7), `lvconvert --repair` writes the recovered metadata into the VGs pmspare LV, promotes it to be the pool metadata LV and keeps the damaged one as a visible ThinPool_metaN backup, so a replacement spare has to be allocated afterwards. Without free extents the repair is not possible. Subtract the metadata size a third time, so one metadata LV worth of extents stays unallocated. The reserve is deliberately limited to what a repair needs, as the utility for a pool that ran full is questionable: - a thin pool cannot be shrunk, so this is a one time reserve and does not help if the pool runs full again - extending does not undo the damage, guest file systems that took I/O errors need an fsck and possibly a restore from backup - pool metadata is limited to 16G, so on very large pools it cannot be extended at all and free extents do not help there - moving disks to another storage temporarily or deleting snapshots is often the preferred solution if metadata is not exhausted Creating a partition for the physical volume, as suggested in the report, is left out. The installer partitions because the disk has to be bootable, not for the sake of LVM, and a data disk added later has no such requirement. All LVM based storages PVE creates for data use the whole device, Ceph OSDs included, so this is the consistent behavior. The standard tooling is not confused by it either and existing pools keep their layout in any case. It should be noted that metadata exhaustion, which was one of the original motivations for this change, is hard to reach with the current defaults. The installations that hit this in practice are older ones, created before metadata was sized at 1% of the pool, and those pools are unaffected by this change. Signed-off-by: Erik Fastermann --- src/PVE/API2/Disks/LVMThin.pm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/PVE/API2/Disks/LVMThin.pm b/src/PVE/API2/Disks/LVMThin.pm index a0ce497..2b14ca1 100644 --- a/src/PVE/API2/Disks/LVMThin.pm +++ b/src/PVE/API2/Disks/LVMThin.pm @@ -153,8 +153,11 @@ __PACKAGE__->register_method({ $metadatasize = 1024 * 1024 if $metadatasize < 1024 * 1024; # but at most 16G, which is the current lvm max $metadatasize = 16 * 1024 * 1024 if $metadatasize > 16 * 1024 * 1024; - # shrink data by needed amount for metadata - $datasize -= 2 * $metadatasize; + # shrink data by twice the metadata size for the pool metadata LV + # and pmspare, and once more to leave the volume group room for + # `lvconvert --repair` + $datasize -= 3 * $metadatasize; + die "device too small for a thin pool\n" if $datasize <= 0; run_command([ '/sbin/lvcreate', -- 2.47.3