namei: move cross-device check to __traverse_mounts

This is preparation to RESOLVE_NO_XDEV fix in following commits.
Also this commit makes LOOKUP_NO_XDEV logic more clear: now we
immediately fail with EXDEV on first mount crossing
instead of waiting for very end.

No functional change intended

Signed-off-by: Askar Safin <safinaskar@zohomail.com>
Link: https://lore.kernel.org/20250825181233.2464822-4-safinaskar@zohomail.com
Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
Askar Safin 2025-08-25 18:12:32 +00:00 committed by Christian Brauner
parent 8b966d00b3
commit 8ded1fde08
No known key found for this signature in database
GPG Key ID: 91C61BC06578DCA2

View File

@ -1489,6 +1489,10 @@ static int __traverse_mounts(struct path *path, unsigned flags, bool *jumped,
// here we know it's positive
flags = path->dentry->d_flags;
need_mntput = true;
if (unlikely(lookup_flags & LOOKUP_NO_XDEV)) {
ret = -EXDEV;
break;
}
continue;
}
}
@ -1518,7 +1522,6 @@ static inline int traverse_mounts(struct path *path, bool *jumped,
int *count, unsigned lookup_flags)
{
unsigned flags = smp_load_acquire(&path->dentry->d_flags);
int ret;
/* fastpath */
if (likely(!(flags & DCACHE_MANAGED_DENTRY))) {
@ -1527,11 +1530,7 @@ static inline int traverse_mounts(struct path *path, bool *jumped,
return -ENOENT;
return 0;
}
ret = __traverse_mounts(path, flags, jumped, count, lookup_flags);
if (*jumped && unlikely(lookup_flags & LOOKUP_NO_XDEV))
return -EXDEV;
return ret;
return __traverse_mounts(path, flags, jumped, count, lookup_flags);
}
int follow_down_one(struct path *path)