[ostree] deltas: Flesh out the open/write/close opcodes
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ostree] deltas: Flesh out the open/write/close opcodes
- Date: Mon, 16 Feb 2015 15:15:00 +0000 (UTC)
commit 7900c82a36b74760357817ca9f33607be471d520
Author: Colin Walters <walters verbum org>
Date: Thu Jan 29 22:32:44 2015 -0500
deltas: Flesh out the open/write/close opcodes
Refactor open-splice-and-close to call open/close. We can't just call
write as that would require duplicating the object size parameter.
.../ostree-repo-static-delta-processing.c | 183 +++++++++++++-------
1 files changed, 122 insertions(+), 61 deletions(-)
---
diff --git a/src/libostree/ostree-repo-static-delta-processing.c
b/src/libostree/ostree-repo-static-delta-processing.c
index cd77adb..10372a0 100644
--- a/src/libostree/ostree-repo-static-delta-processing.c
+++ b/src/libostree/ostree-repo-static-delta-processing.c
@@ -54,6 +54,16 @@ typedef struct {
GError **async_error;
OstreeObjectType output_objtype;
+ OstreeRepoTrustedContentBareCommit barecommitstate;
+ guint64 content_size;
+ GOutputStream *content_out;
+ char checksum[65];
+ gboolean have_obj;
+ guint32 uid;
+ guint32 gid;
+ guint32 mode;
+ GVariant *xattrs;
+
const guint8 *output_target;
const guint8 *input_target_csum;
@@ -113,7 +123,6 @@ open_output_target (StaticDeltaExecutionState *state,
{
gboolean ret = FALSE;
guint8 *objcsum;
- char checksum[65];
g_assert (state->checksums != NULL);
g_assert (state->output_target == NULL);
@@ -127,7 +136,7 @@ open_output_target (StaticDeltaExecutionState *state,
state->output_objtype = (OstreeObjectType) *objcsum;
state->output_target = objcsum + 1;
- ostree_checksum_inplace_from_bytes (state->output_target, checksum);
+ ostree_checksum_inplace_from_bytes (state->output_target, state->checksum);
ret = TRUE;
out:
@@ -439,19 +448,48 @@ validate_ofs (StaticDeltaExecutionState *state,
}
static gboolean
+do_content_open_generic (OstreeRepo *repo,
+ StaticDeltaExecutionState *state,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ gs_unref_variant GVariant *modev;
+ guint64 mode_offset;
+ guint64 xattr_offset;
+ guint32 uid, gid, mode;
+
+ if (!read_varuint64 (state, &mode_offset, error))
+ goto out;
+ 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);
+ state->gid = GUINT32_FROM_BE (gid);
+ state->mode = GUINT32_FROM_BE (mode);
+
+ state->xattrs = g_variant_get_child_value (state->xattr_dict, xattr_offset);
+
+ ret = TRUE;
+ out:
+ return ret;
+}
+
+static gboolean
dispatch_open_splice_and_close (OstreeRepo *repo,
StaticDeltaExecutionState *state,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
- char checksum[65];
if (!open_output_target (state, cancellable, error))
goto out;
-
- ostree_checksum_inplace_from_bytes (state->output_target, checksum);
-
+
if (OSTREE_OBJECT_TYPE_IS_META (state->output_objtype))
{
gs_unref_variant GVariant *metadata = NULL;
@@ -469,7 +507,7 @@ dispatch_open_splice_and_close (OstreeRepo *repo,
state->payload_data + offset, length, TRUE, NULL, NULL);
if (!ostree_repo_write_metadata_trusted (state->repo, state->output_objtype,
- checksum,
+ state->checksum,
metadata,
cancellable,
error))
@@ -477,81 +515,54 @@ dispatch_open_splice_and_close (OstreeRepo *repo,
}
else
{
- guint64 mode_offset;
- guint64 xattr_offset;
- guint64 content_size;
guint64 content_offset;
guint64 objlen;
+ guint64 content_size;
+ gsize bytes_written;
gs_unref_object GInputStream *object_input = NULL;
gs_unref_object GInputStream *memin = NULL;
- gs_unref_variant GVariant *xattrs_buf = NULL;
- GVariant *modev;
- GVariant *xattrs;
- guint32 uid, gid, mode;
-
- if (!read_varuint64 (state, &mode_offset, error))
- goto out;
- if (!read_varuint64 (state, &xattr_offset, error))
+
+ if (!do_content_open_generic (repo, state, cancellable, error))
goto out;
+
if (!read_varuint64 (state, &content_size, error))
goto out;
if (!read_varuint64 (state, &content_offset, error))
goto out;
-
if (!validate_ofs (state, content_offset, content_size, error))
goto out;
-
- modev = g_variant_get_child_value (state->mode_dict, mode_offset);
- g_variant_get (modev, "(uuu)", &uid, &gid, &mode);
- uid = GUINT32_FROM_BE (uid);
- gid = GUINT32_FROM_BE (gid);
- mode = GUINT32_FROM_BE (mode);
-
- xattrs = g_variant_get_child_value (state->xattr_dict, xattr_offset);
-
+
/* Fast path for regular files to bare repositories */
- if (S_ISREG (mode) &&
+ if (S_ISREG (state->mode) &&
(repo->mode == OSTREE_REPO_MODE_BARE ||
repo->mode == OSTREE_REPO_MODE_BARE_USER))
{
- OstreeRepoTrustedContentBareCommit barecommitstate = { -1 };
- gs_unref_object GOutputStream *outstream = NULL;
- gsize bytes_written;
- gboolean have_obj;
-
- if (!_ostree_repo_open_trusted_content_bare (repo, checksum,
- content_size,
- &barecommitstate,
- &outstream,
- &have_obj,
+ if (!_ostree_repo_open_trusted_content_bare (repo, state->checksum,
+ state->content_size,
+ &state->barecommitstate,
+ &state->content_out,
+ &state->have_obj,
cancellable, error))
goto out;
-
- if (!have_obj)
+
+ if (!state->have_obj)
{
- if (!g_output_stream_write_all (outstream, state->payload_data + content_offset,
+ if (!g_output_stream_write_all (state->content_out,
+ state->payload_data + content_offset,
content_size,
&bytes_written,
cancellable, error))
goto out;
-
- if (!g_output_stream_flush (outstream, cancellable, error))
- goto out;
}
-
- if (!_ostree_repo_commit_trusted_content_bare (repo, checksum, &barecommitstate,
- uid, gid, mode, xattrs,
- cancellable, error))
- goto out;
}
else
{
/* Slower path, for symlinks and unpacking deltas into archive-z2 */
gs_unref_object GFileInfo *finfo = NULL;
- finfo = _ostree_header_gfile_info_new (mode, uid, gid);
+ finfo = _ostree_header_gfile_info_new (state->mode, state->uid, state->gid);
- if (S_ISLNK (mode))
+ if (S_ISLNK (state->mode))
{
gs_free char *nulterminated_target =
g_strndup ((char*)state->payload_data + content_offset, content_size);
@@ -559,18 +570,18 @@ dispatch_open_splice_and_close (OstreeRepo *repo,
}
else
{
- g_assert (S_ISREG (mode));
+ g_assert (S_ISREG (state->mode));
g_file_info_set_size (finfo, content_size);
memin = g_memory_input_stream_new_from_data (state->payload_data + content_offset,
content_size, NULL);
}
- if (!ostree_raw_file_to_content_stream (memin, finfo, xattrs,
+ if (!ostree_raw_file_to_content_stream (memin, finfo, state->xattrs,
&object_input, &objlen,
cancellable, error))
goto out;
if (!ostree_repo_write_content_trusted (state->repo,
- checksum,
+ state->checksum,
object_input,
objlen,
cancellable,
@@ -579,8 +590,8 @@ dispatch_open_splice_and_close (OstreeRepo *repo,
}
}
- state->checksum_index++;
- state->output_target = NULL;
+ if (!dispatch_close (repo, state, cancellable, error))
+ goto out;
ret = TRUE;
out:
@@ -597,9 +608,25 @@ dispatch_open (OstreeRepo *repo,
{
gboolean ret = FALSE;
+ g_assert (state->output_target == NULL);
+ /* FIXME - lift this restriction */
+ g_assert (repo->mode == OSTREE_REPO_MODE_BARE ||
+ repo->mode == OSTREE_REPO_MODE_BARE_USER);
+
if (!open_output_target (state, cancellable, error))
goto out;
+ if (!do_content_open_generic (repo, state, cancellable, error))
+ goto out;
+
+ if (!_ostree_repo_open_trusted_content_bare (repo, state->checksum,
+ state->content_size,
+ &state->barecommitstate,
+ &state->content_out,
+ &state->have_obj,
+ cancellable, error))
+ goto out;
+
ret = TRUE;
out:
if (!ret)
@@ -614,11 +641,29 @@ dispatch_write (OstreeRepo *repo,
GError **error)
{
gboolean ret = FALSE;
+ guint64 content_size;
+ guint64 content_offset;
+ gsize bytes_written;
+
+ if (!read_varuint64 (state, &content_size, error))
+ goto out;
+ if (!read_varuint64 (state, &content_offset, error))
+ goto out;
+ if (!validate_ofs (state, content_offset, content_size, error))
+ goto out;
- g_assert_not_reached ();
+ if (!state->have_obj)
+ {
+ if (!g_output_stream_write_all (state->content_out,
+ state->payload_data + content_offset,
+ content_size,
+ &bytes_written,
+ cancellable, error))
+ goto out;
+ }
ret = TRUE;
- /* out: */
+ out:
if (!ret)
g_prefix_error (error, "opcode open-splice-and-close: ");
return ret;
@@ -648,11 +693,27 @@ dispatch_close (OstreeRepo *repo,
GError **error)
{
gboolean ret = FALSE;
+
+ if (state->content_out)
+ {
+ if (!g_output_stream_flush (state->content_out, cancellable, error))
+ goto out;
- g_assert_not_reached ();
+ if (!_ostree_repo_commit_trusted_content_bare (repo, state->checksum, &state->barecommitstate,
+ state->uid, state->gid, state->mode,
+ state->xattrs,
+ cancellable, error))
+ goto out;
+ }
+
+ g_clear_pointer (&state->xattrs, g_variant_unref);
+ g_clear_object (&state->content_out);
+ state->checksum_index++;
+ state->output_target = NULL;
+
ret = TRUE;
- /* out: */
+ out:
if (!ret)
g_prefix_error (error, "opcode open-splice-and-close: ");
return ret;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]