]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
mountpoint-util: port to xstatx(), support XAT_FDROOT
authorMike Yuan <me@yhndnzj.com>
Thu, 29 Jan 2026 09:20:00 +0000 (10:20 +0100)
committerMike Yuan <me@yhndnzj.com>
Thu, 5 Feb 2026 13:14:39 +0000 (14:14 +0100)
src/basic/mountpoint-util.c

index d8f57c6b7ae041c65a84d0db925d2e57d89682e7..1f90217dc43708cf17d4a4a7a6dff168511622d3 100644 (file)
@@ -246,31 +246,24 @@ struct file_handle* file_handle_dup(const struct file_handle *fh) {
 int is_mount_point_at(int dir_fd, const char *path, int flags) {
         int r;
 
-        assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
+        assert(dir_fd >= 0 || IN_SET(dir_fd, AT_FDCWD, XAT_FDROOT));
         assert((flags & ~AT_SYMLINK_FOLLOW) == 0);
 
         if (path_equal(path, "/"))
                 return true;
 
-        if (isempty(path)) {
-                if (dir_fd == AT_FDCWD)
-                        path = ".";
-                else {
-                        flags |= AT_EMPTY_PATH;
-                        path = "";
-                }
-        }
-
-        struct statx sx = {}; /* explicitly initialize the struct to make msan silent. */
-        if (statx(dir_fd, path,
-                  at_flags_normalize_nofollow(flags) |
-                  AT_NO_AUTOMOUNT |            /* don't trigger automounts – mounts are a local concept, hence no need to trigger automounts to determine STATX_ATTR_MOUNT_ROOT */
-                  AT_STATX_DONT_SYNC,          /* don't go to the network for this – for similar reasons */
-                  STATX_TYPE|STATX_INO,
-                  &sx) < 0)
-                return -errno;
+        if (dir_fd == XAT_FDROOT && isempty(path))
+                return true;
 
-        r = statx_warn_mount_root(&sx, LOG_DEBUG);
+        struct statx sx;
+        r = xstatx_full(dir_fd, path,
+                        at_flags_normalize_nofollow(flags) |
+                        AT_NO_AUTOMOUNT |            /* don't trigger automounts – mounts are a local concept, hence no need to trigger automounts to determine STATX_ATTR_MOUNT_ROOT */
+                        AT_STATX_DONT_SYNC,          /* don't go to the network for this – for similar reasons */
+                        STATX_TYPE|STATX_INO,
+                        /* optional_mask = */ 0,
+                        STATX_ATTR_MOUNT_ROOT,
+                        &sx);
         if (r < 0)
                 return r;
 
@@ -307,23 +300,19 @@ int path_is_mount_point_full(const char *path, const char *root, int flags) {
         return is_mount_point_at(dir_fd, /* path= */ NULL, flags);
 }
 
-int path_get_mnt_id_at(int dir_fd, const char *path, int *ret) {
+static int path_get_mnt_id_at_internal(int dir_fd, const char *path, bool unique, uint64_t *ret) {
         struct statx sx;
         int r;
 
-        assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
+        assert(dir_fd >= 0 || IN_SET(dir_fd, AT_FDCWD, XAT_FDROOT));
         assert(ret);
 
-        if (statx(dir_fd,
-                  strempty(path),
-                  (isempty(path) ? AT_EMPTY_PATH : AT_SYMLINK_NOFOLLOW) |
-                  AT_NO_AUTOMOUNT |    /* don't trigger automounts, mnt_id is a local concept */
-                  AT_STATX_DONT_SYNC,  /* don't go to the network, mnt_id is a local concept */
-                  STATX_MNT_ID,
-                  &sx) < 0)
-                return -errno;
-
-        r = statx_warn_mount_id(&sx, LOG_DEBUG);
+        r = xstatx(dir_fd, path,
+                   AT_SYMLINK_NOFOLLOW |
+                   AT_NO_AUTOMOUNT |    /* don't trigger automounts, mnt_id is a local concept */
+                   AT_STATX_DONT_SYNC,  /* don't go to the network, mnt_id is a local concept */
+                   unique ? STATX_MNT_ID_UNIQUE : STATX_MNT_ID,
+                   &sx);
         if (r < 0)
                 return r;
 
@@ -331,28 +320,23 @@ int path_get_mnt_id_at(int dir_fd, const char *path, int *ret) {
         return 0;
 }
 
-int path_get_unique_mnt_id_at(int dir_fd, const char *path, uint64_t *ret) {
-        struct statx sx;
-
-        assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
-        assert(ret);
-
-        if (statx(dir_fd,
-                  strempty(path),
-                  (isempty(path) ? AT_EMPTY_PATH : AT_SYMLINK_NOFOLLOW) |
-                  AT_NO_AUTOMOUNT |    /* don't trigger automounts, mnt_id is a local concept */
-                  AT_STATX_DONT_SYNC,  /* don't go to the network, mnt_id is a local concept */
-                  STATX_MNT_ID_UNIQUE,
-                  &sx) < 0)
-                return -errno;
+int path_get_mnt_id_at(int dir_fd, const char *path, int *ret) {
+        uint64_t mnt_id;
+        int r;
 
-        if (!FLAGS_SET(sx.stx_mask, STATX_MNT_ID_UNIQUE))
-                return -EOPNOTSUPP;
+        r = path_get_mnt_id_at_internal(dir_fd, path, /* unique = */ false, &mnt_id);
+        if (r < 0)
+                return r;
 
-        *ret = sx.stx_mnt_id;
+        assert(mnt_id <= INT_MAX);
+        *ret = (int) mnt_id;
         return 0;
 }
 
+int path_get_unique_mnt_id_at(int dir_fd, const char *path, uint64_t *ret) {
+        return path_get_mnt_id_at_internal(dir_fd, path, /* unique = */ true, ret);
+}
+
 bool fstype_is_network(const char *fstype) {
         const char *x;