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 D262E1FF0B2 for ; Mon, 07 Sep 2026 07:09:09 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id D8F60215AA; Mon, 07 Sep 2026 07:08:56 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788757721; x=1789362521; darn=lists.proxmox.com; h=content-transfer-encoding:content-type:mime-version:message-id:date :subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to :content-type; bh=iZnAd8aHT2X9TAE9bjUR4U3hla6hFoefJt1EgaivpWk=; b=aS3dUhGN3OYCKWfaD/Wdkk1gUR4QltkswjoxsSS/aMtm6ceTGjf+giFWjffaoPU82R 6mwHNn5fHriw4Gi0QUc7sKk4nnE3vivA/NPwqW8Jj4Hic1VEQUVbONFCHgiJqX4xgUpI +LmiMhLV8DSi3fjV2B09jBdimqJeX8US2LaL0f1bCBclUjHONO1A0WR01BVH/gLjQ0o6 kDKgVRlQQ41WnlLOZF2KyDW/oDk+DXA27DsdL1cMamrnYb8rEynH6PUBvNRTcgdAXd1/ GVD1AcEErfEmvO9yLbBPl0RNxm6BCsmobR4FK7UQ8dPQTELhuCM6wAri0VlYWTHAUnff wouw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788757721; x=1789362521; h=content-transfer-encoding:content-type:mime-version:message-id:date :subject:cc:to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to:content-type; bh=iZnAd8aHT2X9TAE9bjUR4U3hla6hFoefJt1EgaivpWk=; b=brgh4axtbN0rVmUIk2EHCTqyedyEsI4SIhISE9cf2C9BxKpHTSMxSqVONZatB5JUqM FQvjlhcGuRKNDzxDml3MIVYbPZTcugcx6UYTNSS/DYS7iM9dt+MCsafj195BGeYenzSA /r8pKVI72Ib8uBqC79nIC7VsUBFh6daBBXBnk82gP7xu/u/W5iVx9D+bFEvNbpswAOyf p5qoJ2XZbgmV1sNsq3nzKaJcBgxeLSrMektCc3Qg6mz1nWv7+2hC7wKe4inlcMVblz+P 7rufz9KNWC+AaoHlQ8EOSRr18sjno1Vn9d6ZP9AoZDvILW+KCztvTZx/ktRzeo897Q7Q M8+Q== X-Gm-Message-State: AFuF++nNqwB3gB+k9r+IfAVol0MVw3KmfChWyhbW2Bxha7F/Sta2HfXL +KKTWcTpJSfUNpBM6aO5+8nnZrTgKzX3Tk39moa+DO0K2x5D3ejaC6Hgx2A7/QTZ X-Gm-Gg: AYBFou16UWL1YXGKo9R1bOE7apFRMboEI1AAqu72gruBqkjCmz0vLzt2O9/S+WOldzZ XnzBqogosG1Bh/x8fWua8Kx23p6kdFucmCnRXZaPT6MBPirh8ongKkcin45C/2ZVBN1TOKsi6UT e+90RqtTFltPS3KYFan6jW/oIBcak5EH+InyEwkl7iDvTIOQODLCsZpcwkgUkIWBr5pKd0derst vnkNgSr5vW8muDrfrfGuBYuLTRPDWvvqd20pnFi6pDZEqVU3C0dD2c0GymFDam8POtASrpsfLpd bD8u7iVbEu8llWntJmdAVQ6RqyQnCrgf4+FQQ80wa/Ji0SsK8n4JUMGZGxj3snnvUv2NCAUW4JO 47kyxj7p3P0J2GYKttgrYuv39Rw4Sspd24a2IfQU0HhKWveJUkzBfEdiLrPxJA1hCIPaIRYC+Lh PddftZ4b/2f3UbaUQpWM7UL/qmw8P2ZGHLHElavI0bcSCNz92M1dOvtT8= X-Received: by 2002:a17:90b:268d:b0:398:bdb0:adb7 with SMTP id 98e67ed59e1d1-39b261e1beemr34160230a91.16.1788757720455; Sun, 06 Sep 2026 22:08:40 -0700 (PDT) From: Ciro Iriarte To: pve-devel@lists.proxmox.com Subject: [PATCH storage] btrfs: fix clone_image cloning live data instead of the requested snapshot Date: Mon, 07 Sep 2026 02:06:38 -0300 Message-ID: <20260907.btrfsclonesnapfix@cyruspy.gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.105 Adjusted score from AWL reputation of From: address DKIM_SIGNED 0.1 Message has a DKIM or DK signature, not necessarily valid DKIM_VALID -0.1 Message has at least one valid DKIM or DK signature DKIM_VALID_AU -0.1 Message has a valid DKIM or DK signature from author's domain DKIM_VALID_EF -0.1 Message has a valid DKIM or DK signature from envelope-from domain DMARC_PASS -0.1 DMARC pass policy FREEMAIL_FROM 0.001 Sender email is commonly abused enduser mail provider RCVD_IN_DNSWL_NONE -0.0001 Sender listed at https://www.dnswl.org/, no trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: E6L7WJSCBZMTN6HJSGCPOAMC4ILZHYT7 X-Message-ID-Hash: E6L7WJSCBZMTN6HJSGCPOAMC4ILZHYT7 X-MailFrom: cyruspy@gmail.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 X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: clone_image() takes $snap but never passed it to filesystem_path(), so it always resolved the live subvolume. Cloning from a snapshot therefore produced a clone of the CURRENT state while the caller believed it had cloned the snapshot. This is reachable from the GUI and the API, not a dormant path: volume_has_feature() advertises 'clone' for the 'snap' key on raw volumes, and PVE::Storage::clone_image() passes the snapshot straight through, so cloning a VM from one of its snapshots on a btrfs storage silently gets current data. Nothing errors out and the clone is perfectly readable, which is what makes it easy to miss -- the disk simply holds different content than the snapshot it was named after. Reproduced on a loop-backed btrfs by writing known content, snapshotting, then overwriting the source: clone_image($snap) returned the post-overwrite md5. With $snap passed through it returns the snapshot's md5. Found while implementing copy-offload for this plugin, which needs the same distinction and is where the question came up. Generated-By: Claude (https://claude.ai) Signed-off-by: Ciro Iriarte Co-Authored-By: Claude --- src/PVE/Storage/BTRFSPlugin.pm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/PVE/Storage/BTRFSPlugin.pm b/src/PVE/Storage/BTRFSPlugin.pm index fb47aa0..f58a1bb 100644 --- a/src/PVE/Storage/BTRFSPlugin.pm +++ b/src/PVE/Storage/BTRFSPlugin.pm @@ -298,7 +298,10 @@ sub clone_image { $imagedir .= "/$vmid"; mkpath $imagedir; - my $path = $class->filesystem_path($scfg, $volname); + # Clone the snapshot the caller asked for, not the live subvolume. Dropping $snap + # here silently produced a clone of the CURRENT state while the caller believed it + # had cloned the snapshot. + my $path = $class->filesystem_path($scfg, $volname, $snap); my $newname = $class->find_free_diskname($storeid, $scfg, $vmid, $format, 1); # For btrfs subvolumes we don't actually need the "link": -- 2.54.0