]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
dirent-util: use statx() in readdir_ensure_type()
authorLennart Poettering <lennart@poettering.net>
Thu, 7 Oct 2021 20:55:20 +0000 (22:55 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 7 Oct 2021 21:13:40 +0000 (23:13 +0200)
Let's ask exactly for the one field we actually want to know, i.e.
STATX_TYPE.

(While we are at it, also copy over the inode number, if we have it,
simply to report the most recent info we have)

(Also, see AT_NO_AUTOMOUNT, so that we don't trigger automounts here.
After all, if we want to know the inode type of a dirent here, then
there's not need to trigger the automount, the inode type is not going
to change by that.)

src/basic/dirent-util.c

index 366cc077f3e4a4be4ead7b1fc3ff9f098327acde..ee2aff0f4d0bae3f06f1087932edc1280121c5e1 100644 (file)
@@ -5,10 +5,12 @@
 
 #include "dirent-util.h"
 #include "path-util.h"
+#include "stat-util.h"
 #include "string-util.h"
 
 static int dirent_ensure_type(DIR *d, struct dirent *de) {
-        struct stat st;
+        STRUCT_STATX_DEFINE(sx);
+        int r;
 
         assert(d);
         assert(de);
@@ -21,10 +23,17 @@ static int dirent_ensure_type(DIR *d, struct dirent *de) {
                 return 0;
         }
 
-        if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
-                return -errno;
+        /* Let's ask only for the type, nothing else. */
+        r = statx_fallback(dirfd(d), de->d_name, AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, STATX_TYPE, &sx);
+        if (r < 0)
+                return r;
 
-        de->d_type = IFTODT(st.st_mode);
+        assert(FLAGS_SET(sx.stx_mask, STATX_TYPE));
+        de->d_type = IFTODT(sx.stx_mode);
+
+        /* If the inode is passed too, update the field, i.e. report most recent data */
+        if (FLAGS_SET(sx.stx_mask, STATX_INO))
+                de->d_ino = sx.stx_ino;
 
         return 0;
 }