mountpoint-util: port to xstatx(), support XAT_FDROOT

This commit is contained in:
Mike Yuan
2026-02-05 14:14:39 +01:00
parent 1cf84c5642
commit 56adac1193
+32 -48
View 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 = "";
}
}
if (dir_fd == XAT_FDROOT && isempty(path))
return true;
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;
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;
int path_get_mnt_id_at(int dir_fd, const char *path, int *ret) {
uint64_t mnt_id;
int r;
assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
assert(ret);
r = path_get_mnt_id_at_internal(dir_fd, path, /* unique = */ false, &mnt_id);
if (r < 0)
return r;
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;
if (!FLAGS_SET(sx.stx_mask, STATX_MNT_ID_UNIQUE))
return -EOPNOTSUPP;
*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;