lib/repo: Fix loading commitstate with parent repos
authorColin Walters <walters@verbum.org>
Wed, 25 Oct 2017 17:13:17 +0000 (13:13 -0400)
committerSimon McVittie <smcv@debian.org>
Thu, 26 Oct 2017 23:19:45 +0000 (00:19 +0100)
This makes the code nicer too. Properly unit testing this though really wants
like a whole set of stuff around parent repos...but we do have coverage of the
non-parent path in the current pull tests.

Closes: https://github.com/ostreedev/ostree/issues/1306
Closes: #1308
Approved by: alexlarsson
Origin: upstream, 2017.13, commit:90ebd48f6aaf45c47b48c44354359f973dcf22a8

Gbp-Pq: Topic 2017.13
Gbp-Pq: Name lib-repo-Fix-loading-commitstate-with-parent-repos.patch

src/libostree/ostree-repo.c

index 0632ee2d8d19da5de59ce2ced4533191ce17b342..eac5610b5e882e6788438a311a9b4d234e550fd2 100644 (file)
@@ -2807,6 +2807,7 @@ load_metadata_internal (OstreeRepo       *self,
                         GVariant        **out_variant,
                         GInputStream    **out_stream,
                         guint64          *out_size,
+                        OstreeRepoCommitState *out_state,
                         GCancellable     *cancellable,
                         GError          **error)
 {
@@ -2817,6 +2818,7 @@ load_metadata_internal (OstreeRepo       *self,
   g_autoptr(GVariant) ret_variant = NULL;
 
   g_return_val_if_fail (OSTREE_OBJECT_TYPE_IS_META (objtype), FALSE);
+  g_return_val_if_fail (objtype == OSTREE_OBJECT_TYPE_COMMIT || out_state == NULL, FALSE);
 
   /* Special caching for dirmeta objects, since they're commonly referenced many
    * times.
@@ -2904,11 +2906,24 @@ load_metadata_internal (OstreeRepo       *self,
 
       if (out_size)
         *out_size = stbuf.st_size;
+
+      if (out_state)
+        {
+          g_autofree char *commitpartial_path = _ostree_get_commitpartial_path (sha256);
+          *out_state = 0;
+
+          if (!glnx_fstatat_allow_noent (self->repo_dir_fd, commitpartial_path, NULL, 0, error))
+            return FALSE;
+          if (errno == 0)
+            *out_state |= OSTREE_REPO_COMMIT_STATE_PARTIAL;
+        }
     }
   else if (self->parent_repo)
     {
-      if (!ostree_repo_load_variant (self->parent_repo, objtype, sha256, &ret_variant, error))
-        return FALSE;
+      /* Directly recurse to simplify out parameters */
+      return load_metadata_internal (self->parent_repo, objtype, sha256, error_if_not_found,
+                                     out_variant, out_stream, out_size, out_state,
+                                     cancellable, error);
     }
   else if (error_if_not_found)
     {
@@ -3220,7 +3235,7 @@ ostree_repo_load_object_stream (OstreeRepo         *self,
   if (OSTREE_OBJECT_TYPE_IS_META (objtype))
     {
       if (!load_metadata_internal (self, objtype, checksum, TRUE, NULL,
-                                   &ret_input, &size,
+                                   &ret_input, &size, NULL,
                                    cancellable, error))
         return FALSE;
     }
@@ -3516,7 +3531,7 @@ ostree_repo_load_variant_if_exists (OstreeRepo       *self,
                                     GError          **error)
 {
   return load_metadata_internal (self, objtype, sha256, FALSE,
-                                 out_variant, NULL, NULL, NULL, error);
+                                 out_variant, NULL, NULL, NULL, NULL, error);
 }
 
 /**
@@ -3538,7 +3553,7 @@ ostree_repo_load_variant (OstreeRepo       *self,
                           GError          **error)
 {
   return load_metadata_internal (self, objtype, sha256, TRUE,
-                                 out_variant, NULL, NULL, NULL, error);
+                                 out_variant, NULL, NULL, NULL, NULL, error);
 }
 
 /**
@@ -3561,31 +3576,8 @@ ostree_repo_load_commit (OstreeRepo            *self,
                          OstreeRepoCommitState *out_state,
                          GError               **error)
 {
-  if (out_variant)
-    {
-      if (!load_metadata_internal (self, OSTREE_OBJECT_TYPE_COMMIT, checksum, TRUE,
-                                   out_variant, NULL, NULL, NULL, error))
-        return FALSE;
-    }
-
-  if (out_state)
-    {
-      g_autofree char *commitpartial_path = _ostree_get_commitpartial_path (checksum);
-      struct stat stbuf;
-
-      *out_state = 0;
-
-      if (fstatat (self->repo_dir_fd, commitpartial_path, &stbuf, 0) == 0)
-        {
-          *out_state |= OSTREE_REPO_COMMIT_STATE_PARTIAL;
-        }
-      else if (errno != ENOENT)
-        {
-          return glnx_throw_errno_prefix (error, "fstatat(%s)", commitpartial_path);
-        }
-    }
-
-  return TRUE;
+  return load_metadata_internal (self, OSTREE_OBJECT_TYPE_COMMIT, checksum, TRUE,
+                                 out_variant, NULL, NULL, out_state, NULL, error);
 }
 
 /**