From: Mike Yuan Date: Thu, 29 Jan 2026 09:48:43 +0000 (+0100) Subject: various: use xstatx() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=10072d8be44a3687221adc042cf9b9b45b4c9689;p=thirdparty%2Fsystemd.git various: use xstatx() --- diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c index 197d015f37e..99eff99874d 100644 --- a/src/basic/fd-util.c +++ b/src/basic/fd-util.c @@ -1077,30 +1077,23 @@ int path_is_root_at(int dir_fd, const char *path) { } int fds_are_same_mount(int fd1, int fd2) { - struct statx sx1 = {}, sx2 = {}; /* explicitly initialize the struct to make msan silent. */ + struct statx sx1, sx2; + int r; assert(fd1 >= 0 || IN_SET(fd1, AT_FDCWD, XAT_FDROOT)); assert(fd2 >= 0 || IN_SET(fd2, AT_FDCWD, XAT_FDROOT)); - const char *fn1; - if (fd1 == XAT_FDROOT) { - fd1 = AT_FDCWD; - fn1 = "/"; - } else - fn1 = ""; - - if (statx(fd1, fn1, AT_EMPTY_PATH, STATX_TYPE|STATX_INO|STATX_MNT_ID, &sx1) < 0) - return -errno; - - const char *fn2; - if (fd2 == XAT_FDROOT) { - fd2 = AT_FDCWD; - fn2 = "/"; - } else - fn2 = ""; + r = xstatx(fd1, /* path = */ NULL, AT_EMPTY_PATH, + STATX_TYPE|STATX_INO|STATX_MNT_ID, + &sx1); + if (r < 0) + return r; - if (statx(fd2, fn2, AT_EMPTY_PATH, STATX_TYPE|STATX_INO|STATX_MNT_ID, &sx2) < 0) - return -errno; + r = xstatx(fd2, /* path = */ NULL, AT_EMPTY_PATH, + STATX_TYPE|STATX_INO|STATX_MNT_ID, + &sx2); + if (r < 0) + return r; return statx_inode_same(&sx1, &sx2) && statx_mount_same(&sx1, &sx2); } diff --git a/src/basic/xattr-util.c b/src/basic/xattr-util.c index 2d0577979e2..68ee83d899e 100644 --- a/src/basic/xattr-util.c +++ b/src/basic/xattr-util.c @@ -419,9 +419,6 @@ int getcrtime_at( assert(fd >= 0 || fd == AT_FDCWD); assert((at_flags & ~(AT_SYMLINK_FOLLOW|AT_EMPTY_PATH)) == 0); - if (isempty(path)) - at_flags |= AT_EMPTY_PATH; - /* So here's the deal: the creation/birth time (crtime/btime) of a file is a relatively newly supported concept * on Linux (or more strictly speaking: a concept that only recently got supported in the API, it was * implemented on various file systems on the lower level since a while, but never was accessible). However, we @@ -432,11 +429,13 @@ int getcrtime_at( * concept is useful for determining how "old" a file really is, and hence using the older of the two makes * most sense. */ - if (statx(fd, strempty(path), - at_flags_normalize_nofollow(at_flags)|AT_STATX_DONT_SYNC, - STATX_BTIME, - &sx) >= 0 && - FLAGS_SET(sx.stx_mask, STATX_BTIME) && sx.stx_btime.tv_sec != 0) + r = xstatx_full(fd, path, + at_flags_normalize_nofollow(at_flags)|AT_STATX_DONT_SYNC, + /* mandatory_mask = */ 0, + STATX_BTIME, + /* mandatory_attributes = */ 0, + &sx); + if (r > 0 && sx.stx_btime.tv_sec != 0) /* > 0: all optional masks are supported */ a = statx_timestamp_load(&sx.stx_btime); else a = USEC_INFINITY; diff --git a/src/shared/find-esp.c b/src/shared/find-esp.c index f2df84cd48e..3ba9b8a4b60 100644 --- a/src/shared/find-esp.c +++ b/src/shared/find-esp.c @@ -285,20 +285,20 @@ static int verify_fsroot_dir( if (r < 0 && r != -EADDRNOTAVAIL) return log_error_errno(r, "Failed to extract filename of \"%s\": %m", path); - if (statx(dir_fd, strempty(f), - AT_SYMLINK_NOFOLLOW|(isempty(f) ? AT_EMPTY_PATH : 0), - STATX_TYPE|STATX_INO, &sx) < 0) - return log_full_errno((searching && errno == ENOENT) || - (unprivileged_mode && ERRNO_IS_PRIVILEGE(errno)) ? LOG_DEBUG : LOG_ERR, errno, + r = xstatx_full(dir_fd, f, + AT_SYMLINK_NOFOLLOW, + STATX_TYPE|STATX_INO, + /* optional_mask = */ 0, + STATX_ATTR_MOUNT_ROOT, + &sx); + if (r < 0) + return log_full_errno((searching && r == -ENOENT) || + (unprivileged_mode && ERRNO_IS_NEG_PRIVILEGE(r)) ? LOG_DEBUG : LOG_ERR, r, "Failed to determine block device node of \"%s\": %m", path); if (!S_ISDIR(sx.stx_mode)) return log_error_errno(SYNTHETIC_ERRNO(ENOTDIR), "Path \"%s\" is not a directory", path); - r = statx_warn_mount_root(&sx, LOG_ERR); - if (r < 0) - return r; - if (!FLAGS_SET(sx.stx_attributes, STATX_ATTR_MOUNT_ROOT)) return log_full_errno(searching ? LOG_DEBUG : LOG_ERR, SYNTHETIC_ERRNO(searching ? EADDRNOTAVAIL : ENODEV), diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index a2ab8ded9bd..59adcc61cac 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -586,12 +586,13 @@ static int opendir_and_stat( return 0; } - if (statx(dirfd(d), "", AT_EMPTY_PATH, STATX_MODE|STATX_INO|STATX_ATIME|STATX_MTIME, &sx) < 0) - return log_error_errno(errno, "statx(%s) failed: %m", path); - - r = statx_warn_mount_root(&sx, LOG_ERR); + r = xstatx_full(dirfd(d), /* path = */ NULL, AT_EMPTY_PATH, + STATX_MODE|STATX_INO|STATX_ATIME|STATX_MTIME, + /* optional_mask = */ 0, + STATX_ATTR_MOUNT_ROOT, + &sx); if (r < 0) - return r; + return log_error_errno(r, "statx(%s) failed: %m", path); *ret_mountpoint = FLAGS_SET(sx.stx_attributes, STATX_ATTR_MOUNT_ROOT); *ret = TAKE_PTR(d); @@ -683,35 +684,22 @@ static int dir_cleanup( if (dot_or_dot_dot(de->d_name)) continue; - /* If statx() is supported, use it. It's preferable over fstatat() since it tells us - * explicitly where we are looking at a mount point, for free as side information. Determining - * the same information without statx() is hard, see the complexity of path_is_mount_point(), - * and also much slower as it requires a number of syscalls instead of just one. Hence, when - * we have modern statx() we use it instead of fstat() and do proper mount point checks, - * while on older kernels's well do traditional st_dev based detection of mount points. - * - * Using statx() for detecting mount points also has the benefit that we handle weird file - * systems such as overlayfs better where each file is originating from a different - * st_dev. */ - struct statx sx; - if (statx(dirfd(d), de->d_name, - AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, - STATX_TYPE|STATX_MODE|STATX_UID|STATX_ATIME|STATX_MTIME|STATX_CTIME|STATX_BTIME, - &sx) < 0) { - if (errno == ENOENT) - continue; - + r = xstatx_full(dirfd(d), de->d_name, + AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, + STATX_TYPE|STATX_MODE|STATX_UID, + STATX_ATIME|STATX_MTIME|STATX_CTIME|STATX_BTIME, + STATX_ATTR_MOUNT_ROOT, + &sx); + if (r == -ENOENT) + continue; + if (r < 0) { /* FUSE, NFS mounts, SELinux might return EACCES */ - log_full_errno(errno == EACCES ? LOG_DEBUG : LOG_ERR, errno, + log_full_errno(r == -EACCES ? LOG_DEBUG : LOG_ERR, r, "statx(%s/%s) failed: %m", p, de->d_name); continue; } - r = statx_warn_mount_root(&sx, LOG_ERR); - if (r < 0) - return r; - if (FLAGS_SET(sx.stx_attributes, STATX_ATTR_MOUNT_ROOT)) { log_debug("Ignoring \"%s/%s\": different mount points.", p, de->d_name); continue;