[ostree] core: Use at-relative lookup for locating objects too



commit b97249d4f90e7d1e10a41b73d73dbd703148084e
Author: Colin Walters <walters verbum org>
Date:   Sat Sep 7 04:47:40 2013 -0400

    core: Use at-relative lookup for locating objects too
    
    Add new internal API to both fstatat() and write a pathname for the
    given object.  Use it in commit, and also wrapped in the old
    GFile-based API.
    
    This is more efficient.

 src/libostree/ostree-repo-commit.c  |   30 +++++++++-------
 src/libostree/ostree-repo-private.h |    9 +++++
 src/libostree/ostree-repo.c         |   62 ++++++++++++++++++++++++++---------
 3 files changed, 72 insertions(+), 29 deletions(-)
---
diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c
index a90cdc8..ce2c62b 100644
--- a/src/libostree/ostree-repo-commit.c
+++ b/src/libostree/ostree-repo-commit.c
@@ -34,20 +34,16 @@
 
 static gboolean
 commit_loose_object_trusted (OstreeRepo        *self,
-                             const char        *checksum,
-                             OstreeObjectType   objtype,
+                             const char        *loose_path,
                              const char        *tempfile_name,
                              GCancellable      *cancellable,
                              GError           **error)
 {
   gboolean ret = FALSE;
   char loose_prefix[3];
-  char loose_objpath[_OSTREE_LOOSE_PATH_MAX];
-
-  _ostree_loose_path (loose_objpath, checksum, objtype, self->mode);
 
-  loose_prefix[0] = loose_objpath[0];
-  loose_prefix[1] = loose_objpath[1];
+  loose_prefix[0] = loose_path[0];
+  loose_prefix[1] = loose_path[1];
   loose_prefix[2] = '\0';
   if (G_UNLIKELY (mkdirat (self->objects_dir_fd, loose_prefix, 0777) == -1))
     {
@@ -60,7 +56,7 @@ commit_loose_object_trusted (OstreeRepo        *self,
     }
 
   if (G_UNLIKELY (renameat (self->tmp_dir_fd, tempfile_name,
-                            self->objects_dir_fd, loose_objpath) < 0))
+                            self->objects_dir_fd, loose_path) == -1))
     {
       if (errno != EEXIST)
         {
@@ -155,6 +151,7 @@ write_object (OstreeRepo         *self,
   GChecksum *checksum = NULL;
   gboolean temp_file_is_regular;
   gboolean is_symlink = FALSE;
+  char loose_objpath[_OSTREE_LOOSE_PATH_MAX];
 
   g_return_val_if_fail (self->in_transaction, FALSE);
   
@@ -165,9 +162,15 @@ write_object (OstreeRepo         *self,
 
   if (expected_checksum)
     {
-      if (!_ostree_repo_find_object (self, objtype, expected_checksum, &stored_path,
-                                     cancellable, error))
+      if (!_ostree_repo_has_loose_object (self, expected_checksum, objtype,
+                                          &have_obj, loose_objpath,
+                                          cancellable, error))
         goto out;
+      if (have_obj)
+        {
+          ret = TRUE;
+          goto out;
+        }
     }
 
   repo_mode = ostree_repo_get_mode (self);
@@ -290,8 +293,9 @@ write_object (OstreeRepo         *self,
         }
     }
           
-  if (!ostree_repo_has_object (self, objtype, actual_checksum, &have_obj,
-                               cancellable, error))
+  if (!_ostree_repo_has_loose_object (self, actual_checksum, objtype,
+                                      &have_obj, loose_objpath,
+                                      cancellable, error))
     goto out;
           
   do_commit = !have_obj;
@@ -358,7 +362,7 @@ write_object (OstreeRepo         *self,
               (void) close (fd);
             }
         }
-      if (!commit_loose_object_trusted (self, actual_checksum, objtype, temp_filename,
+      if (!commit_loose_object_trusted (self, loose_objpath, temp_filename,
                                         cancellable, error))
         goto out;
       g_clear_pointer (&temp_filename, g_free);
diff --git a/src/libostree/ostree-repo-private.h b/src/libostree/ostree-repo-private.h
index de65df6..0060ca4 100644
--- a/src/libostree/ostree-repo-private.h
+++ b/src/libostree/ostree-repo-private.h
@@ -77,6 +77,15 @@ _ostree_repo_find_object (OstreeRepo           *self,
                           GError             **error);
 
 gboolean
+_ostree_repo_has_loose_object (OstreeRepo           *self,
+                               const char           *checksum,
+                               OstreeObjectType      objtype,
+                               gboolean             *out_is_stored,
+                               char                 *loose_path_buf,
+                               GCancellable         *cancellable,
+                               GError             **error);
+
+gboolean
 _ostree_repo_get_loose_object_dirs (OstreeRepo       *self,
                                     GPtrArray       **out_object_dirs,
                                     GCancellable     *cancellable,
diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c
index 7db4697..db3869e 100644
--- a/src/libostree/ostree-repo.c
+++ b/src/libostree/ostree-repo.c
@@ -989,34 +989,64 @@ ostree_repo_load_object_stream (OstreeRepo         *self,
   return ret;
 }
 
+/*
+ * _ostree_repo_has_loose_object:
+ * @loose_path_buf: Buffer of size _OSTREE_LOOSE_PATH_MAX
+ *
+ * Locate object in repository; if it exists, @out_is_stored will be
+ * set to TRUE.  @loose_path_buf is always set to the loose path.
+ */
 gboolean
-_ostree_repo_find_object (OstreeRepo           *self,
-                          OstreeObjectType      objtype,
-                          const char           *checksum,
-                          GFile               **out_stored_path,
-                          GCancellable         *cancellable,
-                          GError             **error)
+_ostree_repo_has_loose_object (OstreeRepo           *self,
+                               const char           *checksum,
+                               OstreeObjectType      objtype,
+                               gboolean             *out_is_stored,
+                               char                 *loose_path_buf,
+                               GCancellable         *cancellable,
+                               GError             **error)
 {
   gboolean ret = FALSE;
   struct stat stbuf;
-  gs_unref_object GFile *object_path = NULL;
-  gs_unref_object GFile *ret_stored_path = NULL;
+  int res;
 
-  object_path = _ostree_repo_get_object_path (self, checksum, objtype);
+  _ostree_loose_path (loose_path_buf, checksum, objtype, self->mode);
 
-  if (lstat (gs_file_get_path_cached (object_path), &stbuf) == 0)
-    {
-      ret_stored_path = object_path;
-      object_path = NULL; /* Transfer ownership */
-    }
-  else if (errno != ENOENT)
+  do
+    res = fstatat (self->objects_dir_fd, loose_path_buf, &stbuf, AT_SYMLINK_NOFOLLOW);
+  while (G_UNLIKELY (res == -1 && errno == EINTR));
+  if (res == -1 && errno != ENOENT)
     {
       ot_util_set_error_from_errno (error, errno);
       goto out;
     }
 
   ret = TRUE;
-  ot_transfer_out_value (out_stored_path, &ret_stored_path);
+  *out_is_stored = (res != -1);
+ out:
+  return ret;
+}
+
+gboolean
+_ostree_repo_find_object (OstreeRepo           *self,
+                          OstreeObjectType      objtype,
+                          const char           *checksum,
+                          GFile               **out_stored_path,
+                          GCancellable         *cancellable,
+                          GError             **error)
+{
+  gboolean ret = FALSE;
+  gboolean has_object;
+  char loose_path[_OSTREE_LOOSE_PATH_MAX];
+
+  if (!_ostree_repo_has_loose_object (self, checksum, objtype, &has_object, loose_path, 
+                                      cancellable, error))
+    goto out;
+
+  ret = TRUE;
+  if (has_object)
+    *out_stored_path = g_file_resolve_relative_path (self->objects_dir, loose_path);
+  else
+    *out_stored_path = NULL;
 out:
   return ret;
 }


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