stat-util: teach statx_mount_same() STATX_MNT_ID_UNIQUE
So far statx_mount_same() assumed STATX_MNT_ID_UNIQUE didn't exist. However it does exist, hence do something useful if we see it set. Note that this creates a certain ambiguity: if we compare one statx struct with STATX_MNT_ID_UNIQUE and one without it (but with the regular mnt id), then we cnanot really come to a clear conclusion, hence need to introduce a third, unknown state. Note that we don't request STATX_MNT_ID_UNIQUE yet wherever we call statx_mount_same(). THis will be added in a later commit.
This commit is contained in:
+14
-5
@@ -379,11 +379,20 @@ int chaseat(int dir_fd, const char *path, ChaseFlags flags, char **ret_path, int
|
||||
* root tree we operate in is allowed, where an inode is moved up the tree while we
|
||||
* look at it, and thus get the current path wrong and think we are deeper down than
|
||||
* we actually are. */
|
||||
if (FLAGS_SET(flags, CHASE_AT_RESOLVE_IN_ROOT) &&
|
||||
(empty_or_root(done) || (statx_inode_same(&stx, &root_stx) && statx_mount_same(&stx, &root_stx)))) {
|
||||
if (FLAGS_SET(flags, CHASE_STEP))
|
||||
goto chased_one;
|
||||
continue;
|
||||
if (FLAGS_SET(flags, CHASE_AT_RESOLVE_IN_ROOT)) {
|
||||
bool is_root = empty_or_root(done);
|
||||
if (!is_root && statx_inode_same(&stx, &root_stx)) {
|
||||
r = statx_mount_same(&stx, &root_stx);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
is_root = r > 0;
|
||||
}
|
||||
if (is_root) {
|
||||
if (FLAGS_SET(flags, CHASE_STEP))
|
||||
goto chased_one;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
fd_parent = openat(fd, "..", O_CLOEXEC|O_NOFOLLOW|O_PATH|O_DIRECTORY);
|
||||
|
||||
+5
-1
@@ -1094,7 +1094,11 @@ int fds_inode_and_mount_same(int fd1, int fd2) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return statx_inode_same(&sx1, &sx2) && statx_mount_same(&sx1, &sx2);
|
||||
r = statx_mount_same(&sx1, &sx2);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
return statx_inode_same(&sx1, &sx2);
|
||||
}
|
||||
|
||||
int resolve_xat_fdroot(int *fd, const char **path, char **ret_buffer) {
|
||||
|
||||
@@ -675,14 +675,15 @@ bool statx_inode_same(const struct statx *a, const struct statx *b) {
|
||||
a->stx_ino == b->stx_ino;
|
||||
}
|
||||
|
||||
bool statx_mount_same(const struct statx *a, const struct statx *b) {
|
||||
int statx_mount_same(const struct statx *a, const struct statx *b) {
|
||||
if (!statx_is_set(a) || !statx_is_set(b))
|
||||
return false;
|
||||
|
||||
assert(FLAGS_SET(a->stx_mask, STATX_MNT_ID));
|
||||
assert(FLAGS_SET(b->stx_mask, STATX_MNT_ID));
|
||||
if ((FLAGS_SET(a->stx_mask, STATX_MNT_ID) && FLAGS_SET(b->stx_mask, STATX_MNT_ID)) ||
|
||||
(FLAGS_SET(a->stx_mask, STATX_MNT_ID_UNIQUE) && FLAGS_SET(b->stx_mask, STATX_MNT_ID_UNIQUE)))
|
||||
return a->stx_mnt_id == b->stx_mnt_id;
|
||||
|
||||
return a->stx_mnt_id == b->stx_mnt_id;
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
usec_t statx_timestamp_load(const struct statx_timestamp *ts) {
|
||||
|
||||
@@ -110,7 +110,7 @@ bool stat_inode_same(const struct stat *a, const struct stat *b);
|
||||
bool stat_inode_unmodified(const struct stat *a, const struct stat *b);
|
||||
|
||||
bool statx_inode_same(const struct statx *a, const struct statx *b);
|
||||
bool statx_mount_same(const struct statx *a, const struct statx *b);
|
||||
int statx_mount_same(const struct statx *a, const struct statx *b);
|
||||
|
||||
int xstatfsat(int dir_fd, const char *path, struct statfs *ret);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user