]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
stat-util: add helper stat_inode_same() for comparing stat's st_dev/st_ino in one
authorLennart Poettering <lennart@poettering.net>
Mon, 14 Feb 2022 16:18:32 +0000 (17:18 +0100)
committerLennart Poettering <lennart@poettering.net>
Mon, 14 Feb 2022 16:27:09 +0000 (17:27 +0100)
We do this all over the place, hence let's add a simple helper that does
this and particularly carefully and thoroughly.

src/basic/stat-util.c
src/basic/stat-util.h

index c2269844f816dd7c871a91cc70ffaa4c91ca614b..298f46440fab540fc42a86787459fc366efe42a6 100644 (file)
@@ -417,6 +417,18 @@ int proc_mounted(void) {
         return r;
 }
 
+bool stat_inode_same(const struct stat *a, const struct stat *b) {
+
+        /* Returns if the specified stat structure references the same (though possibly modified) inode. Does
+         * a thorough check, comparing inode nr, backing device and if the inode is still of the same type. */
+
+        return a && b &&
+                (a->st_mode & S_IFMT) != 0 && /* We use the check for .st_mode if the structure was ever initialized */
+                ((a->st_mode ^ b->st_mode) & S_IFMT) == 0 &&  /* same inode type */
+                a->st_dev == b->st_dev &&
+                a->st_ino == b->st_ino;
+}
+
 bool stat_inode_unmodified(const struct stat *a, const struct stat *b) {
 
         /* Returns if the specified stat structures reference the same, unmodified inode. This check tries to
@@ -428,14 +440,10 @@ bool stat_inode_unmodified(const struct stat *a, const struct stat *b) {
          * about contents of the file. The purpose here is to detect file contents changes, and nothing
          * else. */
 
-        return a && b &&
-                (a->st_mode & S_IFMT) != 0 && /* We use the check for .st_mode if the structure was ever initialized */
-                ((a->st_mode ^ b->st_mode) & S_IFMT) == 0 &&  /* same inode type */
+        return stat_inode_same(a, b) &&
                 a->st_mtim.tv_sec == b->st_mtim.tv_sec &&
                 a->st_mtim.tv_nsec == b->st_mtim.tv_nsec &&
                 (!S_ISREG(a->st_mode) || a->st_size == b->st_size) && /* if regular file, compare file size */
-                a->st_dev == b->st_dev &&
-                a->st_ino == b->st_ino &&
                 (!(S_ISCHR(a->st_mode) || S_ISBLK(a->st_mode)) || a->st_rdev == b->st_rdev); /* if device node, also compare major/minor, because we can */
 }
 
index f7d2f12aa9dcb7642b5b9b1e8ce45263cd8d131e..5f4741cf647637f1daf040b6dc9dd2827a75c2c2 100644 (file)
@@ -92,6 +92,7 @@ int device_path_parse_major_minor(const char *path, mode_t *ret_mode, dev_t *ret
 
 int proc_mounted(void);
 
+bool stat_inode_same(const struct stat *a, const struct stat *b);
 bool stat_inode_unmodified(const struct stat *a, const struct stat *b);
 
 int statx_fallback(int dfd, const char *path, int flags, unsigned mask, struct statx *sx);