mirror of
https://github.com/webmin/webmin.git
synced 2026-08-22 23:10:34 +01:00
Fix to clarify Btrfs qgroup limit retry behavior
https://github.com/webmin/webmin/pull/2807#discussion_r3708456970
This commit is contained in:
@@ -1482,9 +1482,9 @@ return defined($_[0]) && $_[0] =~ /^\d+\/\d+$/ ? 1 : 0;
|
||||
|
||||
Sets the referenced or exclusive byte limit for a Btrfs qgroup. If qgroup is
|
||||
undef, path must be a subvolume and its level-0 qgroup is changed. If bytes
|
||||
is undef, the limit is removed. If an exceeded limit blocks the update, quota
|
||||
enforcement is temporarily overridden for one retry. Returns undef on success
|
||||
or an error message on failure.
|
||||
is undef, the limit is removed. If quota enforcement on path or one of its
|
||||
parent qgroups blocks the transaction, it is temporarily overridden for one
|
||||
retry. Returns undef on success or an error message on failure.
|
||||
|
||||
=cut
|
||||
sub set_btrfs_qgroup_limit
|
||||
@@ -1502,9 +1502,10 @@ push(@args, $qgroup) if (defined($qgroup));
|
||||
push(@args, $path);
|
||||
my ($out, $err) = &run_btrfs_command(1, @args);
|
||||
|
||||
# An exceeded qgroup can block the metadata write needed to raise or remove its
|
||||
# own limit. Retry once with the kernel's administrative override, preserving
|
||||
# the previous state and restoring enforcement immediately after the command.
|
||||
# A limit on the command path or one of its parent qgroups can block the
|
||||
# transaction needed to update any qgroup limit. Retry once with the kernel's
|
||||
# administrative override, preserving the previous state and restoring
|
||||
# enforcement immediately after the command.
|
||||
if ($err && $err =~ /disk quota exceeded/i) {
|
||||
my $uuid = &btrfs_filesystem_uuid($path);
|
||||
my $sysfs = $btrfs_sysfs_root || "/sys/fs/btrfs";
|
||||
|
||||
@@ -68,8 +68,8 @@ $same_referenced = &same_limit(
|
||||
$same_exclusive = &same_limit(
|
||||
$max_exclusive, $qgroup->{'max_exclusive'});
|
||||
|
||||
# Apply only changed limits, keeping an unrelated existing over-limit setting
|
||||
# from causing Btrfs to reject an otherwise valid update.
|
||||
# Apply only changed limits so each independent setting is left untouched when
|
||||
# the submitted value already matches it.
|
||||
if (!$same_referenced) {
|
||||
$err = &set_btrfs_qgroup_limit(
|
||||
$dir, $in{'qgroup'}, $max_referenced, 0);
|
||||
|
||||
@@ -287,8 +287,8 @@ is(main::set_btrfs_qgroup_limit("/srv/btrfs", "1/100", "1M"),
|
||||
is(main::assign_btrfs_qgroup("/srv/btrfs", "bad", "1/100"),
|
||||
"Invalid child Btrfs qgroup ID", "invalid child assignment is rejected");
|
||||
|
||||
# An existing over-limit qgroup must not prevent an administrator from raising
|
||||
# or removing its limit. The kernel override is restored after the retry.
|
||||
# A qgroup-limit transaction rejected by quota enforcement is retried once,
|
||||
# and the kernel override is restored immediately afterward.
|
||||
my $override_root = tempdir(CLEANUP => 1);
|
||||
my $override_uuid = "abcdef01-2345-6789-abcd-ef0123456789";
|
||||
make_path("$override_root/$override_uuid");
|
||||
@@ -305,12 +305,12 @@ local $main::btrfs_sysfs_root = $override_root;
|
||||
{ 'out' => "", 'status' => 0 },
|
||||
);
|
||||
is(main::set_btrfs_qgroup_limit("/srv/btrfs", "1/100", 2097152),
|
||||
undef, "over-limit qgroup updates retry with the administrative override");
|
||||
undef, "an EDQUOT limit update retries with the administrative override");
|
||||
open($override_fh, '<', "$override_root/$override_uuid/quota_override")
|
||||
or die $!;
|
||||
is(<$override_fh>, "0\n", "quota enforcement is restored after the retry");
|
||||
close($override_fh);
|
||||
is(scalar(@commands), 3, "one status lookup and one limit retry are run");
|
||||
is(scalar(@commands), 3, "one UUID lookup and one limit retry are run");
|
||||
|
||||
@responses = ({ 'out' => "ERROR: qgroup exists\n", 'status' => 1 });
|
||||
is(main::create_btrfs_qgroup("/srv/btrfs", "1/100"),
|
||||
|
||||
Reference in New Issue
Block a user