[gvfs] fuse: Track the size of open files properly
- From: Ross Lagerwall <rossl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gvfs] fuse: Track the size of open files properly
- Date: Sun, 26 Oct 2014 15:59:43 +0000 (UTC)
commit 3800f5297b10f34a17502983ca11f89efae9ddea
Author: Ross Lagerwall <rosslagerwall gmail com>
Date: Sat Jul 26 10:37:02 2014 +0100
fuse: Track the size of open files properly
Previously, if a getattr() for an open file could not get the size
information, the file position was returned as the size. This is
incorrect if seek or ftruncate had previously been used on the stream.
Instead, track the size of the open file and return this value. In
addition, use this size in preference to the size returned by
g_file_query_info() if a stream is open (this only happens if the stream
doesn't support g_file_query_info_on_write()) since the tracked size is
more likely to be correct due to implementing g_file_replace by writing
to a temporary file. Tracking the size is only necessary for files
which are created or opened with O_TRUNC since files opened with
O_APPEND will be appended in-place.
https://bugzilla.gnome.org/show_bug.cgi?id=632296
client/gvfsfusedaemon.c | 28 ++++++++++++++++++++++++----
1 files changed, 24 insertions(+), 4 deletions(-)
---
diff --git a/client/gvfsfusedaemon.c b/client/gvfsfusedaemon.c
index d8440eb..92ddf0f 100644
--- a/client/gvfsfusedaemon.c
+++ b/client/gvfsfusedaemon.c
@@ -70,6 +70,7 @@ typedef struct {
FileOp op;
gpointer stream;
goffset pos;
+ goffset size;
} FileHandle;
static GThread *subthread = NULL;
@@ -216,6 +217,7 @@ file_handle_new (const gchar *path)
g_mutex_init (&file_handle->mutex);
file_handle->op = FILE_OP_NONE;
file_handle->path = g_strdup (path);
+ file_handle->size = -1;
g_hash_table_insert (global_active_fh_map, file_handle, file_handle);
@@ -274,6 +276,7 @@ file_handle_close_stream (FileHandle *file_handle)
g_object_unref (file_handle->stream);
file_handle->stream = NULL;
file_handle->op = FILE_OP_NONE;
+ file_handle->size = -1;
}
}
@@ -898,12 +901,12 @@ vfs_getattr (const gchar *path, struct stat *sbuf)
if (fh)
{
- goffset pos;
+ goffset size;
g_mutex_lock (&fh->mutex);
result = getattr_for_file_handle (fh, sbuf);
- pos = fh->pos;
+ size = fh->size;
g_mutex_unlock (&fh->mutex);
file_handle_unref (fh);
@@ -915,13 +918,19 @@ vfs_getattr (const gchar *path, struct stat *sbuf)
/* Some backends don't create new files until their stream has
* been closed. So, if the path doesn't exist, but we have a
* stream associated with it, pretend it's there. */
+
+ /* If we're tracking an open file's size, use that in preference
+ * to the stat information since it may be incorrect if
+ * g_file_replace writes to a temporary file. */
+ if (size != -1)
+ sbuf->st_size = size;
+
if (result != 0)
{
result = 0;
sbuf->st_mode = S_IFREG | S_IRUSR | S_IWUSR | S_IXUSR;
sbuf->st_uid = daemon_uid;
sbuf->st_gid = daemon_gid;
- sbuf->st_size = pos;
sbuf->st_nlink = 1;
sbuf->st_blksize = 512;
sbuf->st_blocks = (sbuf->st_size + 511) / 512;
@@ -979,6 +988,7 @@ setup_input_stream (GFile *file, FileHandle *fh)
g_output_stream_close (fh->stream, NULL, NULL);
g_object_unref (fh->stream);
fh->stream = NULL;
+ fh->size = -1;
}
}
@@ -1026,7 +1036,10 @@ setup_output_stream (GFile *file, FileHandle *fh, int flags)
if (!fh->stream)
{
if (flags & O_TRUNC)
- fh->stream = g_file_replace (file, NULL, FALSE, 0, NULL, &error);
+ {
+ fh->stream = g_file_replace (file, NULL, FALSE, 0, NULL, &error);
+ fh->size = 0;
+ }
else if (flags & O_APPEND)
fh->stream = g_file_append_to (file, 0, NULL, &error);
else
@@ -1190,6 +1203,7 @@ vfs_create (const gchar *path, mode_t mode, struct fuse_file_info *fi)
file_handle_close_stream (fh);
fh->stream = file_output_stream;
+ fh->size = 0;
fh->op = FILE_OP_WRITE;
g_mutex_unlock (&fh->mutex);
@@ -1462,6 +1476,9 @@ write_stream (FileHandle *fh,
}
}
+ if (fh->size != -1 && fh->pos > fh->size)
+ fh->size = fh->pos;
+
return result;
}
@@ -1986,6 +2003,9 @@ truncate_stream (GFile *file, FileHandle *fh, off_t size)
g_error_free (error);
}
+ if (result == 0 && fh->size != -1)
+ fh->size = size;
+
return result;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]