Index: ChangeLog
===================================================================
--- ChangeLog	(revision 2355)
+++ ChangeLog	(revision 2359)
@@ -1,3 +1,30 @@
+2009-04-01  Hans Petter Jansson  <hpj@novell.com>
+
+        * client/gvfsfusedaemon.c
+        (vfs_flush)
+        (vfs_fsync): Hold file mutex while closing stream.
+
+2009-04-01  Hans Petter Jansson  <hpj@novell.com>
+
+        Related to bug #574968 - gvfs ftp backend appears to not wait for ftpd
+        return code on STOR.
+
+        * client/gvfsfusedaemon.c
+        (vfs_fsync): Implement by closing stream.
+
+2009-04-01  Hans Petter Jansson  <hpj@novell.com>
+
+        * client/gvfsfusedaemon.c
+        (errno_from_error): Add G_IO_ERROR_WOULD_BLOCK -> EAGAIN mapping.
+
+2009-04-01  Hans Petter Jansson  <hpj@novell.com>
+
+        Potential fix for bug #574968 - gvfs ftp backend appears to not wait
+        for ftpd return code on STOR.
+
+        * client/gvfsfusedaemon.c
+        (vfs_flush): Implement by closing stream.
+
 2009-03-31  Alexander Larsson  <alexl@redhat.com>
 
         * client/gdaemonmount.c:
Index: client/gvfsfusedaemon.c
===================================================================
--- client/gvfsfusedaemon.c	(revision 2355)
+++ client/gvfsfusedaemon.c	(revision 2359)
@@ -165,6 +165,7 @@ errno_from_error (GError *error)
       { G_IO_ERROR_WRONG_ETAG,         EIO          },
       { G_IO_ERROR_TIMED_OUT,          EIO          },
       { G_IO_ERROR_BUSY,               EBUSY        },
+      { G_IO_ERROR_WOULD_BLOCK,        EAGAIN       },
       { -1,                            -1           }
     };
 
@@ -1406,8 +1407,42 @@ vfs_write (const gchar *path, const gcha
 static gint
 vfs_flush (const gchar *path, struct fuse_file_info *fi)
 {
+  FileHandle *fh = get_file_handle_from_info (fi);
+
   debug_print ("vfs_flush: %s\n", path);
 
+  if (fh)
+    {
+      g_mutex_lock (fh->mutex);
+      file_handle_close_stream (fh);
+      g_mutex_unlock (fh->mutex);
+
+      /* get_file_handle_from_info () adds a "working ref", so release that. */
+      file_handle_unref (fh);
+    }
+
+  /* TODO: Error handling. */
+  return 0;
+}
+
+static gint
+vfs_fsync (const gchar *path, gint sync_data_only, struct fuse_file_info *fi)
+{
+  FileHandle *fh = get_file_handle_from_info (fi);
+
+  debug_print ("vfs_flush: %s\n", path);
+
+  if (fh)
+    {
+      g_mutex_lock (fh->mutex);
+      file_handle_close_stream (fh);
+      g_mutex_unlock (fh->mutex);
+
+      /* get_file_handle_from_info () adds a "working ref", so release that. */
+      file_handle_unref (fh);
+    }
+
+  /* TODO: Error handling. */
   return 0;
 }
 
@@ -2290,6 +2325,7 @@ static struct fuse_operations vfs_oper =
   .create      = vfs_create,
   .release     = vfs_release,
   .flush       = vfs_flush,
+  .fsync       = vfs_fsync,
 
   .read        = vfs_read,
   .write       = vfs_write,
