zfs itself does not track the refquota per snapshot so we need handle
this ourselves. this implementation tries to do so by leveraging a
user property per snapshot.

Signed-off-by: Shannon Sterz <s.st...@proxmox.com>
---

this approach is not backward compatible, meaning that changes to volume
sizes between snapshot before this patch will still be affected by this
issue. however, it is fairly self-contained, does not require us to rely
on the container config and works well with replication.

we could fall back to resetting the refquota higher up in the call chain
in case the storage doesn't manage to do it by itself. however, that
comes with the potential downside of users messing with their configs
und us resizing the disk when we shouldn't.

 src/PVE/Storage/ZFSPoolPlugin.pm | 46 +++++++++++++++++++++++++++++++-
 1 file changed, 45 insertions(+), 1 deletion(-)

diff --git a/src/PVE/Storage/ZFSPoolPlugin.pm b/src/PVE/Storage/ZFSPoolPlugin.pm
index cdf5868..2474b7f 100644
--- a/src/PVE/Storage/ZFSPoolPlugin.pm
+++ b/src/PVE/Storage/ZFSPoolPlugin.pm
@@ -482,9 +482,28 @@ sub volume_size_info {
 sub volume_snapshot {
     my ($class, $scfg, $storeid, $volname, $snap) = @_;

-    my $vname = ($class->parse_volname($volname))[1];
+    my (undef, $vname, undef, undef, undef, undef, $format) = 
$class->parse_volname($volname);

     $class->zfs_request($scfg, undef, 'snapshot', 
"$scfg->{pool}/$vname\@$snap");
+
+    # if this is a subvol, track refquota information with snapshot, as zfs 
does
+    # not track this property via snapshosts and consequently does not roll it
+    # back
+    if ($format eq 'subvol') {
+        my $refquota = $class->zfs_request(
+            $scfg, undef, 'get', 'refquota', '-o', 'value', '-Hp', 
"$scfg->{pool}/$vname",
+        );
+
+        chomp($refquota);
+
+        $class->zfs_request(
+            $scfg,
+            undef,
+            'set',
+            "pve-storage:refquota=${refquota}",
+            "$scfg->{pool}/$vname\@$snap",
+        );
+    }
 }

 sub volume_snapshot_delete {
@@ -503,6 +522,31 @@ sub volume_snapshot_rollback {

     my $msg = $class->zfs_request($scfg, undef, 'rollback', 
"$scfg->{pool}/$vname\@$snap");

+    if ($format eq 'subvol') {
+    }
+
+    # if this is a subvol, check if we tracked the refquota manually via user 
properties and if so,
+    # set it appropriatelly again
+    if ($format eq 'subvol') {
+        my $refquota = $class->zfs_request(
+            $scfg,
+            undef,
+            'get',
+            'pve-storage:refquota',
+            '-o',
+            'value',
+            '-Hp',
+            "$scfg->{pool}/$vname\@$snap",
+        );
+
+        chomp($refquota);
+
+        if ($refquota =~ m/^\d+$/) {
+            $class->zfs_request($scfg, undef, 'set', "refquota=${refquota}",
+                "$scfg->{pool}/$vname");
+        }
+    }
+
     # we have to unmount rollbacked subvols, to invalidate wrong kernel
     # caches, they get mounted in activate volume again
     # see zfs bug #10931 https://github.com/openzfs/zfs/issues/10931
--
2.47.2



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to