]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
various: use xstatx()
authorMike Yuan <me@yhndnzj.com>
Thu, 29 Jan 2026 09:48:43 +0000 (10:48 +0100)
committerMike Yuan <me@yhndnzj.com>
Thu, 5 Feb 2026 13:14:40 +0000 (14:14 +0100)
src/basic/fd-util.c
src/basic/xattr-util.c
src/shared/find-esp.c
src/tmpfiles/tmpfiles.c

index 197d015f37ead5f100ae4f4c60c77178a89d4755..99eff99874d14316ec5b04529927b604f29e4b9d 100644 (file)
@@ -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);
 }
index 2d0577979e217c97d648b965b9babc897d802de4..68ee83d899edef88fe1bf2d2d842d1003adf366c 100644 (file)
@@ -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;
index f2df84cd48e6ab2677827d48ae15a54edcfdb05d..3ba9b8a4b601b722483bf90652962f84952425a4 100644 (file)
@@ -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),
index a2ab8ded9bd8501b257710689ffdf8dbecf70964..59adcc61cac4f3c30b17fcc85bd05ea11cc27918 100644 (file)
@@ -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;