From: Lennart Poettering Date: Thu, 7 Oct 2021 20:55:20 +0000 (+0200) Subject: dirent-util: use statx() in readdir_ensure_type() X-Git-Tag: v250-rc1~547^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3214129369a0daa6558565a93aa17eb8ada69bc3;p=thirdparty%2Fsystemd.git dirent-util: use statx() in readdir_ensure_type() 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.) --- diff --git a/src/basic/dirent-util.c b/src/basic/dirent-util.c index 366cc077f3e..ee2aff0f4d0 100644 --- a/src/basic/dirent-util.c +++ b/src/basic/dirent-util.c @@ -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; }