fix #6561: zfspool: track refquota for subvolumes via user properties
ZFS itself does not track the refquota per snapshot, so this needs to be handled by Proxmox VE. Otherwise, rolling back a volume that has been resized since the snapshot was taken, will retain the new size. This is problematic, as it means the value in the guest config does not match the size of the disk on the storage anymore. This implementation does so by leveraging a user property per snapshot. Reported-by: Lukas Wagner <l.wagner@proxmox.com> Suggested-by: Fabian Grünbichler <f.gruenbichler@proxmox.com> Signed-off-by: Shannon Sterz <s.sterz@proxmox.com> Reviewed-by: Fiona Ebner <f.ebner@proxmox.com> Link: https://lore.proxmox.com/20250729121151.159797-1-s.sterz@proxmox.com [FE: improve capitalization and wording in commit message] Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
This commit is contained in:
committed by
Fiona Ebner
parent
d0239ba9c0
commit
a9315a0ed3
@ -482,9 +482,25 @@ sub volume_size_info {
|
|||||||
sub volume_snapshot {
|
sub volume_snapshot {
|
||||||
my ($class, $scfg, $storeid, $volname, $snap) = @_;
|
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);
|
||||||
|
my $snapshot_name = "$scfg->{pool}/$vname\@$snap";
|
||||||
|
|
||||||
$class->zfs_request($scfg, undef, 'snapshot', "$scfg->{pool}/$vname\@$snap");
|
$class->zfs_request($scfg, undef, 'snapshot', $snapshot_name);
|
||||||
|
|
||||||
|
# if this is a subvol, track refquota information via user properties. zfs
|
||||||
|
# does not track this property for snapshosts and consequently does not roll
|
||||||
|
# it back. so track this information manually.
|
||||||
|
if ($format eq 'subvol') {
|
||||||
|
my $refquota = $class->zfs_get_properties($scfg, 'refquota', "$scfg->{pool}/$vname");
|
||||||
|
|
||||||
|
$class->zfs_request(
|
||||||
|
$scfg,
|
||||||
|
undef,
|
||||||
|
'set',
|
||||||
|
"pve-storage:refquota=${refquota}",
|
||||||
|
$snapshot_name,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub volume_snapshot_delete {
|
sub volume_snapshot_delete {
|
||||||
@ -500,8 +516,24 @@ sub volume_snapshot_rollback {
|
|||||||
my ($class, $scfg, $storeid, $volname, $snap) = @_;
|
my ($class, $scfg, $storeid, $volname, $snap) = @_;
|
||||||
|
|
||||||
my (undef, $vname, undef, undef, undef, undef, $format) = $class->parse_volname($volname);
|
my (undef, $vname, undef, undef, undef, undef, $format) = $class->parse_volname($volname);
|
||||||
|
my $snapshot_name = "$scfg->{pool}/$vname\@$snap";
|
||||||
|
|
||||||
my $msg = $class->zfs_request($scfg, undef, 'rollback', "$scfg->{pool}/$vname\@$snap");
|
my $msg = $class->zfs_request($scfg, undef, 'rollback', $snapshot_name);
|
||||||
|
|
||||||
|
# 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_get_properties($scfg, 'pve-storage:refquota', $snapshot_name);
|
||||||
|
|
||||||
|
if ($refquota =~ m/^\d+$/) {
|
||||||
|
$class->zfs_request(
|
||||||
|
$scfg, undef, 'set', "refquota=${refquota}", "$scfg->{pool}/$vname",
|
||||||
|
);
|
||||||
|
} elsif ($refquota ne "-") {
|
||||||
|
# refquota user property was set, but not a number -> warn
|
||||||
|
warn "property for refquota tracking contained unknown value '$refquota'\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# we have to unmount rollbacked subvols, to invalidate wrong kernel
|
# we have to unmount rollbacked subvols, to invalidate wrong kernel
|
||||||
# caches, they get mounted in activate volume again
|
# caches, they get mounted in activate volume again
|
||||||
|
|||||||
Reference in New Issue
Block a user