diff options
author | Tomas Bzatek <tbzatek@redhat.com> | 2012-06-20 12:14:49 +0200 |
---|---|---|
committer | Tomas Bzatek <tbzatek@redhat.com> | 2012-06-20 12:14:49 +0200 |
commit | b6164bc173223ee726f3102e3c7ed2bb9d2aad5b (patch) | |
tree | 7089173ca3985eca33cf97c32e92b8bb9e885e4d /client | |
parent | 872e874b9ee1bf326c6d436151a917f8f39e31ec (diff) | |
download | gvfs-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.c | 21 |
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, ¤t_size) && - current_size == size) - { - /* Don't have to do anything to succeed */ + else if (file_handle_get_size (fh, ¤t_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 { |