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,
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
#include "ostree-ref.h"
#include "ostree-repo.h"
#include "ostree-remote-private.h"
-#include "libglnx.h"
+#include "otutil.h"
G_BEGIN_DECLS
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);
gboolean
_ostree_repo_commit_trusted_content_bare (OstreeRepo *self,
const char *checksum,
- OstreeRepoContentBareCommit *state,
+ OtTmpfile *tmpf,
guint32 uid,
guint32 gid,
guint32 mode,
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);
GError **async_error;
OstreeObjectType output_objtype;
- OstreeRepoContentBareCommit barecommitstate;
+ OtTmpfile tmpf;
guint64 content_size;
GOutputStream *content_out;
GChecksum *content_checksum;
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;
}
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);
{
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;
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;
}
}
- 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))
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;