diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index fcb0a5c9..9012cb89 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -1803,6 +1803,7 @@ static gboolean map_variant_file_check_header_string (GFile *path, const GVariantType *variant_type, const char *expected_header, + gboolean trusted, GVariant **out_variant, GCancellable *cancellable, GError **error) @@ -1811,7 +1812,7 @@ map_variant_file_check_header_string (GFile *path, const char *header; ot_lvariant GVariant *ret_variant = NULL; - if (!ot_util_variant_map (path, variant_type, &ret_variant, error)) + if (!ot_util_variant_map (path, variant_type, trusted, &ret_variant, error)) goto out; g_variant_get_child (ret_variant, 0, "&s", &header); @@ -1899,7 +1900,7 @@ list_pack_checksums_from_superindex_file (GFile *superindex_path, GVariantIter *data_variant_iter = NULL; if (!ot_util_variant_map (superindex_path, OSTREE_PACK_SUPER_INDEX_VARIANT_FORMAT, - &superindex_variant, error)) + TRUE, &superindex_variant, error)) goto out; g_variant_get (superindex_variant, "(&s@a{sv}a(ayay)a(ayay))", @@ -2293,7 +2294,7 @@ ostree_repo_resync_cached_remote_pack_indexes (OstreeRepo *self, ret_uncached_data_indexes = g_ptr_array_new_with_free_func (g_free); if (!ot_util_variant_map (superindex_path, OSTREE_PACK_SUPER_INDEX_VARIANT_FORMAT, - &superindex_variant, error)) + FALSE, &superindex_variant, error)) goto out; if (!ostree_validate_structureof_pack_superindex (superindex_variant, error)) @@ -2438,7 +2439,7 @@ ostree_repo_map_cached_remote_pack_index (OstreeRepo *self, cached_pack_path = get_pack_index_path (cache_dir, is_meta, pack_checksum); if (!ot_util_variant_map (cached_pack_path, OSTREE_PACK_INDEX_VARIANT_FORMAT, - &ret_variant, error)) + FALSE, &ret_variant, error)) goto out; ret = TRUE; @@ -2470,7 +2471,7 @@ ostree_repo_add_cached_remote_pack_index (OstreeRepo *self, if (!map_variant_file_check_header_string (cached_path, OSTREE_PACK_INDEX_VARIANT_FORMAT, "OSTv0PACKINDEX", - &input_index_variant, + FALSE, &input_index_variant, cancellable, error)) goto out; @@ -3437,7 +3438,7 @@ ostree_repo_load_pack_index (OstreeRepo *self, path = get_pack_index_path (priv->pack_dir, is_meta, pack_checksum); if (!map_variant_file_check_header_string (path, OSTREE_PACK_INDEX_VARIANT_FORMAT, - "OSTv0PACKINDEX", + "OSTv0PACKINDEX", TRUE, &ret_variant, cancellable, error)) goto out; @@ -3539,7 +3540,7 @@ ostree_repo_load_file (OstreeRepo *self, ot_lvariant GVariant *archive_meta = NULL; if (!ot_util_variant_map (loose_path, OSTREE_FILE_HEADER_GVARIANT_FORMAT, - &archive_meta, error)) + TRUE, &archive_meta, error)) goto out; if (!ostree_file_header_parse (archive_meta, &ret_file_info, &ret_xattrs, @@ -3826,21 +3827,13 @@ repo_find_object (OstreeRepo *self, ot_lobj GFile *ret_stored_path = NULL; ot_lfree char *ret_pack_checksum = NULL; - if (out_stored_path) - { - object_path = ostree_repo_get_object_path (self, checksum, objtype); - - if (lstat (ot_gfile_get_path_cached (object_path), &stbuf) == 0) - { - ret_stored_path = object_path; - object_path = NULL; - } - else - { - g_clear_object (&object_path); - } - } - if (!ret_stored_path || lookup_all) + /* Look up metadata in packs first, but content loose first. We + * want to find loose content since that's preferable for + * hardlinking scenarios. + * + * Metadata is much more efficient packed. + */ + if (OSTREE_OBJECT_TYPE_IS_META (objtype)) { if (out_pack_checksum) { @@ -3849,6 +3842,47 @@ repo_find_object (OstreeRepo *self, cancellable, error)) goto out; } + if (!ret_pack_checksum || lookup_all) + { + object_path = ostree_repo_get_object_path (self, checksum, objtype); + + if (lstat (ot_gfile_get_path_cached (object_path), &stbuf) == 0) + { + ret_stored_path = object_path; + object_path = NULL; + } + else + { + g_clear_object (&object_path); + } + } + } + else + { + if (out_stored_path) + { + object_path = ostree_repo_get_object_path (self, checksum, objtype); + + if (lstat (ot_gfile_get_path_cached (object_path), &stbuf) == 0) + { + ret_stored_path = object_path; + object_path = NULL; + } + else + { + g_clear_object (&object_path); + } + } + if (!ret_stored_path || lookup_all) + { + if (out_pack_checksum) + { + if (!find_object_in_packs (self, checksum, objtype, + &ret_pack_checksum, &ret_pack_offset, + cancellable, error)) + goto out; + } + } } ret = TRUE; @@ -3945,7 +3979,7 @@ ostree_repo_load_variant (OstreeRepo *self, if (object_path != NULL) { if (!ot_util_variant_map (object_path, ostree_metadata_variant_type (objtype), - &ret_variant, error)) + TRUE, &ret_variant, error)) goto out; } else if (pack_checksum != NULL) diff --git a/src/libotutil/ot-variant-utils.c b/src/libotutil/ot-variant-utils.c index 9e50ace6..93b69b84 100644 --- a/src/libotutil/ot-variant-utils.c +++ b/src/libotutil/ot-variant-utils.c @@ -108,10 +108,11 @@ ot_util_variant_take_ref (GVariant *variant) * Note the returned @out_variant is not floating. */ gboolean -ot_util_variant_map (GFile *src, +ot_util_variant_map (GFile *src, const GVariantType *type, - GVariant **out_variant, - GError **error) + gboolean trusted, + GVariant **out_variant, + GError **error) { gboolean ret = FALSE; const char *path = NULL; @@ -126,7 +127,7 @@ ot_util_variant_map (GFile *src, ret_variant = g_variant_new_from_data (type, g_mapped_file_get_contents (mfile), g_mapped_file_get_length (mfile), - FALSE, + trusted, (GDestroyNotify) g_mapped_file_unref, mfile); mfile = NULL; diff --git a/src/libotutil/ot-variant-utils.h b/src/libotutil/ot-variant-utils.h index 95ed2e9c..f03325ba 100644 --- a/src/libotutil/ot-variant-utils.h +++ b/src/libotutil/ot-variant-utils.h @@ -59,6 +59,7 @@ gboolean ot_util_variant_save (GFile *dest, gboolean ot_util_variant_map (GFile *src, const GVariantType *type, + gboolean trusted, GVariant **out_variant, GError **error); diff --git a/src/ostree/ostree-pull.c b/src/ostree/ostree-pull.c index 652cff33..67d10e72 100644 --- a/src/ostree/ostree-pull.c +++ b/src/ostree/ostree-pull.c @@ -1008,8 +1008,8 @@ fetch_content (OtPullData *pull_data, cancellable, error)) goto out; - if (!ot_util_variant_map (temp_path, OSTREE_FILE_HEADER_GVARIANT_FORMAT, &file_meta, - error)) + if (!ot_util_variant_map (temp_path, OSTREE_FILE_HEADER_GVARIANT_FORMAT, FALSE, + &file_meta, error)) goto out; if (!ostree_file_header_parse (file_meta, &file_info, &xattrs, error)) diff --git a/src/ostree/ot-builtin-commit.c b/src/ostree/ot-builtin-commit.c index 4fe36748..a00c6027 100644 --- a/src/ostree/ot-builtin-commit.c +++ b/src/ostree/ot-builtin-commit.c @@ -263,7 +263,8 @@ ostree_builtin_commit (int argc, char **argv, GFile *repo_path, GError **error) else if (metadata_bin_path) { metadata_f = ot_gfile_new_for_path (metadata_bin_path); - if (!ot_util_variant_map (metadata_f, G_VARIANT_TYPE ("a{sv}"), &metadata, error)) + if (!ot_util_variant_map (metadata_f, G_VARIANT_TYPE ("a{sv}"), TRUE, + &metadata, error)) goto out; } else diff --git a/src/ostree/ot-builtin-fsck.c b/src/ostree/ot-builtin-fsck.c index 362f0260..04f80115 100644 --- a/src/ostree/ot-builtin-fsck.c +++ b/src/ostree/ot-builtin-fsck.c @@ -68,7 +68,7 @@ fsck_one_pack_file (OtFsckData *data, pack_index_path = g_file_resolve_relative_path (ostree_repo_get_path (data->repo), path); if (!ot_util_variant_map (pack_index_path, - OSTREE_PACK_INDEX_VARIANT_FORMAT, + OSTREE_PACK_INDEX_VARIANT_FORMAT, FALSE, &index_variant, error)) goto out; diff --git a/src/ostree/ot-builtin-pack.c b/src/ostree/ot-builtin-pack.c index 0c0d12b3..2fc6defb 100644 --- a/src/ostree/ot-builtin-pack.c +++ b/src/ostree/ot-builtin-pack.c @@ -284,7 +284,7 @@ pack_one_meta_object (OtRepackData *data, object_path = ostree_repo_get_object_path (data->repo, checksum, objtype); if (!ot_util_variant_map (object_path, ostree_metadata_variant_type (objtype), - &metadata_v, error)) + TRUE, &metadata_v, error)) goto out; ret_packed_object = g_variant_new ("(y@ayv)", (guchar) objtype, diff --git a/src/ostree/ot-builtin-show.c b/src/ostree/ot-builtin-show.c index a6fe3f43..8edc4c72 100644 --- a/src/ostree/ot-builtin-show.c +++ b/src/ostree/ot-builtin-show.c @@ -67,7 +67,7 @@ do_print_variant_generic (const GVariantType *type, f = ot_gfile_new_for_path (filename); - if (!ot_util_variant_map (f, type, &variant, error)) + if (!ot_util_variant_map (f, type, TRUE, &variant, error)) goto out; print_variant (variant);