[gvfs] fuse: Support ftruncate() where requested size > current size



commit b6164bc173223ee726f3102e3c7ed2bb9d2aad5b
Author: Tomas Bzatek <tbzatek redhat com>
Date:   Wed Jun 20 12:14:49 2012 +0200

    fuse: Support ftruncate() where requested size > current size
    
    When ftruncate is called with a size greater than the current size
    of the file, the expected behavior is that the file size increases to
    the requested size, and the new space is zero-filled.  SQLite depends
    on this behavior when opening a database using 'write-ahead log'
    journaling.
    
    Based on original patch by Jeff Smith <whydoubt yahoo com>

 client/gvfsfusedaemon.c |   21 +++++++++++++++++----
 1 files changed, 17 insertions(+), 4 deletions(-)
---
diff --git a/client/gvfsfusedaemon.c b/client/gvfsfusedaemon.c
index 8cf1c01..7827923 100644
--- a/client/gvfsfusedaemon.c
+++ b/client/gvfsfusedaemon.c
@@ -1891,10 +1891,23 @@ vfs_ftruncate (const gchar *path, off_t size, struct fuse_file_info *fi)
                       fh->stream = NULL;
                     }
                 }
-              else if (file_handle_get_size (fh, &current_size) &&
-		       current_size == size)
-		{
-		  /* Don't have to do anything to succeed */
+              else if (file_handle_get_size (fh, &current_size))
+                {
+                  if (current_size == size)
+                    {
+                      /* Don't have to do anything to succeed */
+                    }
+                  else if ((current_size < size) && g_seekable_can_seek (G_SEEKABLE (fh->stream)))
+                    {
+                      /* If the truncated size is larger than the current size
+                       * then we need to pad out the difference with 0's */
+                     goffset orig_pos = g_seekable_tell (G_SEEKABLE (fh->stream));
+                     gsize buf_size = size - current_size;
+                     gpointer buf = g_malloc0 (buf_size);
+                     write_stream (fh, buf, buf_size, current_size);
+                     g_free (buf);
+                     g_seekable_seek (G_SEEKABLE (fh->stream), orig_pos, G_SEEK_SET, NULL, NULL);
+                    }
 		}
 	      else
 		{



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]