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.
This commit is contained in:
Ondrej Holy 2023-03-06 10:30:20 +01:00
parent e75ba524fd
commit 406143b072

View File

@ -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;
}