diff options
author | Colin Walters <walters@verbum.org> | 2017-06-28 13:41:52 -0400 |
---|---|---|
committer | Atomic Bot <atomic-devel@projectatomic.io> | 2017-06-29 14:46:18 +0000 |
commit | 6f2ea23e8a96cf7dddadf0eae1b4f831db88d67f (patch) | |
tree | f3c472ab9e35f2029738d152f52f2763ceed878f /src/libotutil/ot-fs-utils.c | |
parent | 9d10bdfd0d90d6ea6a31bbd89243f3b23ff51e8d (diff) | |
download | ostree-6f2ea23e8a96cf7dddadf0eae1b4f831db88d67f.tar.gz |
libutil: Add a helper for O_TMPFILE + mmap()
I added `glnx_open_anonymous_tmpfile()`, but then later noticed
that the usage of this was really to be combined with `mmap()`,
and we had two versions of that in the delta code. Add a helper.
(Bigger picture...how is this different from glibc's "mmap() of /dev/zero"
approach for large chunks? One advantage is the storage can be "swapped" to
`/var/tmp`, but still deleted automatically, rather than requiring swap space)
Closes: #973
Approved by: jlebon
Diffstat (limited to 'src/libotutil/ot-fs-utils.c')
-rw-r--r-- | src/libotutil/ot-fs-utils.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/src/libotutil/ot-fs-utils.c b/src/libotutil/ot-fs-utils.c index d2bde837..2f0ae19c 100644 --- a/src/libotutil/ot-fs-utils.c +++ b/src/libotutil/ot-fs-utils.c @@ -24,6 +24,7 @@ #include "libglnx.h" #include <sys/xattr.h> #include <gio/gunixinputstream.h> +#include <gio/gunixoutputstream.h> /* Convert a fd-relative path to a GFile* - use * for legacy code. @@ -181,3 +182,29 @@ ot_file_mapat_bytes (int dfd, return g_mapped_file_get_bytes (mfile); } + +/* Given an input stream, splice it to an anonymous file (O_TMPFILE). + * Useful for potentially large but transient files. + */ +GBytes * +ot_map_anonymous_tmpfile_from_content (GInputStream *instream, + GCancellable *cancellable, + GError **error) +{ + g_auto(GLnxTmpfile) tmpf = { 0, }; + if (!glnx_open_anonymous_tmpfile (O_RDWR | O_CLOEXEC, &tmpf, error)) + return NULL; + + g_autoptr(GOutputStream) out = g_unix_output_stream_new (tmpf.fd, FALSE); + gssize n_bytes_written = g_output_stream_splice (out, instream, + G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | + G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, + cancellable, error); + if (n_bytes_written < 0) + return NULL; + + g_autoptr(GMappedFile) mfile = g_mapped_file_new_from_fd (tmpf.fd, FALSE, error); + if (!mfile) + return NULL; + return g_mapped_file_get_bytes (mfile); +} |