From: Colin Walters Date: Sat, 24 Jun 2017 14:28:09 +0000 (-0400) Subject: lib: Use OtTmpFile for static delta processing X-Git-Tag: archive/raspbian/2022.1-3+rpi1~1^2~4^2~35^2~43 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=af3a96755ba4d897852fa8f2cf483c0c21adc40b;p=ostree.git lib: Use OtTmpFile for static delta processing The `OstreeRepoContentBareCommit` struct was basically an `OtTmpFile`, so let's make it one. I moved the "convert to `GOutputStream`" logic into the callers, since that bit can't fail; it makes the implementation much simpler since we can just return the result of `ot_open_tmpfile_linkable_at()`. Prep for `GLnxTmpfile` porting. Closes: #957 Approved by: jlebon --- diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c index 32170ac7..02811c14 100644 --- a/src/libostree/ostree-repo-commit.c +++ b/src/libostree/ostree-repo-commit.c @@ -446,57 +446,39 @@ ot_fallocate (int fd, goffset size, GError **error) return TRUE; } +/* Combines a check for whether or not we already have the object with + * allocating a tempfile if we don't. Used by the static delta code. + */ gboolean _ostree_repo_open_content_bare (OstreeRepo *self, const char *checksum, guint64 content_len, - OstreeRepoContentBareCommit *out_state, - GOutputStream **out_stream, + OtTmpfile *out_tmpf, gboolean *out_have_object, GCancellable *cancellable, GError **error) { - gboolean ret = FALSE; - g_autofree char *temp_filename = NULL; - g_autoptr(GOutputStream) ret_stream = NULL; gboolean have_obj; - if (!_ostree_repo_has_loose_object (self, checksum, OSTREE_OBJECT_TYPE_FILE, &have_obj, cancellable, error)) - goto out; - - if (!have_obj) + return FALSE; + /* Do we already have this object? */ + *out_have_object = have_obj; + if (have_obj) { - int fd; - - if (!glnx_open_tmpfile_linkable_at (self->tmp_dir_fd, ".", O_WRONLY|O_CLOEXEC, - &fd, &temp_filename, error)) - goto out; - - if (!ot_fallocate (fd, content_len, error)) - goto out; - - ret_stream = g_unix_output_stream_new (fd, TRUE); + /* Make sure the tempfile is unset */ + out_tmpf->initialized = 0; + return TRUE; } - ret = TRUE; - if (!have_obj) - { - out_state->temp_filename = temp_filename; - temp_filename = NULL; - out_state->fd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*)ret_stream); - if (out_stream) - *out_stream = g_steal_pointer (&ret_stream); - } - *out_have_object = have_obj; - out: - return ret; + return ot_open_tmpfile_linkable_at (self->tmp_dir_fd, ".", O_WRONLY|O_CLOEXEC, + out_tmpf, error); } gboolean _ostree_repo_commit_trusted_content_bare (OstreeRepo *self, const char *checksum, - OstreeRepoContentBareCommit *state, + OtTmpfile *tmpf, guint32 uid, guint32 gid, guint32 mode, @@ -504,25 +486,22 @@ _ostree_repo_commit_trusted_content_bare (OstreeRepo *self, GCancellable *cancellable, GError **error) { - gboolean ret = FALSE; - - if (state->fd != -1) - { - if (!commit_loose_content_object (self, checksum, - state->temp_filename, - FALSE, uid, gid, mode, - xattrs, state->fd, - cancellable, error)) - { - g_prefix_error (error, "Writing object %s.%s: ", checksum, ostree_object_type_to_string (OSTREE_OBJECT_TYPE_FILE)); - goto out; - } - } + /* I don't think this is necessary, but a similar check was here previously, + * keeping it for extra redundancy. + */ + if (!tmpf->initialized || tmpf->fd == -1) + return TRUE; - ret = TRUE; - out: - g_free (state->temp_filename); - return ret; + if (!commit_loose_content_object (self, checksum, + tmpf->path, + FALSE, uid, gid, mode, + xattrs, tmpf->fd, + cancellable, error)) + return glnx_prefix_error (error, "Writing object %s.%s", checksum, ostree_object_type_to_string (OSTREE_OBJECT_TYPE_FILE)); + /* The path was consumed */ + g_clear_pointer (&tmpf->path, g_free); + tmpf->initialized = FALSE; + return TRUE; } static gboolean diff --git a/src/libostree/ostree-repo-private.h b/src/libostree/ostree-repo-private.h index 0081eb31..1bd797fa 100644 --- a/src/libostree/ostree-repo-private.h +++ b/src/libostree/ostree-repo-private.h @@ -23,7 +23,7 @@ #include "ostree-ref.h" #include "ostree-repo.h" #include "ostree-remote-private.h" -#include "libglnx.h" +#include "otutil.h" G_BEGIN_DECLS @@ -305,17 +305,11 @@ _ostree_repo_commit_loose_final (OstreeRepo *self, GCancellable *cancellable, GError **error); -typedef struct { - int fd; - char *temp_filename; -} OstreeRepoContentBareCommit; - gboolean _ostree_repo_open_content_bare (OstreeRepo *self, const char *checksum, guint64 content_len, - OstreeRepoContentBareCommit *out_state, - GOutputStream **out_stream, + OtTmpfile *out_tmpf, gboolean *out_have_object, GCancellable *cancellable, GError **error); @@ -323,7 +317,7 @@ _ostree_repo_open_content_bare (OstreeRepo *self, gboolean _ostree_repo_commit_trusted_content_bare (OstreeRepo *self, const char *checksum, - OstreeRepoContentBareCommit *state, + OtTmpfile *tmpf, guint32 uid, guint32 gid, guint32 mode, diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index edfd8d4f..4607f2f1 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -1108,7 +1108,7 @@ meta_fetch_on_complete (GObject *object, goto out; } - /* Now delete it, keeping the fd open as the last reference); see comment in + /* Now delete it, keeping the fd open as the last reference; see comment in * corresponding content fetch path. */ ot_cleanup_unlinkat (&tmp_unlinker); diff --git a/src/libostree/ostree-repo-static-delta-processing.c b/src/libostree/ostree-repo-static-delta-processing.c index a0f51262..b8bd6587 100644 --- a/src/libostree/ostree-repo-static-delta-processing.c +++ b/src/libostree/ostree-repo-static-delta-processing.c @@ -56,7 +56,7 @@ typedef struct { GError **async_error; OstreeObjectType output_objtype; - OstreeRepoContentBareCommit barecommitstate; + OtTmpfile tmpf; guint64 content_size; GOutputStream *content_out; GChecksum *content_checksum; @@ -281,6 +281,8 @@ _ostree_static_delta_part_execute (OstreeRepo *repo, ret = TRUE; out: + ot_tmpfile_clear (&state->tmpf); + g_clear_object (&state->content_out); g_clear_pointer (&state->content_checksum, g_checksum_free); return ret; } @@ -419,8 +421,6 @@ do_content_open_generic (OstreeRepo *repo, if (!read_varuint64 (state, &xattr_offset, error)) goto out; - state->barecommitstate.fd = -1; - modev = g_variant_get_child_value (state->mode_dict, mode_offset); g_variant_get (modev, "(uuu)", &uid, &gid, &mode); state->uid = GUINT32_FROM_BE (uid); @@ -608,14 +608,14 @@ dispatch_open_splice_and_close (OstreeRepo *repo, { if (!_ostree_repo_open_content_bare (repo, state->checksum, state->content_size, - &state->barecommitstate, - &state->content_out, + &state->tmpf, &state->have_obj, cancellable, error)) goto out; if (!state->have_obj) { + state->content_out = g_unix_output_stream_new (state->tmpf.fd, FALSE); if (!handle_untrusted_content_checksum (repo, state, cancellable, error)) goto out; @@ -711,11 +711,12 @@ dispatch_open (OstreeRepo *repo, if (!_ostree_repo_open_content_bare (repo, state->checksum, state->content_size, - &state->barecommitstate, - &state->content_out, + &state->tmpf, &state->have_obj, cancellable, error)) goto out; + if (!state->have_obj) + state->content_out = g_unix_output_stream_new (state->tmpf.fd, FALSE); if (!handle_untrusted_content_checksum (repo, state, cancellable, error)) goto out; @@ -899,11 +900,12 @@ dispatch_close (OstreeRepo *repo, } } - if (!_ostree_repo_commit_trusted_content_bare (repo, state->checksum, &state->barecommitstate, + if (!_ostree_repo_commit_trusted_content_bare (repo, state->checksum, &state->tmpf, state->uid, state->gid, state->mode, state->xattrs, cancellable, error)) goto out; + g_clear_object (&state->content_out); } if (!dispatch_unset_read_source (repo, state, cancellable, error)) @@ -911,7 +913,6 @@ dispatch_close (OstreeRepo *repo, g_clear_pointer (&state->xattrs, g_variant_unref); g_clear_pointer (&state->content_checksum, g_checksum_free); - g_clear_object (&state->content_out); state->checksum_index++; state->output_target = NULL;