[PATCH] fuse: Support ftruncate where requested size > current size
- From: Jeff Smith <whydoubt yahoo com>
- To: gvfs-list gnome org
- Cc: Jeff Smith <whydoubt yahoo com>
- Subject: [PATCH] fuse: Support ftruncate where requested size > current size
- Date: Thu, 17 May 2012 23:58:02 -0500
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.
Signed-off-by: Jeff Smith <whydoubt yahoo com>
---
On iOS 5, the SQLite database MediaLibrary.sqlite uses write-ahead
logging. Without this patch, the only way to do anything with the
database (even to dump it) is to copy it from the iPod/iPhone to a
local filesystem, and then work with it.
client/gvfsfusedaemon.c | 26 ++++++++++++++++----------
1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/client/gvfsfusedaemon.c b/client/gvfsfusedaemon.c
index 8cf1c01..9f11678 100644
--- a/client/gvfsfusedaemon.c
+++ b/client/gvfsfusedaemon.c
@@ -1814,6 +1814,7 @@ vfs_rmdir (const gchar *path)
static gboolean
file_handle_get_size (FileHandle *fh,
+ GFile *file,
goffset *size)
{
GFileInfo *info;
@@ -1822,15 +1823,9 @@ file_handle_get_size (FileHandle *fh,
if (fh->stream == NULL)
return FALSE;
- info = NULL;
- if (fh->op == FILE_OP_READ)
- info = g_file_input_stream_query_info (fh->stream,
- G_FILE_ATTRIBUTE_STANDARD_SIZE,
- NULL, NULL);
- else if (fh->op == FILE_OP_WRITE)
- info = g_file_output_stream_query_info (fh->stream,
- G_FILE_ATTRIBUTE_STANDARD_SIZE,
- NULL, NULL);
+ info = g_file_query_info (file,
+ G_FILE_ATTRIBUTE_STANDARD_SIZE,
+ 0, NULL, NULL);
res = FALSE;
if (info)
@@ -1891,11 +1886,22 @@ 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) &&
+ else if (file_handle_get_size (fh, file, ¤t_size) &&
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
{
result = -ENOTSUP;
--
1.7.9.5
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]