From 406143b072ec92c2810f93441f037793215b04d9 Mon Sep 17 00:00:00 2001 From: Ondrej Holy Date: Mon, 6 Mar 2023 10:30:20 +0100 Subject: [PATCH] gfile: Fix file size detection when copying on btrfs When the `g_file_copy` function is used with files on BTRFS, the `GLib-GIO-FATAL-CRITICAL: GFileInfo created without standard::size` error is printed. This is because the `g_file_get_size` function is used to obtain the file size for the progress callback, but it uses the wrong `GFileInfo` object that is meant for attributes to be copied with the file. The file size attribute is missing there obviously. Let's obtain the file size over the `fstat` call the same way as it is done in the `splice_stream_with_progress` function to get rid of those errors and to fix the progress reporting. --- gio/gfile.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/gio/gfile.c b/gio/gfile.c index 84353cb44..8b328e19c 100644 --- a/gio/gfile.c +++ b/gio/gfile.c @@ -3158,15 +3158,25 @@ btrfs_reflink_with_progress (GInputStream *in, gpointer progress_callback_data, GError **error) { - goffset source_size; + goffset total_size; int fd_in, fd_out; int ret, errsv; fd_in = g_file_descriptor_based_get_fd (G_FILE_DESCRIPTOR_BASED (in)); fd_out = g_file_descriptor_based_get_fd (G_FILE_DESCRIPTOR_BASED (out)); + total_size = -1; + /* avoid performance impact of querying total size when it's not needed */ if (progress_callback) - source_size = g_file_info_get_size (info); + { + struct stat sbuf; + + if (fstat (fd_in, &sbuf) == 0) + total_size = sbuf.st_size; + } + + if (total_size == -1) + total_size = 0; /* Btrfs clone ioctl properties: * - Works at the inode level @@ -3201,7 +3211,7 @@ btrfs_reflink_with_progress (GInputStream *in, /* Make sure we send full copied size */ if (progress_callback) - progress_callback (source_size, source_size, progress_callback_data); + progress_callback (total_size, total_size, progress_callback_data); return TRUE; }