summaryrefslogtreecommitdiff
path: root/src/libostree/ostree-repo-commit.c
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2017-10-04 15:06:31 -0400
committerAtomic Bot <atomic-devel@projectatomic.io>2017-10-04 20:42:39 +0000
commit5c7d2dd8be3606d9aec1e6835086f6b4dfcdb6a7 (patch)
treef796da733316a3dc1b36779d889140a624ed50df /src/libostree/ostree-repo-commit.c
parentc511ca0fae0e352d52bb7d1a24b4c1d08c5a8ec9 (diff)
downloadostree-5c7d2dd8be3606d9aec1e6835086f6b4dfcdb6a7.tar.gz
Deduplicate and fix up our use of mmap()
Buried in this large patch is a logical fix: ``` - if (!map) - return glnx_throw_errno_prefix (error, "mmap"); + if (map == (void*)-1) + return glnx_null_throw_errno_prefix (error, "mmap"); ``` Which would have helped me debug another patch I was working on. But it turns out that actually correctly checking for errors from `mmap()` triggers lots of other bugs - basically because we sometimes handle zero-length variants (in detached metadata). When we start actually returning errors due to this, things break. (It wasn't a problem in practice before because most things looked at the zero size, not the data). Anyways there's a bigger picture issue here - a while ago we made a fix to only use `mmap()` for reading metadata from disk only if it was large enough (i.e. `>16k`). But that didn't help various other paths in the pull code and others that were directly doing the `mmap()`. Fix this by having a proper low level fs helper that does "read all data from fd+offset into GBytes", which handles the size check. Then the `GVariant` bits are just a clean layer on top of this. (At the small cost of an additional allocation) Side note: I had to remind myself, but the reason we can't just use `GMappedFile` here is it doesn't support passing an offset into `mmap()`. Closes: #1251 Approved by: jlebon
Diffstat (limited to 'src/libostree/ostree-repo-commit.c')
-rw-r--r--src/libostree/ostree-repo-commit.c41
1 files changed, 22 insertions, 19 deletions
diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c
index 029dd01b..a9ae4af2 100644
--- a/src/libostree/ostree-repo-commit.c
+++ b/src/libostree/ostree-repo-commit.c
@@ -2212,26 +2212,29 @@ ostree_repo_read_commit_detached_metadata (OstreeRepo *self,
char buf[_OSTREE_LOOSE_PATH_MAX];
_ostree_loose_path (buf, checksum, OSTREE_OBJECT_TYPE_COMMIT_META, self->mode);
- g_autoptr(GVariant) ret_metadata = NULL;
- if (self->commit_stagedir.initialized &&
- !ot_util_variant_map_at (self->commit_stagedir.fd, buf,
- G_VARIANT_TYPE ("a{sv}"),
- OT_VARIANT_MAP_ALLOW_NOENT | OT_VARIANT_MAP_TRUSTED, &ret_metadata, error))
- return glnx_prefix_error (error, "Unable to read existing detached metadata");
-
- if (ret_metadata == NULL &&
- !ot_util_variant_map_at (self->objects_dir_fd, buf,
- G_VARIANT_TYPE ("a{sv}"),
- OT_VARIANT_MAP_ALLOW_NOENT | OT_VARIANT_MAP_TRUSTED, &ret_metadata, error))
- return glnx_prefix_error (error, "Unable to read existing detached metadata");
-
- if (ret_metadata == NULL && self->parent_repo)
+ if (self->commit_stagedir.initialized)
+ {
+ glnx_fd_close int fd = -1;
+ if (!ot_openat_ignore_enoent (self->commit_stagedir.fd, buf, &fd, error))
+ return FALSE;
+ if (fd != -1)
+ return ot_variant_read_fd (fd, 0, G_VARIANT_TYPE ("a{sv}"), TRUE,
+ out_metadata, error);
+ }
+
+ glnx_fd_close int fd = -1;
+ if (!ot_openat_ignore_enoent (self->objects_dir_fd, buf, &fd, error))
+ return FALSE;
+ if (fd != -1)
+ return ot_variant_read_fd (fd, 0, G_VARIANT_TYPE ("a{sv}"), TRUE,
+ out_metadata, error);
+
+ if (self->parent_repo)
return ostree_repo_read_commit_detached_metadata (self->parent_repo,
- checksum,
- out_metadata,
- cancellable,
- error);
- ot_transfer_out_value (out_metadata, &ret_metadata);
+ checksum, out_metadata,
+ cancellable, error);
+ /* Nothing found */
+ *out_metadata = NULL;
return TRUE;
}