On June 24, 2021 12:01 pm, Wolfgang Bumiller wrote:
> Signed-off-by: Wolfgang Bumiller <w.bumil...@proxmox.com>
> ---
> Difference to the main btrfs series v2:
>   * removed double-eval to catch errors when setting limits in
>     alloc_image
>   Note that the issue that subvols are created with size zero was an
>   issue in pve-container.
>   Volume resizing is fixed in patch 3
> 
>  PVE/Storage/BTRFSPlugin.pm | 93 +++++++++++++++++++++++---------------
>  1 file changed, 57 insertions(+), 36 deletions(-)
> 
> diff --git a/PVE/Storage/BTRFSPlugin.pm b/PVE/Storage/BTRFSPlugin.pm
> index 5360dca..179186b 100644
> --- a/PVE/Storage/BTRFSPlugin.pm
> +++ b/PVE/Storage/BTRFSPlugin.pm
> @@ -57,6 +57,14 @@ sub properties {
>           type => 'boolean',
>           default => 0,
>       },
> +     quotas => {
> +         description => "If enabled, containers will use subvolumes 
> directly, using quotas"
> +             . " for space accounting, instead of using ext4 formatted 
> images files."
> +             . " While this removes a file system layer for containers, 
> there is a risk of"
> +             . " performance degrading over time.",
> +         type => 'boolean',
> +         default => 0,
> +     },
>      };
>  }
>  
> @@ -71,6 +79,7 @@ sub options {
>       format => { optional => 1 },
>       is_mountpoint => { optional => 1 },
>       nocow => { optional => 1 },
> +     quotas => { optional => 1 },
>       # TODO: The new variant of mkdir with  `populate` vs `create`...
>      };
>  }
> @@ -336,27 +345,20 @@ sub alloc_image {
>       $path = "$subvol/disk.raw";
>      }
>  
> -    if ($fmt eq 'subvol' && !!$size) {
> +    if ($fmt eq 'subvol' && !!$size && !$scfg->{quotas}) {
>       # NOTE: `btrfs send/recv` actually drops quota information so 
> supporting subvolumes with
>       # quotas doesn't play nice with send/recv.
> -     die "btrfs quotas are currently not supported, use an unsized subvolume 
> or a raw file\n";
> +     die "btrfs quotas are currently disabled, use an unsized subvolume or a 
> raw file\n";
>      }
>  
>      $class->btrfs_cmd(['subvolume', 'create', '--', $subvol]);
>  
>      eval {
>       if ($fmt eq 'subvol') {
> -         # Nothing to do for now...
> -
> -         # This is how we *would* do it:
> -         # # Use the subvol's default 0/$id qgroup
> -         # eval {
> -         #     # This call should happen at storage creation instead and 
> therefore governed by a
> -         #     # configuration option!
> -         #     # $class->btrfs_cmd(['quota', 'enable', $subvol]);
> -         #     my $id = $class->btrfs_get_subvol_id($subvol);
> -         #     $class->btrfs_cmd(['qgroup', 'limit', "${size}k", "0/$id", 
> $subvol]);
> -         # };
> +         if (!!$size) {
> +             my $id = $class->btrfs_get_subvol_id($subvol);
> +             $class->btrfs_cmd(['qgroup', 'limit', "${size}k", "0/$id", 
> $subvol]);
> +         }
>       } elsif ($fmt eq 'raw') {
>           sysopen my $fh, $path, O_WRONLY | O_CREAT | O_EXCL
>               or die "failed to create raw file '$path' - $!\n";
> @@ -434,27 +436,26 @@ sub free_image {
>      return undef;
>  }
>  
> -# Currently not used because quotas clash with send/recv.
> -# my sub btrfs_subvol_quota {
> -#     my ($class, $path) = @_;
> -#     my $id = '0/' . $class->btrfs_get_subvol_id($path);
> -#     my $search = qr/^\Q$id\E\s+(\d)+\s+\d+\s+(\d+)\s*$/;
> -#     my ($used, $size);
> -#     $class->btrfs_cmd(['qgroup', 'show', '--raw', '-rf', '--', $path], sub 
> {
> -#    return if defined($size);
> -#    if ($_[0] =~ $search) {
> -#        ($used, $size) = ($1, $2);
> -#    }
> -#     });
> -#     if (!defined($size)) {
> -#    # syslog should include more information:
> -#    syslog('err', "failed to get subvolume size for: $path (id $id)");
> -#    # UI should only see the last path component:
> -#    $path =~ s|^.*/||;
> -#    die "failed to get subvolume size for $path\n";
> -#     }
> -#     return wantarray ? ($used, $size) : $size;
> -# }
> +my sub btrfs_subvol_quota {
> +    my ($class, $path) = @_;
> +    my $id = '0/' . $class->btrfs_get_subvol_id($path);
> +    my $search = qr/^\Q$id\E\s+(\d)+\s+\d+\s+(\d+)\s*$/;
> +    my ($used, $size);
> +    $class->btrfs_cmd(['qgroup', 'show', '--raw', '-rf', '--', $path], sub {
> +     return if defined($size);
> +     if ($_[0] =~ $search) {
> +         ($used, $size) = ($1, $2);
> +     }
> +    });
> +    if (!defined($size)) {
> +     # syslog should include more information:
> +     syslog('err', "failed to get subvolume size for: $path (id $id)");

this is still missing the use statement..

> +     # UI should only see the last path component:
> +     $path =~ s|^.*/||;
> +     die "failed to get subvolume size for $path\n";
> +    }
> +    return wantarray ? ($used, $size) : $size;
> +}
>  
>  sub volume_size_info {
>      my ($class, $scfg, $storeid, $volname, $timeout) = @_;
> @@ -466,7 +467,9 @@ sub volume_size_info {
>      if ($format eq 'subvol') {
>       my $ctime = (stat($path))[10];
>       my ($used, $size) = (0, 0);
> -     #my ($used, $size) = btrfs_subvol_quota($class, $path); # uses wantarray
> +     if ($scfg->{quotas}) {
> +         ($used, $size) = btrfs_subvol_quota($class, $path);
> +     }
>       return wantarray ? ($size, 'subvol', $used, undef, $ctime) : 1;
>      }
>  
> @@ -478,6 +481,9 @@ sub volume_resize {
>  
>      my $format = ($class->parse_volname($volname))[6];
>      if ($format eq 'subvol') {
> +     die "subvolumes can only be resized with quotas enabled\n"
> +         if !$scfg->{quotas};
> +
>       my $path = $class->filesystem_path($scfg, $volname);
>       my $id = '0/' . $class->btrfs_get_subvol_id($path);
>       $class->btrfs_cmd(['qgroup', 'limit', '--', "${size}k", "0/$id", 
> $path]);
> @@ -638,7 +644,9 @@ sub list_images {
>           ($size, $format, $used, $parent, $ctime) = 
> PVE::Storage::Plugin::file_size_info("$fn/disk.raw");
>       } elsif ($ext eq 'subvol') {
>           ($used, $size) = (0, 0);
> -         #($used, $size) = btrfs_subvol_quota($class, $fn);
> +         if ($scfg->{quotas}) {
> +             ($used, $size) = btrfs_subvol_quota($class, $fn);
> +         }
>           $format = 'subvol';
>       } else {
>           ($size, $format, $used, $parent, $ctime) = 
> PVE::Storage::Plugin::file_size_info($fn);
> @@ -680,6 +688,9 @@ sub volume_export_formats {
>      my $format = ($class->parse_volname($volname))[6];
>      return @result if $format ne 'raw' && $format ne 'subvol';
>  
> +    # Currently we don't allow using btrfs-send/recv with quotas on 
> subvolumes.
> +    return @result if $scfg->{quotas} && $format eq 'subvol';
> +
>      return ('btrfs', @result);
>  }
>  
> @@ -726,6 +737,11 @@ sub volume_export {
>      die "btrfs-sending volumes of type $volume_format ('$volname') is not 
> supported\n"
>       if $volume_format ne 'raw' && $volume_format ne 'subvol';
>  
> +    if ($scfg->{quotas} && $format eq 'subvol') {
> +     die "btrfs-sending volumes of type $volume_format ('$volname') with 
> quotas enabled is"
> +         . " currently not supported\n";
> +    }
> +
>      my $path = $class->path($scfg, $volname, $storeid);
>  
>      if ($volume_format eq 'raw') {
> @@ -782,6 +798,11 @@ sub volume_import {
>      die "btrfs-receiving volumes of type $volume_format ('$volname') is not 
> supported\n"
>       if $volume_format ne 'raw' && $volume_format ne 'subvol';
>  
> +    if ($scfg->{quotas} && $format eq 'subvol') {
> +     die "btrfs-receiving volumes of type $volume_format ('$volname') with 
> quotas enabled is"
> +         . " currently not supported\n";
> +    }
> +
>      if (defined($base_snapshot)) {
>       my $path = $class->path($scfg, $volname, $storeid, $base_snapshot);
>       die "base snapshot '$base_snapshot' not found - no such directory 
> '$path'\n"
> -- 
> 2.30.2
> 
> 
> 
> _______________________________________________
> pve-devel mailing list
> pve-devel@lists.proxmox.com
> https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
> 
> 
> 


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

Reply via email to