GNOME Bugzilla – Bug 614696
gvfsfusedaemon.c: File handle not released in vfs_open() and recreated in vfs_truncate()
Last modified: 2018-09-21 17:03:04 UTC
This can cause access conflicts (i.e. opening the same file twice) and unexpected behaviour, like https://bugzilla.gnome.org/show_bug.cgi?id=608908 The possible solution is to use algorithm from vfs_ftruncate() in vfs_truncate() with some minor changes. Please see the patch in attachment.
The patch did not upload correctly, please see below --- a/client/gvfsfusedaemon.c 2009-11-18 15:14:51.000000000 +0300 +++ b/client/gvfsfusedaemon.c 2010-04-03 02:02:55.000000000 +0400 @@ -1832,20 +1832,23 @@ } static gint -vfs_ftruncate (const gchar *path, off_t size, struct fuse_file_info *fi) +process_truncate (const gchar *path, off_t size, struct fuse_file_info *fi, gboolean ftruncate) { GFile *file; GError *error = NULL; gint result = 0; goffset current_size; - debug_print ("vfs_ftruncate: %s\n", path); - file = file_from_full_path (path); if (file) { - FileHandle *fh = get_file_handle_from_info (fi); + FileHandle *fh = NULL; + if (ftruncate) { + fh = get_file_handle_from_info (fi); + } else { + fh = get_file_handle_for_path (path); + } if (fh) { @@ -1894,6 +1897,13 @@ } } + /*If truncate() called, close stream*/ + if (!ftruncate && fh->stream) { + g_output_stream_close (fh->stream, NULL, NULL); + g_object_unref (fh->stream); + fh->stream = NULL; + } + g_mutex_unlock (fh->mutex); file_handle_unref (fh); } @@ -1909,70 +1919,26 @@ result = -ENOENT; } - debug_print ("vfs_ftruncate: -> %s\n", g_strerror (-result)); + return result; +} +static gint +vfs_ftruncate (const gchar *path, off_t size, struct fuse_file_info *fi) +{ + gint result = 0; + debug_print ("vfs_ftruncate: %s\n", path); + result = process_truncate(path, size, fi, TRUE); + debug_print ("vfs_ftruncate: -> %s\n", g_strerror (-result)); return result; } static gint vfs_truncate (const gchar *path, off_t size) { - GFile *file; - GError *error = NULL; - gint result = 0; - - debug_print ("vfs_truncate: %s\n", path); - - file = file_from_full_path (path); - - if (file) - { - GFileOutputStream *file_output_stream = NULL; - FileHandle *fh; - - /* Get a file handle just to lock the path while we're working */ - fh = get_file_handle_for_path (path); - if (fh) - g_mutex_lock (fh->mutex); - - if (size == 0) - { - file_output_stream = g_file_replace (file, 0, FALSE, 0, NULL, &error); - } - else - { - file_output_stream = g_file_append_to (file, 0, NULL, &error); - if (file_output_stream) - g_seekable_truncate (G_SEEKABLE (file_output_stream), size, NULL, &error); - } - - if (error) - { - result = -errno_from_error (error); - g_error_free (error); - } - - if (file_output_stream) - { - g_output_stream_close (G_OUTPUT_STREAM (file_output_stream), NULL, NULL); - g_object_unref (file_output_stream); - } - - if (fh) - { - g_mutex_unlock (fh->mutex); - file_handle_unref (fh); - } - - g_object_unref (file); - } - else - { - result = -ENOENT; - } - + gint result = 0; + debug_print ("vfs_truncate: %s\n", path); + result = process_truncate(path, size, NULL, FALSE); debug_print ("vfs_truncate: -> %s\n", g_strerror (-result)); - return result; }
I've posted a patch in bug 627567 which should solve most issues. I'm also waiting for a reply from FUSE folks. The vfs_truncate() and vfs_ftruncate() functions might be adapted according to their reply.
-- GitLab Migration Automatic Message -- This bug has been migrated to GNOME's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/gvfs/issues/144.