From 1e8aeb2c6e3a071643b86fa4fb9311a8c3449c38 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Wed, 14 Feb 2018 11:50:51 +0100 Subject: [PATCH] commit: create .payload-link also for existing objects For various reasons, the .payload-link could be missing from the repository (e.g. previously linking to a file that is not deleted, payload-threshold setting changed), so attempt to create the .payload-link even if the target object is already present in the repository. Signed-off-by: Giuseppe Scrivano --- src/libostree/ostree-repo-commit.c | 45 ++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c index 0bdb70038b..45aec5e589 100644 --- a/src/libostree/ostree-repo-commit.c +++ b/src/libostree/ostree-repo-commit.c @@ -589,6 +589,31 @@ create_regular_tmpfile_linkable_with_content (OstreeRepo *self, return TRUE; } +static gboolean +_create_payload_link (OstreeRepo *self, + const char *actual_checksum, + const char *actual_payload_checksum, + GFileInfo *file_info, + GCancellable *cancellable, + GError **error) +{ + if (actual_payload_checksum && g_file_info_get_size (file_info) >= self->payload_link_threshold) + { + if (symlinkat (actual_checksum, commit_tmp_dfd (self), actual_payload_checksum) < 0) + { + if (errno != EEXIST) + return glnx_throw_errno (error); + } + else + { + g_auto(OtCleanupUnlinkat) tmp_unlinker = { commit_tmp_dfd (self), g_strdup (actual_payload_checksum) }; + if (!commit_path_final (self, actual_payload_checksum, OSTREE_OBJECT_TYPE_PAYLOAD_LINK, &tmp_unlinker, cancellable, error)) + return FALSE; + } + } + return TRUE; +} + /* The main driver for writing a content (regfile or symlink) object. * There are a variety of tricky cases here; for example, bare-user * repos store symlinks as regular files. Computing checksums @@ -806,6 +831,10 @@ write_content_object (OstreeRepo *self, g_mutex_lock (&self->txn_lock); self->txn.stats.content_objects_total++; g_mutex_unlock (&self->txn_lock); + + if (!_create_payload_link (self, actual_checksum, actual_payload_checksum, file_info, cancellable, error)) + return FALSE; + if (out_csum) *out_csum = ostree_checksum_to_bytes (actual_checksum); /* Note early return */ @@ -919,20 +948,8 @@ write_content_object (OstreeRepo *self, cancellable, error)) return FALSE; - if (!has_payload_object && actual_payload_checksum && g_file_info_get_size (file_info) >= self->payload_link_threshold) - { - if (symlinkat (actual_checksum, commit_tmp_dfd (self), actual_payload_checksum) < 0) - { - if (errno != EEXIST) - return glnx_throw_errno (error); - } - else - { - g_auto(OtCleanupUnlinkat) tmp_unlinker = { commit_tmp_dfd (self), g_strdup (actual_payload_checksum) }; - if (!commit_path_final (self, actual_payload_checksum, OSTREE_OBJECT_TYPE_PAYLOAD_LINK, &tmp_unlinker, cancellable, error)) - return FALSE; - } - } + if (!_create_payload_link (self, actual_checksum, actual_payload_checksum, file_info, cancellable, error)) + return FALSE; } /* Update statistics */