After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 614696 - gvfsfusedaemon.c: File handle not released in vfs_open() and recreated in vfs_truncate()
gvfsfusedaemon.c: File handle not released in vfs_open() and recreated in vfs...
Status: RESOLVED OBSOLETE
Product: gvfs
Classification: Core
Component: fuse
1.6.x
Other Linux
: Normal normal
: ---
Assigned To: gvfs-maint
gvfs-maint
Depends on:
Blocks:
 
 
Reported: 2010-04-02 23:02 UTC by potter000
Modified: 2018-09-21 17:03 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description potter000 2010-04-02 23:02:47 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.
Comment 1 potter000 2010-04-02 23:04:50 UTC
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;
 }
Comment 2 Tomas Bzatek 2010-10-13 15:03:23 UTC
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.
Comment 3 GNOME Infrastructure Team 2018-09-21 17:03:04 UTC
-- 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.