[pve-devel] [PATCH pve-storage] fix #6561: zfspool: track refquota for subvolumes via user properties
Shannon Sterz
s.sterz at proxmox.com
Mon Jul 28 16:43:59 CEST 2025
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.sterz at 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
More information about the pve-devel
mailing list