[gvfs/nfs] Address another round of reviews
- From: Ross Lagerwall <rossl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gvfs/nfs] Address another round of reviews
- Date: Sat, 31 Jan 2015 16:14:11 +0000 (UTC)
commit 8c21c76edf7051748648d5f8195a82222ce8f468
Author: Ross Lagerwall <rosslagerwall gmail com>
Date: Sat Jan 31 16:13:33 2015 +0000
Address another round of reviews
daemon/gvfsbackendnfs.c | 102 +++++++++++++++++++++++++++++-----------------
1 files changed, 64 insertions(+), 38 deletions(-)
---
diff --git a/daemon/gvfsbackendnfs.c b/daemon/gvfsbackendnfs.c
index 845576f..4a52043 100644
--- a/daemon/gvfsbackendnfs.c
+++ b/daemon/gvfsbackendnfs.c
@@ -87,18 +87,28 @@ g_vfs_backend_nfs_init (GVfsBackendNfs *backend)
}
static void
-g_vfs_backend_nfs_finalize (GObject *object)
+g_vfs_backend_nfs_destroy_context (GVfsBackendNfs *backend)
{
- GVfsBackendNfs *backend = G_VFS_BACKEND_NFS (object);
+ if (backend->ctx)
+ {
+ nfs_destroy_context (backend->ctx);
+ backend->ctx = NULL;
+ }
if (backend->source)
{
g_source_destroy (backend->source);
g_source_unref (backend->source);
+ backend->source = NULL;
}
+}
- if (backend->ctx)
- nfs_destroy_context (backend->ctx);
+static void
+g_vfs_backend_nfs_finalize (GObject *object)
+{
+ GVfsBackendNfs *backend = G_VFS_BACKEND_NFS (object);
+
+ g_vfs_backend_nfs_destroy_context (backend);
if (G_OBJECT_CLASS (g_vfs_backend_nfs_parent_class)->finalize)
(*G_OBJECT_CLASS (g_vfs_backend_nfs_parent_class)->finalize) (object);
@@ -117,14 +127,8 @@ nfs_source_prepare (GSource *source, gint *timeout)
if (fd < 0)
{
- GVfsBackendNfs *backend = nfs_source->backend;
-
- g_vfs_backend_force_unmount (G_VFS_BACKEND (backend));
- nfs_destroy_context (nfs_source->ctx);
- backend->ctx = NULL;
- g_source_destroy (source);
- g_source_unref (source);
- backend->source = NULL;
+ g_vfs_backend_force_unmount (G_VFS_BACKEND (nfs_source->backend));
+ g_vfs_backend_nfs_destroy_context (nfs_source->backend);
}
else if (fd != nfs_source->fd)
{
@@ -152,16 +156,10 @@ nfs_source_dispatch (GSource *source, GSourceFunc callback, gpointer user_data)
g_source_query_unix_fd (source, nfs_source->tag));
if (err)
{
- GVfsBackendNfs *backend = nfs_source->backend;
-
g_warning ("nfs_service error: %d, %s\n",
err, nfs_get_error (nfs_source->ctx));
- g_vfs_backend_force_unmount (G_VFS_BACKEND (backend));
- nfs_destroy_context (nfs_source->ctx);
- backend->ctx = NULL;
- g_source_destroy (source);
- g_source_unref (source);
- backend->source = NULL;
+ g_vfs_backend_force_unmount (G_VFS_BACKEND (nfs_source->backend));
+ g_vfs_backend_nfs_destroy_context (nfs_source->backend);
}
return G_SOURCE_CONTINUE;
@@ -182,8 +180,8 @@ do_mount (GVfsBackend *backend,
const char *host;
char *basename, *display_name, *export = NULL;
int err;
- int pathlen = strlen (mount_spec->mount_prefix);
- int exportlen = 0;
+ size_t pathlen = strlen (mount_spec->mount_prefix);
+ size_t exportlen = SIZE_MAX;
static GSourceFuncs nfs_source_callbacks = {
nfs_source_prepare,
NULL,
@@ -194,25 +192,34 @@ do_mount (GVfsBackend *backend,
host = g_mount_spec_get (mount_spec, "host");
export_list = mount_getexports (host);
- /* Find the longest matching mount. E.g. if the given mount_prefix is
- * /some/long/path * and there exist two mounts, /some and /some/long, match
- * against the latter. */
+ /* Find the shortest matching mount. E.g. if the given mount_prefix is
+ * /some/long/path and there exist two mounts, /some and /some/long, match
+ * against /some. */
for (ptr = export_list; ptr; ptr = ptr->ex_next)
{
+ /* First check that the NFS mount point is a prefix of the mount_prefix. */
if (g_str_has_prefix (mount_spec->mount_prefix, ptr->ex_dir))
{
- int this_exportlen = strlen (ptr->ex_dir);
+ size_t this_exportlen = strlen (ptr->ex_dir);
+ /* Check if the mount_prefix is longer than the NFS mount point.
+ * E.g. mount_prefix: /mnt/file, mount point: /mnt */
if (pathlen > this_exportlen)
{
+ /* Check if the mount_prefix has a slash at the correct point.
+ * E.g. if the mount point is /mnt, then it's a match if the
+ * mount_prefix is /mnt/a but not a match if the mount_prefix is
+ * /mnta. Choose it if it is the shortest found so far. */
char *s = mount_spec->mount_prefix + this_exportlen;
- if (*s == '/' && this_exportlen > exportlen)
+ if (*s == '/' && this_exportlen < exportlen)
{
export = ptr->ex_dir;
exportlen = this_exportlen;
}
}
- else if (this_exportlen > exportlen)
+ /* The mount_prefix and NFS mount point are identical. Choose it if
+ * it is the shortest found so far. */
+ else if (this_exportlen < exportlen)
{
export = ptr->ex_dir;
exportlen = this_exportlen;
@@ -246,6 +253,7 @@ do_mount (GVfsBackend *backend,
{
g_vfs_job_failed_from_errno (G_VFS_JOB (job), -err);
}
+ g_free (export);
return;
}
@@ -276,6 +284,7 @@ do_mount (GVfsBackend *backend,
g_mount_spec_set_mount_prefix (nfs_mount_spec, export);
g_vfs_backend_set_mount_spec (backend, nfs_mount_spec);
g_mount_spec_unref (nfs_mount_spec);
+ g_free (export);
/* cache the process's umask for later */
op_backend->umask = umask (0);
@@ -399,11 +408,11 @@ try_read (GVfsBackend *backend,
return TRUE;
}
-static char *
+static const char *
set_type_from_mode (GFileInfo *info, uint64_t mode)
{
GFileType type = G_FILE_TYPE_UNKNOWN;
- char *mimetype = NULL;
+ const char *mimetype = NULL;
if (S_ISREG (mode))
type = G_FILE_TYPE_REGULAR;
@@ -445,11 +454,11 @@ set_type_from_mode (GFileInfo *info, uint64_t mode)
static void
set_name_info (GFileInfo *info,
- char *mimetype,
+ const char *mimetype,
const char *basename,
GFileAttributeMatcher *matcher)
{
- gboolean free_mimetype = FALSE;
+ char *free_mimetype = NULL;
g_file_info_set_name (info, basename);
if (basename[0] == '.')
@@ -470,8 +479,8 @@ set_name_info (GFileInfo *info,
{
if (basename)
{
- mimetype = g_content_type_guess (basename, NULL, 0, NULL);
- free_mimetype = TRUE;
+ free_mimetype = g_content_type_guess (basename, NULL, 0, NULL);
+ mimetype = free_mimetype;
}
else
mimetype = "application/octet-stream";
@@ -511,7 +520,7 @@ set_name_info (GFileInfo *info,
}
if (free_mimetype)
- g_free (mimetype);
+ g_free (free_mimetype);
}
static void
@@ -736,6 +745,9 @@ try_append_to (GVfsBackend *backend,
return TRUE;
}
+/* The following types and functions implement an asynchronous copy which calls
+ * a callback function with a boolean success or failure. This is used in some
+ * cases for backup files when replacing. */
#define COPY_BLKSIZE (64 * 1024)
typedef void (*CopyFileCallback) (gboolean success, void *private_data);
@@ -850,6 +862,16 @@ copy_file (struct nfs_context *ctx,
nfs_open_async (ctx, src, O_RDONLY, copy_open_source_cb, handle);
}
+/* The replace code that follows is relatively straightforward but difficult to
+ * read due to its asynchronous nature.
+ * Firstly, the file is opened with O_EXCL. If this fails, the file exists.
+ * Some checks on the existing file are made. If possible, a temporary file is
+ * opened and renamed over the existing file on close. If a backup is needed,
+ * the existing file is simply renamed to the backup.
+ * If it is not possible to create a temporary file (e.g. due to permissions),
+ * then the file is truncated and writing takes place directly into the file.
+ * However, if a backup needs to be made, the existing file is first copied
+ * into the backup file. */
static void
replace_trunc_cb (int err,
struct nfs_context *ctx,
@@ -1638,7 +1660,7 @@ enumerate_stat_cb (int err,
if (err == 0)
{
struct nfs_stat_64 *st = data;
- char *mimetype;
+ const char *mimetype;
GFileInfo *new_info;
new_info = g_file_info_new ();
@@ -1730,7 +1752,9 @@ enumerate_continue (EnumerateHandle *handle, struct nfs_context *ctx)
}
else
{
- g_vfs_job_enumerate_done (handle->op_job);
+ GVfsJobEnumerate *op_job = handle->op_job;
+ g_slice_free (EnumerateHandle, handle);
+ g_vfs_job_enumerate_done (op_job);
}
}
@@ -1856,6 +1880,7 @@ enumerate_cb (int err, struct nfs_context *ctx, void *data, void *private_data)
}
else
{
+ g_slice_free (EnumerateHandle, handle);
g_vfs_job_failed_from_errno (job, -err);
}
}
@@ -1937,7 +1962,8 @@ stat_cb (int err, struct nfs_context *ctx, void *data, void *private_data)
GVfsJobQueryInfo *op_job = G_VFS_JOB_QUERY_INFO (job);
GFileInfo *info = op_job->file_info;
struct nfs_stat_64 *st = data;
- char *basename, *mimetype, *etag;
+ const char *mimetype;
+ char *basename, *etag;
set_info_from_stat (info, st, op_job->attribute_matcher);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]