[pve-devel] [PATCH storage v5 08/32] common: add deallocate helper function

Fiona Ebner f.ebner at proxmox.com
Fri Mar 21 14:48:28 CET 2025


For punching holes via fallocate. This will be useful for the external
backup provider API to discard parts of the source. The 'file-handle'
mechanism there uses a fuse mount, which does not implement the
BLKDISCARD ioctl, but does implement fallocate.

Signed-off-by: Fiona Ebner <f.ebner at proxmox.com>
---

New in v5.

 src/PVE/Storage/Common.pm | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/src/PVE/Storage/Common.pm b/src/PVE/Storage/Common.pm
index 3ae20dd..32ed26a 100644
--- a/src/PVE/Storage/Common.pm
+++ b/src/PVE/Storage/Common.pm
@@ -3,6 +3,13 @@ package PVE::Storage::Common;
 use strict;
 use warnings;
 
+use PVE::Syscall;
+
+use constant {
+    FALLOC_FL_KEEP_SIZE => 0x01, # see linux/falloc.h
+    FALLOC_FL_PUNCH_HOLE => 0x02, # see linux/falloc.h
+};
+
 =pod
 
 =head1 NAME
@@ -51,4 +58,27 @@ sub align_size_up : prototype($$) {
     return $aligned_size;
 }
 
+=pod
+
+=head3 deallocate
+
+    deallocate($file_handle, $offset, $length)
+
+Deallocates the range with C<$length> many bytes starting from offset C<$offset>
+for the file associated to the file handle C<$file_handle>. Dies on failure.
+
+=cut
+
+sub deallocate : prototype($$$) {
+    my ($file_handle, $offset, $length) = @_;
+
+    my $mode = FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE;
+    $offset = int($offset);
+    $length = int($length);
+
+    if (syscall(PVE::Syscall::fallocate, fileno($file_handle), $mode, $offset, $length) != 0) {
+	die "fallocate: punch hole failed (offset: $offset, length: $length) - $!\n";
+    }
+}
+
 1;
-- 
2.39.5





More information about the pve-devel mailing list