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.
This commit is contained in:
parent
9910c0ddf4
commit
ebe35dbefe
|
|
@ -887,7 +887,7 @@ ostree_create_temp_file_from_input (GFile *dir,
|
||||||
g_free (possible_name);
|
g_free (possible_name);
|
||||||
possible_name = subst_xxxxxx (tmp_name->str);
|
possible_name = subst_xxxxxx (tmp_name->str);
|
||||||
g_clear_object (&possible_file);
|
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,
|
if (!ostree_create_file_from_input (possible_file, finfo, xattrs, input,
|
||||||
objtype,
|
objtype,
|
||||||
|
|
|
||||||
|
|
@ -755,6 +755,39 @@ stage_object_impl (OstreeRepo *self,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error);
|
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
|
static gboolean
|
||||||
impl_stage_archive_file_object_from_raw (OstreeRepo *self,
|
impl_stage_archive_file_object_from_raw (OstreeRepo *self,
|
||||||
GFileInfo *file_info,
|
GFileInfo *file_info,
|
||||||
|
|
@ -828,12 +861,13 @@ impl_stage_archive_file_object_from_raw (OstreeRepo *self,
|
||||||
else
|
else
|
||||||
actual_checksum = g_checksum_get_string (ret_checksum);
|
actual_checksum = g_checksum_get_string (ret_checksum);
|
||||||
|
|
||||||
g_hash_table_insert (priv->pending_transaction_tmpfiles,
|
if (!insert_into_transaction (self, actual_checksum, OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT,
|
||||||
create_checksum_and_objtype (actual_checksum, OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT),
|
content_temp_file, error))
|
||||||
g_strdup (ot_gfile_get_basename_cached (content_temp_file)));
|
goto out;
|
||||||
g_hash_table_insert (priv->pending_transaction_tmpfiles,
|
|
||||||
create_checksum_and_objtype (actual_checksum, OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META),
|
if (!insert_into_transaction (self, actual_checksum, OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META,
|
||||||
g_strdup (ot_gfile_get_basename_cached (meta_temp_file)));
|
meta_temp_file, error))
|
||||||
|
goto out;
|
||||||
|
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
ot_transfer_out_value (out_checksum, &ret_checksum);
|
ot_transfer_out_value (out_checksum, &ret_checksum);
|
||||||
|
|
@ -910,7 +944,7 @@ stage_object_impl (OstreeRepo *self,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!ostree_create_temp_file_from_input (priv->transaction_dir,
|
if (!ostree_create_temp_file_from_input (priv->transaction_dir,
|
||||||
"store-tmp-", NULL,
|
ostree_object_type_to_string (objtype), NULL,
|
||||||
file_info, xattrs, input,
|
file_info, xattrs, input,
|
||||||
objtype,
|
objtype,
|
||||||
&temp_file,
|
&temp_file,
|
||||||
|
|
@ -933,9 +967,9 @@ stage_object_impl (OstreeRepo *self,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_hash_table_insert (priv->pending_transaction_tmpfiles,
|
if (!insert_into_transaction (self, actual_checksum, objtype,
|
||||||
create_checksum_and_objtype (actual_checksum, objtype),
|
temp_file, error))
|
||||||
g_strdup (ot_gfile_get_basename_cached (temp_file)));
|
goto out;
|
||||||
g_clear_object (&temp_file);
|
g_clear_object (&temp_file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue