[ostree/wip/fsync: 8/11] libotutil: Make use of dirfd-relative API in ot_gfile_replace_contents_fsync()



commit 85fcbb7516d2b122978fadf6be48f8b672ce3a2e
Author: Colin Walters <walters verbum org>
Date:   Tue Apr 8 18:31:33 2014 -0400

    libotutil: Make use of dirfd-relative API in ot_gfile_replace_contents_fsync()
    
    It's just more efficient.

 src/libotutil/ot-gio-utils.c |   28 ++++++++++++++++++++--------
 1 files changed, 20 insertions(+), 8 deletions(-)
---
diff --git a/src/libotutil/ot-gio-utils.c b/src/libotutil/ot-gio-utils.c
index 3313570..5b3dcfc 100644
--- a/src/libotutil/ot-gio-utils.c
+++ b/src/libotutil/ot-gio-utils.c
@@ -284,16 +284,23 @@ ot_gfile_replace_contents_fsync (GFile          *path,
                                  GError        **error)
 {
   gboolean ret = FALSE;
+  int parent_dfd;
   int fd;
+  const char *target_basename = gs_file_get_basename_cached (path);
   gs_unref_object GFile *parent = NULL;
-  gs_unref_object GFile *tmpfile = NULL;
+  gs_free char *tmpname = NULL;
   gs_unref_object GOutputStream *stream = NULL;
   gs_unref_object GInputStream *instream = NULL;
 
   parent = g_file_get_parent (path);
 
-  if (!gs_file_open_in_tmpdir (parent, 0644, &tmpfile, &stream,
-                               cancellable, error))
+  if (!gs_file_open_dir_fd (parent, &parent_dfd,
+                            cancellable, error))
+    goto out;
+
+  if (!gs_file_open_in_tmpdir_at (parent_dfd, 0644,
+                                  &tmpname, &stream,
+                                  cancellable, error))
     goto out;
 
   g_assert (G_IS_FILE_DESCRIPTOR_BASED (stream));
@@ -320,15 +327,20 @@ ot_gfile_replace_contents_fsync (GFile          *path,
   if (!g_output_stream_close (stream, cancellable, error))
     goto out;
 
-  if (!gs_file_rename (tmpfile, path, cancellable, error))
-    goto out;
+  if (renameat (parent_dfd, tmpname, parent_dfd, target_basename) == -1)
+    {
+      ot_util_set_error_from_errno (error, errno);
+      goto out;
+    }
 
-  g_clear_object (&tmpfile);
+  g_clear_pointer (&tmpname, g_free);
 
   ret = TRUE;
  out:
-  if (tmpfile)
-    (void) gs_file_unlink (tmpfile, NULL, NULL);
+  if (tmpname)
+    (void) unlinkat (parent_dfd, tmpname, 0);
+  if (parent_dfd != -1)
+    (void) close (parent_dfd);
   return ret;
 }
 


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