From ebe35dbefe1c39b98ff86db34f7fc5d24fbc2cef Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sun, 15 Jan 2012 12:25:52 -0500 Subject: [PATCH] core: Ensure we delete duplicate files in a transaction If multiple files have the same hash, we need to ensure we're not overwriting other tempfiles in the same transaction. Instead just delete them, since we know they're in the repo. --- src/libostree/ostree-core.c | 2 +- src/libostree/ostree-repo.c | 54 ++++++++++++++++++++++++++++++------- 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/src/libostree/ostree-core.c b/src/libostree/ostree-core.c index 90cf6ce6..c2dfd11c 100644 --- a/src/libostree/ostree-core.c +++ b/src/libostree/ostree-core.c @@ -887,7 +887,7 @@ ostree_create_temp_file_from_input (GFile *dir, g_free (possible_name); possible_name = subst_xxxxxx (tmp_name->str); g_clear_object (&possible_file); - possible_file = ot_gfile_new_for_path (possible_name); + possible_file = g_file_get_child (dir, possible_name); if (!ostree_create_file_from_input (possible_file, finfo, xattrs, input, objtype, diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index 9def9e56..c0863656 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -755,6 +755,39 @@ stage_object_impl (OstreeRepo *self, GCancellable *cancellable, GError **error); +static gboolean +insert_into_transaction (OstreeRepo *self, + const char *checksum, + OstreeObjectType objtype, + GFile *tempfile_path, + GError **error) +{ + gboolean ret = FALSE; + OstreeRepoPrivate *priv = GET_PRIVATE (self); + char *key; + + key = create_checksum_and_objtype (checksum, objtype); + + if (g_hash_table_lookup (priv->pending_transaction_tmpfiles, key)) + { + if (unlink (ot_gfile_get_path_cached (tempfile_path)) < 0) + { + ot_util_set_error_from_errno (error, errno); + goto out; + } + g_free (key); + } + else + { + g_hash_table_insert (priv->pending_transaction_tmpfiles, + key, g_strdup (ot_gfile_get_basename_cached (tempfile_path))); + } + + ret = TRUE; + out: + return ret; +} + static gboolean impl_stage_archive_file_object_from_raw (OstreeRepo *self, GFileInfo *file_info, @@ -828,12 +861,13 @@ impl_stage_archive_file_object_from_raw (OstreeRepo *self, else actual_checksum = g_checksum_get_string (ret_checksum); - g_hash_table_insert (priv->pending_transaction_tmpfiles, - create_checksum_and_objtype (actual_checksum, OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT), - g_strdup (ot_gfile_get_basename_cached (content_temp_file))); - g_hash_table_insert (priv->pending_transaction_tmpfiles, - create_checksum_and_objtype (actual_checksum, OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META), - g_strdup (ot_gfile_get_basename_cached (meta_temp_file))); + if (!insert_into_transaction (self, actual_checksum, OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT, + content_temp_file, error)) + goto out; + + if (!insert_into_transaction (self, actual_checksum, OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META, + meta_temp_file, error)) + goto out; ret = TRUE; ot_transfer_out_value (out_checksum, &ret_checksum); @@ -910,7 +944,7 @@ stage_object_impl (OstreeRepo *self, else { if (!ostree_create_temp_file_from_input (priv->transaction_dir, - "store-tmp-", NULL, + ostree_object_type_to_string (objtype), NULL, file_info, xattrs, input, objtype, &temp_file, @@ -933,9 +967,9 @@ stage_object_impl (OstreeRepo *self, } } - g_hash_table_insert (priv->pending_transaction_tmpfiles, - create_checksum_and_objtype (actual_checksum, objtype), - g_strdup (ot_gfile_get_basename_cached (temp_file))); + if (!insert_into_transaction (self, actual_checksum, objtype, + temp_file, error)) + goto out; g_clear_object (&temp_file); } }