[libglnx] fdio: Use O_EXCL for anonymous tmpfiles



commit 806bb46e054d2c960f129503dddf724383700899
Author: Colin Walters <walters verbum org>
Date:   Mon Sep 11 16:58:53 2017 -0400

    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.

 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)
     {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]