lib/commit: Fix object sizes metadata for multiple commits

The object sizes hash table was only being cleared when the repo was
finalized. That means that performing multiple commits while the repo
was open would reuse all the object sizes metadata for each commit.

Clear the hash table when the sizes metadata is setup and when it's
added to a commit. This still does not fix the issue all the way since
it does nothing to prevent the program from constructing multiple
commits simultaneously. To handle that, the object sizes hash table
should be attached to the MutableTree since that has the commit state.
However, the MutableTree is gone when the commit is actually created.
The hash table would have to be transferred to the root file when
writing the MutableTree. That would be an awkward addition to
OstreeRepoFile, though. Add a FIXME to capture that.
This commit is contained in:
Dan Nicholson 2019-10-23 09:12:08 -06:00
parent 694b741a36
commit 8ec7d6322f
2 changed files with 18 additions and 1 deletions

View File

@ -352,7 +352,13 @@ repo_setup_generate_sizes (OstreeRepo *self,
if (modifier && modifier->flags & OSTREE_REPO_COMMIT_MODIFIER_FLAGS_GENERATE_SIZES)
{
if (ostree_repo_get_mode (self) == OSTREE_REPO_MODE_ARCHIVE)
self->generate_sizes = TRUE;
{
self->generate_sizes = TRUE;
/* Clear any stale data in the object sizes hash table */
if (self->object_sizes != NULL)
g_hash_table_remove_all (self->object_sizes);
}
else
g_debug ("Not generating sizes for non-archive repo");
}
@ -428,6 +434,9 @@ add_size_index_to_metadata (OstreeRepo *self,
g_variant_builder_add (builder, "{sv}", "ostree.sizes",
g_variant_builder_end (&index_builder));
/* Clear the object sizes hash table for a subsequent commit. */
g_hash_table_remove_all (self->object_sizes);
}
return g_variant_ref_sink (g_variant_builder_end (builder));

View File

@ -143,6 +143,14 @@ struct OstreeRepo {
guint zlib_compression_level;
GHashTable *loose_object_devino_hash;
GHashTable *updated_uncompressed_dirs;
/* FIXME: The object sizes hash table is really per-commit state, not repo
* state. Using a single table for the repo means that commits cannot be
* built simultaneously if they're adding size information. This data should
* probably be in OstreeMutableTree, but that's gone by the time the actual
* commit is constructed. At that point the only commit state is in the root
* OstreeRepoFile.
*/
GHashTable *object_sizes;
/* Cache the repo's device/inode to use for comparisons elsewhere */