From: Mike Yuan Date: Thu, 29 Jan 2026 09:20:00 +0000 (+0100) Subject: mountpoint-util: port to xstatx(), support XAT_FDROOT X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=56adac11935455e00a3127cf0d7676bae7bcc9fe;p=thirdparty%2Fsystemd.git mountpoint-util: port to xstatx(), support XAT_FDROOT --- diff --git a/src/basic/mountpoint-util.c b/src/basic/mountpoint-util.c index d8f57c6b7ae..1f90217dc43 100644 --- a/src/basic/mountpoint-util.c +++ b/src/basic/mountpoint-util.c @@ -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;