mountpoint-util: port to xstatx(), support XAT_FDROOT
This commit is contained in:
+32
-48
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user