]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
macro: add READ_NOW() macro for force reading of memory, making a copy
authorLennart Poettering <lennart@poettering.net>
Thu, 23 Apr 2020 08:42:01 +0000 (10:42 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 23 Apr 2020 10:11:24 +0000 (12:11 +0200)
When accessing journal files we generally are fine when values change
beneath our feet, while we are looking at them, as long as they change
from something valid to zero. This is required since we nowadays
forcibly unallocate journal files on vacuuming, to ensure they are
actually released.

However, we need to make sure that the validity checks we enforce are
done on suitable copies of the fields in the file. Thus provide a macro
that forces a copy, and disallows the compiler from merging our copy
with the actually memory where it is from.

src/basic/macro.h

index 79530132e3018b1dd3d2e58615aacebe85178c11..6ee22868337744b29d1a418703012c8296813843 100644 (file)
@@ -585,4 +585,17 @@ static inline int __coverity_check_and_return__(int condition) {
         DEFINE_PUBLIC_TRIVIAL_REF_FUNC(type, name);                    \
         DEFINE_PUBLIC_TRIVIAL_UNREF_FUNC(type, name, free_func);
 
+/* A macro to force copying of a variable from memory. This is useful whenever we want to read something from
+ * memory and want to make sure the compiler won't optimize away the destination variable for us. It's not
+ * supposed to be a full CPU memory barrier, i.e. CPU is still allowed to reorder the reads, but it is not
+ * allowed to remove our local copies of the variables. We want this to work for unaligned memory, hence
+ * memcpy() is great for our purposes. */
+#define READ_NOW(x)                                                     \
+        ({                                                              \
+                typeof(x) _copy;                                        \
+                memcpy(&_copy, &(x), sizeof(_copy));                    \
+                asm volatile ("" : : : "memory");                       \
+                _copy;                                                  \
+        })
+
 #include "log.h"