Projects
Mega:23.03
systemd
_service:tar_scm:backport-mount-util-fix-fd_is_...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm:backport-mount-util-fix-fd_is_mount_point-when-both-the-paren.patch of Package systemd
From 8de173ff933510200ac3db77f1ae713f2c4acdc3 Mon Sep 17 00:00:00 2001 From: Franck Bui <fbui@suse.com> Date: Thu, 30 Sep 2021 14:05:36 +0200 Subject: [PATCH] mount-util: fix fd_is_mount_point() when both the parent and directory are network fs The second call to name_to_handle_at_loop() didn't check for the specific errors that can happen when the parent dir is mounted by nfs and instead of falling back like it's done for the child dir, fd_is_mount_point() failed in this case. (cherry picked from commit 964ccab8286a7e75d7e9107f574f5cb23752bd5d) Conflict:NA Reference:https://github.com/systemd/systemd/commit/8de173ff933510200ac3db77f1ae713f2c4acdc3 --- src/basic/mountpoint-util.c | 68 ++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 27 deletions(-) diff --git a/src/basic/mountpoint-util.c b/src/basic/mountpoint-util.c index 8c836a1b74..e7a5a99551 100644 --- a/src/basic/mountpoint-util.c +++ b/src/basic/mountpoint-util.c @@ -157,6 +157,19 @@ static bool filename_possibly_with_slash_suffix(const char *s) { return filename_is_valid(copied); } +static bool is_name_to_handle_at_fatal_error(int err) { + /* name_to_handle_at() can return "acceptable" errors that are due to the context. For + * example the kernel does not support name_to_handle_at() at all (ENOSYS), or the syscall + * was blocked (EACCES/EPERM; maybe through seccomp, because we are running inside of a + * container), or the mount point is not triggered yet (EOVERFLOW, think nfs4), or some + * general name_to_handle_at() flakiness (EINVAL). However other errors are not supposed to + * happen and therefore are considered fatal ones. */ + + assert(err < 0); + + return !IN_SET(err, -EOPNOTSUPP, -ENOSYS, -EACCES, -EPERM, -EOVERFLOW, -EINVAL); +} + int fd_is_mount_point(int fd, const char *filename, int flags) { _cleanup_free_ struct file_handle *h = NULL, *h_parent = NULL; int mount_id = -1, mount_id_parent = -1; @@ -206,39 +219,40 @@ int fd_is_mount_point(int fd, const char *filename, int flags) { return false; /* symlinks are never mount points */ r = name_to_handle_at_loop(fd, filename, &h, &mount_id, flags); - if (IN_SET(r, -ENOSYS, -EACCES, -EPERM, -EOVERFLOW, -EINVAL)) - /* This kernel does not support name_to_handle_at() at all (ENOSYS), or the syscall was blocked - * (EACCES/EPERM; maybe through seccomp, because we are running inside of a container?), or the mount - * point is not triggered yet (EOVERFLOW, think nfs4), or some general name_to_handle_at() flakiness - * (EINVAL): fall back to simpler logic. */ - goto fallback_fdinfo; - else if (r == -EOPNOTSUPP) - /* This kernel or file system does not support name_to_handle_at(), hence let's see if the upper fs - * supports it (in which case it is a mount point), otherwise fall back to the traditional stat() - * logic */ + if (r < 0) { + if (is_name_to_handle_at_fatal_error(r)) + return r; + if (r != -EOPNOTSUPP) + goto fallback_fdinfo; + + /* This kernel or file system does not support name_to_handle_at(), hence let's see + * if the upper fs supports it (in which case it is a mount point), otherwise fall + * back to the traditional stat() logic */ nosupp = true; - else if (r < 0) - return r; + } r = name_to_handle_at_loop(fd, "", &h_parent, &mount_id_parent, AT_EMPTY_PATH); - if (r == -EOPNOTSUPP) { + if (r < 0) { + if (is_name_to_handle_at_fatal_error(r)) + return r; + if (r != -EOPNOTSUPP) + goto fallback_fdinfo; if (nosupp) - /* Neither parent nor child do name_to_handle_at()? We have no choice but to fall back. */ + /* Both the parent and the directory can't do name_to_handle_at() */ goto fallback_fdinfo; - else - /* The parent can't do name_to_handle_at() but the directory we are interested in can? If so, - * it must be a mount point. */ - return 1; - } else if (r < 0) - return r; - /* The parent can do name_to_handle_at() but the directory we are interested in can't? If so, it must - * be a mount point. */ + /* The parent can't do name_to_handle_at() but the directory we are + * interested in can? If so, it must be a mount point. */ + return 1; + } + + /* The parent can do name_to_handle_at() but the directory we are interested in can't? If + * so, it must be a mount point. */ if (nosupp) return 1; - /* If the file handle for the directory we are interested in and its parent are identical, we assume - * this is the root directory, which is a mount point. */ + /* If the file handle for the directory we are interested in and its parent are identical, + * we assume this is the root directory, which is a mount point. */ if (h->handle_bytes == h_parent->handle_bytes && h->handle_type == h_parent->handle_type && @@ -338,10 +352,10 @@ int path_get_mnt_id(const char *path, int *ret) { } r = name_to_handle_at_loop(AT_FDCWD, path, NULL, ret, 0); - if (IN_SET(r, -EOPNOTSUPP, -ENOSYS, -EACCES, -EPERM, -EOVERFLOW, -EINVAL)) /* kernel/fs don't support this, or seccomp blocks access, or untriggered mount, or name_to_handle_at() is flaky */ - return fd_fdinfo_mnt_id(AT_FDCWD, path, 0, ret); + if (r == 0 || is_name_to_handle_at_fatal_error(r)) + return r; - return r; + return fd_fdinfo_mnt_id(AT_FDCWD, path, 0, ret); } bool fstype_is_network(const char *fstype) { -- 2.33.0
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2