Re: [PATCH] fuse: Support ftruncate where requested size > current size



No, not a strong reason.  In my case g_file_output_stream_query_info() was returning a not-supported error, but g_file_query_info() did work.  I just haven't yet had time to go back to dig deeper.

  -- Jeff


-----Original message-----
From: Tomas Bzatek <tbzatek redhat com>
To:
gvfs-list gnome org
Cc:
Jeff Smith <whydoubt yahoo com>
Sent:
Mon, May 21, 2012 14:46:11 GMT+00:00
Subject:
Re: [PATCH] fuse: Support ftruncate where requested size > current size

Great addition, thanks for the patch, we're not giving much love to the
fuse daemon these days.

The second part (zero filling) looks good to me, I just did not get the
first part - not using FGilexxputStream but GFile instead. Was there a
strong reason? I mean, if the file is still open, g_file_query_info()
may not give correct information until the file is closed. This heavily
depends on the particular backend naturally.

--
Tomas Bzatek

On Thu, 2012-05-17 at 23:58 -0500, Jeff Smith wrote:
> 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
> ---
> 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;



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