diff options
author | Colin Walters <walters@verbum.org> | 2017-09-11 16:58:53 -0400 |
---|---|---|
committer | Colin Walters <walters@verbum.org> | 2017-09-12 09:42:47 -0400 |
commit | 806bb46e054d2c960f129503dddf724383700899 (patch) | |
tree | 80a2d965f230ea3030084425f5521981e287a36e | |
parent | 627d4e2f15572e853279d4bb9511ef2618bef6b5 (diff) | |
download | libglnx-806bb46e054d2c960f129503dddf724383700899.tar.gz |
fdio: Use O_EXCL for anonymous tmpfiles
I noticed while reading the manpage for `linkat()` that `O_TMPFILE`
supports `O_EXCL` to mean exactly what we're doing with the anonymous
tmpfile API.
Change the code to start using it; this required refactoring the internals since
we had a check to be sure the caller wasn't passing `O_EXCL` for the
non-anonymous path which we want to keep.
Presumably the storage system could do smarter things if it knows a file will
always be anonymous, e.g. it doesn't need to journal its data.
-rw-r--r-- | glnx-fdio.c | 48 |
1 files changed, 30 insertions, 18 deletions
diff --git a/glnx-fdio.c b/glnx-fdio.c index dc8459d..e8e2167 100644 --- a/glnx-fdio.c +++ b/glnx-fdio.c @@ -180,20 +180,11 @@ glnx_tmpfile_clear (GLnxTmpfile *tmpf) tmpf->initialized = FALSE; } -/* Allocate a temporary file, using Linux O_TMPFILE if available. The file mode - * will be 0600. - * - * The result will be stored in @out_tmpf, which is caller allocated - * so you can store it on the stack in common scenarios. - * - * The directory fd @dfd must live at least as long as the output @out_tmpf. - */ -gboolean -glnx_open_tmpfile_linkable_at (int dfd, - const char *subpath, - int flags, - GLnxTmpfile *out_tmpf, - GError **error) +static gboolean +open_tmpfile_core (int dfd, const char *subpath, + int flags, + GLnxTmpfile *out_tmpf, + GError **error) { const guint mode = 0600; glnx_fd_close int fd = -1; @@ -201,9 +192,6 @@ glnx_open_tmpfile_linkable_at (int dfd, dfd = glnx_dirfd_canonicalize (dfd); - /* Don't allow O_EXCL, as that has a special meaning for O_TMPFILE */ - g_return_val_if_fail ((flags & O_EXCL) == 0, FALSE); - /* Creates a temporary file, that shall be renamed to "target" * later. If possible, this uses O_TMPFILE – in which case * "ret_path" will be returned as NULL. If not possible a the @@ -260,6 +248,29 @@ glnx_open_tmpfile_linkable_at (int dfd, return FALSE; } +/* Allocate a temporary file, using Linux O_TMPFILE if available. The file mode + * will be 0600. + * + * The result will be stored in @out_tmpf, which is caller allocated + * so you can store it on the stack in common scenarios. + * + * The directory fd @dfd must live at least as long as the output @out_tmpf. + */ +gboolean +glnx_open_tmpfile_linkable_at (int dfd, + const char *subpath, + int flags, + GLnxTmpfile *out_tmpf, + GError **error) +{ + /* Don't allow O_EXCL, as that has a special meaning for O_TMPFILE; + * it's used for glnx_open_anonymous_tmpfile(). + */ + g_return_val_if_fail ((flags & O_EXCL) == 0, FALSE); + + return open_tmpfile_core (dfd, subpath, flags, out_tmpf, error); +} + /* A variant of `glnx_open_tmpfile_linkable_at()` which doesn't support linking. * Useful for true temporary storage. The fd will be allocated in /var/tmp to * ensure maximum storage space. @@ -269,7 +280,8 @@ glnx_open_anonymous_tmpfile (int flags, GLnxTmpfile *out_tmpf, GError **error) { - if (!glnx_open_tmpfile_linkable_at (AT_FDCWD, "/var/tmp", flags, out_tmpf, error)) + /* Add in O_EXCL */ + if (!open_tmpfile_core (AT_FDCWD, "/var/tmp", flags | O_EXCL, out_tmpf, error)) return FALSE; if (out_tmpf->path) { |