summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@redhat.com>2012-06-20 12:14:49 +0200
committerTomas Bzatek <tbzatek@redhat.com>2012-06-20 12:14:49 +0200
commitb6164bc173223ee726f3102e3c7ed2bb9d2aad5b (patch)
tree7089173ca3985eca33cf97c32e92b8bb9e885e4d /client
parent872e874b9ee1bf326c6d436151a917f8f39e31ec (diff)
downloadgvfs-b6164bc173223ee726f3102e3c7ed2bb9d2aad5b.tar.gz
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>
Diffstat (limited to 'client')
-rw-r--r--client/gvfsfusedaemon.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/client/gvfsfusedaemon.c b/client/gvfsfusedaemon.c
index 8cf1c01e..78279239 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
{