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.)
This commit is contained in:
Lennart Poettering
2021-10-07 22:55:20 +02:00
parent ba24ef86e7
commit 3214129369

View 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;
}