diff --git a/subprojects/libglnx/glnx-fdio.c b/subprojects/libglnx/glnx-fdio.c
index 6ae6ec7e327f3cced32466d9513341bfd3600218..3fa73b5d2c18af1d2bfcc88936ca30f75bc4bb4f 100644
--- a/subprojects/libglnx/glnx-fdio.c
+++ b/subprojects/libglnx/glnx-fdio.c
@@ -303,8 +303,8 @@ glnx_open_anonymous_tmpfile_full (int          flags,
 }
 
 /* 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.
+ * Useful for true temporary storage. The fd will be allocated in `$TMPDIR` if
+ * set or `/var/tmp` otherwise.
  *
  * If you need the file on a specific filesystem use glnx_open_anonymous_tmpfile_full()
  * which lets you pass a directory.
@@ -314,7 +314,10 @@ glnx_open_anonymous_tmpfile (int          flags,
                              GLnxTmpfile *out_tmpf,
                              GError     **error)
 {
-  return glnx_open_anonymous_tmpfile_full (flags, "/var/tmp", out_tmpf, error);
+  return glnx_open_anonymous_tmpfile_full (flags,
+                                           getenv("TMPDIR") ?: "/var/tmp",
+                                           out_tmpf,
+                                           error);
 }
 
 /* Use this after calling glnx_open_tmpfile_linkable_at() to give
@@ -826,7 +829,7 @@ glnx_regfile_copy_bytes (int fdf, int fdt, off_t max_bytes)
                   have_cfr = 0;
                   try_cfr = false;
                 }
-              else if (errno == EXDEV)
+              else if (G_IN_SET (errno, EXDEV, EOPNOTSUPP))
                 /* We won't try cfr again for this run, but let's be
                  * conservative and not mark it as available/unavailable until
                  * we know for sure.
@@ -997,8 +1000,11 @@ glnx_file_copy_at (int                   src_dfd,
   if (glnx_regfile_copy_bytes (src_fd, tmp_dest.fd, (off_t) -1) < 0)
     return glnx_throw_errno_prefix (error, "regfile copy");
 
-  if (fchown (tmp_dest.fd, src_stbuf->st_uid, src_stbuf->st_gid) != 0)
-    return glnx_throw_errno_prefix (error, "fchown");
+  if (!(copyflags & GLNX_FILE_COPY_NOCHOWN))
+    {
+      if (fchown (tmp_dest.fd, src_stbuf->st_uid, src_stbuf->st_gid) != 0)
+        return glnx_throw_errno_prefix (error, "fchown");
+    }
 
   if (!(copyflags & GLNX_FILE_COPY_NOXATTRS))
     {
@@ -1102,6 +1108,11 @@ glnx_file_replace_contents_with_perms_at (int                   dfd,
 {
   char *dnbuf = strdupa (subpath);
   const char *dn = dirname (dnbuf);
+  gboolean increasing_mtime = (flags & GLNX_FILE_REPLACE_INCREASING_MTIME) != 0;
+  gboolean nodatasync = (flags & GLNX_FILE_REPLACE_NODATASYNC) != 0;
+  gboolean datasync_new = (flags & GLNX_FILE_REPLACE_DATASYNC_NEW) != 0;
+  struct stat stbuf;
+  gboolean has_stbuf = FALSE;
 
   dfd = glnx_dirfd_canonicalize (dfd);
 
@@ -1125,34 +1136,55 @@ glnx_file_replace_contents_with_perms_at (int                   dfd,
   if (glnx_loop_write (tmpf.fd, buf, len) < 0)
     return glnx_throw_errno_prefix (error, "write");
 
-  if (!(flags & GLNX_FILE_REPLACE_NODATASYNC))
+  if (!nodatasync || increasing_mtime)
     {
-      struct stat stbuf;
-      gboolean do_sync;
-
       if (!glnx_fstatat_allow_noent (dfd, subpath, &stbuf, AT_SYMLINK_NOFOLLOW, error))
         return FALSE;
-      if (errno == ENOENT)
-        do_sync = (flags & GLNX_FILE_REPLACE_DATASYNC_NEW) > 0;
+      has_stbuf = errno != ENOENT;
+    }
+
+  if (!nodatasync)
+    {
+      gboolean do_sync;
+      if (!has_stbuf)
+        do_sync = datasync_new;
       else
         do_sync = TRUE;
 
       if (do_sync)
         {
-          if (fdatasync (tmpf.fd) != 0)
+          if (TEMP_FAILURE_RETRY (fdatasync (tmpf.fd)) != 0)
             return glnx_throw_errno_prefix (error, "fdatasync");
         }
     }
 
   if (uid != (uid_t) -1)
     {
-      if (fchown (tmpf.fd, uid, gid) != 0)
+      if (TEMP_FAILURE_RETRY (fchown (tmpf.fd, uid, gid)) != 0)
         return glnx_throw_errno_prefix (error, "fchown");
     }
 
-  if (fchmod (tmpf.fd, mode) != 0)
+  if (TEMP_FAILURE_RETRY (fchmod (tmpf.fd, mode)) != 0)
     return glnx_throw_errno_prefix (error, "fchmod");
 
+  if (increasing_mtime && has_stbuf)
+    {
+      struct stat fd_stbuf;
+
+      if (fstat (tmpf.fd, &fd_stbuf) != 0)
+        return glnx_throw_errno_prefix (error, "fstat");
+
+      /* We want to ensure that the new file has a st_mtime (i.e. the second precision)
+       * is incrementing to avoid mtime check issues when files change often.
+       */
+      if (fd_stbuf.st_mtime <= stbuf.st_mtime)
+        {
+          struct timespec ts[2] = { {0, UTIME_OMIT}, {stbuf.st_mtime + 1, 0} };
+          if (TEMP_FAILURE_RETRY (futimens (tmpf.fd, ts)) != 0)
+            return glnx_throw_errno_prefix (error, "futimens");
+        }
+    }
+
   if (!glnx_link_tmpfile_at (&tmpf, GLNX_LINK_TMPFILE_REPLACE,
                              dfd, subpath, error))
     return FALSE;
diff --git a/subprojects/libglnx/glnx-fdio.h b/subprojects/libglnx/glnx-fdio.h
index f95e473f8cfdc65e37a1262e3d69761095597725..3d1f024cc744b55ecab9fa6edba0fa497c4e6bcf 100644
--- a/subprojects/libglnx/glnx-fdio.h
+++ b/subprojects/libglnx/glnx-fdio.h
@@ -43,7 +43,7 @@ G_BEGIN_DECLS
 static inline
 const char *glnx_basename (const char *path)
 {
-  gchar *base = strrchr (path, G_DIR_SEPARATOR);
+  const gchar *base = strrchr (path, G_DIR_SEPARATOR);
 
   if (base)
     return base + 1;
@@ -55,7 +55,7 @@ const char *glnx_basename (const char *path)
 static inline void
 glnx_stdio_file_cleanup (void *filep)
 {
-  FILE *f = filep;
+  FILE *f = (FILE*)filep;
   if (f)
     fclose (f);
 }
@@ -143,12 +143,14 @@ glnx_file_get_contents_utf8_at (int                   dfd,
  * GLnxFileReplaceFlags:
  * @GLNX_FILE_REPLACE_DATASYNC_NEW: Call fdatasync() even if the file did not exist
  * @GLNX_FILE_REPLACE_NODATASYNC: Never call fdatasync()
+ * @GLNX_FILE_REPLACE_INCREASING_MTIME: Ensure that st_mtime increases (in second precision)
  *
  * Flags controlling file replacement.
  */
 typedef enum {
   GLNX_FILE_REPLACE_DATASYNC_NEW = (1 << 0),
   GLNX_FILE_REPLACE_NODATASYNC = (1 << 1),
+  GLNX_FILE_REPLACE_INCREASING_MTIME = (1 << 2),
 } GLnxFileReplaceFlags;
 
 gboolean
@@ -187,7 +189,8 @@ glnx_regfile_copy_bytes (int fdf, int fdt, off_t max_bytes);
 typedef enum {
   GLNX_FILE_COPY_OVERWRITE = (1 << 0),
   GLNX_FILE_COPY_NOXATTRS = (1 << 1),
-  GLNX_FILE_COPY_DATASYNC = (1 << 2)
+  GLNX_FILE_COPY_DATASYNC = (1 << 2),
+  GLNX_FILE_COPY_NOCHOWN = (1 << 3)
 } GLnxFileCopyFlags;
 
 gboolean
diff --git a/subprojects/libglnx/glnx-macros.h b/subprojects/libglnx/glnx-macros.h
index 700fc75ceed0ab1248a95e4fe03abb8b8bc6c6e9..3177bb6658dad6559b0e48950d85d677430ca19d 100644
--- a/subprojects/libglnx/glnx-macros.h
+++ b/subprojects/libglnx/glnx-macros.h
@@ -52,7 +52,7 @@ G_BEGIN_DECLS
                 unsigned _i_;                                           \
                 for (_i_ = 0; _i_ < G_N_ELEMENTS(_appendees_) && _appendees_[_i_]; _i_++) \
                         _len_ += strlen(_appendees_[_i_]);              \
-                _p_ = _d_ = alloca(_len_ + 1);                          \
+                _p_ = _d_ = (char*) alloca(_len_ + 1);                          \
                 for (_i_ = 0; _i_ < G_N_ELEMENTS(_appendees_) && _appendees_[_i_]; _i_++) \
                         _p_ = stpcpy(_p_, _appendees_[_i_]);            \
                 *_p_ = 0;                                               \
@@ -136,7 +136,7 @@ G_BEGIN_DECLS
          guard && ({ g_hash_table_iter_init (&it, ht), TRUE; });               \
          guard = FALSE)                                                        \
             for (kt k; guard; guard = FALSE)                                   \
-                for (vt v; g_hash_table_iter_next (&it, (gpointer)&k, (gpointer)&v);)
+                for (vt v; g_hash_table_iter_next (&it, (void**)&k, (void**)&v);)
 
 
 /* Cleaner method to iterate over a GHashTable. I.e. rather than
diff --git a/subprojects/libglnx/glnx-xattrs.c b/subprojects/libglnx/glnx-xattrs.c
index 79a14cd372e29b79644abc773baf8234711d1b62..892d5343e882fee166aa7fab84626f5a079f5c03 100644
--- a/subprojects/libglnx/glnx-xattrs.c
+++ b/subprojects/libglnx/glnx-xattrs.c
@@ -283,7 +283,7 @@ set_all_xattrs_for_path (const char    *path,
       const guint8* value_data = g_variant_get_fixed_array (value, &value_len, 1);
 
       if (lsetxattr (path, (char*)name, (char*)value_data, value_len, 0) < 0)
-        return glnx_throw_errno_prefix (error, "lsetxattr");
+        return glnx_throw_errno_prefix (error, "lsetxattr(%s)", name);
     }
 
   return TRUE;
@@ -351,7 +351,7 @@ glnx_fd_set_all_xattrs (int            fd,
       const guint8* value_data = g_variant_get_fixed_array (value, &value_len, 1);
 
       if (TEMP_FAILURE_RETRY (fsetxattr (fd, (char*)name, (char*)value_data, value_len, 0)) < 0)
-        return glnx_throw_errno_prefix (error, "fsetxattr");
+        return glnx_throw_errno_prefix (error, "Setting xattrs: fsetxattr(%s)", name);
     }
 
   return TRUE;
@@ -378,11 +378,11 @@ glnx_lgetxattrat (int            dfd,
 
   ssize_t bytes_read, real_size;
   if (TEMP_FAILURE_RETRY (bytes_read = lgetxattr (pathbuf, attribute, NULL, 0)) < 0)
-    return glnx_null_throw_errno_prefix (error, "lgetxattr");
+    return glnx_null_throw_errno_prefix (error, "lgetxattr(%s)", attribute);
 
   g_autofree guint8 *buf = g_malloc (bytes_read);
   if (TEMP_FAILURE_RETRY (real_size = lgetxattr (pathbuf, attribute, buf, bytes_read)) < 0)
-    return glnx_null_throw_errno_prefix (error, "lgetxattr");
+    return glnx_null_throw_errno_prefix (error, "lgetxattr(%s)", attribute);
 
   return g_bytes_new_take (g_steal_pointer (&buf), real_size);
 }
@@ -403,11 +403,11 @@ glnx_fgetxattr_bytes (int            fd,
   ssize_t bytes_read, real_size;
 
   if (TEMP_FAILURE_RETRY (bytes_read = fgetxattr (fd, attribute, NULL, 0)) < 0)
-    return glnx_null_throw_errno_prefix (error, "fgetxattr");
+    return glnx_null_throw_errno_prefix (error, "fgetxattr(%s)", attribute);
 
   g_autofree guint8 *buf = g_malloc (bytes_read);
   if (TEMP_FAILURE_RETRY (real_size = fgetxattr (fd, attribute, buf, bytes_read)) < 0)
-    return glnx_null_throw_errno_prefix (error, "fgetxattr");
+    return glnx_null_throw_errno_prefix (error, "fgetxattr(%s)", attribute);
 
   return g_bytes_new_take (g_steal_pointer (&buf), real_size);
 }
@@ -437,7 +437,7 @@ glnx_lsetxattrat (int            dfd,
   snprintf (pathbuf, sizeof (pathbuf), "/proc/self/fd/%d/%s", dfd, subpath);
 
   if (TEMP_FAILURE_RETRY (lsetxattr (subpath, attribute, value, len, flags)) < 0)
-    return glnx_throw_errno_prefix (error, "lsetxattr");
+    return glnx_throw_errno_prefix (error, "lsetxattr(%s)", attribute);
 
   return TRUE;
 }
diff --git a/subprojects/libglnx/libglnx.m4 b/subprojects/libglnx/libglnx.m4
index 5922805bc7a014812d3da44c8d5b9f3b76a5eb59..5a72e98bd077b7255c62e2a7a9ffd16744d17e6b 100644
--- a/subprojects/libglnx/libglnx.m4
+++ b/subprojects/libglnx/libglnx.m4
@@ -25,10 +25,10 @@ AS_IF([test $enable_otmpfile = yes], [], [
 
 AC_ARG_ENABLE(wrpseudo-compat,
               [AS_HELP_STRING([--enable-wrpseudo-compat],
-                              [Disable use syscall() and filesystem calls to for compatibility with wrpseudo [default=no]])],,
+                              [Disable use of syscall() in some cases for compatibility with pseudo [default=no]])],,
               [enable_wrpseudo_compat=no])
 AS_IF([test $enable_wrpseudo_compat = no], [], [
-  AC_DEFINE([ENABLE_WRPSEUDO_COMPAT], 1, [Define if we should be compatible with wrpseudo])])
+  AC_DEFINE([ENABLE_WRPSEUDO_COMPAT], 1, [Define if we should be compatible with pseudo])])
 
 dnl end LIBGLNX_CONFIGURE
 ])