diff options
author | Lennart Poettering <lennart@poettering.net> | 2021-03-23 22:26:06 +0100 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2021-05-07 11:56:48 +0200 |
commit | 41b24382e7849758e456eef50bbf740a1f097c6e (patch) | |
tree | 1e6c203e816a17df8a2d90a2b35b286c688d5528 | |
parent | 491107a044bdfeb5877c413d0f5421bb7afde158 (diff) | |
download | systemd-41b24382e7849758e456eef50bbf740a1f097c6e.tar.gz |
mountpoint-util: a symlink is never a mount point
The various flavours of stat() basically tell us for free if something
is a symlink. If it is, then it's definitely not a mount point. Use
that.
All other inode types can be mount point, just symlinks cannot.
(cherry picked from commit b898474fecda9e39aa06512ef7ba358c9685d84e)
-rw-r--r-- | src/basic/mountpoint-util.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/src/basic/mountpoint-util.c b/src/basic/mountpoint-util.c index c8f6675eb8..6d47419194 100644 --- a/src/basic/mountpoint-util.c +++ b/src/basic/mountpoint-util.c @@ -196,13 +196,15 @@ int fd_is_mount_point(int fd, const char *filename, int flags) { if (statx(fd, filename, (FLAGS_SET(flags, AT_SYMLINK_FOLLOW) ? 0 : AT_SYMLINK_NOFOLLOW) | (flags & AT_EMPTY_PATH) | - AT_NO_AUTOMOUNT, 0, &sx) < 0) { + AT_NO_AUTOMOUNT, STATX_TYPE, &sx) < 0) { if (!ERRNO_IS_NOT_SUPPORTED(errno) && !ERRNO_IS_PRIVILEGE(errno)) return -errno; /* If statx() is not available or forbidden, fall back to name_to_handle_at() below */ } else if (FLAGS_SET(sx.stx_attributes_mask, STATX_ATTR_MOUNT_ROOT)) /* yay! */ return FLAGS_SET(sx.stx_attributes, STATX_ATTR_MOUNT_ROOT); + else if (FLAGS_SET(sx.stx_mask, STATX_TYPE) && S_ISLNK(sx.stx_mode)) + 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)) @@ -280,6 +282,8 @@ fallback_fstat: flags |= AT_SYMLINK_NOFOLLOW; if (fstatat(fd, filename, &a, flags) < 0) return -errno; + if (S_ISLNK(a.st_mode)) /* Symlinks are never mount points */ + return false; if (fstatat(fd, "", &b, AT_EMPTY_PATH) < 0) return -errno; |